From 5be4a9cc2c8c0c8be66a926975acc3950cb6ef38 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 7 Jul 2021 23:20:11 +0530 Subject: [PATCH 001/311] remove all files --- .eslintrc.js | 18 - .prettierrc.js | 7 - src/Binary/Constants.ts | 205 ----- src/Binary/Decoder.ts | 227 ------ src/Binary/Encoder.ts | 139 ---- src/{Binary => BinaryNode}/GenerateStatics.sh | 0 src/{Binary => BinaryNode}/WAMessage.proto | 0 src/BinaryNode/decode.ts | 204 +++++ src/BinaryNode/encode.ts | 124 +++ src/BinaryNode/index.ts | 8 + src/BinaryNode/types.ts | 212 ++++++ src/Connection/auth.ts | 260 +++++++ src/Connection/chats.ts | 6 + src/Connection/socket.ts | 362 +++++++++ src/Defaults/index.ts | 29 + src/Tests/Common.ts | 2 +- src/Tests/Tests.Messages.ts | 2 +- src/Tests/test.binary.ts | 95 +++ src/Tests/test.connect.ts | 200 +++++ src/Tests/test.queries.ts | 165 ++++ src/Types/Auth.ts | 22 + src/Types/Chat.ts | 44 ++ src/Types/Contact.ts | 15 + src/Types/GroupMetadata.ts | 19 + src/Types/Store.ts | 25 + src/Types/index.ts | 147 ++++ src/Utils/decodeWAMessage.ts | 63 ++ src/Utils/generics.ts | 148 ++++ src/Utils/validateConnection.ts | 106 +++ src/WAConnection/0.Base.ts | 478 ------------ src/WAConnection/1.Validation.ts | 224 ------ src/WAConnection/3.Connect.ts | 196 ----- src/WAConnection/4.Events.ts | 717 ------------------ src/WAConnection/5.User.ts | 255 ------- src/WAConnection/6.MessagesSend.ts | 437 ----------- src/WAConnection/7.MessagesExtra.ts | 481 ------------ src/WAConnection/8.Groups.ts | 202 ----- src/WAConnection/Constants.ts | 506 ------------ src/WAConnection/Mutex.ts | 24 - src/WAConnection/Utils.ts | 469 ------------ src/WAConnection/index.ts | 4 - 41 files changed, 2256 insertions(+), 4591 deletions(-) delete mode 100644 .eslintrc.js delete mode 100644 .prettierrc.js delete mode 100644 src/Binary/Constants.ts delete mode 100644 src/Binary/Decoder.ts delete mode 100644 src/Binary/Encoder.ts rename src/{Binary => BinaryNode}/GenerateStatics.sh (100%) rename src/{Binary => BinaryNode}/WAMessage.proto (100%) create mode 100644 src/BinaryNode/decode.ts create mode 100644 src/BinaryNode/encode.ts create mode 100644 src/BinaryNode/index.ts create mode 100644 src/BinaryNode/types.ts create mode 100644 src/Connection/auth.ts create mode 100644 src/Connection/chats.ts create mode 100644 src/Connection/socket.ts create mode 100644 src/Defaults/index.ts create mode 100644 src/Tests/test.binary.ts create mode 100644 src/Tests/test.connect.ts create mode 100644 src/Tests/test.queries.ts create mode 100644 src/Types/Auth.ts create mode 100644 src/Types/Chat.ts create mode 100644 src/Types/Contact.ts create mode 100644 src/Types/GroupMetadata.ts create mode 100644 src/Types/Store.ts create mode 100644 src/Types/index.ts create mode 100644 src/Utils/decodeWAMessage.ts create mode 100644 src/Utils/generics.ts create mode 100644 src/Utils/validateConnection.ts delete mode 100644 src/WAConnection/0.Base.ts delete mode 100644 src/WAConnection/1.Validation.ts delete mode 100644 src/WAConnection/3.Connect.ts delete mode 100644 src/WAConnection/4.Events.ts delete mode 100644 src/WAConnection/5.User.ts delete mode 100644 src/WAConnection/6.MessagesSend.ts delete mode 100644 src/WAConnection/7.MessagesExtra.ts delete mode 100644 src/WAConnection/8.Groups.ts delete mode 100644 src/WAConnection/Constants.ts delete mode 100644 src/WAConnection/Mutex.ts delete mode 100644 src/WAConnection/Utils.ts delete mode 100644 src/WAConnection/index.ts diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 10a24e6..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - parser: "@typescript-eslint/parser", // Specifies the ESLint parser - parserOptions: { - ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features - sourceType: "module" // Allows for the use of imports - }, - extends: [ - "plugin:@typescript-eslint/recommended", // Uses the recommended rules from the @typescript-eslint/eslint-plugin - "prettier/@typescript-eslint", // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier - "plugin:prettier/recommended" // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array. - ], - rules: { - // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs - // e.g. "@typescript-eslint/explicit-function-return-type": "off", - "@typescript-eslint/no-namespace": "off", - "@typescript-eslint/ban-types": "off" - } -} \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index d1ca80a..0000000 --- a/.prettierrc.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - semi: false, - trailingComma: "all", - singleQuote: true, - printWidth: 120, - tabWidth: 4 -} \ No newline at end of file diff --git a/src/Binary/Constants.ts b/src/Binary/Constants.ts deleted file mode 100644 index d26fd00..0000000 --- a/src/Binary/Constants.ts +++ /dev/null @@ -1,205 +0,0 @@ -import {proto} from '../../WAMessage/WAMessage' - -export namespace WA { - export const Tags = { - LIST_EMPTY: 0, - STREAM_END: 2, - DICTIONARY_0: 236, - DICTIONARY_1: 237, - DICTIONARY_2: 238, - DICTIONARY_3: 239, - LIST_8: 248, - LIST_16: 249, - JID_PAIR: 250, - HEX_8: 251, - BINARY_8: 252, - BINARY_20: 253, - BINARY_32: 254, - NIBBLE_8: 255, - SINGLE_BYTE_MAX: 256, - PACKED_MAX: 254, - } - export const DoubleByteTokens = [] - export const SingleByteTokens = [ - null, - null, - null, - '200', - '400', - '404', - '500', - '501', - '502', - 'action', - 'add', - 'after', - 'archive', - 'author', - 'available', - 'battery', - 'before', - 'body', - 'broadcast', - 'chat', - 'clear', - 'code', - 'composing', - 'contacts', - 'count', - 'create', - 'debug', - 'delete', - 'demote', - 'duplicate', - 'encoding', - 'error', - 'false', - 'filehash', - 'from', - 'g.us', - 'group', - 'groups_v2', - 'height', - 'id', - 'image', - 'in', - 'index', - 'invis', - 'item', - 'jid', - 'kind', - 'last', - 'leave', - 'live', - 'log', - 'media', - 'message', - 'mimetype', - 'missing', - 'modify', - 'name', - 'notification', - 'notify', - 'out', - 'owner', - 'participant', - 'paused', - 'picture', - 'played', - 'presence', - 'preview', - 'promote', - 'query', - 'raw', - 'read', - 'receipt', - 'received', - 'recipient', - 'recording', - 'relay', - 'remove', - 'response', - 'resume', - 'retry', - 's.whatsapp.net', - 'seconds', - 'set', - 'size', - 'status', - 'subject', - 'subscribe', - 't', - 'text', - 'to', - 'true', - 'type', - 'unarchive', - 'unavailable', - 'url', - 'user', - 'value', - 'web', - 'width', - 'mute', - 'read_only', - 'admin', - 'creator', - 'short', - 'update', - 'powersave', - 'checksum', - 'epoch', - 'block', - 'previous', - '409', - 'replaced', - 'reason', - 'spam', - 'modify_tag', - 'message_info', - 'delivery', - 'emoji', - 'title', - 'description', - 'canonical-url', - 'matched-text', - 'star', - 'unstar', - 'media_key', - 'filename', - 'identity', - 'unread', - 'page', - 'page_count', - 'search', - 'media_message', - 'security', - 'call_log', - 'profile', - 'ciphertext', - 'invite', - 'gif', - 'vcard', - 'frequent', - 'privacy', - 'blacklist', - 'whitelist', - 'verify', - 'location', - 'document', - 'elapsed', - 'revoke_invite', - 'expiration', - 'unsubscribe', - 'disable', - 'vname', - 'old_jid', - 'new_jid', - 'announcement', - 'locked', - 'prop', - 'label', - 'color', - 'call', - 'offer', - 'call-id', - 'quick_reply', - 'sticker', - 'pay_t', - 'accept', - 'reject', - 'sticker_pack', - 'invalid', - 'canceled', - 'missed', - 'connected', - 'result', - 'audio', - 'video', - 'recent', - ] - export const Message = proto.WebMessageInfo - export type NodeAttributes = { [key: string]: string } | string | null - export type NodeData = Array | any | null - export type Node = [string, NodeAttributes, NodeData] -} diff --git a/src/Binary/Decoder.ts b/src/Binary/Decoder.ts deleted file mode 100644 index 57a83db..0000000 --- a/src/Binary/Decoder.ts +++ /dev/null @@ -1,227 +0,0 @@ -import { WA } from './Constants' - -export default class Decoder { - buffer: Buffer = null - index = 0 - - checkEOS(length: number) { - if (this.index + length > this.buffer.length) { - throw new Error('end of stream') - } - } - next() { - const value = this.buffer[this.index] - this.index += 1 - return value - } - readByte() { - this.checkEOS(1) - return this.next() - } - readStringFromChars(length: number) { - this.checkEOS(length) - const value = this.buffer.slice(this.index, this.index + length) - - this.index += length - return value.toString ('utf-8') - } - readBytes(n: number): Buffer { - this.checkEOS(n) - const value = this.buffer.slice(this.index, this.index + n) - this.index += n - return value - } - readInt(n: number, littleEndian = false) { - this.checkEOS(n) - let val = 0 - for (let i = 0; i < n; i++) { - const shift = littleEndian ? i : n - 1 - i - val |= this.next() << (shift * 8) - } - return val - } - readInt20() { - this.checkEOS(3) - return ((this.next() & 15) << 16) + (this.next() << 8) + this.next() - } - unpackHex(value: number) { - if (value >= 0 && value < 16) { - return value < 10 ? '0'.charCodeAt(0) + value : 'A'.charCodeAt(0) + value - 10 - } - throw new Error('invalid hex: ' + value) - } - unpackNibble(value: number) { - if (value >= 0 && value <= 9) { - return '0'.charCodeAt(0) + value - } - switch (value) { - case 10: - return '-'.charCodeAt(0) - case 11: - return '.'.charCodeAt(0) - case 15: - return '\0'.charCodeAt(0) - default: - throw new Error('invalid nibble: ' + value) - } - } - unpackByte(tag: number, value: number) { - if (tag === WA.Tags.NIBBLE_8) { - return this.unpackNibble(value) - } else if (tag === WA.Tags.HEX_8) { - return this.unpackHex(value) - } else { - throw new Error('unknown tag: ' + tag) - } - } - readPacked8(tag: number) { - const startByte = this.readByte() - let value = '' - - for (let i = 0; i < (startByte & 127); i++) { - const curByte = this.readByte() - value += String.fromCharCode(this.unpackByte(tag, (curByte & 0xf0) >> 4)) - value += String.fromCharCode(this.unpackByte(tag, curByte & 0x0f)) - } - if (startByte >> 7 !== 0) { - value = value.slice(0, -1) - } - return value - } - readRangedVarInt(min, max, description = 'unknown') { - // value = - throw new Error('WTF; should not be called') - } - isListTag(tag: number) { - return tag === WA.Tags.LIST_EMPTY || tag === WA.Tags.LIST_8 || tag === WA.Tags.LIST_16 - } - readListSize(tag: number) { - switch (tag) { - case WA.Tags.LIST_EMPTY: - return 0 - case WA.Tags.LIST_8: - return this.readByte() - case WA.Tags.LIST_16: - return this.readInt(2) - default: - throw new Error('invalid tag for list size: ' + tag) - } - } - - readString(tag: number): string { - if (tag >= 3 && tag <= 235) { - const token = this.getToken(tag) - return token// === 's.whatsapp.net' ? 'c.us' : token - } - - switch (tag) { - case WA.Tags.DICTIONARY_0: - case WA.Tags.DICTIONARY_1: - case WA.Tags.DICTIONARY_2: - case WA.Tags.DICTIONARY_3: - return this.getTokenDouble(tag - WA.Tags.DICTIONARY_0, this.readByte()) - case WA.Tags.LIST_EMPTY: - return null - case WA.Tags.BINARY_8: - return this.readStringFromChars(this.readByte()) - case WA.Tags.BINARY_20: - return this.readStringFromChars(this.readInt20()) - case WA.Tags.BINARY_32: - return this.readStringFromChars(this.readInt(4)) - case WA.Tags.JID_PAIR: - const i = this.readString(this.readByte()) - const j = this.readString(this.readByte()) - if (typeof i === 'string' && j) { - return i + '@' + j - } - throw new Error('invalid jid pair: ' + i + ', ' + j) - case WA.Tags.HEX_8: - case WA.Tags.NIBBLE_8: - return this.readPacked8(tag) - default: - throw new Error('invalid string with tag: ' + tag) - } - } - readAttributes(n: number) { - if (n !== 0) { - const attributes: WA.NodeAttributes = {} - for (let i = 0; i < n; i++) { - const key = this.readString(this.readByte()) - const b = this.readByte() - - attributes[key] = this.readString(b) - } - return attributes - } - return null - } - readList(tag: number) { - const arr = [...new Array(this.readListSize(tag))] - return arr.map(() => this.readNode()) - } - getToken(index: number) { - if (index < 3 || index >= WA.SingleByteTokens.length) { - throw new Error('invalid token index: ' + index) - } - return WA.SingleByteTokens[index] - } - getTokenDouble(index1, index2): string { - const n = 256 * index1 + index2 - if (n < 0 || n > WA.DoubleByteTokens.length) { - throw new Error('invalid double token index: ' + n) - } - return WA.DoubleByteTokens[n] - } - readNode(): WA.Node { - const listSize = this.readListSize(this.readByte()) - const descrTag = this.readByte() - if (descrTag === WA.Tags.STREAM_END) { - throw new Error('unexpected stream end') - } - - const descr = this.readString(descrTag) - if (listSize === 0 || !descr) { - throw new Error('invalid node') - } - - const attrs = this.readAttributes((listSize - 1) >> 1) - let content: WA.NodeData = null - - if (listSize % 2 === 0) { - const tag = this.readByte() - if (this.isListTag(tag)) { - content = this.readList(tag) - } else { - let decoded: Buffer | string - switch (tag) { - case WA.Tags.BINARY_8: - decoded = this.readBytes(this.readByte()) - break - case WA.Tags.BINARY_20: - decoded = this.readBytes(this.readInt20()) - break - case WA.Tags.BINARY_32: - decoded = this.readBytes(this.readInt(4)) - break - default: - decoded = this.readString(tag) - break - } - - if (descr === 'message' && Buffer.isBuffer(decoded)) { - content = WA.Message.decode(decoded) - } else { - content = decoded - } - } - } - - return [descr, attrs, content] - } - - read(buffer: Buffer) { - this.buffer = buffer - this.index = 0 - return this.readNode() - } -} diff --git a/src/Binary/Encoder.ts b/src/Binary/Encoder.ts deleted file mode 100644 index 63331e9..0000000 --- a/src/Binary/Encoder.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { Message } from 'protobufjs' -import { WA } from './Constants' - -export default class Encoder { - data: number[] = [] - - pushByte(value: number) { - this.data.push(value & 0xff) - } - pushInt(value: number, n: number, littleEndian=false) { - for (let i = 0; i < n; i++) { - const curShift = littleEndian ? i : n - 1 - i - this.data.push((value >> (curShift * 8)) & 0xff) - } - } - pushInt20(value: number) { - this.pushBytes([(value >> 16) & 0x0f, (value >> 8) & 0xff, value & 0xff]) - } - pushBytes(bytes: Uint8Array | Buffer | number[]) { - bytes.forEach (b => this.data.push(b)) - } - writeByteLength(length: number) { - if (length >= 4294967296) throw new Error('string too large to encode: ' + length) - - if (length >= 1 << 20) { - this.pushByte(WA.Tags.BINARY_32) - this.pushInt(length, 4) // 32 bit integer - } else if (length >= 256) { - this.pushByte(WA.Tags.BINARY_20) - this.pushInt20(length) - } else { - this.pushByte(WA.Tags.BINARY_8) - this.pushByte(length) - } - } - writeStringRaw(string: string) { - const bytes = Buffer.from (string, 'utf-8') - this.writeByteLength(bytes.length) - this.pushBytes(bytes) - } - writeJid(left: string, right: string) { - this.pushByte(WA.Tags.JID_PAIR) - left && left.length > 0 ? this.writeString(left) : this.writeToken(WA.Tags.LIST_EMPTY) - this.writeString(right) - } - writeToken(token: number) { - if (token < 245) { - this.pushByte(token) - } else if (token <= 500) { - throw new Error('invalid token') - } - } - writeString(token: string, i: boolean = null) { - if (token === 'c.us') token = 's.whatsapp.net' - - const tokenIndex = WA.SingleByteTokens.indexOf(token) - if (!i && token === 's.whatsapp.net') { - this.writeToken(tokenIndex) - } else if (tokenIndex >= 0) { - if (tokenIndex < WA.Tags.SINGLE_BYTE_MAX) { - this.writeToken(tokenIndex) - } else { - const overflow = tokenIndex - WA.Tags.SINGLE_BYTE_MAX - const dictionaryIndex = overflow >> 8 - if (dictionaryIndex < 0 || dictionaryIndex > 3) { - throw new Error('double byte dict token out of range: ' + token + ', ' + tokenIndex) - } - this.writeToken(WA.Tags.DICTIONARY_0 + dictionaryIndex) - this.writeToken(overflow % 256) - } - } else if (token) { - const jidSepIndex = token.indexOf('@') - if (jidSepIndex <= 0) { - this.writeStringRaw(token) - } else { - this.writeJid(token.slice(0, jidSepIndex), token.slice(jidSepIndex + 1, token.length)) - } - } - } - writeAttributes(attrs: Record | string, keys: string[]) { - if (!attrs) { - return - } - keys.forEach((key) => { - this.writeString(key) - this.writeString(attrs[key]) - }) - } - writeListStart(listSize: number) { - if (listSize === 0) { - this.pushByte(WA.Tags.LIST_EMPTY) - } else if (listSize < 256) { - this.pushBytes([WA.Tags.LIST_8, listSize]) - } else { - this.pushBytes([WA.Tags.LIST_16, listSize]) - } - } - writeChildren(children: string | Array | Buffer | Object) { - if (!children) return - - if (typeof children === 'string') { - this.writeString(children, true) - } else if (Buffer.isBuffer(children)) { - this.writeByteLength (children.length) - this.pushBytes(children) - } else if (Array.isArray(children)) { - this.writeListStart(children.length) - children.forEach(c => c && this.writeNode(c)) - } else if (typeof children === 'object') { - const buffer = WA.Message.encode(children as any).finish() - this.writeByteLength(buffer.length) - this.pushBytes(buffer) - } else { - throw new Error('invalid children: ' + children + ' (' + typeof children + ')') - } - } - getValidKeys(obj: Object) { - return obj ? Object.keys(obj).filter((key) => obj[key] !== null && obj[key] !== undefined) : [] - } - writeNode(node: WA.Node) { - if (!node) { - return - } else if (node.length !== 3) { - throw new Error('invalid node given: ' + node) - } - const validAttributes = this.getValidKeys(node[1]) - - this.writeListStart(2 * validAttributes.length + 1 + (node[2] ? 1 : 0)) - this.writeString(node[0]) - this.writeAttributes(node[1], validAttributes) - this.writeChildren(node[2]) - } - write(data) { - this.data = [] - this.writeNode(data) - - return Buffer.from(this.data) - } -} diff --git a/src/Binary/GenerateStatics.sh b/src/BinaryNode/GenerateStatics.sh similarity index 100% rename from src/Binary/GenerateStatics.sh rename to src/BinaryNode/GenerateStatics.sh diff --git a/src/Binary/WAMessage.proto b/src/BinaryNode/WAMessage.proto similarity index 100% rename from src/Binary/WAMessage.proto rename to src/BinaryNode/WAMessage.proto diff --git a/src/BinaryNode/decode.ts b/src/BinaryNode/decode.ts new file mode 100644 index 0000000..bed96f1 --- /dev/null +++ b/src/BinaryNode/decode.ts @@ -0,0 +1,204 @@ +import { proto } from '../../WAMessage/WAMessage' +import { BinaryNode, DoubleByteTokens, SingleByteTokens, Tags } from './types' + +function decode(buffer: Buffer, makeNode: () => T, indexRef: { index: number }) { + + const checkEOS = (length: number) => { + if (indexRef.index + length > buffer.length) { + throw new Error('end of stream') + } + } + const next = () => { + const value = buffer[indexRef.index] + indexRef.index += 1 + return value + } + const readByte = () => { + checkEOS(1) + return next() + } + const readStringFromChars = (length: number) => { + checkEOS(length) + const value = buffer.slice(indexRef.index, indexRef.index + length) + + indexRef.index += length + return value.toString('utf-8') + } + const readBytes = (n: number) => { + checkEOS(n) + const value = buffer.slice(indexRef.index, indexRef.index + n) + indexRef.index += n + return value + } + const readInt = (n: number, littleEndian = false) => { + checkEOS(n) + let val = 0 + for (let i = 0; i < n; i++) { + const shift = littleEndian ? i : n - 1 - i + val |= next() << (shift * 8) + } + return val + } + const readInt20 = () => { + checkEOS(3) + return ((next() & 15) << 16) + (next() << 8) + next() + } + const unpackHex = (value: number) => { + if (value >= 0 && value < 16) { + return value < 10 ? '0'.charCodeAt(0) + value : 'A'.charCodeAt(0) + value - 10 + } + throw new Error('invalid hex: ' + value) + } + const unpackNibble = (value: number) => { + if (value >= 0 && value <= 9) { + return '0'.charCodeAt(0) + value + } + switch (value) { + case 10: + return '-'.charCodeAt(0) + case 11: + return '.'.charCodeAt(0) + case 15: + return '\0'.charCodeAt(0) + default: + throw new Error('invalid nibble: ' + value) + } + } + const unpackByte = (tag: number, value: number) => { + if (tag === Tags.NIBBLE_8) { + return unpackNibble(value) + } else if (tag === Tags.HEX_8) { + return unpackHex(value) + } else { + throw new Error('unknown tag: ' + tag) + } + } + const readPacked8 = (tag: number) => { + const startByte = readByte() + let value = '' + + for (let i = 0; i < (startByte & 127); i++) { + const curByte = readByte() + value += String.fromCharCode(unpackByte(tag, (curByte & 0xf0) >> 4)) + value += String.fromCharCode(unpackByte(tag, curByte & 0x0f)) + } + if (startByte >> 7 !== 0) { + value = value.slice(0, -1) + } + return value + } + const isListTag = (tag: number) => { + return tag === Tags.LIST_EMPTY || tag === Tags.LIST_8 || tag === Tags.LIST_16 + } + const readListSize = (tag: number) => { + switch (tag) { + case Tags.LIST_EMPTY: + return 0 + case Tags.LIST_8: + return readByte() + case Tags.LIST_16: + return readInt(2) + default: + throw new Error('invalid tag for list size: ' + tag) + } + } + const getToken = (index: number) => { + if (index < 3 || index >= SingleByteTokens.length) { + throw new Error('invalid token index: ' + index) + } + return SingleByteTokens[index] + } + const readString = (tag: number) => { + if (tag >= 3 && tag <= 235) { + const token = getToken(tag) + return token// === 's.whatsapp.net' ? 'c.us' : token + } + + switch (tag) { + case Tags.DICTIONARY_0: + case Tags.DICTIONARY_1: + case Tags.DICTIONARY_2: + case Tags.DICTIONARY_3: + return getTokenDouble(tag - Tags.DICTIONARY_0, readByte()) + case Tags.LIST_EMPTY: + return null + case Tags.BINARY_8: + return readStringFromChars(readByte()) + case Tags.BINARY_20: + return readStringFromChars(readInt20()) + case Tags.BINARY_32: + return readStringFromChars(readInt(4)) + case Tags.JID_PAIR: + const i = readString(readByte()) + const j = readString(readByte()) + if (typeof i === 'string' && j) { + return i + '@' + j + } + throw new Error('invalid jid pair: ' + i + ', ' + j) + case Tags.HEX_8: + case Tags.NIBBLE_8: + return readPacked8(tag) + default: + throw new Error('invalid string with tag: ' + tag) + } + } + const readList = (tag: number) => ( + [...new Array(readListSize(tag))].map(() => decode(buffer, makeNode, indexRef)) + ) + const getTokenDouble = (index1: number, index2: number) => { + const n = 256 * index1 + index2 + if (n < 0 || n > DoubleByteTokens.length) { + throw new Error('invalid double token index: ' + n) + } + return DoubleByteTokens[n] + } + const node = makeNode() + const listSize = readListSize(readByte()) + const descrTag = readByte() + if (descrTag === Tags.STREAM_END) { + throw new Error('unexpected stream end') + } + node.header = readString(descrTag) + if (listSize === 0 || !node.header) { + throw new Error('invalid node') + } + // read the attributes in + const attributesLength = (listSize - 1) >> 1 + for (let i = 0; i < attributesLength; i++) { + const key = readString(readByte()) + const b = readByte() + + node.attributes[key] = readString(b) + } + + if (listSize % 2 === 0) { + const tag = readByte() + if (isListTag(tag)) { + node.data = readList(tag) + } else { + let decoded: Buffer | string + switch (tag) { + case Tags.BINARY_8: + decoded = readBytes(readByte()) + break + case Tags.BINARY_20: + decoded = readBytes(readInt20()) + break + case Tags.BINARY_32: + decoded = readBytes(readInt(4)) + break + default: + decoded = readString(tag) + break + } + + if (node.header === 'message' && Buffer.isBuffer(decoded)) { + node.data = proto.WebMessageInfo.decode(decoded) + } else { + node.data = decoded + } + } + } + return node +} +export default decode \ No newline at end of file diff --git a/src/BinaryNode/encode.ts b/src/BinaryNode/encode.ts new file mode 100644 index 0000000..b1e8f79 --- /dev/null +++ b/src/BinaryNode/encode.ts @@ -0,0 +1,124 @@ +import { proto } from "../../WAMessage/WAMessage"; +import { BinaryNode, SingleByteTokens, Tags } from "./types"; + +const encode = ({ header, attributes, data }: BinaryNode, buffer: number[] = []) => { + + const pushByte = (value: number) => buffer.push(value & 0xff) + + const pushInt = (value: number, n: number, littleEndian=false) => { + for (let i = 0; i < n; i++) { + const curShift = littleEndian ? i : n - 1 - i + buffer.push((value >> (curShift * 8)) & 0xff) + } + } + const pushBytes = (bytes: Uint8Array | Buffer | number[]) => ( + bytes.forEach (b => buffer.push(b)) + ) + const pushInt20 = (value: number) => ( + pushBytes([(value >> 16) & 0x0f, (value >> 8) & 0xff, value & 0xff]) + ) + const pushString = (str: string) => { + const bytes = Buffer.from (str, 'utf-8') + pushBytes(bytes) + } + const writeByteLength = (length: number) => { + if (length >= 4294967296) throw new Error('string too large to encode: ' + length) + + if (length >= 1 << 20) { + pushByte(Tags.BINARY_32) + pushInt(length, 4) // 32 bit integer + } else if (length >= 256) { + pushByte(Tags.BINARY_20) + pushInt20(length) + } else { + pushByte(Tags.BINARY_8) + pushByte(length) + } + } + const writeStringRaw = (string: string) => { + writeByteLength(string.length) + pushString(string) + } + const writeToken = (token: number) => { + if (token < 245) { + pushByte(token) + } else if (token <= 500) { + throw new Error('invalid token') + } + } + const writeString = (token: string, i?: boolean) => { + if (token === 'c.us') token = 's.whatsapp.net' + + const tokenIndex = SingleByteTokens.indexOf(token) + if (!i && token === 's.whatsapp.net') { + writeToken(tokenIndex) + } else if (tokenIndex >= 0) { + if (tokenIndex < Tags.SINGLE_BYTE_MAX) { + writeToken(tokenIndex) + } else { + const overflow = tokenIndex - Tags.SINGLE_BYTE_MAX + const dictionaryIndex = overflow >> 8 + if (dictionaryIndex < 0 || dictionaryIndex > 3) { + throw new Error('double byte dict token out of range: ' + token + ', ' + tokenIndex) + } + writeToken(Tags.DICTIONARY_0 + dictionaryIndex) + writeToken(overflow % 256) + } + } else if (token) { + const jidSepIndex = token.indexOf('@') + if (jidSepIndex <= 0) { + writeStringRaw(token) + } else { + writeJid(token.slice(0, jidSepIndex), token.slice(jidSepIndex + 1, token.length)) + } + } + } + const writeJid = (left: string, right: string) => { + pushByte(Tags.JID_PAIR) + left && left.length > 0 ? writeString(left) : writeToken(Tags.LIST_EMPTY) + writeString(right) + } + const writeListStart = (listSize: number) => { + if (listSize === 0) { + pushByte(Tags.LIST_EMPTY) + } else if (listSize < 256) { + pushBytes([Tags.LIST_8, listSize]) + } else { + pushBytes([Tags.LIST_16, listSize]) + } + } + const validAttributes = Object.keys(attributes).filter(k => ( + typeof attributes[k] !== 'undefined' && attributes[k] !== null + )) + + writeListStart(2*validAttributes.length + 1 + (typeof data !== 'undefined' && data !== null ? 1 : 0)) + writeString(header) + + validAttributes.forEach((key) => { + writeString(key) + writeString(attributes[key]) + }) + + if(data instanceof proto.WebMessageInfo && !Buffer.isBuffer(data)) { + data = Buffer.from(proto.WebMessageInfo.encode(data).finish()) + } + + if (typeof data === 'string') { + writeString(data, true) + } else if (Buffer.isBuffer(data)) { + writeByteLength(data.length) + pushBytes(data) + } else if (Array.isArray(data)) { + writeListStart(data.length) + for(const item of data) { + if(item) encode(item, buffer) + } + } else if(typeof data === 'undefined' || data === null) { + + } else { + throw new Error(`invalid children for header "${header}": ${data} (${typeof data})`) + } + + return Buffer.from(buffer) +} +export default encode \ No newline at end of file diff --git a/src/BinaryNode/index.ts b/src/BinaryNode/index.ts new file mode 100644 index 0000000..3eb830b --- /dev/null +++ b/src/BinaryNode/index.ts @@ -0,0 +1,8 @@ +import decode from './decode' +import encode from './encode' +import { BinaryNode as BinaryNodeType } from './types' + +export default class BinaryNode extends BinaryNodeType { + toBuffer = () => encode(this, []) + static from = (buffer: Buffer) => decode(buffer, () => new BinaryNode(), { index: 0 }) +} \ No newline at end of file diff --git a/src/BinaryNode/types.ts b/src/BinaryNode/types.ts new file mode 100644 index 0000000..9139342 --- /dev/null +++ b/src/BinaryNode/types.ts @@ -0,0 +1,212 @@ +import { proto } from "../../WAMessage/WAMessage" + +export type Attributes = { [key: string]: string } +export type BinaryNodeData = BinaryNode[] | string | Buffer | proto.IWebMessageInfo | undefined +export class BinaryNode { + header: string + attributes: Attributes = {} + data?: BinaryNodeData + + constructor(header?: string, attrs?: Attributes, data?: BinaryNodeData) { + this.header = header + this.attributes = attrs || {} + this.data = data + } +} +export const Tags = { + LIST_EMPTY: 0, + STREAM_END: 2, + DICTIONARY_0: 236, + DICTIONARY_1: 237, + DICTIONARY_2: 238, + DICTIONARY_3: 239, + LIST_8: 248, + LIST_16: 249, + JID_PAIR: 250, + HEX_8: 251, + BINARY_8: 252, + BINARY_20: 253, + BINARY_32: 254, + NIBBLE_8: 255, + SINGLE_BYTE_MAX: 256, + PACKED_MAX: 254, +} +export const DoubleByteTokens = [] +export const SingleByteTokens = [ + null, + null, + null, + '200', + '400', + '404', + '500', + '501', + '502', + 'action', + 'add', + 'after', + 'archive', + 'author', + 'available', + 'battery', + 'before', + 'body', + 'broadcast', + 'chat', + 'clear', + 'code', + 'composing', + 'contacts', + 'count', + 'create', + 'debug', + 'delete', + 'demote', + 'duplicate', + 'encoding', + 'error', + 'false', + 'filehash', + 'from', + 'g.us', + 'group', + 'groups_v2', + 'height', + 'id', + 'image', + 'in', + 'index', + 'invis', + 'item', + 'jid', + 'kind', + 'last', + 'leave', + 'live', + 'log', + 'media', + 'message', + 'mimetype', + 'missing', + 'modify', + 'name', + 'notification', + 'notify', + 'out', + 'owner', + 'participant', + 'paused', + 'picture', + 'played', + 'presence', + 'preview', + 'promote', + 'query', + 'raw', + 'read', + 'receipt', + 'received', + 'recipient', + 'recording', + 'relay', + 'remove', + 'response', + 'resume', + 'retry', + 's.whatsapp.net', + 'seconds', + 'set', + 'size', + 'status', + 'subject', + 'subscribe', + 't', + 'text', + 'to', + 'true', + 'type', + 'unarchive', + 'unavailable', + 'url', + 'user', + 'value', + 'web', + 'width', + 'mute', + 'read_only', + 'admin', + 'creator', + 'short', + 'update', + 'powersave', + 'checksum', + 'epoch', + 'block', + 'previous', + '409', + 'replaced', + 'reason', + 'spam', + 'modify_tag', + 'message_info', + 'delivery', + 'emoji', + 'title', + 'description', + 'canonical-url', + 'matched-text', + 'star', + 'unstar', + 'media_key', + 'filename', + 'identity', + 'unread', + 'page', + 'page_count', + 'search', + 'media_message', + 'security', + 'call_log', + 'profile', + 'ciphertext', + 'invite', + 'gif', + 'vcard', + 'frequent', + 'privacy', + 'blacklist', + 'whitelist', + 'verify', + 'location', + 'document', + 'elapsed', + 'revoke_invite', + 'expiration', + 'unsubscribe', + 'disable', + 'vname', + 'old_jid', + 'new_jid', + 'announcement', + 'locked', + 'prop', + 'label', + 'color', + 'call', + 'offer', + 'call-id', + 'quick_reply', + 'sticker', + 'pay_t', + 'accept', + 'reject', + 'sticker_pack', + 'invalid', + 'canceled', + 'missed', + 'connected', + 'result', + 'audio', + 'video', + 'recent', +] \ No newline at end of file diff --git a/src/Connection/auth.ts b/src/Connection/auth.ts new file mode 100644 index 0000000..398fdcd --- /dev/null +++ b/src/Connection/auth.ts @@ -0,0 +1,260 @@ +import Boom from "boom" +import EventEmitter from "events" +import * as Curve from 'curve25519-js' +import { BaileysEventEmitter, BaileysEventMap, SocketConfig, CurveKeyPair, WAInitResponse, ConnectionState } from "../Types" +import { makeSocket } from "./socket" +import { generateClientID, promiseTimeout } from "../Utils/generics" +import { normalizedAuthInfo, computeChallengeResponse, validateNewConnection } from "../Utils/validateConnection" +import { randomBytes } from "crypto" +import { AuthenticationCredentials } from "../Types" + +const makeAuthSocket = (config: SocketConfig) => { + const { + logger, + version, + browser, + connectTimeoutMs, + pendingRequestTimeoutMs, + maxQRCodes, + printQRInTerminal, + credentials: anyAuthInfo + } = config + const ev = new EventEmitter() as BaileysEventEmitter + + let authInfo = normalizedAuthInfo(anyAuthInfo) || + // generate client id if not there + { clientID: generateClientID() } as AuthenticationCredentials + + const state: ConnectionState = { + phoneConnected: false, + connection: 'connecting', + } + + const socket = makeSocket({ + ...config, + phoneConnectionChanged: phoneConnected => { + if(phoneConnected !== state.phoneConnected) { + updateState({ phoneConnected }) + } + } + }) + const { socketEvents } = socket + let curveKeys: CurveKeyPair + let initTimeout: NodeJS.Timeout + // add close listener + socketEvents.on('ws-close', (error: Boom | Error) => { + logger.info({ error }, 'Closed connection to WhatsApp') + initTimeout && clearTimeout(initTimeout) + // if no reconnects occur + // send close event + updateState({ + connection: 'close', + qr: undefined, + connectionTriesLeft: undefined, + lastDisconnect: { + error, + date: new Date() + } + }) + }) + /** Can you login to WA without scanning the QR */ + const canLogin = () => !!authInfo?.encKey && !!authInfo?.macKey + + const updateState = (update: Partial) => { + Object.assign(state, update) + ev.emit('connection.update', update) + } + + /** + * Logs you out from WA + * If connected, invalidates the credentials with the server + */ + const logout = async() => { + if(state.connection === 'open') { + await socket.sendMessage({ + json: ['admin', 'Conn', 'disconnect'], + tag: 'goodbye' + }) + } + // will call state update to close connection + socket?.end( + Boom.unauthorized('Logged Out') + ) + authInfo = undefined + } + /** Waits for the connection to WA to open up */ + const waitForConnection = async(waitInfinitely: boolean = false) => { + if(state.connection === 'open') return + + let listener: (item: BaileysEventMap['connection.update']) => void + const timeout = waitInfinitely ? undefined : pendingRequestTimeoutMs + if(timeout < 0) { + throw Boom.preconditionRequired('Connection Closed') + } + + await ( + promiseTimeout( + timeout, + (resolve, reject) => { + listener = ({ connection, lastDisconnect }) => { + if(connection === 'open') resolve() + else if(connection == 'close') { + reject(lastDisconnect.error || Boom.preconditionRequired('Connection Closed')) + } + } + ev.on('connection.update', listener) + } + ) + .finally(() => ( + ev.off('state.update', listener) + )) + ) + } + + const generateKeysForAuth = async(ref: string, ttl?: number) => { + curveKeys = Curve.generateKeyPair(randomBytes(32)) + const publicKey = Buffer.from(curveKeys.public).toString('base64') + let qrGens = 0 + + const qrLoop = ttl => { + const qr = [ref, publicKey, authInfo.clientID].join(',') + updateState({ qr }) + + initTimeout = setTimeout(async () => { + if(state.connection !== 'connecting') return + + logger.debug('regenerating QR') + try { + if(qrGens >= maxQRCodes) { + throw new Boom( + 'Too many QR codes', + { statusCode: 429 } + ) + } + // request new QR + const {ref: newRef, ttl: newTTL} = await socket.query({ + json: ['admin', 'Conn', 'reref'], + expect200: true, + longTag: true, + requiresPhoneConnection: false + }) + ttl = newTTL + ref = newRef + } catch (error) { + logger.error({ error }, `error in QR gen`) + if (error.output?.statusCode === 429) { // too many QR requests + socket.end(error) + return + } + } + qrGens += 1 + qrLoop(ttl) + }, ttl || 20_000) // default is 20s, on the off-chance ttl is not present + } + qrLoop(ttl) + } + socketEvents.once('ws-open', async() => { + const canDoLogin = canLogin() + const initQuery = (async () => { + const {ref, ttl} = await socket.query({ + json: ['admin', 'init', version, browser, authInfo.clientID, true], + expect200: true, + longTag: true, + requiresPhoneConnection: false + }) as WAInitResponse + + if (!canDoLogin) { + generateKeysForAuth(ref, ttl) + } + })(); + let loginTag: string + if(canDoLogin) { + // if we have the info to restore a closed session + const json = [ + 'admin', + 'login', + authInfo.clientToken, + authInfo.serverToken, + authInfo.clientID, + 'takeover' + ] + loginTag = socket.generateMessageTag(true) + // send login every 10s + const sendLoginReq = () => { + if(state.connection === 'open') { + logger.warn('Received login timeout req when state=open, ignoring...') + return + } + logger.debug('sending login request') + socket.sendMessage({ + json, + tag: loginTag + }) + initTimeout = setTimeout(sendLoginReq, 10_000) + } + sendLoginReq() + } + await initQuery + + // wait for response with tag "s1" + let response = await Promise.race( + [ + socket.waitForMessage('s1', false, undefined), + ...(loginTag ? [socket.waitForMessage(loginTag, false, connectTimeoutMs)] : []) + + ] + ) + initTimeout && clearTimeout(initTimeout) + initTimeout = undefined + + if(response.status && response.status !== 200) { + throw new Boom(`Unexpected error in login`, { data: response, statusCode: response.status }) + } + // if its a challenge request (we get it when logging in) + if(response[1]?.challenge) { + const json = computeChallengeResponse(response[1].challenge, authInfo) + logger.info('resolving login challenge') + + await socket.query({ json, expect200: true, timeoutMs: connectTimeoutMs }) + + response = await socket.waitForMessage('s2', true) + } + // validate the new connection + const {user, auth} = validateNewConnection(response[1], authInfo, curveKeys)// validate the connection + const isNewLogin = user.jid !== state.user?.jid + + authInfo = auth + // update the keys so we can decrypt traffic + socket.updateKeys({ encKey: auth.encKey, macKey: auth.macKey }) + + updateState({ + connection: 'open', + phoneConnected: true, + user, + isNewLogin, + connectionTriesLeft: undefined, + qr: undefined + }) + }) + + if(printQRInTerminal) { + ev.on('connection.update', async({ qr }) => { + if(qr) { + const QR = await import('qrcode-terminal').catch(err => { + logger.error('QR code terminal not added as dependency') + }) + QR?.generate(qr, { small: true }) + } + }) + } + return { + ...socket, + ev, + getState: () => state, + getAuthInfo: () => authInfo, + waitForConnection, + canLogin, + logout + } +} +export default makeAuthSocket \ No newline at end of file diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts new file mode 100644 index 0000000..68a611c --- /dev/null +++ b/src/Connection/chats.ts @@ -0,0 +1,6 @@ +import { SocketConfig } from "../Types"; + +const makeChatsSocket = (config: SocketConfig) => { + +} +export default makeChatsSocket \ No newline at end of file diff --git a/src/Connection/socket.ts b/src/Connection/socket.ts new file mode 100644 index 0000000..a7b3e6b --- /dev/null +++ b/src/Connection/socket.ts @@ -0,0 +1,362 @@ +import Boom from "boom" +import EventEmitter from "events" +import { STATUS_CODES } from "http" +import { promisify } from "util" +import WebSocket from "ws" +import BinaryNode from "../BinaryNode" +import { DisconnectReason, SocketConfig, SocketQueryOptions, SocketSendMessageOptions } from "../Types" +import { aesEncrypt, hmacSign, promiseTimeout, unixTimestampSeconds } from "../Utils/generics" +import { decodeWAMessage } from "../Utils/decodeWAMessage" +import { WAFlag, WAMetric, WATag } from "../Types" +import { DEFAULT_ORIGIN, DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, PHONE_CONNECTION_CB } from "../Defaults" + +/** + * Connects to WA servers and performs: + * - simple queries (no retry mechanism, wait for connection establishment) + * - listen to messages and emit events + * - query phone connection + */ +export const makeSocket = ({ + waWebSocketUrl, + connectTimeoutMs, + phoneResponseTimeMs, + logger, + agent, + keepAliveIntervalMs, + expectResponseTimeout, + phoneConnectionChanged +}: SocketConfig) => { + const socketEvents = new EventEmitter() + // for generating tags + const referenceDateSeconds = unixTimestampSeconds(new Date()) + const ws = new WebSocket(waWebSocketUrl, undefined, { + origin: DEFAULT_ORIGIN, + timeout: connectTimeoutMs, + agent, + headers: { + 'Accept-Encoding': 'gzip, deflate, br', + 'Accept-Language': 'en-US,en;q=0.9', + 'Cache-Control': 'no-cache', + 'Host': 'web.whatsapp.com', + 'Pragma': 'no-cache', + 'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits', + } + }) + let lastDateRecv: Date + let epoch = 0 + let authInfo: { encKey: Buffer, macKey: Buffer } + let keepAliveReq: NodeJS.Timeout + + let phoneCheckInterval: NodeJS.Timeout + let phoneCheckListeners = 0 + + const sendPromise = promisify(ws.send) + /** generate message tag and increment epoch */ + const generateMessageTag = (longTag: boolean = false) => { + const tag = `${longTag ? referenceDateSeconds : (referenceDateSeconds%1000)}.--${epoch}` + epoch += 1 // increment message count, it makes the 'epoch' field when sending binary messages + return tag + } + const sendRawMessage = (data: Buffer | string) => sendPromise.call(ws, data) as Promise + /** + * Send a message to the WA servers + * @returns the tag attached in the message + * */ + const sendMessage = async( + { json, binaryTag, tag, longTag }: SocketSendMessageOptions + ) => { + tag = tag || generateMessageTag(longTag) + let data: Buffer | string + if(logger.level === 'trace') { + logger.trace({ tag, fromMe: true, json, binaryTag }, 'communication') + } + + if(binaryTag) { + if(!(json instanceof BinaryNode)) { + throw new Boom(`Invalid binary message of type "${typeof json}". Must be BinaryNode`, { statusCode: 400 }) + } + if(!authInfo) { + throw new Boom('No encryption/mac keys to encrypt node with', { statusCode: 400 }) + } + const binary = json.toBuffer() // encode the JSON to the WhatsApp binary format + + const buff = aesEncrypt(binary, authInfo.encKey) // encrypt it using AES and our encKey + const sign = hmacSign(buff, authInfo.macKey) // sign the message using HMAC and our macKey + + data = Buffer.concat([ + Buffer.from(tag + ','), // generate & prefix the message tag + Buffer.from(binaryTag), // prefix some bytes that tell whatsapp what the message is about + sign, // the HMAC sign of the message + buff, // the actual encrypted buffer + ]) + } else { + data = `${tag},${JSON.stringify(json)}` + } + await sendRawMessage(data) + return tag + } + const end = (error: Error | undefined) => { + ws.removeAllListeners('close') + ws.removeAllListeners('error') + ws.removeAllListeners('open') + ws.removeAllListeners('message') + + phoneCheckListeners = 0 + clearInterval(keepAliveReq) + clearPhoneCheckInterval() + + if(ws.readyState !== ws.CLOSED && ws.readyState !== ws.CLOSING) { + socketEvents.emit('ws-close', error) + try { ws.close() } catch { } + } + } + const onMessageRecieved = (message: string | Buffer) => { + if(message[0] === '!') { + // when the first character in the message is an '!', the server is sending a pong frame + const timestamp = message.slice(1, message.length).toString ('utf-8') + lastDateRecv = new Date(parseInt(timestamp)) + socketEvents.emit('received-pong') + } else { + let messageTag: string + let json: any + try { + const dec = decodeWAMessage(message, authInfo) + messageTag = dec[0] + json = dec[1] + if (!json) return + } catch (error) { + end(error) + return + } + //if (this.shouldLogMessages) this.messageLog.push ({ tag: messageTag, json: JSON.stringify(json), fromMe: false }) + + if (logger.level === 'trace') { + logger.trace({ tag: messageTag, fromMe: false, json }, 'communication') + } + + let anyTriggered = false + /* Check if this is a response to a message we sent */ + anyTriggered = socketEvents.emit(`${DEF_TAG_PREFIX}${messageTag}`, json) + /* Check if this is a response to a message we are expecting */ + const l0 = json.header || json[0] || '' + const l1 = json?.attributes || json?.[1] || { } + const l2 = ((json.data || json[2] || [])[0] || [])[0] || '' + + Object.keys(l1).forEach(key => { + anyTriggered = socketEvents.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, json) || anyTriggered + anyTriggered = socketEvents.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, json) || anyTriggered + anyTriggered = socketEvents.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, json) || anyTriggered + }) + anyTriggered = socketEvents.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, json) || anyTriggered + anyTriggered = socketEvents.emit(`${DEF_CALLBACK_PREFIX}${l0}`, json) || anyTriggered + + if (!anyTriggered && logger.level === 'debug') { + logger.debug({ unhandled: true, tag: messageTag, fromMe: false, json }, 'communication recv') + } + } + } + + /** Exits a query if the phone connection is active and no response is still found */ + const exitQueryIfResponseNotExpected = (tag: string, cancel: (error: Boom) => void) => { + let timeout: NodeJS.Timeout + const listener = ([, connected]) => { + if(connected) { + timeout = setTimeout(() => { + logger.info({ tag }, `cancelling wait for message as a response is no longer expected from the phone`) + cancel(new Boom('Not expecting a response', { statusCode: 422 })) + }, expectResponseTimeout) + socketEvents.off(PHONE_CONNECTION_CB, listener) + } + } + socketEvents.on(PHONE_CONNECTION_CB, listener) + return () => { + socketEvents.off(PHONE_CONNECTION_CB, listener) + timeout && clearTimeout(timeout) + } + } + /** interval is started when a query takes too long to respond */ + const startPhoneCheckInterval = () => { + phoneCheckListeners += 1 + if (!phoneCheckInterval) { + // if its been a long time and we haven't heard back from WA, send a ping + phoneCheckInterval = setInterval(() => { + if(phoneCheckListeners <= 0) { + logger.warn('phone check called without listeners') + return + } + logger.info('checking phone connection...') + sendAdminTest() + + phoneConnectionChanged(false) + }, phoneResponseTimeMs) + } + } + const clearPhoneCheckInterval = () => { + phoneCheckListeners -= 1 + if (phoneCheckListeners <= 0) { + clearInterval(phoneCheckInterval) + phoneCheckInterval = undefined + phoneCheckListeners = 0 + } + } + /** checks for phone connection */ + const sendAdminTest = () => sendMessage({ json: ['admin', 'test'] }) + /** + * Wait for a message with a certain tag to be received + * @param tag the message tag to await + * @param json query that was sent + * @param timeoutMs timeout after which the promise will reject + */ + const waitForMessage = async(tag: string, requiresPhoneConnection: boolean, timeoutMs?: number) => { + let onRecv: (json) => void + let onErr: (err) => void + let cancelPhoneChecker: () => void + if (requiresPhoneConnection) { + startPhoneCheckInterval() + cancelPhoneChecker = exitQueryIfResponseNotExpected(tag, onErr) + } + try { + const result = await promiseTimeout(timeoutMs, + (resolve, reject) => { + onRecv = resolve + onErr = err => reject(err || new Boom('Connection Closed', { statusCode: 429 })) + + socketEvents.on(`TAG:${tag}`, onRecv) + socketEvents.on('ws-close', onErr) // if the socket closes, you'll never receive the message + }, + ) + return result as any + } finally { + requiresPhoneConnection && clearPhoneCheckInterval() + cancelPhoneChecker && cancelPhoneChecker() + + socketEvents.off(`TAG:${tag}`, onRecv) + socketEvents.off(`ws-close`, onErr) + } + } + /** + * Query something from the WhatsApp servers + * @param json the query itself + * @param binaryTags the tags to attach if the query is supposed to be sent encoded in binary + * @param timeoutMs timeout after which the query will be failed (set to null to disable a timeout) + * @param tag the tag to attach to the message + */ + const query = async( + {json, timeoutMs, expect200, tag, longTag, binaryTag, requiresPhoneConnection}: SocketQueryOptions + ) => { + tag = tag || generateMessageTag(longTag) + const promise = waitForMessage(tag, requiresPhoneConnection, timeoutMs) + + await sendMessage({ json, tag, binaryTag }) + const response = await promise + const responseStatusCode = +(response.status ? response.status : 200) // default status + // read here: http://getstatuscode.com/599 + if(responseStatusCode === 599) { // the connection has gone bad + end(new Boom('WA server overloaded', { statusCode: 599 })) + } + if(expect200 && Math.floor(responseStatusCode/100) !== 2) { + const message = STATUS_CODES[responseStatusCode] || 'unknown' + throw new Boom( + `Unexpected status in '${Object.values(json)[0] || 'query'}': ${message}(${responseStatusCode})`, + { data: { query: json, message }, statusCode: response.status } + ) + } + return response + } + const startKeepAliveRequest = () => ( + keepAliveReq = setInterval(() => { + if (!lastDateRecv) lastDateRecv = new Date() + const diff = Date.now() - lastDateRecv.getTime() + /* + check if it's been a suspicious amount of time since the server responded with our last seen + it could be that the network is down + */ + if (diff > keepAliveIntervalMs+5000) { + end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost })) + } else if(ws.readyState === ws.OPEN) { + sendRawMessage('?,,') // if its all good, send a keep alive request + } else { + logger.warn('keep alive called when WS not open') + } + }, keepAliveIntervalMs) + ) + + const waitForSocketOpen = async() => { + if(ws.readyState === ws.OPEN) return + if(ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { + throw Boom.preconditionRequired('Connection Closed') + } + let onOpen: () => void + let onClose: (err: Error) => void + await new Promise((resolve, reject) => { + onOpen = () => resolve(undefined) + onClose = reject + socketEvents.on('ws-open', onOpen) + socketEvents.on('ws-close', onClose) + }) + .finally(() => { + socketEvents.off('ws-open', onOpen) + socketEvents.off('ws-close', onClose) + }) + } + + ws.on('message', onMessageRecieved) + ws.on('open', () => { + startKeepAliveRequest() + + logger.info('Opened WS connection to WhatsApp Web') + socketEvents.emit('ws-open') + }) + ws.on('error', end) + ws.on('close', () => end(new Boom('Connection Terminated', { statusCode: DisconnectReason.connectionLost }))) + + socketEvents.on(PHONE_CONNECTION_CB, json => { + if (!json[1]) { + end(new Boom('Connection terminated by phone', { statusCode: DisconnectReason.connectionLost })) + logger.info('Connection terminated by phone, closing...') + } else { + phoneConnectionChanged(true) + } + }) + socketEvents.on('CB:Cmd,type:disconnect', json => { + const {kind} = json[1] + let reason: DisconnectReason + switch(kind) { + case 'replaced': + reason = DisconnectReason.connectionReplaced + break + default: + reason = DisconnectReason.connectionLost + break + } + end(new Boom( + `Connection terminated by server: "${kind || 'unknown'}"`, + { statusCode: reason } + )) + }) + + return { + socketEvents, + ws, + updateKeys: (info: { encKey: Buffer, macKey: Buffer }) => authInfo = info, + waitForSocketOpen, + sendRawMessage, + sendMessage, + generateMessageTag, + waitForMessage, + query, + /** Generic function for action, set queries */ + setQuery: async(nodes: BinaryNode[], binaryTag: WATag = [WAMetric.group, WAFlag.ignore], tag?: string) => ( + query({ + json: ['action', { epoch: epoch.toString(), type: 'set' }, nodes], + binaryTag, + tag, + expect200: true, + requiresPhoneConnection: true + }) as Promise<{ status: number }> + ), + currentEpoch: () => epoch, + end + } +} +export type Socket = ReturnType \ No newline at end of file diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts new file mode 100644 index 0000000..79fc2d8 --- /dev/null +++ b/src/Defaults/index.ts @@ -0,0 +1,29 @@ +import P from "pino" +import type { SocketConfig } from "../Types" +import { Browsers } from "../Utils/generics" + +export const UNAUTHORIZED_CODES = [401, 403, 419] + +export const DEFAULT_ORIGIN = 'https://web.whatsapp.com' +export const DEF_CALLBACK_PREFIX = 'CB:' +export const DEF_TAG_PREFIX = 'TAG:' +export const PHONE_CONNECTION_CB = 'CB:Pong' + +export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { + version: [2, 2123, 8], + browser: Browsers.baileys('Chrome'), + + waWebSocketUrl: 'wss://web.whatsapp.com/ws', + keepAliveIntervalMs: 25_000, + phoneResponseTimeMs: 15_000, + connectTimeoutMs: 30_000, + expectResponseTimeout: 12_000, + logger: P().child({ class: 'baileys' }), + phoneConnectionChanged: () => { }, + maxRetries: 5, + connectCooldownMs: 2500, + pendingRequestTimeoutMs: undefined, + reconnectMode: 'on-connection-error', + maxQRCodes: Infinity, + printQRInTerminal: false, +} diff --git a/src/Tests/Common.ts b/src/Tests/Common.ts index 08e46ef..942f5be 100644 --- a/src/Tests/Common.ts +++ b/src/Tests/Common.ts @@ -39,7 +39,7 @@ export async function sendAndRetrieveMessage(conn: WAConnection, content, type: const chat = conn.chats.get(recipientJid) assert.ok (chat.messages.get(GET_MESSAGE_ID(message.key))) - assert.ok (chat.t >= (unixTimestampSeconds()-5), `expected: ${chat.t} > ${(unixTimestampSeconds()-5)}`) + assert.ok (chat.t >= (unixTimestampSeconds()-5) ) return message } export const WAConnectionTest = (name: string, func: (conn: WAConnection) => void) => ( diff --git a/src/Tests/Tests.Messages.ts b/src/Tests/Tests.Messages.ts index a9b43fc..f271a0f 100644 --- a/src/Tests/Tests.Messages.ts +++ b/src/Tests/Tests.Messages.ts @@ -72,7 +72,7 @@ WAConnectionTest('Messages', conn => { assert.ok (message.message.audioMessage.seconds > 0) await conn.downloadAndSaveMediaMessage(message,'./Media/received_aud') }) - it('should send a voice note', async () => { + it('should send an audio as a voice note', async () => { const content = await fs.readFile('./Media/sonata.mp3') const message = await sendAndRetrieveMessage(conn, content, MessageType.audio, { mimetype: Mimetype.mp4Audio, ptt: true }) diff --git a/src/Tests/test.binary.ts b/src/Tests/test.binary.ts new file mode 100644 index 0000000..7263626 --- /dev/null +++ b/src/Tests/test.binary.ts @@ -0,0 +1,95 @@ +import BinaryNode from '../BinaryNode' + +describe('Binary Coding Tests', () => { + + const TEST_VECTORS: [string, BinaryNode][] = [ + [ + 'f806092f5a0a10f804f80234fc6c0a350a1b39313735323938373131313740732e77686174736170702e6e657410011a143345423030393637354537454433374141424632122b0a292a7069616e6f20726f6f6d2074696d696e6773206172653a2a0a20363a3030414d2d31323a3030414d18b3faa7f3052003f80234fc4c0a410a1b39313735323938373131313740732e77686174736170702e6e657410001a20304643454335333330463634393239433645394132434646443242433845414418bdfaa7f305c00101f80234fc930a350a1b39313735323938373131313740732e77686174736170702e6e657410011a14334542303033433742353339414644303937353312520a50536f727279206672656e2c204920636f756c646e277420756e6465727374616e6420274c69627261272e2054797065202768656c702720746f206b6e6f77207768617420616c6c20492063616e20646f18c1faa7f3052003f80234fc540a410a1b39313735323938373131313740732e77686174736170702e6e657410001a20413132333042384436423041314437393345433241453245413043313638443812090a076c69627261727918c2faa7f305', + new BinaryNode( + 'action', + { last: 'true', add: 'before' }, + [ + new BinaryNode( + 'message', + {}, + { + key: { remoteJid: '917529871117@s.whatsapp.net', fromMe: true, id: '3EB009675E7ED37AABF2' }, + message: { conversation: '*piano room timings are:*\n 6:00AM-12:00AM' }, + messageTimestamp: '1584004403', + status: 'DELIVERY_ACK', + } as any + ), + new BinaryNode( + 'message', + {}, + { + key: { + remoteJid: '917529871117@s.whatsapp.net', + fromMe: false, + id: '0FCEC5330F64929C6E9A2CFFD2BC8EAD', + }, + messageTimestamp: '1584004413', + messageStubType: 'REVOKE', + } as any + ), + new BinaryNode( + 'message', + {}, + { + key: { remoteJid: '917529871117@s.whatsapp.net', fromMe: true, id: '3EB003C7B539AFD09753' }, + message: { + conversation: + "Sorry fren, I couldn't understand 'Libra'. Type 'help' to know what all I can do", + }, + messageTimestamp: '1584004417', + status: 'DELIVERY_ACK', + } as any + ), + new BinaryNode( + 'message', + {}, + { + key: { + remoteJid: '917529871117@s.whatsapp.net', + fromMe: false, + id: 'A1230B8D6B0A1D793EC2AE2EA0C168D8', + }, + message: { conversation: 'library' }, + messageTimestamp: '1584004418', + } as any + ), + ] + ) + ], + [ + 'f8063f2dfafc0831323334353637385027fc0431323334f801f80228fc0701020304050607', + new BinaryNode( + 'picture', + {jid: '12345678@s.whatsapp.net', id: '1234'}, + [ + new BinaryNode( + 'image', + {}, + Buffer.from([1,2,3,4,5,6,7]) + ) + ] + ) + ] + ] + it('should encode/decode strings', () => { + for(const [input, output] of TEST_VECTORS) { + const buff = Buffer.from(input, 'hex') + const node = BinaryNode.from(buff) + expect( + JSON.parse(JSON.stringify(node)) + ).toStrictEqual( + JSON.parse(JSON.stringify(output)) + ) + expect( + node.toBuffer().toString('hex') + ).toStrictEqual( + input + ) + } + }) +}) diff --git a/src/Tests/test.connect.ts b/src/Tests/test.connect.ts new file mode 100644 index 0000000..155f729 --- /dev/null +++ b/src/Tests/test.connect.ts @@ -0,0 +1,200 @@ +import Boom from 'boom' +import P from 'pino' +import BinaryNode from '../BinaryNode' +import makeConnection, { Connection, DisconnectReason } from '../makeConnection' +import { delay } from '../WAConnection/Utils' + +describe('QR Generation', () => { + it('should generate QR', async () => { + const QR_GENS = 1 + const {ev, open} = makeConnection({ + maxRetries: 0, + maxQRCodes: QR_GENS, + logger: P({ level: 'trace' }) + }) + let calledQR = 0 + ev.removeAllListeners('qr') + ev.on('state.update', ({ qr }) => { + if(qr) calledQR += 1 + }) + + await expect(open()).rejects.toThrowError('Too many QR codes') + expect( + Object.keys(ev.eventNames()).filter(key => key.startsWith('TAG:')) + ).toHaveLength(0) + expect(calledQR).toBeGreaterThanOrEqual(QR_GENS) + }, 60_000) +}) + +describe('Test Connect', () => { + const logger = P({ level: 'trace' }) + it('should connect', async () => { + + logger.info('please be ready to scan with your phone') + + const conn = makeConnection({ + logger, + printQRInTerminal: true + }) + await conn.open() + const { user, isNewLogin } = await conn.getState() + expect(user).toHaveProperty('jid') + expect(user).toHaveProperty('name') + expect(isNewLogin).toBe(true) + + conn.close() + }, 65_000) + + it('should restore session', async () => { + const conn = makeConnection({ + printQRInTerminal: true, + logger, + }) + await conn.open() + conn.close() + + await delay(2500) + + await conn.open() + const { user, isNewLogin, qr } = await conn.getState() + expect(user).toHaveProperty('jid') + expect(user).toHaveProperty('name') + expect(isNewLogin).toBe(false) + expect(qr).toBe(undefined) + + conn.close() + }, 65_000) + + it('should logout', async () => { + let conn = makeConnection({ + printQRInTerminal: true, + logger, + }) + await conn.open() + const { user, qr } = await conn.getState() + expect(user).toHaveProperty('jid') + expect(user).toHaveProperty('name') + expect(qr).toBe(undefined) + + const credentials = conn.getAuthInfo() + await conn.logout() + + conn = makeConnection({ + credentials, + logger + }) + await expect(conn.open()).rejects.toThrowError('Unexpected error in login') + }, 65_000) +}) + +describe ('Reconnects', () => { + const verifyConnectionOpen = async (conn: Connection) => { + expect((await conn.getState()).user).toBeDefined() + let failed = false + // check that the connection stays open + conn.ev.on('state.update', ({ connection, lastDisconnect }) => { + if(connection === 'close' && !!lastDisconnect.error) { + failed = true + } + }) + await delay (60*1000) + conn.close () + + expect(failed).toBe(false) + } + it('should dispose correctly on bad_session', async () => { + const conn = makeConnection({ + reconnectMode: 'on-any-error', + credentials: './auth_info.json', + maxRetries: 2, + connectCooldownMs: 500 + }) + let gotClose0 = false + let gotClose1 = false + + const openPromise = conn.open() + + conn.getSocket().ev.once('ws-close', () => { + gotClose0 = true + }) + conn.ev.on('state.update', ({ lastDisconnect }) => { + //@ts-ignore + if(lastDisconnect?.error?.output?.statusCode === DisconnectReason.badSession) { + gotClose1 = true + } + }) + setTimeout (() => conn.getSocket().ws.emit ('message', Buffer.from('some-tag,sdjjij1jo2ejo1je')), 1500) + await openPromise + + console.log('opened connection') + + await delay(1000) + conn.getSocket().ws.emit ('message', Buffer.from('some-tag,sdjjij1jo2ejo1je')) + + await delay(2000) + await conn.waitForConnection() + + conn.close() + + expect(gotClose0).toBe(true) + expect(gotClose1).toBe(true) + }, 20_000) + /** + * the idea is to test closing the connection at multiple points in the connection + * and see if the library cleans up resources correctly + */ + it('should cleanup correctly', async () => { + const conn = makeConnection({ + reconnectMode: 'on-any-error', + credentials: './auth_info.json' + }) + let timeoutMs = 100 + while (true) { + let tmout = setTimeout (() => { + conn.close() + }, timeoutMs) + try { + await conn.open() + clearTimeout (tmout) + break + } catch (error) { + + } + // exponentially increase the timeout disconnect + timeoutMs *= 2 + } + await verifyConnectionOpen(conn) + }, 120_000) + /** + * the idea is to test closing the connection at multiple points in the connection + * and see if the library cleans up resources correctly + */ + it('should disrupt connect loop', async () => { + const conn = makeConnection({ + reconnectMode: 'on-any-error', + credentials: './auth_info.json' + }) + + let timeout = 1000 + let tmout + const endConnection = async () => { + while (!conn.getSocket()) { + await delay(100) + } + conn.getSocket().end(Boom.preconditionRequired('conn close')) + + while (conn.getSocket()) { + await delay(100) + } + + timeout *= 2 + tmout = setTimeout (endConnection, timeout) + } + tmout = setTimeout (endConnection, timeout) + + await conn.open() + clearTimeout (tmout) + + await verifyConnectionOpen(conn) + }, 120_000) +}) \ No newline at end of file diff --git a/src/Tests/test.queries.ts b/src/Tests/test.queries.ts new file mode 100644 index 0000000..f9e28ed --- /dev/null +++ b/src/Tests/test.queries.ts @@ -0,0 +1,165 @@ +import BinaryNode from '../BinaryNode' +import makeConnection from '../makeConnection' +import { delay } from '../WAConnection/Utils' + +describe('Queries', () => { + /*it ('should correctly send updates for chats', async () => { + const conn = makeConnection({ + pendingRequestTimeoutMs: undefined, + credentials: './auth_info.json' + }) + const task = new Promise(resolve => conn.once('chats-received', resolve)) + await conn.connect () + await task + + conn.close () + + const oldChat = conn.chats.all()[0] + oldChat.archive = 'true' // mark the first chat as archived + oldChat.modify_tag = '1234' // change modify tag to detect change + + const promise = new Promise(resolve => conn.once('chats-update', resolve)) + + const result = await conn.connect () + assert.ok (!result.newConnection) + + const chats = await promise as Partial[] + const chat = chats.find (c => c.jid === oldChat.jid) + assert.ok (chat) + + assert.ok ('archive' in chat) + assert.strictEqual (Object.keys(chat).length, 3) + assert.strictEqual (Object.keys(chats).length, 1) + + conn.close () + }) + it ('should correctly send updates for contacts', async () => { + const conn = makeConnection () + conn.pendingRequestTimeoutMs = null + conn.loadAuthInfo('./auth_info.json') + + const task: any = new Promise(resolve => conn.once('contacts-received', resolve)) + await conn.connect () + const initialResult = await task + assert.strictEqual( + initialResult.updatedContacts.length, + Object.keys(conn.contacts).length + ) + + + conn.close () + + const [jid] = Object.keys(conn.contacts) + const oldContact = conn.contacts[jid] + oldContact.name = 'Lol' + oldContact.index = 'L' + + const promise = new Promise(resolve => conn.once('contacts-received', resolve)) + + const result = await conn.connect () + assert.ok (!result.newConnection) + + const {updatedContacts} = await promise as { updatedContacts: Partial[] } + const contact = updatedContacts.find (c => c.jid === jid) + assert.ok (contact) + + assert.ok ('name' in contact) + assert.strictEqual (Object.keys(contact).length, 3) + assert.strictEqual (Object.keys(updatedContacts).length, 1) + + conn.close () + })*/ + it('should queue requests when closed', async () => { + const conn = makeConnection({ + credentials: './auth_info.json' + }) + await conn.open() + await delay(2000) + + conn.close() + const { user: { jid } } = await conn.getState() + const task: Promise = conn.query({ + json: ['query', 'Status', jid] + }) + + await delay(2000) + + conn.open() + const json = await task + + expect(json.status).toBeDefined() + + conn.close() + }, 65_000) + + it('[MANUAL] should recieve query response after phone disconnect', async () => { + const conn = makeConnection ({ + printQRInTerminal: true, + credentials: './auth_info.json' + }) + await conn.open() + const { phoneConnected } = await conn.getState() + expect(phoneConnected).toBe(true) + + try { + const waitForEvent = expect => new Promise (resolve => { + conn.ev.on('state.update', ({phoneConnected}) => { + if (phoneConnected === expect) { + conn.ev.removeAllListeners('state.update') + resolve(undefined) + } + }) + }) + + console.log('disconnect your phone from the internet') + await delay(10_000) + console.log('phone should be disconnected now, testing...') + + const query = conn.query({ + json: new BinaryNode( + 'query', + { + epoch: conn.getSocket().currentEpoch().toString(), + type: 'message', + jid: '1234@s.whatsapp.net', + kind: 'before', + count: '10', + } + ), + requiresPhoneConnection: true, + expect200: false + }) + await waitForEvent(false) + + console.log('reconnect your phone to the internet') + await waitForEvent(true) + + console.log('reconnected successfully') + + await expect(query).resolves.toBeDefined() + } finally { + conn.close() + } + }, 65_000) + + it('should re-execute query on connection closed error', async () => { + const conn = makeConnection({ + credentials: './auth_info.json' + }) + await conn.open() + const { user: { jid } } = await conn.getState() + const task: Promise = conn.query({ json: ['query', 'Status', jid], waitForOpen: true }) + + await delay(20) + // fake cancel the connection + conn.getSocket().ev.emit('message', '1234,["Pong",false]') + + await delay(2000) + + const json = await task + + expect(json.status).toBeDefined() + + conn.close() + }, 65_000) +}) \ No newline at end of file diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts new file mode 100644 index 0000000..aeaa907 --- /dev/null +++ b/src/Types/Auth.ts @@ -0,0 +1,22 @@ + +export interface AuthenticationCredentials { + clientID: string + serverToken: string + clientToken: string + encKey: Buffer + macKey: Buffer +} +export interface AuthenticationCredentialsBase64 { + clientID: string + serverToken: string + clientToken: string + encKey: string + macKey: string +} +export interface AuthenticationCredentialsBrowser { + WABrowserId: string + WASecretBundle: {encKey: string, macKey: string} | string + WAToken1: string + WAToken2: string +} +export type AnyAuthenticationCredentials = AuthenticationCredentialsBrowser | AuthenticationCredentialsBase64 | AuthenticationCredentials \ No newline at end of file diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts new file mode 100644 index 0000000..5e3ac08 --- /dev/null +++ b/src/Types/Chat.ts @@ -0,0 +1,44 @@ +import type KeyedDB from "@adiwajshing/keyed-db"; +import type { proto } from '../../WAMessage/WAMessage' +import type { GroupMetadata } from "./GroupMetadata"; + +/** set of statuses visible to other people; see updatePresence() in WhatsAppWeb.Send */ +export enum Presence { + unavailable = 'unavailable', // "offline" + available = 'available', // "online" + composing = 'composing', // "typing..." + recording = 'recording', // "recording..." + paused = 'paused', // stop typing +} + +export interface PresenceData { + lastKnownPresence?: Presence + lastSeen?: number + name?: string +} + +export interface Chat { + jid: string + + t: number + /** number of unread messages, is < 0 if the chat is manually marked unread */ + count: number + archive?: 'true' | 'false' + clear?: 'true' | 'false' + read_only?: 'true' | 'false' + mute?: string + pin?: string + spam?: 'false' | 'true' + modify_tag?: string + name?: string + /** when ephemeral messages were toggled on */ + eph_setting_ts?: string + /** how long each message lasts for */ + ephemeral?: string + + // Baileys added properties + messages: KeyedDB + imgUrl?: string + presences?: { [k: string]: PresenceData } + metadata?: GroupMetadata +} \ No newline at end of file diff --git a/src/Types/Contact.ts b/src/Types/Contact.ts new file mode 100644 index 0000000..2103534 --- /dev/null +++ b/src/Types/Contact.ts @@ -0,0 +1,15 @@ +export interface Contact { + verify?: string + /** name of the contact, the contact has set on their own on WA */ + notify?: string + jid: string + /** I have no idea */ + vname?: string + /** name of the contact, you have saved on your WA */ + name?: string + index?: string + /** short name for the contact */ + short?: string + // Baileys Added + imgUrl?: string +} \ No newline at end of file diff --git a/src/Types/GroupMetadata.ts b/src/Types/GroupMetadata.ts new file mode 100644 index 0000000..1d5a6c4 --- /dev/null +++ b/src/Types/GroupMetadata.ts @@ -0,0 +1,19 @@ +import { Contact } from "./Contact"; + +export type GroupParticipant = (Contact & { isAdmin: boolean; isSuperAdmin: boolean }) + +export interface GroupMetadata { + id: string + owner: string + subject: string + creation: number + desc?: string + descOwner?: string + descId?: string + /** is set when the group only allows admins to change group settings */ + restrict?: 'true' | 'false' + /** is set when the group only allows admins to write messages */ + announce?: 'true' | 'false' + // Baileys modified array + participants: GroupParticipant[] +} \ No newline at end of file diff --git a/src/Types/Store.ts b/src/Types/Store.ts new file mode 100644 index 0000000..9c5c65e --- /dev/null +++ b/src/Types/Store.ts @@ -0,0 +1,25 @@ +import type KeyedDB from '@adiwajshing/keyed-db' +import type { Chat } from './Chat' +import type { Contact } from './Contact' + +export type WAConnectionState = 'open' | 'connecting' | 'close' + +export type ConnectionState = { + user?: Contact + phoneConnected: boolean + phoneInfo?: any + connection: WAConnectionState + lastDisconnect?: { + error: Error, + date: Date + }, + isNewLogin?: boolean + connectionTriesLeft?: number + qr?: string +} + +export type BaileysState = { + connection: ConnectionState + chats: KeyedDB + contacts: { [jid: string]: Contact } +} \ No newline at end of file diff --git a/src/Types/index.ts b/src/Types/index.ts new file mode 100644 index 0000000..b16999b --- /dev/null +++ b/src/Types/index.ts @@ -0,0 +1,147 @@ +export * from './Auth' +export * from './GroupMetadata' +export * from './Chat' +export * from './Contact' +export * from './Store' + +import type EventEmitter from "events" +import type { Agent } from "https" +import type { Logger } from "pino" +import type { URL } from "url" +import type BinaryNode from "../BinaryNode" +import { AnyAuthenticationCredentials } from './Auth' +import { ConnectionState } from './Store' + +/** used for binary messages */ +export enum WAMetric { + debugLog = 1, + queryResume = 2, + liveLocation = 3, + queryMedia = 4, + queryChat = 5, + queryContact = 6, + queryMessages = 7, + presence = 8, + presenceSubscribe = 9, + group = 10, + read = 11, + chat = 12, + received = 13, + picture = 14, + status = 15, + message = 16, + queryActions = 17, + block = 18, + queryGroup = 19, + queryPreview = 20, + queryEmoji = 21, + queryRead = 22, + queryVCard = 29, + queryStatus = 30, + queryStatusUpdate = 31, + queryLiveLocation = 33, + queryLabel = 36, + queryQuickReply = 39 +} + +/** used for binary messages */ +export enum WAFlag { + available = 160, + other = 136, // don't know this one + ignore = 1 << 7, + acknowledge = 1 << 6, + unavailable = 1 << 4, + expires = 1 << 3, + composing = 1 << 2, + recording = 1 << 2, + paused = 1 << 2 +} + +/** Tag used with binary queries */ +export type WATag = [WAMetric, WAFlag] + +export type SocketSendMessageOptions = { + json: BinaryNode | any[] + binaryTag?: WATag + tag?: string + longTag?: boolean +} + +export type WAVersion = [number, number, number] +export type WABrowserDescription = [string, string, string] +export type ReconnectMode = 'no-reconnects' | 'on-any-error' | 'on-connection-error' + +export type SocketConfig = { + /** the WS url to connect to WA */ + waWebSocketUrl: string | URL + /** Fails the connection if the connection times out in this time interval or no data is received */ + connectTimeoutMs: number + /** max time for the phone to respond to a connectivity test */ + phoneResponseTimeMs: number + /** ping-pong interval for WS connection */ + keepAliveIntervalMs: number + + expectResponseTimeout: number + /** proxy agent */ + agent?: Agent + logger: Logger + + version: WAVersion + browser: WABrowserDescription + /** maximum attempts to connect */ + maxRetries: number + connectCooldownMs: number + /** agent used for fetch requests -- uploading/downloading media */ + fetchAgent?: Agent + /** credentials used to sign back in */ + credentials?: AnyAuthenticationCredentials | string + /** + * Sometimes WA does not send the chats, + * this keeps pinging the phone to send the chats over + * */ + queryChatsTillReceived?: boolean + /** */ + pendingRequestTimeoutMs: number + reconnectMode: ReconnectMode + maxQRCodes: number + /** should the QR be printed in the terminal */ + printQRInTerminal: boolean + + phoneConnectionChanged: (connected: boolean) => void +} + +export type SocketQueryOptions = SocketSendMessageOptions & { + timeoutMs?: number + expect200?: boolean + requiresPhoneConnection?: boolean +} + +export enum DisconnectReason { + connectionClosedIntentionally = 428, + connectionReplaced = 440, + connectionLost = 408, + timedOut = 408, + credentialsInvalidated = 401, + badSession = 500 +} + +export type WAInitResponse = { + ref: string + ttl: number + status: 200 +} + +export type QueryOptions = SocketQueryOptions & { + waitForOpen?: boolean + maxRetries?: number + startDebouncedTimeout?: boolean +} +export type CurveKeyPair = { private: Uint8Array; public: Uint8Array } + +export type BaileysEventMap = { + 'connection.update': Partial +} +export interface BaileysEventEmitter extends EventEmitter { + on(event: T, listener: (arg: BaileysEventMap[T]) => void): this + emit(event: T, arg: BaileysEventMap[T]): boolean +} \ No newline at end of file diff --git a/src/Utils/decodeWAMessage.ts b/src/Utils/decodeWAMessage.ts new file mode 100644 index 0000000..c0d759c --- /dev/null +++ b/src/Utils/decodeWAMessage.ts @@ -0,0 +1,63 @@ +import Boom from "boom" +import BinaryNode from "../BinaryNode" +import { aesDecrypt, hmacSign } from "./generics" +import { DisconnectReason, WATag } from "../Types" + +export const decodeWAMessage = ( + message: string | Buffer, + auth: { macKey: Buffer, encKey: Buffer }, + fromMe: boolean=false +) => { + + let commaIndex = message.indexOf(',') // all whatsapp messages have a tag and a comma, followed by the actual message + if (commaIndex < 0) throw new Boom('invalid message', { data: message }) // if there was no comma, then this message must be not be valid + + if (message[commaIndex+1] === ',') commaIndex += 1 + let data = message.slice(commaIndex+1, message.length) + + // get the message tag. + // If a query was done, the server will respond with the same message tag we sent the query with + const messageTag: string = message.slice(0, commaIndex).toString() + let json: any + let tags: WATag + if (data.length > 0) { + if (typeof data === 'string') { + json = JSON.parse(data) // parse the JSON + } else { + const { macKey, encKey } = auth || {} + if (!macKey || !encKey) { + throw new Boom('recieved encrypted buffer when auth creds unavailable', { data: message, statusCode: DisconnectReason.badSession }) + } + /* + If the data recieved was not a JSON, then it must be an encrypted message. + Such a message can only be decrypted if we're connected successfully to the servers & have encryption keys + */ + if (fromMe) { + tags = [data[0], data[1]] + data = data.slice(2, data.length) + } + + const checksum = data.slice(0, 32) // the first 32 bytes of the buffer are the HMAC sign of the message + data = data.slice(32, data.length) // the actual message + const computedChecksum = hmacSign(data, macKey) // compute the sign of the message we recieved using our macKey + + if (checksum.equals(computedChecksum)) { + // the checksum the server sent, must match the one we computed for the message to be valid + const decrypted = aesDecrypt(data, encKey) // decrypt using AES + json = BinaryNode.from(decrypted) // decode the binary message into a JSON array + } else { + throw new Boom('Bad checksum', { + data: { + received: checksum.toString('hex'), + computed: computedChecksum.toString('hex'), + data: data.slice(0, 80).toString(), + tag: messageTag, + message: message.slice(0, 80).toString() + }, + statusCode: DisconnectReason.badSession + }) + } + } + } + return [messageTag, json, tags] as const +} \ No newline at end of file diff --git a/src/Utils/generics.ts b/src/Utils/generics.ts new file mode 100644 index 0000000..b524074 --- /dev/null +++ b/src/Utils/generics.ts @@ -0,0 +1,148 @@ +import Boom from 'boom' +import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes } from 'crypto' +import HKDF from 'futoin-hkdf' +import { platform, release } from 'os' + +const PLATFORM_MAP = { + 'aix': 'AIX', + 'darwin': 'Mac OS', + 'win32': 'Windows', + 'android': 'Android' +} +export const Browsers = { + ubuntu: browser => ['Ubuntu', browser, '18.04'] as [string, string, string], + macOS: browser => ['Mac OS', browser, '10.15.3'] as [string, string, string], + baileys: browser => ['Baileys', browser, '4.0.0'] as [string, string, string], + /** The appropriate browser based on your OS & release */ + appropriate: browser => [ PLATFORM_MAP[platform()] || 'Ubuntu', browser, release() ] as [string, string, string] +} +export const toNumber = (t: Long | number) => (t['low'] || t) as number + +export const whatsappID = (jid: string) => jid?.replace ('@c.us', '@s.whatsapp.net') +export const isGroupID = (jid: string) => jid?.endsWith ('@g.us') + +export function shallowChanges (old: T, current: T, {lookForDeletedKeys}: {lookForDeletedKeys: boolean}): Partial { + let changes: Partial = {} + for (let key in current) { + if (old[key] !== current[key]) { + changes[key] = current[key] || null + } + } + if (lookForDeletedKeys) { + for (let key in old) { + if (!changes[key] && old[key] !== current[key]) { + changes[key] = current[key] || null + } + } + } + return changes +} + +/** decrypt AES 256 CBC; where the IV is prefixed to the buffer */ +export function aesDecrypt(buffer: Buffer, key: Buffer) { + return aesDecryptWithIV(buffer.slice(16, buffer.length), key, buffer.slice(0, 16)) +} +/** decrypt AES 256 CBC */ +export function aesDecryptWithIV(buffer: Buffer, key: Buffer, IV: Buffer) { + const aes = createDecipheriv('aes-256-cbc', key, IV) + return Buffer.concat([aes.update(buffer), aes.final()]) +} +// encrypt AES 256 CBC; where a random IV is prefixed to the buffer +export function aesEncrypt(buffer: Buffer, key: Buffer) { + const IV = randomBytes(16) + const aes = createCipheriv('aes-256-cbc', key, IV) + return Buffer.concat([IV, aes.update(buffer), aes.final()]) // prefix IV to the buffer +} +// encrypt AES 256 CBC with a given IV +export function aesEncrypWithIV(buffer: Buffer, key: Buffer, IV: Buffer) { + const aes = createCipheriv('aes-256-cbc', key, IV) + return Buffer.concat([aes.update(buffer), aes.final()]) // prefix IV to the buffer +} +// sign HMAC using SHA 256 +export function hmacSign(buffer: Buffer, key: Buffer) { + return createHmac('sha256', key).update(buffer).digest() +} +export function sha256(buffer: Buffer) { + return createHash('sha256').update(buffer).digest() +} +// HKDF key expansion +export function hkdf(buffer: Buffer, expandedLength: number, info = null) { + return HKDF(buffer, expandedLength, { salt: Buffer.alloc(32), info: info, hash: 'SHA-256' }) +} +/** unix timestamp of a date in seconds */ +export const unixTimestampSeconds = (date: Date = new Date()) => Math.floor(date.getTime()/1000) + +export type DebouncedTimeout = ReturnType +export const debouncedTimeout = (intervalMs: number = 1000, task: () => void = undefined) => { + let timeout: NodeJS.Timeout + return { + start: (newIntervalMs?: number, newTask?: () => void) => { + task = newTask || task + intervalMs = newIntervalMs || intervalMs + timeout && clearTimeout(timeout) + timeout = setTimeout(task, intervalMs) + }, + cancel: () => { + timeout && clearTimeout(timeout) + timeout = undefined + }, + setTask: (newTask: () => void) => task = newTask, + setInterval: (newInterval: number) => intervalMs = newInterval + } +} + +export const delay = (ms: number) => delayCancellable (ms).delay +export const delayCancellable = (ms: number) => { + const stack = new Error().stack + let timeout: NodeJS.Timeout + let reject: (error) => void + const delay: Promise = new Promise((resolve, _reject) => { + timeout = setTimeout(resolve, ms) + reject = _reject + }) + const cancel = () => { + clearTimeout (timeout) + reject( + new Boom('Cancelled', { + statusCode: 500, + data: { + stack + } + }) + ) + } + return { delay, cancel } +} +export async function promiseTimeout(ms: number, promise: (resolve: (v?: T)=>void, reject: (error) => void) => void) { + if (!ms) return new Promise (promise) + const stack = new Error().stack + // Create a promise that rejects in milliseconds + let {delay, cancel} = delayCancellable (ms) + const p = new Promise ((resolve, reject) => { + delay + .then(() => reject( + new Boom('Timed Out', { + statusCode: 408, + data: { + stack + } + }) + )) + .catch (err => reject(err)) + + promise (resolve, reject) + }) + .finally (cancel) + return p as Promise +} +// whatsapp requires a message tag for every message, we just use the timestamp as one +export function generateMessageTag(epoch?: number) { + let tag = unixTimestampSeconds().toString() + if (epoch) tag += '.--' + epoch // attach epoch if provided + return tag +} +// generate a random 16 byte client ID +export const generateClientID = () => randomBytes(16).toString('base64') +// generate a random ID to attach to a message +// this is the format used for WA Web 4 byte hex prefixed with 3EB0 +export const generateMessageID = () => '3EB0' + randomBytes(4).toString('hex').toUpperCase() \ No newline at end of file diff --git a/src/Utils/validateConnection.ts b/src/Utils/validateConnection.ts new file mode 100644 index 0000000..94f7279 --- /dev/null +++ b/src/Utils/validateConnection.ts @@ -0,0 +1,106 @@ +import Boom from 'boom' +import * as Curve from 'curve25519-js' +import type { Contact } from '../Types/Contact' +import type { AnyAuthenticationCredentials, AuthenticationCredentials, CurveKeyPair } from "../Types" +import { aesDecrypt, hkdf, hmacSign, whatsappID } from './generics' +import { readFileSync } from 'fs' + +export const normalizedAuthInfo = (authInfo: AnyAuthenticationCredentials | string) => { + if (!authInfo) return + + if (typeof authInfo === 'string') { + const file = readFileSync(authInfo, { encoding: 'utf-8' }) // load a closed session back if it exists + authInfo = JSON.parse(file) as AnyAuthenticationCredentials + } + if ('clientID' in authInfo) { + authInfo = { + clientID: authInfo.clientID, + serverToken: authInfo.serverToken, + clientToken: authInfo.clientToken, + encKey: Buffer.isBuffer(authInfo.encKey) ? authInfo.encKey : Buffer.from(authInfo.encKey, 'base64'), + macKey: Buffer.isBuffer(authInfo.macKey) ? authInfo.macKey : Buffer.from(authInfo.macKey, 'base64'), + } + } else { + const secretBundle: {encKey: string, macKey: string} = typeof authInfo.WASecretBundle === 'string' ? JSON.parse (authInfo.WASecretBundle): authInfo.WASecretBundle + authInfo = { + clientID: authInfo.WABrowserId.replace(/\"/g, ''), + serverToken: authInfo.WAToken2.replace(/\"/g, ''), + clientToken: authInfo.WAToken1.replace(/\"/g, ''), + encKey: Buffer.from(secretBundle.encKey, 'base64'), // decode from base64 + macKey: Buffer.from(secretBundle.macKey, 'base64'), // decode from base64 + } + } + return authInfo as AuthenticationCredentials +} +/** +* Once the QR code is scanned and we can validate our connection, or we resolved the challenge when logging back in +* @private +* @param json +*/ +export const validateNewConnection = ( + json: { [_: string]: any }, + auth: AuthenticationCredentials, + curveKeys: CurveKeyPair +) => { + // set metadata: one's WhatsApp ID [cc][number]@s.whatsapp.net, name on WhatsApp, info about the phone + const onValidationSuccess = () => { + const user: Contact = { + jid: whatsappID(json.wid), + name: json.pushname + } + return { user, auth, phone: json.phone } + } + if (!json.secret) { + // if we didn't get a secret, we don't need it, we're validated + if (json.clientToken && json.clientToken !== auth.clientToken) { + auth = { ...auth, clientToken: json.clientToken } + } + if (json.serverToken && json.serverToken !== auth.serverToken) { + auth = { ...auth, serverToken: json.serverToken } + } + return onValidationSuccess() + } + const secret = Buffer.from(json.secret, 'base64') + if (secret.length !== 144) { + throw new Error ('incorrect secret length received: ' + secret.length) + } + + // generate shared key from our private key & the secret shared by the server + const sharedKey = Curve.sharedKey(curveKeys.private, secret.slice(0, 32)) + // expand the key to 80 bytes using HKDF + const expandedKey = hkdf(sharedKey as Buffer, 80) + + // perform HMAC validation. + const hmacValidationKey = expandedKey.slice(32, 64) + const hmacValidationMessage = Buffer.concat([secret.slice(0, 32), secret.slice(64, secret.length)]) + + const hmac = hmacSign(hmacValidationMessage, hmacValidationKey) + + if (!hmac.equals(secret.slice(32, 64))) { + // if the checksums didn't match + throw new Boom('HMAC validation failed', { statusCode: 400 }) + } + + // computed HMAC should equal secret[32:64] + // expandedKey[64:] + secret[64:] are the keys, encrypted using AES, that are used to encrypt/decrypt the messages recieved from WhatsApp + // they are encrypted using key: expandedKey[0:32] + const encryptedAESKeys = Buffer.concat([ + expandedKey.slice(64, expandedKey.length), + secret.slice(64, secret.length), + ]) + const decryptedKeys = aesDecrypt(encryptedAESKeys, expandedKey.slice(0, 32)) + // set the credentials + auth = { + encKey: decryptedKeys.slice(0, 32), // first 32 bytes form the key to encrypt/decrypt messages + macKey: decryptedKeys.slice(32, 64), // last 32 bytes from the key to sign messages + clientToken: json.clientToken, + serverToken: json.serverToken, + clientID: auth.clientID, + } + return onValidationSuccess() +} +export const computeChallengeResponse = (challenge: string, auth: AuthenticationCredentials) => { + const bytes = Buffer.from(challenge, 'base64') // decode the base64 encoded challenge string + const signed = hmacSign(bytes, auth.macKey).toString('base64') // sign the challenge string with our macKey + return[ 'admin', 'challenge', signed, auth.serverToken, auth.clientID] // prepare to send this signed string with the serverToken & clientID +} \ No newline at end of file diff --git a/src/WAConnection/0.Base.ts b/src/WAConnection/0.Base.ts deleted file mode 100644 index 1a3865f..0000000 --- a/src/WAConnection/0.Base.ts +++ /dev/null @@ -1,478 +0,0 @@ -import WS from 'ws' -import * as fs from 'fs' -import * as Utils from './Utils' -import Encoder from '../Binary/Encoder' -import Decoder from '../Binary/Decoder' -import got, { Method } from 'got' -import { - AuthenticationCredentials, - WAUser, - WANode, - WATag, - BaileysError, - WAMetric, - WAFlag, - DisconnectReason, - WAConnectionState, - AnyAuthenticationCredentials, - WAContact, - WAQuery, - ReconnectMode, - WAConnectOptions, - MediaConnInfo, - DEFAULT_ORIGIN, -} from './Constants' -import { EventEmitter } from 'events' -import KeyedDB from '@adiwajshing/keyed-db' -import { STATUS_CODES } from 'http' -import { Agent } from 'https' -import pino from 'pino' - -const logger = pino({ prettyPrint: { levelFirst: true, ignore: 'hostname', translateTime: true }, prettifier: require('pino-pretty') }) - -export class WAConnection extends EventEmitter { - /** The version of WhatsApp Web we're telling the servers we are */ - version: [number, number, number] = [2, 2123, 8] - /** The Browser we're telling the WhatsApp Web servers we are */ - browserDescription: [string, string, string] = Utils.Browsers.baileys ('Chrome') - /** Metadata like WhatsApp id, name set on WhatsApp etc. */ - user: WAUser - /** Should requests be queued when the connection breaks in between; if 0, then an error will be thrown */ - pendingRequestTimeoutMs: number = null - /** The connection state */ - state: WAConnectionState = 'close' - connectOptions: WAConnectOptions = { - maxIdleTimeMs: 60_000, - maxRetries: 10, - connectCooldownMs: 4000, - phoneResponseTime: 15_000, - maxQueryResponseTime: 10_000, - alwaysUseTakeover: true, - queryChatsTillReceived: true, - logQR: true - } - /** When to auto-reconnect */ - autoReconnect = ReconnectMode.onConnectionLost - /** Whether the phone is connected */ - phoneConnected: boolean = false - /** key to use to order chats */ - chatOrderingKey = Utils.waChatKey(false) - - logger = logger.child ({ class: 'Baileys' }) - - /** log messages */ - shouldLogMessages = false - messageLog: { tag: string, json: string, fromMe: boolean, binaryTags?: any[] }[] = [] - - maxCachedMessages = 50 - - lastChatsReceived: Date - chats = new KeyedDB (Utils.waChatKey(false), value => value.jid) - contacts: { [k: string]: WAContact } = {} - blocklist: string[] = [] - - /** Data structure of tokens & IDs used to establish one's identiy to WhatsApp Web */ - protected authInfo: AuthenticationCredentials - /** Curve keys to initially authenticate */ - protected curveKeys: { private: Uint8Array; public: Uint8Array } - /** The websocket connection */ - protected conn: WS - protected msgCount = 0 - protected keepAliveReq: NodeJS.Timeout - protected encoder = new Encoder() - protected decoder = new Decoder() - protected phoneCheckInterval - protected phoneCheckListeners = 0 - - protected referenceDate = new Date () // used for generating tags - protected lastSeen: Date = null // last keep alive received - protected initTimeout: NodeJS.Timeout - - protected lastDisconnectTime: Date = null - protected lastDisconnectReason: DisconnectReason - - protected mediaConn: MediaConnInfo - protected connectionDebounceTimeout = Utils.debouncedTimeout( - 1000, - () => this.state === 'connecting' && this.endConnection(DisconnectReason.timedOut) - ) - // timeout to know when we're done recieving messages - protected messagesDebounceTimeout = Utils.debouncedTimeout(2000) - // ping chats till recieved - protected chatsDebounceTimeout = Utils.debouncedTimeout(10_000) - /** - * Connect to WhatsAppWeb - * @param options the connect options - */ - async connect() { - return null - } - async unexpectedDisconnect (error: DisconnectReason) { - if (this.state === 'open') { - const willReconnect = - (this.autoReconnect === ReconnectMode.onAllErrors || - (this.autoReconnect === ReconnectMode.onConnectionLost && error !== DisconnectReason.replaced)) && - error !== DisconnectReason.invalidSession // do not reconnect if credentials have been invalidated - - this.closeInternal(error, willReconnect) - willReconnect && ( - this.connect() - .catch(err => {}) // prevent unhandled exeception - ) - } else { - this.endConnection(error) - } - } - /** - * base 64 encode the authentication credentials and return them - * these can then be used to login again by passing the object to the connect () function. - * @see connect () in WhatsAppWeb.Session - */ - base64EncodedAuthInfo() { - return { - clientID: this.authInfo.clientID, - serverToken: this.authInfo.serverToken, - clientToken: this.authInfo.clientToken, - encKey: this.authInfo.encKey.toString('base64'), - macKey: this.authInfo.macKey.toString('base64'), - } - } - /** Can you login to WA without scanning the QR */ - canLogin () { - return !!this.authInfo?.encKey && !!this.authInfo?.macKey - } - /** Clear authentication info so a new connection can be created */ - clearAuthInfo () { - this.authInfo = null - return this - } - /** - * Load in the authentication credentials - * @param authInfo the authentication credentials or file path to auth credentials - */ - loadAuthInfo(authInfo: AnyAuthenticationCredentials | string) { - if (!authInfo) throw new Error('given authInfo is null') - - if (typeof authInfo === 'string') { - this.logger.info(`loading authentication credentials from ${authInfo}`) - const file = fs.readFileSync(authInfo, { encoding: 'utf-8' }) // load a closed session back if it exists - authInfo = JSON.parse(file) as AnyAuthenticationCredentials - } - if ('clientID' in authInfo) { - this.authInfo = { - clientID: authInfo.clientID, - serverToken: authInfo.serverToken, - clientToken: authInfo.clientToken, - encKey: Buffer.isBuffer(authInfo.encKey) ? authInfo.encKey : Buffer.from(authInfo.encKey, 'base64'), - macKey: Buffer.isBuffer(authInfo.macKey) ? authInfo.macKey : Buffer.from(authInfo.macKey, 'base64'), - } - } else { - const secretBundle: {encKey: string, macKey: string} = typeof authInfo.WASecretBundle === 'string' ? JSON.parse (authInfo.WASecretBundle): authInfo.WASecretBundle - this.authInfo = { - clientID: authInfo.WABrowserId.replace(/\"/g, ''), - serverToken: authInfo.WAToken2.replace(/\"/g, ''), - clientToken: authInfo.WAToken1.replace(/\"/g, ''), - encKey: Buffer.from(secretBundle.encKey, 'base64'), // decode from base64 - macKey: Buffer.from(secretBundle.macKey, 'base64'), // decode from base64 - } - } - return this - } - /** - * Wait for a message with a certain tag to be received - * @param tag the message tag to await - * @param json query that was sent - * @param timeoutMs timeout after which the promise will reject - */ - async waitForMessage(tag: string, requiresPhoneConnection: boolean, timeoutMs?: number) { - let onRecv: (json) => void - let onErr: (err) => void - let cancelPhoneChecker: () => void - if (requiresPhoneConnection) { - this.startPhoneCheckInterval() - cancelPhoneChecker = this.exitQueryIfResponseNotExpected(tag, err => onErr(err)) - } - try { - const result = await Utils.promiseTimeout(timeoutMs, - (resolve, reject) => { - onRecv = resolve - onErr = ({ reason, status }) => reject(new BaileysError(reason, { status })) - this.on (`TAG:${tag}`, onRecv) - this.on ('ws-close', onErr) // if the socket closes, you'll never receive the message - }, - ) - return result as any - } finally { - requiresPhoneConnection && this.clearPhoneCheckInterval() - this.off (`TAG:${tag}`, onRecv) - this.off (`ws-close`, onErr) - cancelPhoneChecker && cancelPhoneChecker() - } - } - /** Generic function for action, set queries */ - async setQuery (nodes: WANode[], binaryTags: WATag = [WAMetric.group, WAFlag.ignore], tag?: string) { - const json = ['action', {epoch: this.msgCount.toString(), type: 'set'}, nodes] - const result = await this.query({ json, binaryTags, tag, expect200: true, requiresPhoneConnection: true }) as Promise<{status: number}> - return result - } - /** - * Query something from the WhatsApp servers - * @param json the query itself - * @param binaryTags the tags to attach if the query is supposed to be sent encoded in binary - * @param timeoutMs timeout after which the query will be failed (set to null to disable a timeout) - * @param tag the tag to attach to the message - */ - async query(q: WAQuery): Promise { - let {json, binaryTags, tag, timeoutMs, expect200, waitForOpen, longTag, requiresPhoneConnection, startDebouncedTimeout, maxRetries} = q - requiresPhoneConnection = requiresPhoneConnection !== false - waitForOpen = waitForOpen !== false - let triesLeft = maxRetries || 2 - tag = tag || this.generateMessageTag(longTag) - - while (triesLeft >= 0) { - if (waitForOpen) await this.waitForConnection() - - const promise = this.waitForMessage(tag, requiresPhoneConnection, timeoutMs) - - if (this.logger.level === 'trace') { - this.logger.trace ({ fromMe: true },`${tag},${JSON.stringify(json)}`) - } - - if (binaryTags) tag = await this.sendBinary(json as WANode, binaryTags, tag) - else tag = await this.sendJSON(json, tag) - - try { - const response = await promise - if (expect200 && response.status && Math.floor(+response.status / 100) !== 2) { - const message = STATUS_CODES[response.status] || 'unknown' - throw new BaileysError ( - `Unexpected status in '${json[0] || 'query'}': ${STATUS_CODES[response.status]}(${response.status})`, - {query: json, message, status: response.status} - ) - } - if (startDebouncedTimeout) { - this.connectionDebounceTimeout.start() - } - return response - } catch (error) { - if (triesLeft === 0) { - throw error - } - // read here: http://getstatuscode.com/599 - if (error.status === 599) { - this.unexpectedDisconnect (DisconnectReason.badSession) - } else if ( - (error.message === 'close' || error.message === 'lost') && - waitForOpen && - this.state !== 'close' && - (this.pendingRequestTimeoutMs === null || - this.pendingRequestTimeoutMs > 0)) { - // nothing here - } else throw error - - triesLeft -= 1 - this.logger.debug(`query failed due to ${error}, retrying...`) - } - } - } - protected exitQueryIfResponseNotExpected(tag: string, cancel: ({ reason, status }) => void) { - let timeout: NodeJS.Timeout - const listener = ({ connected }) => { - if(connected) { - timeout = setTimeout(() => { - this.logger.info({ tag }, `cancelling wait for message as a response is no longer expected from the phone`) - cancel({ reason: 'Not expecting a response', status: 422 }) - }, this.connectOptions.maxQueryResponseTime) - this.off('connection-phone-change', listener) - } - } - this.on('connection-phone-change', listener) - return () => { - this.off('connection-phone-change', listener) - timeout && clearTimeout(timeout) - } - } - /** interval is started when a query takes too long to respond */ - protected startPhoneCheckInterval () { - this.phoneCheckListeners += 1 - if (!this.phoneCheckInterval) { - // if its been a long time and we haven't heard back from WA, send a ping - this.phoneCheckInterval = setInterval (() => { - if (!this.conn) return // if disconnected, then don't do anything - - this.logger.info('checking phone connection...') - this.sendAdminTest () - if(this.phoneConnected !== false) { - this.phoneConnected = false - this.emit ('connection-phone-change', { connected: false }) - } - }, this.connectOptions.phoneResponseTime) - } - - } - protected clearPhoneCheckInterval () { - this.phoneCheckListeners -= 1 - if (this.phoneCheckListeners <= 0) { - this.phoneCheckInterval && clearInterval (this.phoneCheckInterval) - this.phoneCheckInterval = undefined - this.phoneCheckListeners = 0 - } - - } - /** checks for phone connection */ - protected async sendAdminTest () { - return this.sendJSON (['admin', 'test']) - } - /** - * Send a binary encoded message - * @param json the message to encode & send - * @param tags the binary tags to tell WhatsApp what the message is all about - * @param tag the tag to attach to the message - * @return the message tag - */ - protected async sendBinary(json: WANode, tags: WATag, tag: string = null, longTag: boolean = false) { - const binary = this.encoder.write(json) // encode the JSON to the WhatsApp binary format - - let buff = Utils.aesEncrypt(binary, this.authInfo.encKey) // encrypt it using AES and our encKey - const sign = Utils.hmacSign(buff, this.authInfo.macKey) // sign the message using HMAC and our macKey - tag = tag || this.generateMessageTag(longTag) - - if (this.shouldLogMessages) this.messageLog.push ({ tag, json: JSON.stringify(json), fromMe: true, binaryTags: tags }) - - buff = Buffer.concat([ - Buffer.from(tag + ','), // generate & prefix the message tag - Buffer.from(tags), // prefix some bytes that tell whatsapp what the message is about - sign, // the HMAC sign of the message - buff, // the actual encrypted buffer - ]) - await this.send(buff) // send it off - return tag - } - /** - * Send a plain JSON message to the WhatsApp servers - * @param json the message to send - * @param tag the tag to attach to the message - * @returns the message tag - */ - protected async sendJSON(json: any[] | WANode, tag: string = null, longTag: boolean = false) { - tag = tag || this.generateMessageTag(longTag) - if (this.shouldLogMessages) this.messageLog.push ({ tag, json: JSON.stringify(json), fromMe: true }) - await this.send(`${tag},${JSON.stringify(json)}`) - return tag - } - /** Send some message to the WhatsApp servers */ - protected async send(m) { - this.conn.send(m) - } - protected async waitForConnection () { - if (this.state === 'open') return - - let onOpen: () => void - let onClose: ({ reason }) => void - - if (this.pendingRequestTimeoutMs !== null && this.pendingRequestTimeoutMs <= 0) { - throw new BaileysError(DisconnectReason.close, { status: 428 }) - } - await ( - Utils.promiseTimeout ( - this.pendingRequestTimeoutMs, - (resolve, reject) => { - onClose = ({ reason }) => { - if (reason === DisconnectReason.invalidSession || reason === DisconnectReason.intentional) { - reject (new Error(reason)) - } - } - onOpen = resolve - this.on ('close', onClose) - this.on ('open', onOpen) - } - ) - .finally(() => { - this.off ('open', onOpen) - this.off ('close', onClose) - }) - ) - } - /** - * Disconnect from the phone. Your auth credentials become invalid after sending a disconnect request. - * @see close() if you just want to close the connection - */ - async logout () { - this.authInfo = null - if (this.state === 'open') { - //throw new Error("You're not even connected, you can't log out") - await new Promise(resolve => this.conn.send('goodbye,["admin","Conn","disconnect"]', null, resolve)) - } - this.user = undefined - this.chats.clear() - this.contacts = {} - this.close() - } - /** Close the connection to WhatsApp Web */ - close () { - this.closeInternal (DisconnectReason.intentional) - } - protected closeInternal (reason?: DisconnectReason, isReconnecting: boolean=false) { - this.logger.info (`closed connection, reason ${reason}${isReconnecting ? ', reconnecting in a few seconds...' : ''}`) - - this.state = 'close' - this.phoneConnected = false - this.lastDisconnectReason = reason - this.lastDisconnectTime = new Date () - - this.endConnection(reason) - // reconnecting if the timeout is active for the reconnect loop - this.emit ('close', { reason, isReconnecting }) - } - protected endConnection (reason: DisconnectReason) { - this.conn?.removeAllListeners ('close') - this.conn?.removeAllListeners ('error') - this.conn?.removeAllListeners ('open') - this.conn?.removeAllListeners ('message') - - this.initTimeout && clearTimeout (this.initTimeout) - this.connectionDebounceTimeout.cancel() - this.messagesDebounceTimeout.cancel() - this.chatsDebounceTimeout.cancel() - this.keepAliveReq && clearInterval(this.keepAliveReq) - this.phoneCheckListeners = 0 - this.clearPhoneCheckInterval () - - this.emit ('ws-close', { reason }) - - try { - this.conn?.close() - //this.conn?.terminate() - } catch { - - } - this.conn = undefined - this.lastSeen = undefined - this.msgCount = 0 - } - /** - * Does a fetch request with the configuration of the connection - */ - protected fetchRequest = ( - endpoint: string, - method: Method = 'GET', - body?: any, - agent?: Agent, - headers?: {[k: string]: string}, - followRedirect = true - ) => ( - got(endpoint, { - method, - body, - followRedirect, - headers: { Origin: DEFAULT_ORIGIN, ...(headers || {}) }, - agent: { https: agent || this.connectOptions.fetchAgent } - }) - ) - generateMessageTag (longTag: boolean = false) { - const seconds = Utils.unixTimestampSeconds(this.referenceDate) - const tag = `${longTag ? seconds : (seconds%1000)}.--${this.msgCount}` - this.msgCount += 1 // increment message count, it makes the 'epoch' field when sending binary messages - return tag - } -} diff --git a/src/WAConnection/1.Validation.ts b/src/WAConnection/1.Validation.ts deleted file mode 100644 index 7bbaaec..0000000 --- a/src/WAConnection/1.Validation.ts +++ /dev/null @@ -1,224 +0,0 @@ -import * as Curve from 'curve25519-js' -import * as Utils from './Utils' -import {WAConnection as Base} from './0.Base' -import { WAMetric, WAFlag, BaileysError, Presence, WAUser, WAInitResponse, WAOpenResult } from './Constants' - -export class WAConnection extends Base { - - /** Authenticate the connection */ - protected async authenticate (reconnect?: string) { - // if no auth info is present, that is, a new session has to be established - // generate a client ID - if (!this.authInfo?.clientID) { - this.authInfo = { clientID: Utils.generateClientID() } as any - } - const canLogin = this.canLogin() - this.referenceDate = new Date () // refresh reference date - - this.connectionDebounceTimeout.start() - - const initQuery = (async () => { - const {ref, ttl} = await this.query({ - json: ['admin', 'init', this.version, this.browserDescription, this.authInfo?.clientID, true], - expect200: true, - waitForOpen: false, - longTag: true, - requiresPhoneConnection: false, - startDebouncedTimeout: true - }) as WAInitResponse - - if (!canLogin) { - this.connectionDebounceTimeout.cancel() // stop the debounced timeout for QR gen - this.generateKeysForAuth (ref, ttl) - } - })(); - let loginTag: string - if (canLogin) { - // if we have the info to restore a closed session - const json = [ - 'admin', - 'login', - this.authInfo?.clientToken, - this.authInfo?.serverToken, - this.authInfo?.clientID, - ] - loginTag = this.generateMessageTag(true) - - if (reconnect) json.push(...['reconnect', reconnect.replace('@s.whatsapp.net', '@c.us')]) - else json.push ('takeover') - // send login every 10s - const sendLoginReq = () => { - if (!this.conn || this.conn?.readyState !== this.conn.OPEN) { - this.logger.warn('Received login timeout req when WS not open, ignoring...') - return - } - if (this.state === 'open') { - this.logger.warn('Received login timeout req when state=open, ignoring...') - return - } - this.logger.debug('sending login request') - this.sendJSON(json, loginTag) - this.initTimeout = setTimeout(sendLoginReq, 10_000) - } - sendLoginReq() - } - - await initQuery - - // wait for response with tag "s1" - let response = await Promise.race( - [ - this.waitForMessage('s1', false, undefined), - loginTag && this.waitForMessage(loginTag, false, undefined) - ] - .filter(Boolean) - ) - this.connectionDebounceTimeout.start() - this.initTimeout && clearTimeout (this.initTimeout) - this.initTimeout = null - - if (response.status && response.status !== 200) { - throw new BaileysError(`Unexpected error in login`, { response, status: response.status }) - } - // if its a challenge request (we get it when logging in) - if (response[1]?.challenge) { - await this.respondToChallenge(response[1].challenge) - response = await this.waitForMessage('s2', true) - } - - const result = this.validateNewConnection(response[1])// validate the connection - if (result.user.jid !== this.user?.jid) { - result.isNewUser = true - // clear out old data - this.chats.clear() - this.contacts = {} - } - this.user = result.user - - this.logger.info('validated connection successfully') - - return result - } - /** - * Refresh QR Code - * @returns the new ref - */ - async requestNewQRCodeRef() { - const response = await this.query({ - json: ['admin', 'Conn', 'reref'], - expect200: true, - waitForOpen: false, - longTag: true, - requiresPhoneConnection: false - }) - return response as WAInitResponse - } - /** - * Once the QR code is scanned and we can validate our connection, or we resolved the challenge when logging back in - * @private - * @param {object} json - */ - private validateNewConnection(json) { - // set metadata: one's WhatsApp ID [cc][number]@s.whatsapp.net, name on WhatsApp, info about the phone - const onValidationSuccess = () => ({ - user: { - jid: Utils.whatsappID(json.wid), - name: json.pushname, - phone: json.phone, - imgUrl: null - }, - auth: this.authInfo - }) as WAOpenResult - - if (!json.secret) { - // if we didn't get a secret, we don't need it, we're validated - if (json.clientToken && json.clientToken !== this.authInfo.clientToken) { - this.authInfo = { ...this.authInfo, clientToken: json.clientToken } - } - if (json.serverToken && json.serverToken !== this.authInfo.serverToken) { - this.authInfo = { ...this.authInfo, serverToken: json.serverToken } - } - return onValidationSuccess() - } - const secret = Buffer.from(json.secret, 'base64') - if (secret.length !== 144) { - throw new Error ('incorrect secret length received: ' + secret.length) - } - - // generate shared key from our private key & the secret shared by the server - const sharedKey = Curve.sharedKey(this.curveKeys.private, secret.slice(0, 32)) - // expand the key to 80 bytes using HKDF - const expandedKey = Utils.hkdf(sharedKey as Buffer, 80) - - // perform HMAC validation. - const hmacValidationKey = expandedKey.slice(32, 64) - const hmacValidationMessage = Buffer.concat([secret.slice(0, 32), secret.slice(64, secret.length)]) - - const hmac = Utils.hmacSign(hmacValidationMessage, hmacValidationKey) - - if (!hmac.equals(secret.slice(32, 64))) { - // if the checksums didn't match - throw new BaileysError ('HMAC validation failed', json) - } - - // computed HMAC should equal secret[32:64] - // expandedKey[64:] + secret[64:] are the keys, encrypted using AES, that are used to encrypt/decrypt the messages recieved from WhatsApp - // they are encrypted using key: expandedKey[0:32] - const encryptedAESKeys = Buffer.concat([ - expandedKey.slice(64, expandedKey.length), - secret.slice(64, secret.length), - ]) - const decryptedKeys = Utils.aesDecrypt(encryptedAESKeys, expandedKey.slice(0, 32)) - // set the credentials - this.authInfo = { - encKey: decryptedKeys.slice(0, 32), // first 32 bytes form the key to encrypt/decrypt messages - macKey: decryptedKeys.slice(32, 64), // last 32 bytes from the key to sign messages - clientToken: json.clientToken, - serverToken: json.serverToken, - clientID: this.authInfo.clientID, - } - return onValidationSuccess() - } - /** - * When logging back in (restoring a previously closed session), WhatsApp may challenge one to check if one still has the encryption keys - * WhatsApp does that by asking for us to sign a string it sends with our macKey - */ - protected respondToChallenge(challenge: string) { - const bytes = Buffer.from(challenge, 'base64') // decode the base64 encoded challenge string - const signed = Utils.hmacSign(bytes, this.authInfo.macKey).toString('base64') // sign the challenge string with our macKey - const json = ['admin', 'challenge', signed, this.authInfo.serverToken, this.authInfo.clientID] // prepare to send this signed string with the serverToken & clientID - - this.logger.info('resolving login challenge') - return this.query({json, expect200: true, waitForOpen: false, startDebouncedTimeout: true}) - } - /** When starting a new session, generate a QR code by generating a private/public key pair & the keys the server sends */ - protected generateKeysForAuth(ref: string, ttl?: number) { - this.curveKeys = Curve.generateKeyPair(Utils.randomBytes(32)) - const publicKey = Buffer.from(this.curveKeys.public).toString('base64') - - const qrLoop = ttl => { - const qr = [ref, publicKey, this.authInfo.clientID].join(',') - this.emit ('qr', qr) - - this.initTimeout = setTimeout (async () => { - if (this.state === 'open') return - - this.logger.debug ('regenerating QR') - try { - const {ref: newRef, ttl: newTTL} = await this.requestNewQRCodeRef() - ttl = newTTL - ref = newRef - } catch (error) { - this.logger.warn ({ error }, `error in QR gen`) - // @ts-ignore - if (error.status === 429 && this.state !== 'open') { // too many QR requests - this.endConnection(error.message) - return - } - } - qrLoop (ttl) - }, ttl || 20_000) // default is 20s, on the off-chance ttl is not present - } - qrLoop (ttl) - } -} diff --git a/src/WAConnection/3.Connect.ts b/src/WAConnection/3.Connect.ts deleted file mode 100644 index 0dc4f56..0000000 --- a/src/WAConnection/3.Connect.ts +++ /dev/null @@ -1,196 +0,0 @@ -import * as Utils from './Utils' -import { KEEP_ALIVE_INTERVAL_MS, BaileysError, WAConnectOptions, DisconnectReason, UNAUTHORIZED_CODES, CancelledError, WAOpenResult, DEFAULT_ORIGIN, WS_URL } from './Constants' -import {WAConnection as Base} from './1.Validation' -import Decoder from '../Binary/Decoder' -import WS from 'ws' - -const DEF_CALLBACK_PREFIX = 'CB:' -const DEF_TAG_PREFIX = 'TAG:' - -export class WAConnection extends Base { - /** Connect to WhatsApp Web */ - async connect () { - // if we're already connected, throw an error - if (this.state !== 'close') { - throw new BaileysError('cannot connect when state=' + this.state, { status: 409 }) - } - - const options = this.connectOptions - const newConnection = !this.authInfo - - this.state = 'connecting' - this.emit ('connecting') - - let tries = 0 - let lastConnect = this.lastDisconnectTime - let result: WAOpenResult - while (this.state === 'connecting') { - tries += 1 - try { - const diff = lastConnect ? new Date().getTime()-lastConnect.getTime() : Infinity - result = await this.connectInternal ( - options, - diff > this.connectOptions.connectCooldownMs ? 0 : this.connectOptions.connectCooldownMs - ) - this.phoneConnected = true - this.state = 'open' - } catch (error) { - lastConnect = new Date() - - const loggedOut = error instanceof BaileysError && UNAUTHORIZED_CODES.includes(error.status) - const willReconnect = !loggedOut && (tries < options?.maxRetries) && (this.state === 'connecting') - const reason = loggedOut ? DisconnectReason.invalidSession : error.message - - this.logger.warn ({ error }, `connect attempt ${tries} failed: ${error}${ willReconnect ? ', retrying...' : ''}`) - - if ((this.state as string) !== 'close' && !willReconnect) { - this.closeInternal (reason) - } - if (!willReconnect) throw error - } - } - if (newConnection) result.newConnection = newConnection - this.emit ('open', result) - - this.logger.info ('opened connection to WhatsApp Web') - - this.conn.on ('close', () => this.unexpectedDisconnect (DisconnectReason.close)) - - return result - } - /** Meat of the connect logic */ - protected async connectInternal (options: WAConnectOptions, delayMs?: number) { - const rejections: ((e?: Error) => void)[] = [] - const rejectAll = (e: Error) => rejections.forEach (r => r(e)) - const rejectAllOnWSClose = ({ reason }) => rejectAll(new Error(reason)) - // actual connect - const connect = () => ( - new Promise((resolve, reject) => { - rejections.push (reject) - // determine whether reconnect should be used or not - const shouldUseReconnect = (this.lastDisconnectReason === DisconnectReason.close || - this.lastDisconnectReason === DisconnectReason.lost) && - !this.connectOptions.alwaysUseTakeover - const reconnectID = shouldUseReconnect && this.user.jid.replace ('@s.whatsapp.net', '@c.us') - - this.conn = new WS(WS_URL, null, { - origin: DEFAULT_ORIGIN, - timeout: this.connectOptions.maxIdleTimeMs, - agent: options.agent, - headers: { - 'Accept-Encoding': 'gzip, deflate, br', - 'Accept-Language': 'en-US,en;q=0.9', - 'Cache-Control': 'no-cache', - 'Host': 'web.whatsapp.com', - 'Pragma': 'no-cache', - 'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits', - } - }) - - this.conn.on('message', data => this.onMessageRecieved(data as any)) - - this.conn.once('open', async () => { - this.startKeepAliveRequest() - this.logger.info(`connected to WhatsApp Web server, authenticating via ${reconnectID ? 'reconnect' : 'takeover'}`) - - try { - this.connectionDebounceTimeout.setInterval(this.connectOptions.maxIdleTimeMs) - const authResult = await this.authenticate(reconnectID) - - this.conn - .removeAllListeners('error') - .removeAllListeners('close') - this.connectionDebounceTimeout.start() - resolve(authResult as WAOpenResult) - } catch (error) { - reject(error) - } - }) - this.conn.on('error', rejectAll) - this.conn.on('close', () => rejectAll(new Error(DisconnectReason.close))) - }) as Promise - ) - - this.on ('ws-close', rejectAllOnWSClose) - try { - if (delayMs) { - const {delay, cancel} = Utils.delayCancellable (delayMs) - rejections.push (cancel) - await delay - } - const result = await connect () - return result - } catch (error) { - if (this.conn) { - this.endConnection(error.message) - } - throw error - } finally { - this.off ('ws-close', rejectAllOnWSClose) - } - } - private onMessageRecieved(message: string | Buffer) { - if (message[0] === '!') { - // when the first character in the message is an '!', the server is sending a pong frame - const timestamp = message.slice(1, message.length).toString ('utf-8') - this.lastSeen = new Date(parseInt(timestamp)) - this.emit ('received-pong') - } else { - let messageTag: string - let json: any - try { - const dec = Utils.decryptWA (message, this.authInfo?.macKey, this.authInfo?.encKey, new Decoder()) - messageTag = dec[0] - json = dec[1] - } catch (error) { - this.logger.error ({ error }, `encountered error in decrypting message, closing: ${error}`) - - this.unexpectedDisconnect(DisconnectReason.badSession) - } - - if (this.shouldLogMessages) this.messageLog.push ({ tag: messageTag, json: JSON.stringify(json), fromMe: false }) - if (!json) return - - if (this.logger.level === 'trace') { - this.logger.trace(messageTag + ',' + JSON.stringify(json)) - } - - let anyTriggered = false - /* Check if this is a response to a message we sent */ - anyTriggered = this.emit (`${DEF_TAG_PREFIX}${messageTag}`, json) - /* Check if this is a response to a message we are expecting */ - const l0 = json[0] || '' - const l1 = typeof json[1] !== 'object' || json[1] === null ? {} : json[1] - const l2 = ((json[2] || [])[0] || [])[0] || '' - - Object.keys(l1).forEach(key => { - anyTriggered = this.emit (`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, json) || anyTriggered; - anyTriggered = this.emit (`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, json) || anyTriggered; - anyTriggered = this.emit (`${DEF_CALLBACK_PREFIX}${l0},${key}`, json) || anyTriggered; - }) - anyTriggered = this.emit (`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, json) || anyTriggered; - anyTriggered = this.emit (`${DEF_CALLBACK_PREFIX}${l0}`, json) || anyTriggered; - - if (anyTriggered) return - - if (this.logger.level === 'debug') { - this.logger.debug({ unhandled: true }, messageTag + ',' + JSON.stringify(json)) - } - } - } - /** Send a keep alive request every X seconds, server updates & responds with last seen */ - private startKeepAliveRequest() { - this.keepAliveReq && clearInterval (this.keepAliveReq) - - this.keepAliveReq = setInterval(() => { - if (!this.lastSeen) this.lastSeen = new Date () - const diff = new Date().getTime() - this.lastSeen.getTime() - /* - check if it's been a suspicious amount of time since the server responded with our last seen - it could be that the network is down - */ - if (diff > KEEP_ALIVE_INTERVAL_MS+5000) this.unexpectedDisconnect(DisconnectReason.lost) - else if (this.conn) this.send('?,,') // if its all good, send a keep alive request - }, KEEP_ALIVE_INTERVAL_MS) - } -} diff --git a/src/WAConnection/4.Events.ts b/src/WAConnection/4.Events.ts deleted file mode 100644 index 994d600..0000000 --- a/src/WAConnection/4.Events.ts +++ /dev/null @@ -1,717 +0,0 @@ -import * as QR from 'qrcode-terminal' -import { WAConnection as Base } from './3.Connect' -import { WAMessage, WAContact, WAChat, WAMessageProto, WA_MESSAGE_STUB_TYPE, WA_MESSAGE_STATUS_TYPE, PresenceUpdate, BaileysEvent, DisconnectReason, WAOpenResult, Presence, WAParticipantAction, WAGroupMetadata, WANode, WAPresenceData, WAChatUpdate, BlocklistUpdate, WAContactUpdate, WAMetric, WAFlag } from './Constants' -import { whatsappID, unixTimestampSeconds, GET_MESSAGE_ID, WA_MESSAGE_ID, newMessagesDB, shallowChanges, toNumber, isGroupID } from './Utils' -import KeyedDB from '@adiwajshing/keyed-db' -import { Mutex } from './Mutex' - -export class WAConnection extends Base { - - constructor () { - super () - this.setMaxListeners (30) - this.chatsDebounceTimeout.setTask(() => { - this.logger.debug('pinging with chats query') - this.sendChatsQuery(this.msgCount) - - this.chatsDebounceTimeout.start() - }) - this.on('open', () => { - // send queries WA Web expects - this.sendBinary (['query', {type: 'contacts', epoch: '1'}, null], [ WAMetric.queryContact, WAFlag.ignore ]) - this.sendBinary (['query', {type: 'status', epoch: '1'}, null], [ WAMetric.queryStatus, WAFlag.ignore ]) - this.sendBinary (['query', {type: 'quick_reply', epoch: '1'}, null], [ WAMetric.queryQuickReply, WAFlag.ignore ]) - this.sendBinary (['query', {type: 'label', epoch: '1'}, null], [ WAMetric.queryLabel, WAFlag.ignore ]) - this.sendBinary (['query', {type: 'emoji', epoch: '1'}, null], [ WAMetric.queryEmoji, WAFlag.ignore ]) - this.sendBinary (['action', {type: 'set', epoch: '1'}, [['presence', {type: Presence.available}, null]] ], [ WAMetric.presence, WAFlag.available ]) - - if(this.connectOptions.queryChatsTillReceived) { - this.chatsDebounceTimeout.start() - } else { - this.sendChatsQuery(1) - } - - this.logger.debug('sent init queries') - }) - // on disconnects - this.on('CB:Cmd,type:disconnect', json => ( - this.state === 'open' && this.unexpectedDisconnect(json[1].kind || 'unknown') - )) - this.on('CB:Pong', json => { - if (!json[1]) { - this.unexpectedDisconnect(DisconnectReason.close) - this.logger.info('Connection terminated by phone, closing...') - } else if (this.phoneConnected !== json[1]) { - this.phoneConnected = json[1] - this.emit ('connection-phone-change', { connected: this.phoneConnected }) - } - }) - // chats received - this.on('CB:response,type:chat', json => { - if (json[1].duplicate || !json[2]) return - - this.chatsDebounceTimeout.cancel() - const chats = new KeyedDB(this.chatOrderingKey, c => c.jid) - - json[2].forEach(([item, chat]: [any, WAChat]) => { - if (!chat) { - this.logger.warn (`unexpectedly got null chat: ${item}`, chat) - return - } - chat.jid = whatsappID (chat.jid) - chat.t = +chat.t - chat.count = +chat.count - chat.messages = newMessagesDB() - // chats data (log json to see what it looks like) - chats.insertIfAbsent(chat) - }) - this.logger.info (`received ${json[2].length} chats`) - - const oldChats = this.chats - const updatedChats = [] - let hasNewChats = false - - chats.all().forEach (chat => { - const respectiveContact = this.contacts[chat.jid] - chat.name = respectiveContact?.name || respectiveContact?.notify || chat.name - - const oldChat = oldChats.get(chat.jid) - if (!oldChat) { - hasNewChats = true - } else { - chat.messages = oldChat.messages - if (oldChat.t !== chat.t || oldChat.modify_tag !== chat.modify_tag) { - const changes = shallowChanges (oldChat, chat, { lookForDeletedKeys: true }) - delete chat.metadata // remove group metadata as that may have changed; TODO, write better mechanism for this - delete changes.messages - - updatedChats.push({ ...changes, jid: chat.jid }) - } - } - }) - this.chats = chats - this.lastChatsReceived = new Date() - - updatedChats.length > 0 && this.emit('chats-update', updatedChats) - - this.emit('chats-received', { hasNewChats }) - }) - // we store these last messages - const lastMessages = {} - // keep track of overlaps, - // if there are no overlaps of messages and we had messages present, we clear the previous messages - // this prevents missing messages in conversations - let overlaps: { [_: string]: { requiresOverlap: boolean, didOverlap?: boolean } } = {} - const onLastBatchOfDataReceived = () => { - // find which chats had missing messages - // list out all the jids, and how many messages we've cached now - const chatsWithMissingMessages = Object.keys(overlaps).map(jid => { - // if there was no overlap, delete previous messages - if (!overlaps[jid].didOverlap && overlaps[jid].requiresOverlap) { - this.logger.debug(`received messages for ${jid}, but did not overlap with previous messages, clearing...`) - const chat = this.chats.get(jid) - if (chat) { - const message = chat.messages.get(lastMessages[jid]) - const remainingMessages = chat.messages.paginatedByValue(message, this.maxCachedMessages, undefined, 'after') - chat.messages = newMessagesDB([message, ...remainingMessages]) - return { jid, count: chat.messages.length } // return number of messages we've left - } - } - }).filter(Boolean) - this.emit('initial-data-received', { chatsWithMissingMessages }) - } - // messages received - const messagesUpdate = (json, style: 'previous' | 'last') => { - //console.log('msg ', json[1]) - this.messagesDebounceTimeout.start(undefined, onLastBatchOfDataReceived) - if (style === 'last') { - overlaps = {} - } - const messages = json[2] as WANode[] - if (messages) { - const updates: { [k: string]: KeyedDB } = {} - messages.reverse().forEach (([,, message]: ['message', null, WAMessage]) => { - const jid = message.key.remoteJid - const chat = this.chats.get(jid) - - const mKeyID = WA_MESSAGE_ID(message) - if (chat) { - if (style === 'previous') { - const fm = chat.messages.get(lastMessages[jid]) - if (!fm) return - const prevEpoch = fm['epoch'] - message['epoch'] = prevEpoch-1 - } else if (style === 'last') { - // no overlap required, if there were no previous messages - overlaps[jid] = { requiresOverlap: chat.messages.length > 0 } - - const lm = chat.messages.all()[chat.messages.length-1] - const prevEpoch = (lm && lm['epoch']) || 0 - // hacky way to allow more previous messages - message['epoch'] = prevEpoch+1000 - } - if (chat.messages.upsert(message).length > 0) { - overlaps[jid] = { ...(overlaps[jid] || { requiresOverlap: true }), didOverlap: true } - } - updates[jid] = updates[jid] || newMessagesDB() - updates[jid].upsert(message) - - lastMessages[jid] = mKeyID - } else if (!chat) this.logger.debug({ jid }, `chat not found`) - }) - if (Object.keys(updates).length > 0) { - this.emit ('chats-update', - Object.keys(updates).map(jid => ({ jid, messages: updates[jid] })) - ) - } - } - } - this.on('CB:action,add:last', json => messagesUpdate(json, 'last')) - this.on('CB:action,add:before', json => messagesUpdate(json, 'previous')) - this.on('CB:action,add:unread', json => messagesUpdate(json, 'previous')) - - // contacts received - this.on('CB:response,type:contacts', json => { - if (json[1].duplicate || !json[2]) return - const contacts = this.contacts - const updatedContacts: WAContact[] = [] - - json[2].forEach(([type, contact]: ['user', WAContact]) => { - if (!contact) return this.logger.info (`unexpectedly got null contact: ${type}`, contact) - - contact.jid = whatsappID (contact.jid) - const presentContact = contacts[contact.jid] - if (presentContact) { - const changes = shallowChanges(presentContact, contact, { lookForDeletedKeys: false }) - if (changes && Object.keys(changes).length > 0) { - updatedContacts.push({ ...changes, jid: contact.jid }) - } - } else updatedContacts.push(contact) - - contacts[contact.jid] = { ...(presentContact || {}), ...contact } - }) - // update chat names - const updatedChats = [] - this.chats.all().forEach(c => { - const contact = contacts[c.jid] - if (contact) { - const name = contact?.name || contact?.notify || c.name - if (name !== c.name) { - updatedChats.push({ jid: c.jid, name }) - } - } - }) - updatedChats.length > 0 && this.emit('chats-update', updatedChats) - - this.logger.info (`received ${json[2].length} contacts`) - this.contacts = contacts - - this.emit('contacts-received', { updatedContacts }) - }) - // new messages - this.on('CB:action,add:relay,message', json => { - const message = json[2][0][2] as WAMessage - this.chatAddMessageAppropriate (message) - }) - this.on('CB:Chat,cmd:action', json => { - const data = json[1].data - if (data) { - const emitGroupParticipantsUpdate = (action: WAParticipantAction) => this.emitParticipantsUpdate - (json[1].id, data[2].participants.map(whatsappID), action) - const emitGroupUpdate = (data: Partial) => this.emitGroupUpdate(json[1].id, data) - - switch (data[0]) { - case "promote": - emitGroupParticipantsUpdate('promote') - break - case "demote": - emitGroupParticipantsUpdate('demote') - break - case "desc_add": - emitGroupUpdate({ ...data[2], descOwner: data[1] }) - break - default: - this.logger.debug({ unhandled: true }, json) - break - } - } - }) - // presence updates - this.on('CB:Presence', json => { - const chatUpdate = this.applyingPresenceUpdate(json[1]) - chatUpdate && this.emit('chat-update', chatUpdate) - }) - // If a message has been updated (usually called when a video message gets its upload url, or live locations) - this.on ('CB:action,add:update,message', json => { - const message: WAMessage = json[2][0][2] - const jid = whatsappID(message.key.remoteJid) - const chat = this.chats.get(jid) - if (!chat) return - // reinsert to update - const oldMessage = chat.messages.get (WA_MESSAGE_ID(message)) - if (oldMessage) { - message['epoch'] = oldMessage['epoch'] - if (chat.messages.upsert(message).length) { - const chatUpdate: Partial = { jid, messages: newMessagesDB([ message ]) } - this.emit ('chat-update', chatUpdate) - } - } else { - this.logger.debug ({ unhandled: true }, 'received message update for non-present message from ' + jid) - } - }) - // message status updates - const onMessageStatusUpdate = json => { - json = json[2][0][1] - const MAP = { - read: WA_MESSAGE_STATUS_TYPE.READ, - message: WA_MESSAGE_STATUS_TYPE.DELIVERY_ACK, - error: WA_MESSAGE_STATUS_TYPE.ERROR - } - this.onMessageStatusUpdate( - whatsappID(json.jid), - { id: json.index, fromMe: json.owner === 'true' }, - MAP[json.type] - ) - } - this.on('CB:action,add:relay,received', onMessageStatusUpdate) - this.on('CB:action,,received', onMessageStatusUpdate) - - this.on('CB:Msg,cmd:ack', json => ( - this.onMessageStatusUpdate( - whatsappID(json[1].to), - { id: json[1].id, fromMe: true }, - +json[1].ack + 1 - ) - )) - - // If a user's contact has changed - this.on ('CB:action,,user', json => { - const node = json[2][0] - if (node) { - const user = node[1] as WAContact - user.jid = whatsappID(user.jid) - - this.contacts[user.jid] = user - this.emit('contact-update', user) - - const chat = this.chats.get (user.jid) - if (chat) { - chat.name = user.name || user.notify || chat.name - this.emit ('chat-update', { jid: chat.jid, name: chat.name }) - } - } - }) - // chat archive, pin etc. - this.on('CB:action,,chat', json => { - json = json[2][0] - - const updateType = json[1].type - const jid = whatsappID(json[1]?.jid) - - const chat = this.chats.get(jid) - if (!chat) return - - const FUNCTIONS = { - 'delete': () => { - chat['delete'] = 'true' - this.chats.deleteById(chat.jid) - return 'delete' - }, - 'clear': () => { - if (!json[2]) chat.messages.clear () - else json[2].forEach(item => chat.messages.filter(m => m.key.id !== item[1].index)) - return 'clear' - }, - 'archive': () => { - this.chats.update(chat.jid, chat => chat.archive = 'true') - return 'archive' - }, - 'unarchive': () => { - delete chat.archive - return 'archive' - }, - 'pin': () => { - chat.pin = json[1].pin - return 'pin' - } - } - const func = FUNCTIONS [updateType] - - if (func) { - const property = func () - this.emit ('chat-update', { jid, [property]: chat[property] || 'false' }) - } - }) - // profile picture updates - this.on('CB:Cmd,type:picture', async json => { - json = json[1] - const jid = whatsappID(json.jid) - const imgUrl = await this.getProfilePicture(jid).catch(() => '') - const contact = this.contacts[jid] - if (contact) { - contact.imgUrl = imgUrl - this.emit('contact-update', { jid, imgUrl }) - } - const chat = this.chats.get(jid) - if (chat) { - chat.imgUrl = imgUrl - this.emit ('chat-update', { jid, imgUrl }) - } - }) - // status updates - this.on('CB:Status,status', async json => { - const jid = whatsappID(json[1].id) - this.emit ('contact-update', { jid, status: json[1].status }) - }) - // User Profile Name Updates - this.on ('CB:Conn,pushname', json => { - if (this.user) { - const name = json[1].pushname - if(this.user.name !== name) { - this.user.name = name // update on client too - this.emit ('contact-update', { jid: this.user.jid, name }) - } - } - }) - // read updates - this.on ('CB:action,,read', async json => { - const update = json[2][0][1] - const jid = whatsappID(update.jid) - const chat = this.chats.get (jid) - if(chat) { - if (update.type === 'false') chat.count = -1 - else chat.count = 0 - - this.emit ('chat-update', { jid: chat.jid, count: chat.count }) - } else { - this.logger.warn('recieved read update for unknown chat ' + jid) - } - }) - this.on('qr', qr => { - if (this.connectOptions.logQR) { - QR.generate(qr, { small: true }) - } - }); - - // blocklist updates - this.on('CB:Blocklist', json => { - json = json[1] - const initial = this.blocklist - this.blocklist = json.blocklist - - const added = this.blocklist.filter(id => !initial.includes(id)) - const removed = initial.filter(id => !this.blocklist.includes(id)) - - const update: BlocklistUpdate = { added, removed } - - this.emit('blocklist-update', update) - }) - } - protected sendChatsQuery(epoch: number) { - return this.sendBinary(['query', {type: 'chat', epoch: epoch.toString()}, null], [ WAMetric.queryChat, WAFlag.ignore ]) - } - /** Get the URL to download the profile picture of a person/group */ - @Mutex (jid => jid) - async getProfilePicture(jid: string | null) { - const response = await this.query({ - json: ['query', 'ProfilePicThumb', jid || this.user.jid], - expect200: true, - requiresPhoneConnection: false - }) - return response.eurl as string - } - protected applyingPresenceUpdate(update: PresenceUpdate) { - const chatId = whatsappID(update.id) - const jid = whatsappID(update.participant || update.id) - - const chat = this.chats.get(chatId) - if (chat && jid.endsWith('@s.whatsapp.net')) { // if its a single chat - chat.presences = chat.presences || {} - - const presence = { ...(chat.presences[jid] || {}) } as WAPresenceData - - if (update.t) presence.lastSeen = +update.t - else if (update.type === Presence.unavailable && (presence.lastKnownPresence === Presence.available || presence.lastKnownPresence === Presence.composing)) { - presence.lastSeen = unixTimestampSeconds() - } - presence.lastKnownPresence = update.type - // no update - if(presence.lastKnownPresence === chat.presences[jid]?.lastKnownPresence && presence.lastSeen === chat.presences[jid]?.lastSeen) { - return - } - - const contact = this.contacts[jid] - if (contact) { - presence.name = contact.name || contact.notify || contact.vname - } - - chat.presences[jid] = presence - return { jid: chatId, presences: { [jid]: presence } } as Partial - } - } - /** inserts an empty chat into the DB */ - protected chatAdd (jid: string, name?: string, properties: Partial = {}) { - const chat: WAChat = { - jid, - name, - t: unixTimestampSeconds(), - messages: newMessagesDB(), - count: 0, - ...(properties || {}) - } - if(this.chats.insertIfAbsent(chat).length) { - this.emit('chat-new', chat) - return chat - } - } - protected onMessageStatusUpdate(jid: string, key: { id: string, fromMe: boolean }, status: WA_MESSAGE_STATUS_TYPE) { - const chat = this.chats.get( whatsappID(jid) ) - const msg = chat?.messages.get(GET_MESSAGE_ID(key)) - if (msg) { - if (typeof status !== 'undefined') { - if (status > msg.status || status === WA_MESSAGE_STATUS_TYPE.ERROR) { - msg.status = status - this.emit('chat-update', { jid: chat.jid, messages: newMessagesDB([ msg ]) }) - } - } else { - this.logger.warn({ update: status }, 'received unknown message status update') - } - } else { - this.logger.debug ({ unhandled: true, update: status, key }, 'received message status update for non-present message') - } - } - protected contactAddOrGet (jid: string) { - jid = whatsappID(jid) - if (!this.contacts[jid]) this.contacts[jid] = { jid } - return this.contacts[jid] - } - /** find a chat or return an error */ - protected assertChatGet = jid => { - const chat = this.chats.get (jid) - if (!chat) throw new Error (`chat '${jid}' not found`) - return chat - } - /** Adds the given message to the appropriate chat, if the chat doesn't exist, it is created */ - protected async chatAddMessageAppropriate (message: WAMessage) { - const jid = whatsappID(message.key.remoteJid) - if(isGroupID(jid) && !jid.includes('-')) { - this.logger.warn({ gid: jid }, 'recieved odd group ID') - return - } - const chat = this.chats.get(jid) || await this.chatAdd (jid) - this.chatAddMessage (message, chat) - } - protected chatAddMessage (message: WAMessage, chat: WAChat) { - // store updates in this - const chatUpdate: WAChatUpdate = { jid: chat.jid } - // add to count if the message isn't from me & there exists a message - if (!message.key.fromMe && message.message) { - chat.count += 1 - chatUpdate.count = chat.count - - const participant = whatsappID(message.participant || chat.jid) - const contact = chat.presences && chat.presences[participant] - if (contact?.lastKnownPresence === Presence.composing) { // update presence - const update = this.applyingPresenceUpdate({ id: chat.jid, participant, type: Presence.available }) - update && Object.assign(chatUpdate, update) - } - } - - const ephemeralProtocolMsg = message.message?.ephemeralMessage?.message?.protocolMessage - if ( - ephemeralProtocolMsg && - ephemeralProtocolMsg.type === WAMessageProto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING - ) { - chatUpdate.eph_setting_ts = message.messageTimestamp.toString() - chatUpdate.ephemeral = ephemeralProtocolMsg.ephemeralExpiration.toString() - - if (ephemeralProtocolMsg.ephemeralExpiration) { - chat.eph_setting_ts = chatUpdate.eph_setting_ts - chat.ephemeral = chatUpdate.ephemeral - } else { - delete chat.eph_setting_ts - delete chat.ephemeral - } - } - - const messages = chat.messages - const protocolMessage = message.message?.protocolMessage - // if it's a message to delete another message - if (protocolMessage) { - switch (protocolMessage.type) { - case WAMessageProto.ProtocolMessage.ProtocolMessageType.REVOKE: - const found = chat.messages.get (GET_MESSAGE_ID(protocolMessage.key)) - if (found?.message) { - this.logger.info ('deleting message: ' + protocolMessage.key.id + ' in chat: ' + protocolMessage.key.remoteJid) - - found.messageStubType = WA_MESSAGE_STUB_TYPE.REVOKE - delete found.message - chatUpdate.messages = newMessagesDB([ found ]) - } - break - default: - break - } - } else if (!messages.get(WA_MESSAGE_ID(message))) { // if the message is not already there - - const lastEpoch = (messages.last && messages.last['epoch']) || 0 - message['epoch'] = lastEpoch+1 - - messages.insert (message) - while (messages.length > this.maxCachedMessages) { - messages.delete (messages.all()[0]) // delete oldest messages - } - // only update if it's an actual message - if (message.message && !ephemeralProtocolMsg) { - this.chats.update(chat.jid, chat => { - chat.t = +toNumber(message.messageTimestamp) - chatUpdate.t = chat.t - // a new message unarchives the chat - if (chat.archive) { - delete chat.archive - chatUpdate.archive = 'false' - } - }) - } - chatUpdate.hasNewMessage = true - chatUpdate.messages = newMessagesDB([ message ]) - // check if the message is an action - if (message.messageStubType) { - const jid = chat.jid - //let actor = whatsappID (message.participant) - let participants: string[] - const emitParticipantsUpdate = (action: WAParticipantAction) => ( - this.emitParticipantsUpdate(jid, participants, action) - ) - const emitGroupUpdate = (update: Partial) => this.emitGroupUpdate(jid, update) - - switch (message.messageStubType) { - case WA_MESSAGE_STUB_TYPE.CHANGE_EPHEMERAL_SETTING: - chatUpdate.eph_setting_ts = message.messageTimestamp.toString() - chatUpdate.ephemeral = message.messageStubParameters[0] - - if (+chatUpdate.ephemeral) { - chat.eph_setting_ts = chatUpdate.eph_setting_ts - chat.ephemeral = chatUpdate.ephemeral - } else { - delete chat.eph_setting_ts - delete chat.ephemeral - } - break - case WA_MESSAGE_STUB_TYPE.GROUP_PARTICIPANT_LEAVE: - case WA_MESSAGE_STUB_TYPE.GROUP_PARTICIPANT_REMOVE: - participants = message.messageStubParameters.map (whatsappID) - emitParticipantsUpdate('remove') - // mark the chat read only if you left the group - if (participants.includes(this.user.jid)) { - chat.read_only = 'true' - chatUpdate.read_only = 'true' - } - break - case WA_MESSAGE_STUB_TYPE.GROUP_PARTICIPANT_ADD: - case WA_MESSAGE_STUB_TYPE.GROUP_PARTICIPANT_INVITE: - case WA_MESSAGE_STUB_TYPE.GROUP_PARTICIPANT_ADD_REQUEST_JOIN: - participants = message.messageStubParameters.map (whatsappID) - if (participants.includes(this.user.jid) && chat.read_only === 'true') { - delete chat.read_only - chatUpdate.read_only = 'false' - } - emitParticipantsUpdate('add') - break - case WA_MESSAGE_STUB_TYPE.GROUP_CHANGE_ANNOUNCE: - const announce = message.messageStubParameters[0] === 'on' ? 'true' : 'false' - emitGroupUpdate({ announce }) - break - case WA_MESSAGE_STUB_TYPE.GROUP_CHANGE_RESTRICT: - const restrict = message.messageStubParameters[0] === 'on' ? 'true' : 'false' - emitGroupUpdate({ restrict }) - break - case WA_MESSAGE_STUB_TYPE.GROUP_CHANGE_SUBJECT: - case WA_MESSAGE_STUB_TYPE.GROUP_CREATE: - chat.name = message.messageStubParameters[0] - chatUpdate.name = chat.name - if (chat.metadata) chat.metadata.subject = chat.name - break - } - } - } - - this.emit('chat-update', chatUpdate) - } - protected emitParticipantsUpdate = (jid: string, participants: string[], action: WAParticipantAction) => { - const chat = this.chats.get(jid) - const meta = chat?.metadata - if (meta) { - switch (action) { - case 'add': - participants.forEach(jid => ( - meta.participants.push({ ...this.contactAddOrGet(jid), isAdmin: false, isSuperAdmin: false }) - )) - break - case 'remove': - meta.participants = meta.participants.filter(p => !participants.includes(p.jid)) - break - case 'promote': - case 'demote': - const isAdmin = action==='promote' - meta.participants.forEach(p => { - if (participants.includes( p.jid )) p.isAdmin = isAdmin - }) - break - } - } - this.emit ('group-participants-update', { jid, participants, action }) - } - protected emitGroupUpdate = (jid: string, update: Partial) => { - const chat = this.chats.get(jid) - if (chat.metadata) Object.assign(chat.metadata, update) - this.emit ('group-update', { jid, ...update }) - } - protected chatUpdateTime = (chat, stamp: number) => this.chats.update (chat.jid, c => c.t = stamp) - /** sets the profile picture of a chat */ - protected async setProfilePicture (chat: WAChat) { - chat.imgUrl = await this.getProfilePicture (chat.jid).catch (err => '') - } - - // Add all event types - - /** when the connection has opened successfully */ - on (event: 'open', listener: (result: WAOpenResult) => void): this - /** when the connection is opening */ - on (event: 'connecting', listener: () => void): this - /** when the connection has closed */ - on (event: 'close', listener: (err: {reason?: DisconnectReason | string, isReconnecting: boolean}) => void): this - /** when the socket is closed */ - on (event: 'ws-close', listener: (err: {reason?: DisconnectReason | string}) => void): this - /** when a new QR is generated, ready for scanning */ - on (event: 'qr', listener: (qr: string) => void): this - /** when the connection to the phone changes */ - on (event: 'connection-phone-change', listener: (state: {connected: boolean}) => void): this - /** when a contact is updated */ - on (event: 'contact-update', listener: (update: WAContactUpdate) => void): this - /** when a new chat is added */ - on (event: 'chat-new', listener: (chat: WAChat) => void): this - /** when contacts are sent by WA */ - on (event: 'contacts-received', listener: (u: { updatedContacts: Partial[] }) => void): this - /** when chats are sent by WA, and when all messages are received */ - on (event: 'chats-received', listener: (update: {hasNewChats?: boolean}) => void): this - /** when all initial messages are received from WA */ - on (event: 'initial-data-received', listener: (update: {chatsWithMissingMessages: { jid: string, count: number }[] }) => void): this - /** when multiple chats are updated (new message, updated message, deleted, pinned, etc) */ - on (event: 'chats-update', listener: (chats: WAChatUpdate[]) => void): this - /** when a chat is updated (new message, updated message, read message, deleted, pinned, presence updated etc) */ - on (event: 'chat-update', listener: (chat: WAChatUpdate) => void): this - /** when participants are added to a group */ - on (event: 'group-participants-update', listener: (update: {jid: string, participants: string[], actor?: string, action: WAParticipantAction}) => void): this - /** when the group is updated */ - on (event: 'group-update', listener: (update: Partial & {jid: string, actor?: string}) => void): this - /** when WA sends back a pong */ - on (event: 'received-pong', listener: () => void): this - /** when a user is blocked or unblockd */ - on (event: 'blocklist-update', listener: (update: BlocklistUpdate) => void): this - - on (event: BaileysEvent | string, listener: (json: any) => void): this - - on (event: BaileysEvent | string, listener: (...args: any[]) => void) { return super.on (event, listener) } - emit (event: BaileysEvent | string, ...args: any[]) { return super.emit (event, ...args) } -} diff --git a/src/WAConnection/5.User.ts b/src/WAConnection/5.User.ts deleted file mode 100644 index 9d04c4f..0000000 --- a/src/WAConnection/5.User.ts +++ /dev/null @@ -1,255 +0,0 @@ -import {WAConnection as Base} from './4.Events' -import { Presence, WABroadcastListInfo, WAProfilePictureChange, WALoadChatOptions, WAChatIndex, BlocklistUpdate, WABusinessProfile } from './Constants' -import { - WAMessage, - WANode, - WAMetric, - WAFlag, -} from '../WAConnection/Constants' -import { generateProfilePicture, whatsappID } from './Utils' -import { Mutex } from './Mutex' -import { URL } from 'url' - -// All user related functions -- get profile picture, set status etc. - -export class WAConnection extends Base { - /** - * Query whether a given number is registered on WhatsApp - * @param str phone number/jid you want to check for - * @returns undefined if the number doesn't exists, otherwise the correctly formatted jid - */ - isOnWhatsApp = async (str: string) => { - if (this.state !== 'open') { - return this.isOnWhatsAppNoConn(str) - } - const { status, jid, biz } = await this.query({json: ['query', 'exist', str], requiresPhoneConnection: false}) - if (status === 200) return { exists: true, jid: whatsappID(jid), isBusiness: biz as boolean} - } - /** - * Query whether a given number is registered on WhatsApp, without needing to open a WS connection - * @param str phone number/jid you want to check for - * @returns undefined if the number doesn't exists, otherwise the correctly formatted jid - */ - isOnWhatsAppNoConn = async (str: string) => { - let phone = str.split('@')[0] - const url = `https://wa.me/${phone}` - const response = await this.fetchRequest(url, 'GET', undefined, undefined, undefined, false) - const loc = response.headers.location as string - if (!loc) { - this.logger.warn({ url, status: response.statusCode }, 'did not get location from request') - return - } - const locUrl = new URL('', loc) - if (!locUrl.pathname.endsWith('send/')) { - return - } - phone = locUrl.searchParams.get('phone') - return { exists: true, jid: `${phone}@s.whatsapp.net` } - } - /** - * Tell someone about your presence -- online, typing, offline etc. - * @param jid the ID of the person/group who you are updating - * @param type your presence - */ - updatePresence = (jid: string | null, type: Presence) => this.sendBinary( - [ 'action', - {epoch: this.msgCount.toString(), type: 'set'}, - [ ['presence', { type: type, to: jid }, null] ] - ], - [WAMetric.presence, WAFlag[type] ], // weird stuff WA does - undefined, - true - ) - /** Request an update on the presence of a user */ - requestPresenceUpdate = async (jid: string) => this.query({ json: ['action', 'presence', 'subscribe', jid] }) - /** Query the status of the person (see groupMetadata() for groups) */ - async getStatus (jid?: string) { - const status: { status: string } = await this.query({ json: ['query', 'Status', jid || this.user.jid], requiresPhoneConnection: false }) - return status - } - async setStatus (status: string) { - const response = await this.setQuery ( - [ - [ - 'status', - null, - Buffer.from (status, 'utf-8') - ] - ] - ) - this.emit ('contact-update', { jid: this.user.jid, status }) - return response - } - /** Updates business profile. */ - async updateBusinessProfile(profile: WABusinessProfile) { - if (profile.business_hours?.config) { - profile.business_hours.business_config = profile.business_hours.config - delete profile.business_hours.config - } - const json = ['action', "editBusinessProfile", {...profile, v: 2}] - let response; - try { - response = await this.query({ json, expect200: true, requiresPhoneConnection: true }) - } catch (_) { - return {status: 400} - } - return { status: response.status } - } - async updateProfileName (name: string) { - const response = (await this.setQuery ( - [ - [ - 'profile', - { - name - }, - null - ] - ] - )) as any as {status: number, pushname: string} - if (response.status === 200) { - this.user.name = response.pushname; - this.emit ('contact-update', { jid: this.user.jid, name }) - } - return response - } - /** Get your contacts */ - async getContacts() { - const json = ['query', { epoch: this.msgCount.toString(), type: 'contacts' }, null] - const response = await this.query({ json, binaryTags: [WAMetric.queryContact, WAFlag.ignore], expect200: true, requiresPhoneConnection: true }) // this has to be an encrypted query - return response - } - /** Get the stories of your contacts */ - async getStories() { - const json = ['query', { epoch: this.msgCount.toString(), type: 'status' }, null] - const response = await this.query({json, binaryTags: [WAMetric.queryStatus, WAFlag.ignore], expect200: true, requiresPhoneConnection: true }) as WANode - if (Array.isArray(response[2])) { - return response[2].map (row => ( - { - unread: row[1]?.unread, - count: row[1]?.count, - messages: Array.isArray(row[2]) ? row[2].map (m => m[2]) : [] - } as {unread: number, count: number, messages: WAMessage[]} - )) - } - return [] - } - /** Fetch your chats */ - async getChats() { - const json = ['query', { epoch: this.msgCount.toString(), type: 'chat' }, null] - return this.query({ json, binaryTags: [5, WAFlag.ignore], expect200: true }) // this has to be an encrypted query - } - /** Query broadcast list info */ - async getBroadcastListInfo(jid: string) { - return this.query({ - json: ['query', 'contact', jid], - expect200: true, - requiresPhoneConnection: true - }) as Promise - } - /** - * Load chats in a paginated manner + gets the profile picture - * @param before chats before the given cursor - * @param count number of results to return - * @param searchString optionally search for users - * @returns the chats & the cursor to fetch the next page - */ - loadChats (count: number, before: string | null, options: WALoadChatOptions = {}) { - const searchString = options.searchString?.toLowerCase() - const chats = this.chats.paginated (before, count, options && (chat => ( - (typeof options?.custom !== 'function' || options?.custom(chat)) && - (typeof searchString === 'undefined' || chat.name?.toLowerCase().includes (searchString) || chat.jid?.includes(searchString)) - ))) - const cursor = (chats[chats.length-1] && chats.length >= count) && this.chatOrderingKey.key (chats[chats.length-1]) - return { chats, cursor } - } - /** - * Update the profile picture - * @param jid - * @param img - */ - @Mutex (jid => jid) - async updateProfilePicture (jid: string, img: Buffer) { - jid = whatsappID (jid) - const data = await generateProfilePicture (img) - const tag = this.generateMessageTag () - const query: WANode = [ - 'picture', - { jid: jid, id: tag, type: 'set' }, - [ - ['image', null, data.img], - ['preview', null, data.preview] - ] - ] - const response = await (this.setQuery ([query], [WAMetric.picture, 136], tag) as Promise) - if (jid === this.user.jid) this.user.imgUrl = response.eurl - else if (this.chats.get(jid)) { - this.chats.get(jid).imgUrl = response.eurl - this.emit ('chat-update', { jid, imgUrl: response.eurl }) - } - return response - } - /** - * Add or remove user from blocklist - * @param jid the ID of the person who you are blocking/unblocking - * @param type type of operation - */ - @Mutex (jid => jid) - async blockUser (jid: string, type: 'add' | 'remove' = 'add') { - const json: WANode = [ - 'block', - { - type: type, - }, - [ - ['user', { jid }, null] - ], - ] - const result = await this.setQuery ([json], [WAMetric.block, WAFlag.ignore]) - - if (result.status === 200) { - if (type === 'add') { - this.blocklist.push(jid) - } else { - const index = this.blocklist.indexOf(jid); - if (index !== -1) { - this.blocklist.splice(index, 1); - } - } - - // Blocklist update event - const update: BlocklistUpdate = { added: [], removed: [] } - let key = type === 'add' ? 'added' : 'removed' - update[key] = [ jid ] - this.emit('blocklist-update', update) - } - - return result - } - /** - * Query Business Profile (Useful for VCards) - * @param jid Business Jid - * @returns {WABusinessProfile} profile object or undefined if not business account - */ - async getBusinessProfile(jid: string) { - jid = whatsappID(jid) - const { - profiles: [{ - profile, - wid - }] - } = await this.query({ - json: ["query", "businessProfile", [ - { - "wid": jid.replace('@s.whatsapp.net', '@c.us') - } - ], 84], - expect200: true, - requiresPhoneConnection: false, - }) - return { - ...profile, - wid: whatsappID(wid) - } - } -} diff --git a/src/WAConnection/6.MessagesSend.ts b/src/WAConnection/6.MessagesSend.ts deleted file mode 100644 index 3dd2fe4..0000000 --- a/src/WAConnection/6.MessagesSend.ts +++ /dev/null @@ -1,437 +0,0 @@ -import {WAConnection as Base} from './5.User' -import {createReadStream, promises as fs} from 'fs' -import { - MessageOptions, - MessageType, - Mimetype, - MimetypeMap, - MediaPathMap, - WALocationMessage, - WAContactMessage, - WAContactsArrayMessage, - WAGroupInviteMessage, - WATextMessage, - WAMessageContent, WAMetric, WAFlag, WAMessage, BaileysError, WA_MESSAGE_STATUS_TYPE, WAMessageProto, MediaConnInfo, MessageTypeProto, URL_REGEX, WAUrlInfo, WA_DEFAULT_EPHEMERAL, WAMediaUpload -} from './Constants' -import { isGroupID, generateMessageID, extensionForMediaMessage, whatsappID, unixTimestampSeconds, getAudioDuration, newMessagesDB, encryptedStream, decryptMediaMessageBuffer, generateThumbnail } from './Utils' -import { Mutex } from './Mutex' -import { Readable } from 'stream' - -export class WAConnection extends Base { - /** - * Send a message to the given ID (can be group, single, or broadcast) - * @param id the id to send to - * @param message the message can be a buffer, plain string, location message, extended text message - * @param type type of message - * @param options Extra options - */ - async sendMessage( - id: string, - message: string | WATextMessage | WALocationMessage | WAContactMessage | WAContactsArrayMessage | WAGroupInviteMessage | WAMediaUpload, - type: MessageType, - options: MessageOptions = {}, - ) { - const waMessage = await this.prepareMessage (id, message, type, options) - await this.relayWAMessage (waMessage, { waitForAck: options.waitForAck !== false }) - return waMessage - } - /** Prepares a message for sending via sendWAMessage () */ - async prepareMessage( - id: string, - message: string | WATextMessage | WALocationMessage | WAContactMessage | WAContactsArrayMessage | WAGroupInviteMessage | WAMediaUpload, - type: MessageType, - options: MessageOptions = {}, - ) { - const content = await this.prepareMessageContent( - message, - type, - options - ) - const preparedMessage = this.prepareMessageFromContent(id, content, options) - return preparedMessage - } - /** - * Toggles disappearing messages for the given chat - * - * @param jid the chat to toggle - * @param ephemeralExpiration 0 to disable, enter any positive number to enable disappearing messages for the specified duration; - * For the default see WA_DEFAULT_EPHEMERAL - */ - async toggleDisappearingMessages(jid: string, ephemeralExpiration?: number, opts: { waitForAck: boolean } = { waitForAck: true }) { - if(isGroupID(jid)) { - const tag = this.generateMessageTag(true) - await this.setQuery([ - [ - 'group', - { id: tag, jid, type: 'prop', author: this.user.jid }, - [ [ 'ephemeral', { value: ephemeralExpiration.toString() }, null ] ] - ] - ], [WAMetric.group, WAFlag.other], tag) - } else { - const message = this.prepareMessageFromContent( - jid, - this.prepareDisappearingMessageSettingContent(ephemeralExpiration), - {} - ) - await this.relayWAMessage(message, opts) - } - } - /** Prepares the message content */ - async prepareMessageContent (message: string | WATextMessage | WALocationMessage | WAContactMessage | WAContactsArrayMessage | WAGroupInviteMessage | WAMediaUpload, type: MessageType, options: MessageOptions) { - let m: WAMessageContent = {} - switch (type) { - case MessageType.text: - case MessageType.extendedText: - if (typeof message === 'string') message = {text: message} as WATextMessage - - if ('text' in message) { - if (options.detectLinks !== false && message.text.match(URL_REGEX)) { - try { - message = await this.generateLinkPreview (message.text) - } catch (error) { // ignore if fails - this.logger.trace(`failed to generate link preview for message '${message.text}': ${error}`) - } - } - m.extendedTextMessage = WAMessageProto.ExtendedTextMessage.fromObject(message as any) - } else { - throw new BaileysError ('message needs to be a string or object with property \'text\'', message) - } - break - case MessageType.location: - case MessageType.liveLocation: - m.locationMessage = WAMessageProto.LocationMessage.fromObject(message as any) - break - case MessageType.contact: - m.contactMessage = WAMessageProto.ContactMessage.fromObject(message as any) - break - case MessageType.contactsArray: - m.contactsArrayMessage = WAMessageProto.ContactsArrayMessage.fromObject(message as any) - break - case MessageType.groupInviteMessage: - m.groupInviteMessage = WAMessageProto.GroupInviteMessage.fromObject(message as any) - break - case MessageType.image: - case MessageType.sticker: - case MessageType.document: - case MessageType.video: - case MessageType.audio: - m = await this.prepareMessageMedia(message as Buffer, type, options) - break - } - return WAMessageProto.Message.fromObject (m) - } - prepareDisappearingMessageSettingContent(ephemeralExpiration?: number) { - ephemeralExpiration = ephemeralExpiration || 0 - const content: WAMessageContent = { - ephemeralMessage: { - message: { - protocolMessage: { - type: WAMessageProto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING, - ephemeralExpiration - } - } - } - } - return WAMessageProto.Message.fromObject(content) - } - /** Prepare a media message for sending */ - async prepareMessageMedia(media: WAMediaUpload, mediaType: MessageType, options: MessageOptions = {}) { - if (mediaType === MessageType.document && !options.mimetype) { - throw new Error('mimetype required to send a document') - } - if (mediaType === MessageType.sticker && options.caption) { - throw new Error('cannot send a caption with a sticker') - } - if (!options.mimetype) { - options.mimetype = MimetypeMap[mediaType] - } - let isGIF = false - if (options.mimetype === Mimetype.gif) { - isGIF = true - options.mimetype = MimetypeMap[MessageType.video] - } - const requiresDurationComputation = mediaType === MessageType.audio && !options.duration - const requiresThumbnailComputation = (mediaType === MessageType.image || mediaType === MessageType.video) && !('thumbnail' in options) - const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation - const { - mediaKey, - encBodyPath, - bodyPath, - fileEncSha256, - fileSha256, - fileLength, - didSaveToTmpPath - } = await encryptedStream(media, mediaType, requiresOriginalForSomeProcessing) - // url safe Base64 encode the SHA256 hash of the body - const fileEncSha256B64 = encodeURIComponent( - fileEncSha256.toString('base64') - .replace(/\+/g, '-') - .replace(/\//g, '_') - .replace(/\=+$/, '') - ) - if(requiresThumbnailComputation) { - await generateThumbnail(bodyPath, mediaType, options) - } - if (requiresDurationComputation) { - try { - options.duration = await getAudioDuration(bodyPath) - } catch (error) { - this.logger.debug ({ error }, 'failed to obtain audio duration: ' + error.message) - } - } - // send a query JSON to obtain the url & auth token to upload our media - let json = await this.refreshMediaConn(options.forceNewMediaOptions) - - let mediaUrl: string - for (let host of json.hosts) { - const auth = encodeURIComponent(json.auth) // the auth token - const url = `https://${host.hostname}${MediaPathMap[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` - - try { - const {body: responseText} = await this.fetchRequest( - url, - 'POST', - createReadStream(encBodyPath), - options.uploadAgent, - { 'Content-Type': 'application/octet-stream' } - ) - const result = JSON.parse(responseText) - mediaUrl = result?.url - - if (mediaUrl) break - else { - json = await this.refreshMediaConn(true) - throw new Error (`upload failed, reason: ${JSON.stringify(result)}`) - } - } catch (error) { - const isLast = host.hostname === json.hosts[json.hosts.length-1].hostname - this.logger.error (`Error in uploading to ${host.hostname} (${error}) ${isLast ? '' : ', retrying...'}`) - } - } - if (!mediaUrl) throw new Error('Media upload failed on all hosts') - // remove tmp files - await Promise.all( - [ - fs.unlink(encBodyPath), - didSaveToTmpPath && bodyPath && fs.unlink(bodyPath) - ] - .filter(Boolean) - ) - - const message = { - [mediaType]: MessageTypeProto[mediaType].fromObject( - { - url: mediaUrl, - mediaKey: mediaKey, - mimetype: options.mimetype, - fileEncSha256: fileEncSha256, - fileSha256: fileSha256, - fileLength: fileLength, - seconds: options.duration, - fileName: options.filename || 'file', - gifPlayback: isGIF || undefined, - caption: options.caption, - ptt: options.ptt - } - ) - } - return WAMessageProto.Message.fromObject(message)// as WAMessageContent - } - /** prepares a WAMessage for sending from the given content & options */ - prepareMessageFromContent(id: string, message: WAMessageContent, options: MessageOptions) { - if (!options.timestamp) options.timestamp = new Date() // set timestamp to now - if (typeof options.sendEphemeral === 'undefined') options.sendEphemeral = 'chat' - // prevent an annoying bug (WA doesn't accept sending messages with '@c.us') - id = whatsappID (id) - - const key = Object.keys(message)[0] - const timestamp = unixTimestampSeconds(options.timestamp) - const quoted = options.quoted - - if (options.contextInfo) message[key].contextInfo = options.contextInfo - - if (quoted) { - const participant = quoted.key.fromMe ? this.user.jid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid) - - message[key].contextInfo = message[key].contextInfo || { } - message[key].contextInfo.participant = participant - message[key].contextInfo.stanzaId = quoted.key.id - message[key].contextInfo.quotedMessage = quoted.message - - // if a participant is quoted, then it must be a group - // hence, remoteJid of group must also be entered - if (quoted.key.participant) { - message[key].contextInfo.remoteJid = quoted.key.remoteJid - } - } - if (options?.thumbnail) { - message[key].jpegThumbnail = Buffer.from(options.thumbnail, 'base64') - } - - const chat = this.chats.get(id) - if ( - // if we want to send a disappearing message - ((options?.sendEphemeral === 'chat' && chat?.ephemeral) || - options?.sendEphemeral === true) && - // and it's not a protocol message -- delete, toggle disappear message - key !== 'protocolMessage' && - // already not converted to disappearing message - key !== 'ephemeralMessage' - ) { - message[key].contextInfo = { - ...(message[key].contextInfo || {}), - expiration: chat?.ephemeral || WA_DEFAULT_EPHEMERAL, - ephemeralSettingTimestamp: chat?.eph_setting_ts - } - message = { - ephemeralMessage: { - message - } - } - } - message = WAMessageProto.Message.fromObject (message) - - const messageJSON = { - key: { - remoteJid: id, - fromMe: true, - id: options?.messageId || generateMessageID(), - }, - message: message, - messageTimestamp: timestamp, - messageStubParameters: [], - participant: id.includes('@g.us') ? this.user.jid : null, - status: WA_MESSAGE_STATUS_TYPE.PENDING - } - return WAMessageProto.WebMessageInfo.fromObject (messageJSON) - } - /** Relay (send) a WAMessage; more advanced functionality to send a built WA Message, you may want to stick with sendMessage() */ - async relayWAMessage(message: WAMessage, { waitForAck } = { waitForAck: true }) { - const json = ['action', {epoch: this.msgCount.toString(), type: 'relay'}, [['message', null, message]]] - const flag = message.key.remoteJid === this.user?.jid ? WAFlag.acknowledge : WAFlag.ignore // acknowledge when sending message to oneself - const mID = message.key.id - message.status = WA_MESSAGE_STATUS_TYPE.PENDING - const promise = this.query({ - json, - binaryTags: [WAMetric.message, flag], - tag: mID, - expect200: true, - requiresPhoneConnection: true - }) - .then(() => message.status = WA_MESSAGE_STATUS_TYPE.SERVER_ACK) - - if (waitForAck) { - await promise - } else { - const emitUpdate = (status: WA_MESSAGE_STATUS_TYPE) => { - message.status = status - this.emit('chat-update', { jid: message.key.remoteJid, messages: newMessagesDB([ message ]) }) - } - promise - .then(() => emitUpdate(WA_MESSAGE_STATUS_TYPE.SERVER_ACK)) - .catch(() => emitUpdate(WA_MESSAGE_STATUS_TYPE.ERROR)) - } - await this.chatAddMessageAppropriate (message) - } - /** - * Fetches the latest url & media key for the given message. - * You may need to call this when the message is old & the content is deleted off of the WA servers - * @param message - */ - @Mutex (message => message?.key?.id) - async updateMediaMessage (message: WAMessage) { - const content = message.message?.audioMessage || message.message?.videoMessage || message.message?.imageMessage || message.message?.stickerMessage || message.message?.documentMessage - if (!content) throw new BaileysError (`given message ${message.key.id} is not a media message`, message) - - const query = ['query',{type: 'media', index: message.key.id, owner: message.key.fromMe ? 'true' : 'false', jid: message.key.remoteJid, epoch: this.msgCount.toString()},null] - const response = await this.query ({ - json: query, - binaryTags: [WAMetric.queryMedia, WAFlag.ignore], - expect200: true, - requiresPhoneConnection: true - }) - Object.keys (response[1]).forEach (key => content[key] = response[1][key]) // update message - } - async downloadMediaMessage (message: WAMessage): Promise - async downloadMediaMessage (message: WAMessage, type: 'buffer'): Promise - async downloadMediaMessage (message: WAMessage, type: 'stream'): Promise - /** - * Securely downloads the media from the message. - * Renews the download url automatically, if necessary. - */ - @Mutex (message => message?.key?.id) - async downloadMediaMessage (message: WAMessage, type: 'buffer' | 'stream' = 'buffer') { - let mContent = message.message?.ephemeralMessage?.message || message.message - if (!mContent) throw new BaileysError('No message present', { status: 400 }) - - const downloadMediaMessage = async () => { - const stream = await decryptMediaMessageBuffer(mContent) - if(type === 'buffer') { - let buffer = Buffer.from([]) - for await(const chunk of stream) { - buffer = Buffer.concat([buffer, chunk]) - } - return buffer - } - return stream - } - - try { - const buff = await downloadMediaMessage() - return buff - } catch (error) { - if (error instanceof BaileysError && error.status === 404) { // media needs to be updated - this.logger.info (`updating media of message: ${message.key.id}`) - await this.updateMediaMessage (message) - mContent = message.message?.ephemeralMessage?.message || message.message - const buff = await downloadMediaMessage() - return buff - } - throw error - } - } - /** - * Securely downloads the media from the message and saves to a file. - * Renews the download url automatically, if necessary. - * @param message the media message you want to decode - * @param filename the name of the file where the media will be saved - * @param attachExtension should the parsed extension be applied automatically to the file - */ - async downloadAndSaveMediaMessage (message: WAMessage, filename: string, attachExtension: boolean=true) { - const extension = extensionForMediaMessage (message.message) - const trueFileName = attachExtension ? (filename + '.' + extension) : filename - const buffer = await this.downloadMediaMessage(message) - - await fs.writeFile(trueFileName, buffer) - return trueFileName - } - /** Query a string to check if it has a url, if it does, return required extended text message */ - async generateLinkPreview (text: string) { - const query = ['query', {type: 'url', url: text, epoch: this.msgCount.toString()}, null] - const response = await this.query ({json: query, binaryTags: [26, WAFlag.ignore], expect200: true, requiresPhoneConnection: false}) - - if (response[1]) response[1].jpegThumbnail = response[2] - const data = response[1] as WAUrlInfo - - const content = {text} as WATextMessage - content.canonicalUrl = data['canonical-url'] - content.matchedText = data['matched-text'] - content.jpegThumbnail = data.jpegThumbnail - content.description = data.description - content.title = data.title - content.previewType = 0 - return content - } - @Mutex () - protected async refreshMediaConn (forceGet = false) { - if (!this.mediaConn || forceGet || (new Date().getTime()-this.mediaConn.fetchDate.getTime()) > this.mediaConn.ttl*1000) { - this.mediaConn = await this.getNewMediaConn() - this.mediaConn.fetchDate = new Date() - } - return this.mediaConn - } - protected async getNewMediaConn () { - const {media_conn} = await this.query({json: ['query', 'mediaConn'], requiresPhoneConnection: false}) - return media_conn as MediaConnInfo - } -} diff --git a/src/WAConnection/7.MessagesExtra.ts b/src/WAConnection/7.MessagesExtra.ts deleted file mode 100644 index 2e255e7..0000000 --- a/src/WAConnection/7.MessagesExtra.ts +++ /dev/null @@ -1,481 +0,0 @@ -import {WAConnection as Base} from './6.MessagesSend' -import { MessageType, WAMessageKey, MessageInfo, WAMessageContent, WAMetric, WAFlag, WANode, WAMessage, WAMessageProto, ChatModification, BaileysError, WAChatIndex, WAChat } from './Constants' -import { whatsappID, delay, toNumber, unixTimestampSeconds, GET_MESSAGE_ID, isGroupID, newMessagesDB } from './Utils' -import { Mutex } from './Mutex' - -export class WAConnection extends Base { - - @Mutex () - async loadAllUnreadMessages () { - const tasks = this.chats.all() - .filter(chat => chat.count > 0) - .map (chat => this.loadMessages(chat.jid, chat.count)) - const list = await Promise.all (tasks) - const combined: WAMessage[] = [] - list.forEach (({messages}) => combined.push(...messages)) - return combined - } - /** Get the message info, who has read it, who its been delivered to */ - @Mutex ((jid, messageID) => jid+messageID) - async messageInfo (jid: string, messageID: string) { - const query = ['query', {type: 'message_info', index: messageID, jid: jid, epoch: this.msgCount.toString()}, null] - const [,,response] = await this.query ({ - json: query, - binaryTags: [WAMetric.queryRead, WAFlag.ignore], - expect200: true, - requiresPhoneConnection: true - }) - - const info: MessageInfo = {reads: [], deliveries: []} - if (response) { - const reads = response.filter (node => node[0] === 'read') - if (reads[0]) { - info.reads = reads[0][2].map (item => item[1]) - } - const deliveries = response.filter (node => node[0] === 'delivery') - if (deliveries[0]) { - info.deliveries = deliveries[0][2].map (item => item[1]) - } - } - return info - } - /** - * Marks a chat as read/unread; updates the chat object too - * @param jid the ID of the person/group whose message you want to mark read - * @param unread unreads the chat, if true - */ - @Mutex (jid => jid) - async chatRead (jid: string, type: 'unread' | 'read' = 'read') { - jid = whatsappID (jid) - const chat = this.assertChatGet (jid) - - const count = type === 'unread' ? '-2' : Math.abs(chat.count).toString() - if (type === 'unread' || chat.count !== 0) { - const idx = await this.getChatIndex(jid) - await this.setQuery ([ - ['read', { jid, count, ...idx, participant: undefined }, null] - ], [ WAMetric.read, WAFlag.ignore ]) - } - chat.count = type === 'unread' ? -1 : 0 - this.emit ('chat-update', {jid, count: chat.count}) - } - /** - * Sends a read receipt for a given message; - * does not update the chat do @see chatRead - * @deprecated just use chatRead() - * @param jid the ID of the person/group whose message you want to mark read - * @param messageKey the key of the message - * @param count number of messages to read, set to < 0 to unread a message - */ - async sendReadReceipt(jid: string, messageKey: WAMessageKey, count: number) { - const attributes = { - jid, - count: count.toString(), - index: messageKey?.id, - participant: messageKey?.participant || undefined, - owner: messageKey?.fromMe?.toString() - } - const read = await this.setQuery ([['read', attributes, null]], [ WAMetric.read, WAFlag.ignore ]) - return read - } - async fetchMessagesFromWA (jid: string, count: number, indexMessage?: { id?: string; fromMe?: boolean }, mostRecentFirst: boolean = true) { - const json = [ - 'query', - { - epoch: this.msgCount.toString(), - type: 'message', - jid: jid, - kind: mostRecentFirst ? 'before' : 'after', - count: count.toString(), - index: indexMessage?.id, - owner: indexMessage?.fromMe === false ? 'false' : 'true', - }, - null, - ] - const response = await this.query({json, binaryTags: [WAMetric.queryMessages, WAFlag.ignore], expect200: false, requiresPhoneConnection: true}) - return (response[2] as WANode[])?.map(item => item[2] as WAMessage) || [] - } - /** - * Load the conversation with a group or person - * @param count the number of messages to load - * @param cursor the data for which message to offset the query by - * @param mostRecentFirst retrieve the most recent message first or retrieve from the converation start - */ - @Mutex (jid => jid) - async loadMessages ( - jid: string, - count: number, - cursor?: { id?: string; fromMe?: boolean }, - mostRecentFirst: boolean = true - ) { - jid = whatsappID(jid) - - const retrieve = (count: number, indexMessage: any) => this.fetchMessagesFromWA (jid, count, indexMessage, mostRecentFirst) - - const chat = this.chats.get (jid) - const hasCursor = cursor?.id && typeof cursor?.fromMe !== 'undefined' - const cursorValue = hasCursor && chat?.messages.get (GET_MESSAGE_ID(cursor)) - - let messages: WAMessage[] - if (chat?.messages && mostRecentFirst && (!hasCursor || cursorValue)) { - messages = chat.messages.paginatedByValue (cursorValue, count, null, 'before') - - const diff = count - messages.length - if (diff < 0) { - messages = messages.slice(-count) // get the last X messages - } else if (diff > 0) { - const fMessage = chat.messages.all()[0] - let fepoch = (fMessage && fMessage['epoch']) || 0 - const extra = await retrieve (diff, messages[0]?.key || cursor) - // add to DB - for (let i = extra.length-1;i >= 0; i--) { - const m = extra[i] - fepoch -= 1 - m['epoch'] = fepoch - - if(chat.messages.length < this.maxCachedMessages) { - chat.messages.insertIfAbsent(m) - } - } - messages.unshift (...extra) - } - } else messages = await retrieve (count, cursor) - - if (messages[0]) cursor = { id: messages[0].key.id, fromMe: messages[0].key.fromMe } - else cursor = null - - return {messages, cursor} - } - /** - * Load the entire friggin conversation with a group or person - * @param onMessage callback for every message retrieved - * @param chunkSize the number of messages to load in a single request - * @param mostRecentFirst retrieve the most recent message first or retrieve from the converation start - */ - loadAllMessages(jid: string, onMessage: (m: WAMessage) => Promise|void, chunkSize = 25, mostRecentFirst = true) { - let offsetID = null - const loadMessage = async () => { - const {messages} = await this.loadMessages(jid, chunkSize, offsetID, mostRecentFirst) - // callback with most recent message first (descending order of date) - let lastMessage - if (mostRecentFirst) { - for (let i = messages.length - 1; i >= 0; i--) { - await onMessage(messages[i]) - lastMessage = messages[i] - } - } else { - for (let i = 0; i < messages.length; i++) { - await onMessage(messages[i]) - lastMessage = messages[i] - } - } - // if there are still more messages - if (messages.length >= chunkSize) { - offsetID = lastMessage.key // get the last message - await delay(200) - return loadMessage() - } - } - return loadMessage() as Promise - } - /** - * Find a message in a given conversation - * @param chunkSize the number of messages to load in a single request - * @param onMessage callback for every message retrieved, if return true -- the loop will break - */ - async findMessage (jid: string, chunkSize: number, onMessage: (m: WAMessage) => boolean) { - const chat = this.chats.get (whatsappID(jid)) - let count = chat?.messages?.all().length || chunkSize - let offsetID - while (true) { - const {messages, cursor} = await this.loadMessages(jid, count, offsetID, true) - // callback with most recent message first (descending order of date) - for (let i = messages.length - 1; i >= 0; i--) { - if (onMessage(messages[i])) return - } - if (messages.length === 0) return - // if there are more messages - offsetID = cursor - await delay (200) - } - } - /** - * Loads all messages sent after a specific date - */ - async messagesReceivedAfter (date: Date, onlyUnrespondedMessages = false) { - const stamp = unixTimestampSeconds (date) - // find the index where the chat timestamp becomes greater - const idx = this.chats.all ().findIndex (c => c.t < stamp) - // all chats before that index -- i.e. all chats that were updated after that - const chats = this.chats.all ().slice (0, idx) - - const messages: WAMessage[] = [] - await Promise.all ( - chats.map (async chat => { - await this.findMessage (chat.jid, 5, m => { - if (toNumber(m.messageTimestamp) < stamp || (onlyUnrespondedMessages && m.key.fromMe)) return true - messages.push (m) - }) - }) - ) - return messages - } - /** Load a single message specified by the ID */ - async loadMessage (jid: string, id: string) { - let message: WAMessage - - jid = whatsappID (jid) - const chat = this.chats.get (jid) - if (chat) { - // see if message is present in cache - message = chat.messages.get (GET_MESSAGE_ID({ id, fromMe: true })) || chat.messages.get (GET_MESSAGE_ID({ id, fromMe: false })) - } - if (!message) { - // load the message before the given message - let messages = (await this.loadMessages (jid, 1, {id, fromMe: true})).messages - if (!messages[0]) messages = (await this.loadMessages (jid, 1, {id, fromMe: false})).messages - // the message after the loaded message is the message required - const actual = await this.loadMessages (jid, 1, messages[0] && messages[0].key, false) - message = actual.messages[0] - } - return message - } - /** - * Search WhatsApp messages with a given text string - * @param txt the search string - * @param inJid the ID of the chat to search in, set to null to search all chats - * @param count number of results to return - * @param page page number of results (starts from 1) - */ - async searchMessages(txt: string, inJid: string | null, count: number, page: number) { - const json = [ - 'query', - { - epoch: this.msgCount.toString(), - type: 'search', - search: Buffer.from(txt, 'utf-8'), - count: count.toString(), - page: page.toString(), - jid: inJid - }, - null, - ] - - const response: WANode = await this.query({json, binaryTags: [24, WAFlag.ignore], expect200: true}) // encrypt and send off - const messages = response[2] ? response[2].map (row => row[2]) : [] - return { - last: response[1]['last'] === 'true', - messages: messages as WAMessage[] - } - } - /** - * Delete a message in a chat for yourself - * @param messageKey key of the message you want to delete - */ - @Mutex (m => m.remoteJid) - async clearMessage (messageKey: WAMessageKey) { - const tag = Math.round(Math.random ()*1000000) - const attrs: WANode = [ - 'chat', - { jid: messageKey.remoteJid, modify_tag: tag.toString(), type: 'clear' }, - [ - ['item', {owner: `${messageKey.fromMe}`, index: messageKey.id}, null] - ] - ] - const result = await this.setQuery ([attrs]) - - const chat = this.chats.get (whatsappID(messageKey.remoteJid)) - if (chat) { - const value = chat.messages.get (GET_MESSAGE_ID(messageKey)) - value && chat.messages.delete (value) - } - return result - } - /** - * Star or unstar a message - * @param messageKey key of the message you want to star or unstar - */ - @Mutex (m => m.remoteJid) - async starMessage (messageKey: WAMessageKey, type: 'star' | 'unstar' = 'star') { - const attrs: WANode = [ - 'chat', - { - jid: messageKey.remoteJid, - type - }, - [ - ['item', {owner: `${messageKey.fromMe}`, index: messageKey.id}, null] - ] - ] - const result = await this.setQuery ([attrs]) - - const chat = this.chats.get (whatsappID(messageKey.remoteJid)) - if (result.status == 200 && chat) { - const message = chat.messages.get (GET_MESSAGE_ID(messageKey)) - if (message) { - message.starred = type === 'star' - - const chatUpdate: Partial = { jid: messageKey.remoteJid, messages: newMessagesDB([ message ]) } - this.emit ('chat-update', chatUpdate) - } - } - return result - } - /** - * Delete a message in a chat for everyone - * @param id the person or group where you're trying to delete the message - * @param messageKey key of the message you want to delete - */ - async deleteMessage (k: string | WAMessageKey, messageKey?: WAMessageKey) { - if (typeof k === 'object') { - messageKey = k - } - const json: WAMessageContent = { - protocolMessage: { - key: messageKey, - type: WAMessageProto.ProtocolMessage.ProtocolMessageType.REVOKE - } - } - const waMessage = this.prepareMessageFromContent (messageKey.remoteJid, json, {}) - await this.relayWAMessage (waMessage) - return waMessage - } - /** - * Generate forwarded message content like WA does - * @param message the message to forward - * @param forceForward will show the message as forwarded even if it is from you - */ - generateForwardMessageContent (message: WAMessage, forceForward: boolean=false) { - let content = message.message - if (!content) throw new BaileysError ('no content in message', { status: 400 }) - content = WAMessageProto.Message.fromObject(content) // hacky copy - - let key = Object.keys(content)[0] - - let score = content[key].contextInfo?.forwardingScore || 0 - score += message.key.fromMe && !forceForward ? 0 : 1 - if (key === MessageType.text) { - content[MessageType.extendedText] = { text: content[key] } - delete content[MessageType.text] - - key = MessageType.extendedText - } - if (score > 0) content[key].contextInfo = { forwardingScore: score, isForwarded: true } - else content[key].contextInfo = {} - return content - } - /** - * Forward a message like WA - * @param jid the chat ID to forward to - * @param message the message to forward - * @param forceForward will show the message as forwarded even if it is from you - */ - async forwardMessage(jid: string, message: WAMessage, forceForward: boolean=false) { - const content = this.generateForwardMessageContent(message, forceForward) - const waMessage = this.prepareMessageFromContent (jid, content, {}) - await this.relayWAMessage (waMessage) - return waMessage - } - /** - * Clear the chat messages - * @param jid the ID of the person/group you are modifiying - * @param includeStarred delete starred messages, default false - */ - async modifyChat (jid: string, type: ChatModification.clear, includeStarred?: boolean): Promise<{status: number;}>; - /** - * Modify a given chat (archive, pin etc.) - * @param jid the ID of the person/group you are modifiying - * @param durationMs only for muting, how long to mute the chat for - */ - async modifyChat (jid: string, type: ChatModification.pin | ChatModification.mute, durationMs: number): Promise<{status: number;}>; - /** - * Modify a given chat (archive, pin etc.) - * @param jid the ID of the person/group you are modifiying - */ - async modifyChat (jid: string, type: ChatModification | (keyof typeof ChatModification)): Promise<{status: number;}>; - @Mutex ((jid, type) => jid+type) - async modifyChat (jid: string, type: (keyof typeof ChatModification), arg?: number | boolean): Promise<{status: number;}> { - jid = whatsappID (jid) - const chat = this.assertChatGet (jid) - - let chatAttrs: Record = {jid: jid} - if (type === ChatModification.mute && !arg) { - throw new BaileysError( - 'duration must be set to the timestamp of the time of pinning/unpinning of the chat', - { status: 400 } - ) - } - - const durationMs:number = arg as number || 0 - const includeStarred:boolean = arg as boolean - let index: WAChatIndex; - switch (type) { - case ChatModification.pin: - case ChatModification.mute: - const strStamp = (unixTimestampSeconds() + Math.floor(durationMs/1000)).toString() - chatAttrs.type = type - chatAttrs[type] = strStamp - break - case ChatModification.unpin: - case ChatModification.unmute: - chatAttrs.type = type.replace ('un', '') // replace 'unpin' with 'pin' - chatAttrs.previous = chat[type.replace ('un', '')] - break - case ChatModification.clear: - chatAttrs.type = type - chatAttrs.star = includeStarred ? 'true' : 'false' - index = await this.getChatIndex(jid) - chatAttrs = { ...chatAttrs, ...index } - delete chatAttrs.participant - break - default: - chatAttrs.type = type - index = await this.getChatIndex(jid) - chatAttrs = { ...chatAttrs, ...index } - break - } - - const response = await this.setQuery ([['chat', chatAttrs, null]], [ WAMetric.chat, WAFlag.ignore ]) - - if (chat && response.status === 200) { - switch(type) { - case ChatModification.clear: - if (includeStarred) { - chat.messages.clear() - } else { - chat.messages = chat.messages.filter(m => m.starred) - } - break - case ChatModification.delete: - this.chats.deleteById(jid) - this.emit('chat-update', { jid, delete: 'true' }) - break - default: - this.chats.update(jid, chat => { - if (type.includes('un')) { - type = type.replace ('un', '') as ChatModification - delete chat[type.replace('un','')] - this.emit ('chat-update', { jid, [type]: false }) - } else { - chat[type] = chatAttrs[type] || 'true' - this.emit ('chat-update', { jid, [type]: chat[type] }) - } - }) - break - } - } - return response - } - protected async getChatIndex (jid: string): Promise { - const chatAttrs = {} as WAChatIndex - const { messages: [msg] } = await this.loadMessages(jid, 1) - if (msg) { - chatAttrs.index = msg.key.id - chatAttrs.owner = msg.key.fromMe.toString() as 'true' | 'false' - } - if (isGroupID(jid)) { - chatAttrs.participant = msg.key.fromMe ? this.user?.jid : whatsappID(msg.participant || msg.key.participant) - } - return chatAttrs - } -} diff --git a/src/WAConnection/8.Groups.ts b/src/WAConnection/8.Groups.ts deleted file mode 100644 index 379768d..0000000 --- a/src/WAConnection/8.Groups.ts +++ /dev/null @@ -1,202 +0,0 @@ -import {WAConnection as Base} from './7.MessagesExtra' -import { WAMetric, WAFlag, WANode, WAGroupMetadata, WAGroupCreateResponse, WAGroupModification, BaileysError } from '../WAConnection/Constants' -import { GroupSettingChange } from './Constants' -import { generateMessageID, whatsappID } from '../WAConnection/Utils' -import { Mutex } from './Mutex' - -export class WAConnection extends Base { - /** Generic function for group queries */ - async groupQuery(type: string, jid?: string, subject?: string, participants?: string[], additionalNodes?: WANode[]) { - const tag = this.generateMessageTag() - const json: WANode = [ - 'group', - { - author: this.user.jid, - id: tag, - type: type, - jid: jid, - subject: subject, - }, - participants ? participants.map(jid => ['participant', { jid }, null]) : additionalNodes, - ] - const result = await this.setQuery ([json], [WAMetric.group, 136], tag) - return result - } - /** - * Get the metadata of the group - * Baileys automatically caches & maintains this state - */ - @Mutex(jid => jid) - async groupMetadata (jid: string) { - const chat = this.chats.get(jid) - let metadata = chat?.metadata - if (!metadata) { - if (chat?.read_only) { - metadata = await this.groupMetadataMinimal(jid) - } else { - metadata = await this.fetchGroupMetadataFromWA(jid) - } - if (chat) chat.metadata = metadata - } - return metadata - } - /** Get the metadata of the group from WA */ - fetchGroupMetadataFromWA = async (jid: string) => { - const metadata = await this.query({json: ['query', 'GroupMetadata', jid], expect200: true}) - metadata.participants = metadata.participants.map(p => ( - { ...this.contactAddOrGet(p.id), ...p } - )) - return metadata as WAGroupMetadata - } - /** Get the metadata (works after you've left the group also) */ - groupMetadataMinimal = async (jid: string) => { - const query = ['query', {type: 'group', jid: jid, epoch: this.msgCount.toString()}, null] - const response = await this.query({json: query, binaryTags: [WAMetric.group, WAFlag.ignore], expect200: true}) - const json = response[2][0] - const creatorDesc = json[1] - const participants = json[2] ? json[2].filter (item => item[0] === 'participant') : [] - const description = json[2] ? json[2].find (item => item[0] === 'description') : null - return { - id: jid, - owner: creatorDesc?.creator, - creator: creatorDesc?.creator, - creation: parseInt(creatorDesc?.create), - subject: null, - desc: description && description[2].toString('utf-8'), - participants: participants.map (item => ( - { ...this.contactAddOrGet(item[1].jid), isAdmin: item[1].type === 'admin' } - )) - } as WAGroupMetadata - } - /** - * Create a group - * @param title like, the title of the group - * @param participants people to include in the group - */ - groupCreate = async (title: string, participants: string[]) => { - const response = await this.groupQuery('create', null, title, participants) as WAGroupCreateResponse - const gid = response.gid - let metadata: WAGroupMetadata - try { - metadata = await this.groupMetadata (gid) - } catch (error) { - this.logger.warn (`error in group creation: ${error}, switching gid & checking`) - // if metadata is not available - const comps = gid.replace ('@g.us', '').split ('-') - response.gid = `${comps[0]}-${+comps[1] + 1}@g.us` - - metadata = await this.groupMetadata (gid) - this.logger.warn (`group ID switched from ${gid} to ${response.gid}`) - } - await this.chatAdd(response.gid, title, { metadata }) - return response - } - /** - * Leave a group - * @param jid the ID of the group - */ - groupLeave = async (jid: string) => { - const response = await this.groupQuery('leave', jid) - - const chat = this.chats.get (jid) - if (chat) chat.read_only = 'true' - - return response - } - /** - * Update the subject of the group - * @param {string} jid the ID of the group - * @param {string} title the new title of the group - */ - groupUpdateSubject = async (jid: string, title: string) => { - const chat = this.chats.get (jid) - if (chat?.name === title) throw new BaileysError ('redundant change', { status: 400 }) - - const response = await this.groupQuery('subject', jid, title) - if (chat) chat.name = title - - return response - } - - /** - * Update the group description - * @param {string} jid the ID of the group - * @param {string} title the new title of the group - */ - groupUpdateDescription = async (jid: string, description: string) => { - const metadata = await this.groupMetadata (jid) - const node: WANode = [ - 'description', - {id: generateMessageID(), prev: metadata?.descId}, - Buffer.from (description, 'utf-8') - ] - const response = await this.groupQuery ('description', jid, null, null, [node]) - return response - } - /** - * Add somebody to the group - * @param jid the ID of the group - * @param participants the people to add - */ - groupAdd = (jid: string, participants: string[]) => - this.groupQuery('add', jid, null, participants) as Promise - /** - * Remove somebody from the group - * @param jid the ID of the group - * @param participants the people to remove - */ - groupRemove = (jid: string, participants: string[]) => - this.groupQuery('remove', jid, null, participants) as Promise - /** - * Make someone admin on the group - * @param jid the ID of the group - * @param participants the people to make admin - */ - groupMakeAdmin = (jid: string, participants: string[]) => - this.groupQuery('promote', jid, null, participants) as Promise - /** - * Make demote an admin on the group - * @param jid the ID of the group - * @param participants the people to make admin - */ - groupDemoteAdmin = (jid: string, participants: string[]) => - this.groupQuery('demote', jid, null, participants) as Promise - /** - * Make demote an admin on the group - * @param jid the ID of the group - * @param participants the people to make admin - */ - groupSettingChange = (jid: string, setting: GroupSettingChange, onlyAdmins: boolean) => { - const node: WANode = [ setting, {value: onlyAdmins ? 'true' : 'false'}, null ] - return this.groupQuery('prop', jid, null, null, [node]) as Promise<{status: number}> - } - /** - * Get the invite link of the given group - * @param jid the ID of the group - * @returns invite code - */ - async groupInviteCode(jid: string) { - const json = ['query', 'inviteCode', jid] - const response = await this.query({json, expect200: true, requiresPhoneConnection: false}) - return response.code as string - } - /** - * Join group via invite code - * @param code the invite code - * @returns Object containing gid - */ - async acceptInvite(code: string) { - const json = ['action', 'invite', code] - const response = await this.query({json, expect200: true}) - return response - } - /** - * Revokes the current invite link for a group chat - * @param jid the ID of the group - */ - async revokeInvite(jid: string) { - const json = ['action', 'inviteReset', jid] - const response = await this.query({json, expect200: true}) - return response - } -} diff --git a/src/WAConnection/Constants.ts b/src/WAConnection/Constants.ts deleted file mode 100644 index df47251..0000000 --- a/src/WAConnection/Constants.ts +++ /dev/null @@ -1,506 +0,0 @@ -import { WA } from '../Binary/Constants' -import { proto } from '../../WAMessage/WAMessage' -import { Agent } from 'https' -import KeyedDB from '@adiwajshing/keyed-db' -import { URL } from 'url' - -export const WS_URL = 'wss://web.whatsapp.com/ws' -export const DEFAULT_ORIGIN = 'https://web.whatsapp.com' - -export const KEEP_ALIVE_INTERVAL_MS = 20*1000 -export const WA_DEFAULT_EPHEMERAL = 7*24*60*60 - -// export the WAMessage Prototypes -export { proto as WAMessageProto } -export type WANode = WA.Node -export type WAMessage = proto.WebMessageInfo -export type WAMessageContent = proto.IMessage -export type WAContactMessage = proto.ContactMessage -export type WAContactsArrayMessage = proto.ContactsArrayMessage -export type WAGroupInviteMessage = proto.GroupInviteMessage -export type WAMessageKey = proto.IMessageKey -export type WATextMessage = proto.ExtendedTextMessage -export type WAContextInfo = proto.IContextInfo -export type WAGenericMediaMessage = proto.IVideoMessage | proto.IImageMessage | proto.IAudioMessage | proto.IDocumentMessage | proto.IStickerMessage -export import WA_MESSAGE_STUB_TYPE = proto.WebMessageInfo.WebMessageInfoStubType -export import WA_MESSAGE_STATUS_TYPE = proto.WebMessageInfo.WebMessageInfoStatus - -export type WAInitResponse = { - ref: string - ttl: number - status: 200 -} - -export interface WABusinessProfile { - description: string - email: string - business_hours: WABusinessHours - website: string[] - categories: WABusinessCategories[] - wid?: string -} - -export type WABusinessCategories = { - id: string - localized_display_name: string -} - -export type WABusinessHours = { - timezone: string - config?: WABusinessHoursConfig[] - business_config?: WABusinessHoursConfig[] -} - -export type WABusinessHoursConfig = { - day_of_week: string - mode: string - open_time?: number - close_time?: number -} - -export interface WALocationMessage { - degreesLatitude: number - degreesLongitude: number - address?: string -} -/** Reverse stub type dictionary */ -export const WA_MESSAGE_STUB_TYPES = function () { - const types = WA_MESSAGE_STUB_TYPE - const dict: Record = {} - Object.keys(types).forEach(element => dict[ types[element] ] = element) - return dict -}() - -export class BaileysError extends Error { - status?: number - context: any - - constructor (message: string, context: any, stack?: string) { - super (message) - this.name = 'BaileysError' - this.status = context.status - this.context = context - if(stack) { - this.stack = stack - } - } -} -export const TimedOutError = (stack?: string) => new BaileysError ('timed out', { status: 408 }, stack) -export const CancelledError = (stack?: string) => new BaileysError ('cancelled', { status: 500 }, stack) - -export interface WAQuery { - json: any[] | WANode - binaryTags?: WATag - timeoutMs?: number - tag?: string - expect200?: boolean - waitForOpen?: boolean - longTag?: boolean - requiresPhoneConnection?: boolean - startDebouncedTimeout?: boolean - maxRetries?: number -} - -export type WAMediaUpload = Buffer | { url: URL | string } - -export enum ReconnectMode { - /** does not reconnect */ - off = 0, - /** reconnects only when the connection is 'lost' or 'close' */ - onConnectionLost = 1, - /** reconnects on all disconnects, including take overs */ - onAllErrors = 2 -} -export type WALoadChatOptions = { - searchString?: string - custom?: (c: WAChat) => boolean -} -export type WAConnectOptions = { - /** fails the connection if no data is received for X seconds */ - maxIdleTimeMs?: number - /** maximum attempts to connect */ - maxRetries?: number - /** max time for the phone to respond to a connectivity test */ - phoneResponseTime?: number - connectCooldownMs?: number - /** agent used for WS connections */ - agent?: Agent - /** agent used for fetch requests -- uploading/downloading media */ - fetchAgent?: Agent - /** Always uses takeover for connections */ - alwaysUseTakeover?: boolean - /** - * Sometimes WA does not send the chats, - * this keeps pinging the phone to send the chats over - * */ - queryChatsTillReceived?: boolean - /** max time for the phone to respond to a query */ - maxQueryResponseTime?: number - /** Log QR to terminal or not */ - logQR?: boolean -} -/** from: https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url */ -export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi - -export type WAConnectionState = 'open' | 'connecting' | 'close' - -export const UNAUTHORIZED_CODES = [401, 419] -/** Types of Disconnect Reasons */ -export enum DisconnectReason { - /** The connection was closed intentionally */ - intentional = 'intentional', - /** The connection was terminated either by the client or server */ - close = 'close', - /** The connection was lost, called when the server stops responding to requests */ - lost = 'lost', - /** When WA Web is opened elsewhere & this session is disconnected */ - replaced = 'replaced', - /** The credentials for the session have been invalidated, i.e. logged out either from the phone or WA Web */ - invalidSession = 'invalid_session', - /** Received a 500 result in a query -- something has gone very wrong */ - badSession = 'bad_session', - /** No idea, can be a sign of log out too */ - unknown = 'unknown', - /** Well, the connection timed out */ - timedOut = 'timed out' -} -export interface MediaConnInfo { - auth: string - ttl: number - hosts: { - hostname: string - }[] - fetchDate: Date -} -export interface AuthenticationCredentials { - clientID: string - serverToken: string - clientToken: string - encKey: Buffer - macKey: Buffer -} -export interface AuthenticationCredentialsBase64 { - clientID: string - serverToken: string - clientToken: string - encKey: string - macKey: string -} -export interface AuthenticationCredentialsBrowser { - WABrowserId: string - WASecretBundle: {encKey: string, macKey: string} | string - WAToken1: string - WAToken2: string -} -export type AnyAuthenticationCredentials = AuthenticationCredentialsBrowser | AuthenticationCredentialsBase64 | AuthenticationCredentials - -export interface WAGroupCreateResponse { - status: number - gid?: string - participants?: [{ [key: string]: any }] -} -export type WAGroupParticipant = (WAContact & { isAdmin: boolean; isSuperAdmin: boolean }) -export interface WAGroupMetadata { - id: string - owner: string - subject: string - creation: number - desc?: string - descOwner?: string - descId?: string - /** is set when the group only allows admins to change group settings */ - restrict?: 'true' | 'false' - /** is set when the group only allows admins to write messages */ - announce?: 'true' | 'false' - // Baileys modified array - participants: WAGroupParticipant[] -} -export interface WAGroupModification { - status: number - participants?: { [key: string]: any } -} -export interface WAPresenceData { - lastKnownPresence?: Presence - lastSeen?: number - name?: string -} -export interface WAContact { - verify?: string - /** name of the contact, the contact has set on their own on WA */ - notify?: string - jid: string - /** I have no idea */ - vname?: string - /** name of the contact, you have saved on your WA */ - name?: string - index?: string - /** short name for the contact */ - short?: string - // Baileys Added - imgUrl?: string -} -export interface WAUser extends WAContact { - phone: any -} -export type WAContactUpdate = Partial & { jid: string, status?: string } -export interface WAChat { - jid: string - - t: number - /** number of unread messages, is < 0 if the chat is manually marked unread */ - count: number - archive?: 'true' | 'false' - clear?: 'true' | 'false' - read_only?: 'true' | 'false' - mute?: string - pin?: string - spam?: 'false' | 'true' - modify_tag?: string - name?: string - /** when ephemeral messages were toggled on */ - eph_setting_ts?: string - /** how long each message lasts for */ - ephemeral?: string - - // Baileys added properties - messages: KeyedDB - imgUrl?: string - presences?: { [k: string]: WAPresenceData } - metadata?: WAGroupMetadata -} -export type WAChatIndex = { index: string, owner: 'true' | 'false', participant?: string } -export type WAChatUpdate = Partial & { jid: string, hasNewMessage?: boolean } -export enum WAMetric { - debugLog = 1, - queryResume = 2, - liveLocation = 3, - queryMedia = 4, - queryChat = 5, - queryContact = 6, - queryMessages = 7, - presence = 8, - presenceSubscribe = 9, - group = 10, - read = 11, - chat = 12, - received = 13, - picture = 14, - status = 15, - message = 16, - queryActions = 17, - block = 18, - queryGroup = 19, - queryPreview = 20, - queryEmoji = 21, - queryRead = 22, - queryVCard = 29, - queryStatus = 30, - queryStatusUpdate = 31, - queryLiveLocation = 33, - queryLabel = 36, - queryQuickReply = 39 -} - -export const STORIES_JID = 'status@broadcast' - -export enum WAFlag { - available = 160, - other = 136, // don't know this one - ignore = 1 << 7, - acknowledge = 1 << 6, - unavailable = 1 << 4, - expires = 1 << 3, - composing = 1 << 2, - recording = 1 << 2, - paused = 1 << 2 -} -/** Tag used with binary queries */ -export type WATag = [WAMetric, WAFlag] -/** set of statuses visible to other people; see updatePresence() in WhatsAppWeb.Send */ -export enum Presence { - unavailable = 'unavailable', // "offline" - available = 'available', // "online" - composing = 'composing', // "typing..." - recording = 'recording', // "recording..." - paused = 'paused', // stop typing -} -/** Set of message types that are supported by the library */ -export enum MessageType { - text = 'conversation', - extendedText = 'extendedTextMessage', - contact = 'contactMessage', - contactsArray = 'contactsArrayMessage', - groupInviteMessage = 'groupInviteMessage', - location = 'locationMessage', - liveLocation = 'liveLocationMessage', - - image = 'imageMessage', - video = 'videoMessage', - sticker = 'stickerMessage', - document = 'documentMessage', - audio = 'audioMessage', - product = 'productMessage' -} - -export const MessageTypeProto = { - [MessageType.image]: proto.ImageMessage, - [MessageType.video]: proto.VideoMessage, - [MessageType.audio]: proto.AudioMessage, - [MessageType.sticker]: proto.StickerMessage, - [MessageType.document]: proto.DocumentMessage, -} -export enum ChatModification { - archive='archive', - unarchive='unarchive', - pin='pin', - unpin='unpin', - mute='mute', - unmute='unmute', - delete='delete', - clear='clear' -} -export const HKDFInfoKeys = { - [MessageType.image]: 'WhatsApp Image Keys', - [MessageType.audio]: 'WhatsApp Audio Keys', - [MessageType.video]: 'WhatsApp Video Keys', - [MessageType.document]: 'WhatsApp Document Keys', - [MessageType.sticker]: 'WhatsApp Image Keys' -} -export enum Mimetype { - jpeg = 'image/jpeg', - png = 'image/png', - mp4 = 'video/mp4', - gif = 'video/gif', - pdf = 'application/pdf', - ogg = 'audio/ogg; codecs=opus', - mp4Audio = 'audio/mp4', - /** for stickers */ - webp = 'image/webp', -} -export interface MessageOptions { - /** the message you want to quote */ - quoted?: WAMessage - /** some random context info (can show a forwarded message with this too) */ - contextInfo?: WAContextInfo - /** optional, if you want to manually set the timestamp of the message */ - timestamp?: Date - /** (for media messages) the caption to send with the media (cannot be sent with stickers though) */ - caption?: string - /** - * For location & media messages -- has to be a base 64 encoded JPEG if you want to send a custom thumb, - * or set to null if you don't want to send a thumbnail. - * Do not enter this field if you want to automatically generate a thumb - * */ - thumbnail?: string - /** (for media messages) specify the type of media (optional for all media types except documents) */ - mimetype?: Mimetype | string - /** (for media messages) file name for the media */ - filename?: string - /** For audio messages, if set to true, will send as a `voice note` */ - ptt?: boolean - /** Optional agent for media uploads */ - uploadAgent?: Agent - /** If set to true (default), automatically detects if you're sending a link & attaches the preview*/ - detectLinks?: boolean - /** Optionally specify the duration of the media (audio/video) in seconds */ - duration?: number - /** Fetches new media options for every media file */ - forceNewMediaOptions?: boolean - /** Wait for the message to be sent to the server (default true) */ - waitForAck?: boolean - /** Should it send as a disappearing messages. - * By default 'chat' -- which follows the setting of the chat */ - sendEphemeral?: 'chat' | boolean - /** Force message id */ - messageId?: string -} -export interface WABroadcastListInfo { - status: number - name: string - recipients?: {id: string}[] -} -export interface WAUrlInfo { - 'canonical-url': string - 'matched-text': string - title: string - description: string - jpegThumbnail?: Buffer -} -export interface WAProfilePictureChange { - status: number - tag: string - eurl: string -} -export interface MessageInfo { - reads: {jid: string, t: string}[] - deliveries: {jid: string, t: string}[] -} -export interface WAMessageStatusUpdate { - from: string - to: string - /** Which participant caused the update (only for groups) */ - participant?: string - timestamp: Date - /** Message IDs read/delivered */ - ids: string[] - /** Status of the Message IDs */ - type: WA_MESSAGE_STATUS_TYPE -} - -export interface WAOpenResult { - /** Was this connection opened via a QR scan */ - newConnection?: true - user: WAUser - isNewUser?: true - auth: AuthenticationCredentials -} - -export enum GroupSettingChange { - messageSend = 'announcement', - settingsChange = 'locked', -} -export interface PresenceUpdate { - id: string - participant?: string - t?: string - type?: Presence - deny?: boolean -} -export interface BlocklistUpdate { - added?: string[] - removed?: string[] -} -// path to upload the media -export const MediaPathMap = { - imageMessage: '/mms/image', - videoMessage: '/mms/video', - documentMessage: '/mms/document', - audioMessage: '/mms/audio', - stickerMessage: '/mms/image', -} -// gives WhatsApp info to process the media -export const MimetypeMap = { - imageMessage: Mimetype.jpeg, - videoMessage: Mimetype.mp4, - documentMessage: Mimetype.pdf, - audioMessage: Mimetype.ogg, - stickerMessage: Mimetype.webp, -} -export type WAParticipantAction = 'add' | 'remove' | 'promote' | 'demote' -export type BaileysEvent = - 'open' | - 'connecting' | - 'close' | - 'ws-close' | - 'qr' | - 'connection-phone-change' | - 'contacts-received' | - 'chats-received' | - 'initial-data-received' | - 'chat-new' | - 'chat-update' | - 'group-participants-update' | - 'group-update' | - 'received-pong' | - 'blocklist-update' | - 'contact-update' diff --git a/src/WAConnection/Mutex.ts b/src/WAConnection/Mutex.ts deleted file mode 100644 index 68c44a8..0000000 --- a/src/WAConnection/Mutex.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * A simple mutex that can be used as a decorator. For examples, see Tests.Mutex.ts - * @param keyGetter if you want to lock functions based on certain arguments, specify the key for the function based on the arguments - */ -export function Mutex (keyGetter?: (...args: any[]) => string) { - let tasks: { [k: string]: Promise } = {} - return function (_, __, descriptor: PropertyDescriptor) { - const originalMethod = descriptor.value - descriptor.value = function (this: Object, ...args) { - const key = (keyGetter && keyGetter.call(this, ...args)) || 'undefined' - - tasks[key] = (async () => { - try { - tasks[key] && await tasks[key] - } catch { - - } - const result = await originalMethod.call(this, ...args) - return result - })() - return tasks[key] - } - } -} \ No newline at end of file diff --git a/src/WAConnection/Utils.ts b/src/WAConnection/Utils.ts deleted file mode 100644 index cd7bac8..0000000 --- a/src/WAConnection/Utils.ts +++ /dev/null @@ -1,469 +0,0 @@ -import * as Crypto from 'crypto' -import { Readable, Transform } from 'stream' -import HKDF from 'futoin-hkdf' -import Jimp from 'jimp' -import {createReadStream, createWriteStream, promises as fs, WriteStream} from 'fs' -import { exec } from 'child_process' -import {platform, release, tmpdir} from 'os' -import HttpsProxyAgent from 'https-proxy-agent' -import { URL } from 'url' -import { Agent } from 'https' -import Decoder from '../Binary/Decoder' -import { MessageType, HKDFInfoKeys, MessageOptions, WAChat, WAMessageContent, BaileysError, WAMessageProto, TimedOutError, CancelledError, WAGenericMediaMessage, WAMessage, WAMessageKey, DEFAULT_ORIGIN, WAMediaUpload } from './Constants' -import KeyedDB from '@adiwajshing/keyed-db' -import got, { Options, Response } from 'got' -import { join } from 'path' -import { IAudioMetadata } from 'music-metadata' - -const platformMap = { - 'aix': 'AIX', - 'darwin': 'Mac OS', - 'win32': 'Windows', - 'android': 'Android' -} -export const Browsers = { - ubuntu: browser => ['Ubuntu', browser, '18.04'] as [string, string, string], - macOS: browser => ['Mac OS', browser, '10.15.3'] as [string, string, string], - baileys: browser => ['Baileys', browser, '3.0'] as [string, string, string], - /** The appropriate browser based on your OS & release */ - appropriate: browser => [ platformMap [platform()] || 'Ubuntu', browser, release() ] as [string, string, string] -} -export const toNumber = (t: Long | number) => (t['low'] || t) as number -export const waChatKey = (pin: boolean) => ({ - key: (c: WAChat) => (pin ? (c.pin ? '1' : '0') : '') + (c.archive === 'true' ? '0' : '1') + c.t.toString(16).padStart(8, '0') + c.jid, - compare: (k1: string, k2: string) => k2.localeCompare (k1) -}) -export const waMessageKey = { - key: (m: WAMessage) => (5000 + (m['epoch'] || 0)).toString(16).padStart(6, '0') + toNumber(m.messageTimestamp).toString(16).padStart(8, '0'), - compare: (k1: string, k2: string) => k1.localeCompare (k2) -} -export const WA_MESSAGE_ID = (m: WAMessage) => GET_MESSAGE_ID (m.key) -export const GET_MESSAGE_ID = (key: WAMessageKey) => `${key.id}|${key.fromMe ? 1 : 0}` - -export const whatsappID = (jid: string) => jid?.replace ('@c.us', '@s.whatsapp.net') -export const isGroupID = (jid: string) => jid?.endsWith ('@g.us') - -export const newMessagesDB = (messages: WAMessage[] = []) => { - const db = new KeyedDB(waMessageKey, WA_MESSAGE_ID) - messages.forEach(m => !db.get(WA_MESSAGE_ID(m)) && db.insert(m)) - return db -} - -export function shallowChanges (old: T, current: T, {lookForDeletedKeys}: {lookForDeletedKeys: boolean}): Partial { - let changes: Partial = {} - for (let key in current) { - if (old[key] !== current[key]) { - changes[key] = current[key] || null - } - } - if (lookForDeletedKeys) { - for (let key in old) { - if (!changes[key] && old[key] !== current[key]) { - changes[key] = current[key] || null - } - } - } - return changes -} - -/** decrypt AES 256 CBC; where the IV is prefixed to the buffer */ -export function aesDecrypt(buffer: Buffer, key: Buffer) { - return aesDecryptWithIV(buffer.slice(16, buffer.length), key, buffer.slice(0, 16)) -} -/** decrypt AES 256 CBC */ -export function aesDecryptWithIV(buffer: Buffer, key: Buffer, IV: Buffer) { - const aes = Crypto.createDecipheriv('aes-256-cbc', key, IV) - return Buffer.concat([aes.update(buffer), aes.final()]) -} -// encrypt AES 256 CBC; where a random IV is prefixed to the buffer -export function aesEncrypt(buffer: Buffer, key: Buffer) { - const IV = randomBytes(16) - const aes = Crypto.createCipheriv('aes-256-cbc', key, IV) - return Buffer.concat([IV, aes.update(buffer), aes.final()]) // prefix IV to the buffer -} -// encrypt AES 256 CBC with a given IV -export function aesEncrypWithIV(buffer: Buffer, key: Buffer, IV: Buffer) { - const aes = Crypto.createCipheriv('aes-256-cbc', key, IV) - return Buffer.concat([aes.update(buffer), aes.final()]) // prefix IV to the buffer -} -// sign HMAC using SHA 256 -export function hmacSign(buffer: Buffer, key: Buffer) { - return Crypto.createHmac('sha256', key).update(buffer).digest() -} -export function sha256(buffer: Buffer) { - return Crypto.createHash('sha256').update(buffer).digest() -} -// HKDF key expansion -export function hkdf(buffer: Buffer, expandedLength: number, info = null) { - return HKDF(buffer, expandedLength, { salt: Buffer.alloc(32), info: info, hash: 'SHA-256' }) -} -// generate a buffer with random bytes of the specified length -export function randomBytes(length) { - return Crypto.randomBytes(length) -} -/** unix timestamp of a date in seconds */ -export const unixTimestampSeconds = (date: Date = new Date()) => Math.floor(date.getTime()/1000) - -export type DebouncedTimeout = ReturnType -export const debouncedTimeout = (intervalMs: number = 1000, task: () => void = undefined) => { - let timeout: NodeJS.Timeout - return { - start: (newIntervalMs?: number, newTask?: () => void) => { - task = newTask || task - intervalMs = newIntervalMs || intervalMs - timeout && clearTimeout(timeout) - timeout = setTimeout(task, intervalMs) - }, - cancel: () => { - timeout && clearTimeout(timeout) - timeout = undefined - }, - setTask: (newTask: () => void) => task = newTask, - setInterval: (newInterval: number) => intervalMs = newInterval - } -} - -export const delay = (ms: number) => delayCancellable (ms).delay -export const delayCancellable = (ms: number) => { - const stack = new Error().stack - let timeout: NodeJS.Timeout - let reject: (error) => void - const delay: Promise = new Promise((resolve, _reject) => { - timeout = setTimeout(resolve, ms) - reject = _reject - }) - const cancel = () => { - clearTimeout (timeout) - reject (CancelledError(stack)) - } - return { delay, cancel } -} -export async function promiseTimeout(ms: number, promise: (resolve: (v?: T)=>void, reject: (error) => void) => void) { - if (!ms) return new Promise (promise) - const stack = new Error().stack - // Create a promise that rejects in milliseconds - let {delay, cancel} = delayCancellable (ms) - const p = new Promise ((resolve, reject) => { - delay - .then(() => reject(TimedOutError(stack))) - .catch (err => reject(err)) - - promise (resolve, reject) - }) - .finally (cancel) - return p as Promise -} -// whatsapp requires a message tag for every message, we just use the timestamp as one -export function generateMessageTag(epoch?: number) { - let tag = unixTimestampSeconds().toString() - if (epoch) tag += '.--' + epoch // attach epoch if provided - return tag -} -// generate a random 16 byte client ID -export function generateClientID() { - return randomBytes(16).toString('base64') -} -// generate a random 16 byte ID to attach to a message -export function generateMessageID() { - return '3EB0' + randomBytes(4).toString('hex').toUpperCase() -} -export function decryptWA (message: string | Buffer, macKey: Buffer, encKey: Buffer, decoder: Decoder, fromMe: boolean=false): [string, Object, [number, number]?] { - let commaIndex = message.indexOf(',') // all whatsapp messages have a tag and a comma, followed by the actual message - if (commaIndex < 0) throw new BaileysError ('invalid message', { message }) // if there was no comma, then this message must be not be valid - - if (message[commaIndex+1] === ',') commaIndex += 1 - let data = message.slice(commaIndex+1, message.length) - - // get the message tag. - // If a query was done, the server will respond with the same message tag we sent the query with - const messageTag: string = message.slice(0, commaIndex).toString() - let json - let tags - if (data.length > 0) { - if (typeof data === 'string') { - json = JSON.parse(data) // parse the JSON - } else { - if (!macKey || !encKey) { - throw new BaileysError ('recieved encrypted buffer when auth creds unavailable', { message }) - } - /* - If the data recieved was not a JSON, then it must be an encrypted message. - Such a message can only be decrypted if we're connected successfully to the servers & have encryption keys - */ - if (fromMe) { - tags = [data[0], data[1]] - data = data.slice(2, data.length) - } - - const checksum = data.slice(0, 32) // the first 32 bytes of the buffer are the HMAC sign of the message - data = data.slice(32, data.length) // the actual message - const computedChecksum = hmacSign(data, macKey) // compute the sign of the message we recieved using our macKey - - if (checksum.equals(computedChecksum)) { - // the checksum the server sent, must match the one we computed for the message to be valid - const decrypted = aesDecrypt(data, encKey) // decrypt using AES - json = decoder.read(decrypted) // decode the binary message into a JSON array - } else { - throw new BaileysError ('checksum failed', { - received: checksum.toString('hex'), - computed: computedChecksum.toString('hex'), - data: data.slice(0, 80).toString(), - tag: messageTag, - message: message.slice(0, 80).toString() - }) - } - } - } - return [messageTag, json, tags] -} -/** generates all the keys required to encrypt/decrypt & sign a media message */ -export function getMediaKeys(buffer, mediaType: MessageType) { - if (typeof buffer === 'string') { - buffer = Buffer.from (buffer.replace('data:;base64,', ''), 'base64') - } - // expand using HKDF to 112 bytes, also pass in the relevant app info - const expandedMediaKey = hkdf(buffer, 112, HKDFInfoKeys[mediaType]) - return { - iv: expandedMediaKey.slice(0, 16), - cipherKey: expandedMediaKey.slice(16, 48), - macKey: expandedMediaKey.slice(48, 80), - } -} -/** Extracts video thumb using FFMPEG */ -const extractVideoThumb = async ( - path: string, - destPath: string, - time: string, - size: { width: number; height: number }, -) => - new Promise((resolve, reject) => { - const cmd = `ffmpeg -ss ${time} -i ${path} -y -s ${size.width}x${size.height} -vframes 1 -f image2 ${destPath}` - exec(cmd, (err) => { - if (err) reject(err) - else resolve() - }) - }) as Promise - -export const compressImage = async (bufferOrFilePath: Buffer | string) => { - const jimp = await Jimp.read(bufferOrFilePath as any) - const result = await jimp.resize(48, 48).getBufferAsync(Jimp.MIME_JPEG) - return result -} -export const generateProfilePicture = async (buffer: Buffer) => { - const jimp = await Jimp.read (buffer) - const min = Math.min(jimp.getWidth (), jimp.getHeight ()) - const cropped = jimp.crop (0, 0, min, min) - return { - img: await cropped.resize(640, 640).getBufferAsync (Jimp.MIME_JPEG), - preview: await cropped.resize(96, 96).getBufferAsync (Jimp.MIME_JPEG) - } -} -export const ProxyAgent = (host: string | URL) => HttpsProxyAgent(host) as any as Agent -/** gets the SHA256 of the given media message */ -export const mediaMessageSHA256B64 = (message: WAMessageContent) => { - const media = Object.values(message)[0] as WAGenericMediaMessage - return media?.fileSha256 && Buffer.from(media.fileSha256).toString ('base64') -} -export async function getAudioDuration (buffer: Buffer | string) { - const musicMetadata = await import ('music-metadata') - let metadata: IAudioMetadata - if(Buffer.isBuffer(buffer)) { - metadata = await musicMetadata.parseBuffer(buffer, null, { duration: true }) - } else { - const rStream = createReadStream(buffer) - metadata = await musicMetadata.parseStream(rStream, null, { duration: true }) - rStream.close() - } - return metadata.format.duration; -} -export const toReadable = (buffer: Buffer) => { - const readable = new Readable({ read: () => {} }) - readable.push(buffer) - readable.push(null) - return readable -} -export const getStream = async (item: WAMediaUpload) => { - if(Buffer.isBuffer(item)) return { stream: toReadable(item), type: 'buffer' } - if(item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) { - return { stream: await getGotStream(item.url), type: 'remote' } - } - return { stream: createReadStream(item.url), type: 'file' } -} -/** generates a thumbnail for a given media, if required */ -export async function generateThumbnail(file: string, mediaType: MessageType, info: MessageOptions) { - if ('thumbnail' in info) { - // don't do anything if the thumbnail is already provided, or is null - if (mediaType === MessageType.audio) { - throw new Error('audio messages cannot have thumbnails') - } - } else if (mediaType === MessageType.image) { - const buff = await compressImage(file) - info.thumbnail = buff.toString('base64') - } else if (mediaType === MessageType.video) { - const imgFilename = join(tmpdir(), generateMessageID() + '.jpg') - try { - await extractVideoThumb(file, imgFilename, '00:00:00', { width: 48, height: 48 }) - const buff = await fs.readFile(imgFilename) - info.thumbnail = buff.toString('base64') - await fs.unlink(imgFilename) - } catch (err) { - console.log('could not generate video thumb: ' + err) - } - } -} -export const getGotStream = async(url: string | URL, options: Options & { isStream?: true } = {}) => { - const fetched = got.stream(url, { ...options, isStream: true }) - await new Promise((resolve, reject) => { - fetched.once('error', reject) - fetched.once('response', ({statusCode: status}: Response) => { - if (status >= 400) { - reject(new BaileysError ( - 'Invalid code (' + status + ') returned', - { status } - )) - } else { - resolve(undefined) - } - }) - }) - return fetched -} -export const encryptedStream = async(media: WAMediaUpload, mediaType: MessageType, saveOriginalFileIfRequired = true) => { - const { stream, type } = await getStream(media) - - const mediaKey = randomBytes(32) - const {cipherKey, iv, macKey} = getMediaKeys(mediaKey, mediaType) - // random name - const encBodyPath = join(tmpdir(), mediaType + generateMessageID() + '.enc') - const encWriteStream = createWriteStream(encBodyPath) - let bodyPath: string - let writeStream: WriteStream - if(type === 'file') { - bodyPath = (media as any).url - } else if(saveOriginalFileIfRequired) { - bodyPath = join(tmpdir(), mediaType + generateMessageID()) - writeStream = createWriteStream(bodyPath) - } - - let fileLength = 0 - const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv) - let hmac = Crypto.createHmac('sha256', macKey).update(iv) - let sha256Plain = Crypto.createHash('sha256') - let sha256Enc = Crypto.createHash('sha256') - - const onChunk = (buff: Buffer) => { - sha256Enc = sha256Enc.update(buff) - hmac = hmac.update(buff) - encWriteStream.write(buff) - } - for await(const data of stream) { - fileLength += data.length - sha256Plain = sha256Plain.update(data) - writeStream && writeStream.write(data) - onChunk(aes.update(data)) - } - onChunk(aes.final()) - - const mac = hmac.digest().slice(0, 10) - sha256Enc = sha256Enc.update(mac) - - const fileSha256 = sha256Plain.digest() - const fileEncSha256 = sha256Enc.digest() - - encWriteStream.write(mac) - encWriteStream.close() - - writeStream && writeStream.close() - - return { - mediaKey, - encBodyPath, - bodyPath, - mac, - fileEncSha256, - fileSha256, - fileLength, - didSaveToTmpPath: type !== 'file' - } -} -/** - * Decode a media message (video, image, document, audio) & return decrypted buffer - * @param message the media message you want to decode - */ -export async function decryptMediaMessageBuffer(message: WAMessageContent): Promise { - /* - One can infer media type from the key in the message - it is usually written as [mediaType]Message. Eg. imageMessage, audioMessage etc. - */ - const type = Object.keys(message)[0] as MessageType - if (!type) { - throw new BaileysError('unknown message type', message) - } - if (type === MessageType.text || type === MessageType.extendedText) { - throw new BaileysError('cannot decode text message', message) - } - if (type === MessageType.location || type === MessageType.liveLocation) { - const buffer = Buffer.from(message[type].jpegThumbnail) - const readable = new Readable({ read: () => {} }) - readable.push(buffer) - readable.push(null) - return readable - } - let messageContent: WAGenericMediaMessage - if (message.productMessage) { - const product = message.productMessage.product?.productImage - if (!product) throw new BaileysError ('product has no image', message) - messageContent = product - } else { - messageContent = message[type] - } - // download the message - const fetched = await getGotStream(messageContent.url, { - headers: { Origin: DEFAULT_ORIGIN } - }) - let remainingBytes = Buffer.from([]) - const { cipherKey, iv } = getMediaKeys(messageContent.mediaKey, type) - const aes = Crypto.createDecipheriv("aes-256-cbc", cipherKey, iv) - - const output = new Transform({ - transform(chunk, _, callback) { - let data = Buffer.concat([remainingBytes, chunk]) - const decryptLength = - Math.floor(data.length / 16) * 16 - remainingBytes = data.slice(decryptLength) - data = data.slice(0, decryptLength) - - try { - this.push(aes.update(data)) - callback() - } catch(error) { - callback(error) - } - }, - final(callback) { - try { - this.push(aes.final()) - callback() - } catch(error) { - callback(error) - } - }, - }) - return fetched.pipe(output, { end: true }) -} -export function extensionForMediaMessage(message: WAMessageContent) { - const getExtension = (mimetype: string) => mimetype.split(';')[0].split('/')[1] - const type = Object.keys(message)[0] as MessageType - let extension: string - if (type === MessageType.location || type === MessageType.liveLocation || type === MessageType.product) { - extension = '.jpeg' - } else { - const messageContent = message[type] as - | WAMessageProto.VideoMessage - | WAMessageProto.ImageMessage - | WAMessageProto.AudioMessage - | WAMessageProto.DocumentMessage - extension = getExtension (messageContent.mimetype) - } - return extension -} \ No newline at end of file diff --git a/src/WAConnection/index.ts b/src/WAConnection/index.ts deleted file mode 100644 index f0cb3ad..0000000 --- a/src/WAConnection/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './8.Groups' -export * from './Utils' -export * from './Constants' -export * from './Mutex' \ No newline at end of file From 89cf8004e98a01fc0a5a591889a10aa47d209d32 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 9 Jul 2021 20:35:07 +0530 Subject: [PATCH 002/311] Wrap up connection + in memory store --- Example/example.ts | 152 +- package.json | 17 +- src/BinaryNode/encode.ts | 11 +- src/BrowserMessageDecoding.ts | 5 +- src/Connection/auth.ts | 29 +- src/Connection/chats.ts | 489 ++- src/Connection/groups.ts | 208 ++ src/Connection/index.ts | 12 + src/Connection/messages.ts | 437 +++ src/Connection/socket.ts | 6 +- src/Defaults/index.ts | 5 + src/Store/in-memory-store.ts | 163 + src/Store/index.ts | 2 + src/Tests/_test.manual_tests.ts | 112 + src/Tests/test.connect.ts | 154 +- src/Types/Chat.ts | 29 +- src/Types/Contact.ts | 1 + src/Types/GroupMetadata.ts | 14 + src/Types/Message.ts | 135 + src/Types/index.ts | 56 +- ...ecodeWAMessage.ts => decode-wa-message.ts} | 2 +- src/Utils/generics.ts | 2 +- src/Utils/messages-media.ts | 286 ++ src/Utils/messages.ts | 355 ++ ...teConnection.ts => validate-connection.ts} | 2 +- src/index.ts | 11 +- yarn.lock | 3259 ++++++++++++----- 27 files changed, 4637 insertions(+), 1317 deletions(-) create mode 100644 src/Connection/groups.ts create mode 100644 src/Connection/index.ts create mode 100644 src/Connection/messages.ts create mode 100644 src/Store/in-memory-store.ts create mode 100644 src/Store/index.ts create mode 100644 src/Tests/_test.manual_tests.ts create mode 100644 src/Types/Message.ts rename src/Utils/{decodeWAMessage.ts => decode-wa-message.ts} (98%) create mode 100644 src/Utils/messages-media.ts create mode 100644 src/Utils/messages.ts rename src/Utils/{validateConnection.ts => validate-connection.ts} (99%) diff --git a/Example/example.ts b/Example/example.ts index 5d51e09..ad85df4 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -1,153 +1,13 @@ -import { - WAConnection, - MessageType, - Presence, - MessageOptions, - Mimetype, - WALocationMessage, - WA_MESSAGE_STUB_TYPES, - ReconnectMode, - ProxyAgent, - waChatKey, -} from '../src/WAConnection' +import makeConnection from '../src' import * as fs from 'fs' async function example() { - const conn = new WAConnection() // instantiate - conn.autoReconnect = ReconnectMode.onConnectionLost // only automatically reconnect when the connection breaks - conn.logger.level = 'debug' // set to 'debug' to see what kind of stuff you can implement - // attempt to reconnect at most 10 times in a row - conn.connectOptions.maxRetries = 10 - conn.chatOrderingKey = waChatKey(true) // order chats such that pinned chats are on top - conn.on('chats-received', ({ hasNewChats }) => { - console.log(`you have ${conn.chats.length} chats, new chats available: ${hasNewChats}`) + const conn = makeConnection({ + credentials: './auth_info.json' }) - conn.on('contacts-received', () => { - console.log(`you have ${Object.keys(conn.contacts).length} contacts`) + conn.ev.on('connection.update', state => { + console.log(state) }) - conn.on('initial-data-received', () => { - console.log('received all initial messages') - }) - - // loads the auth file credentials if present - /* Note: one can take this auth_info.json file and login again from any computer without having to scan the QR code, - and get full access to one's WhatsApp. Despite the convenience, be careful with this file */ - fs.existsSync('./auth_info.json') && conn.loadAuthInfo ('./auth_info.json') - // uncomment the following line to proxy the connection; some random proxy I got off of: https://proxyscrape.com/free-proxy-list - //conn.connectOptions.agent = ProxyAgent ('http://1.0.180.120:8080') - await conn.connect() - // credentials are updated on every connect - const authInfo = conn.base64EncodedAuthInfo() // get all the auth info we need to restore this session - fs.writeFileSync('./auth_info.json', JSON.stringify(authInfo, null, '\t')) // save this info to a file - - console.log('oh hello ' + conn.user.name + ' (' + conn.user.jid + ')') - // uncomment to load all unread messages - //const unread = await conn.loadAllUnreadMessages () - //console.log ('you have ' + unread.length + ' unread messages') - - /** - * The universal event for anything that happens - * New messages, updated messages, read & delivered messages, participants typing etc. - */ - conn.on('chat-update', async chat => { - if (chat.presences) { // receive presence updates -- composing, available, etc. - Object.values(chat.presences).forEach(presence => console.log( `${presence.name}'s presence is ${presence.lastKnownPresence} in ${chat.jid}`)) - } - if(chat.imgUrl) { - console.log('imgUrl of chat changed ', chat.imgUrl) - return - } - // only do something when a new message is received - if (!chat.hasNewMessage) { - if(chat.messages) { - console.log('updated message: ', chat.messages.first) - } - return - } - - const m = chat.messages.all()[0] // pull the new message from the update - const messageStubType = WA_MESSAGE_STUB_TYPES[m.messageStubType] || 'MESSAGE' - console.log('got notification of type: ' + messageStubType) - - const messageContent = m.message - // if it is not a regular text or media message - if (!messageContent) return - - if (m.key.fromMe) { - console.log('relayed my own message') - return - } - - let sender = m.key.remoteJid - if (m.key.participant) { - // participant exists if the message is in a group - sender += ' (' + m.key.participant + ')' - } - const messageType = Object.keys (messageContent)[0] // message will always contain one key signifying what kind of message - if (messageType === MessageType.text) { - const text = m.message.conversation - console.log(sender + ' sent: ' + text) - } else if (messageType === MessageType.extendedText) { - const text = m.message.extendedTextMessage.text - console.log(sender + ' sent: ' + text + ' and quoted message: ' + JSON.stringify(m.message)) - } else if (messageType === MessageType.contact) { - const contact = m.message.contactMessage - console.log(sender + ' sent contact (' + contact.displayName + '): ' + contact.vcard) - } else if (messageType === MessageType.location || messageType === MessageType.liveLocation) { - const locMessage = m.message[messageType] as WALocationMessage - console.log(`${sender} sent location (lat: ${locMessage.degreesLatitude}, long: ${locMessage.degreesLongitude})`) - - await conn.downloadAndSaveMediaMessage(m, './Media/media_loc_thumb_in_' + m.key.id) // save location thumbnail - - if (messageType === MessageType.liveLocation) { - console.log(`${sender} sent live location for duration: ${m.duration/60}`) - } - } else { - // if it is a media (audio, image, video, sticker) message - // decode, decrypt & save the media. - // The extension to the is applied automatically based on the media type - try { - const savedFile = await conn.downloadAndSaveMediaMessage(m, './Media/media_in_' + m.key.id) - console.log(sender + ' sent media, saved at: ' + savedFile) - } catch (err) { - console.log('error in decoding message: ' + err) - } - } - // send a reply after 3 seconds - setTimeout(async () => { - await conn.chatRead(m.key.remoteJid) // mark chat read - await conn.updatePresence(m.key.remoteJid, Presence.available) // tell them we're available - await conn.updatePresence(m.key.remoteJid, Presence.composing) // tell them we're composing - - const options: MessageOptions = { quoted: m } - let content - let type: MessageType - const rand = Math.random() - if (rand > 0.66) { // choose at random - content = 'hello!' // send a "hello!" & quote the message recieved - type = MessageType.text - } else if (rand > 0.33) { // choose at random - content = { degreesLatitude: 32.123123, degreesLongitude: 12.12123123 } - type = MessageType.location - } else { - content = fs.readFileSync('./Media/ma_gif.mp4') // load the gif - options.mimetype = Mimetype.gif - type = MessageType.video - } - const response = await conn.sendMessage(m.key.remoteJid, content, type, options) - console.log("sent message with ID '" + response.key.id + "' successfully") - }, 3 * 1000) - }) - - /* example of custom functionality for tracking battery */ - conn.on('CB:action,,battery', json => { - const batteryLevelStr = json[2][0][1].value - const batterylevel = parseInt(batteryLevelStr) - console.log('battery level: ' + batterylevel) - }) - conn.on('close', ({reason, isReconnecting}) => ( - console.log ('oh no got disconnected: ' + reason + ', reconnecting: ' + isReconnecting) - )) } -example().catch((err) => console.log(`encountered error: ${err}`)) \ No newline at end of file +example().catch((err) => console.log(`encountered error`, err)) \ No newline at end of file diff --git a/package.json b/package.json index fdd2621..bf4e3cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@adiwajshing/baileys", - "version": "3.5.1", + "version": "4.0.0", "description": "WhatsApp Web API", "homepage": "https://github.com/adiwajshing/Baileys", "main": "lib/index.js", @@ -33,6 +33,7 @@ }, "dependencies": { "@adiwajshing/keyed-db": "^0.2.2", + "@hapi/boom": "^9.1.3", "curve25519-js": "^0.0.4", "futoin-hkdf": "^1.3.2", "got": "^11.8.1", @@ -42,23 +43,25 @@ "pino": "^6.7.0", "pino-pretty": "^4.3.0", "protobufjs": "^6.10.1", - "qrcode-terminal": "^0.12.0", "ws": "^7.3.1" }, + "optionalDependencies": { + "qrcode-terminal": "^0.12.0" + }, "files": [ "lib/*", "WAMessage/*" ], "devDependencies": { "@types/got": "^9.6.11", - "@types/mocha": "^7.0.2", + "@types/jest": "^26.0.24", "@types/node": "^14.6.2", "@types/pino": "^6.3.2", "@types/ws": "^7.2.6", - "assert": "^2.0.0", - "dotenv": "^8.2.0", - "mocha": "^8.1.3", - "ts-node-dev": "^1.0.0", + "jest": "^27.0.6", + "qrcode-terminal": "^0.12.0", + "ts-jest": "^27.0.3", + "ts-node": "^10.0.0", "typedoc": "^0.20.0-beta.27", "typescript": "^4.0.0" } diff --git a/src/BinaryNode/encode.ts b/src/BinaryNode/encode.ts index b1e8f79..7fe785e 100644 --- a/src/BinaryNode/encode.ts +++ b/src/BinaryNode/encode.ts @@ -17,10 +17,6 @@ const encode = ({ header, attributes, data }: BinaryNode, buffer: number[] = []) const pushInt20 = (value: number) => ( pushBytes([(value >> 16) & 0x0f, (value >> 8) & 0xff, value & 0xff]) ) - const pushString = (str: string) => { - const bytes = Buffer.from (str, 'utf-8') - pushBytes(bytes) - } const writeByteLength = (length: number) => { if (length >= 4294967296) throw new Error('string too large to encode: ' + length) @@ -35,9 +31,10 @@ const encode = ({ header, attributes, data }: BinaryNode, buffer: number[] = []) pushByte(length) } } - const writeStringRaw = (string: string) => { - writeByteLength(string.length) - pushString(string) + const writeStringRaw = (str: string) => { + const bytes = Buffer.from (str, 'utf-8') + writeByteLength(bytes.length) + pushBytes(bytes) } const writeToken = (token: number) => { if (token < 245) { diff --git a/src/BrowserMessageDecoding.ts b/src/BrowserMessageDecoding.ts index addcbec..1a59c19 100644 --- a/src/BrowserMessageDecoding.ts +++ b/src/BrowserMessageDecoding.ts @@ -1,6 +1,5 @@ import fs from 'fs' -import { decryptWA } from './WAConnection' -import Decoder from './Binary/Decoder' +import { decodeWAMessage } from './Utils/decode-wa-message' interface BrowserMessagesInfo { bundle: { encKey: string, macKey: string } @@ -24,7 +23,7 @@ entries.forEach ((e, i) => { wsMessages.push (...e['_webSocketMessages']) } }) -const decrypt = (buffer, fromMe) => decryptWA (buffer, macKey, encKey, new Decoder(), fromMe) +const decrypt = (buffer, fromMe) => decodeWAMessage(buffer, { macKey, encKey }, fromMe) console.log ('parsing ' + wsMessages.length + ' messages') const list = wsMessages.map ((item, i) => { diff --git a/src/Connection/auth.ts b/src/Connection/auth.ts index 398fdcd..87f42c2 100644 --- a/src/Connection/auth.ts +++ b/src/Connection/auth.ts @@ -1,10 +1,10 @@ -import Boom from "boom" +import { Boom } from '@hapi/boom' import EventEmitter from "events" import * as Curve from 'curve25519-js' -import { BaileysEventEmitter, BaileysEventMap, SocketConfig, CurveKeyPair, WAInitResponse, ConnectionState } from "../Types" +import { BaileysEventEmitter, BaileysEventMap, SocketConfig, CurveKeyPair, WAInitResponse, ConnectionState, DisconnectReason } from "../Types" import { makeSocket } from "./socket" import { generateClientID, promiseTimeout } from "../Utils/generics" -import { normalizedAuthInfo, computeChallengeResponse, validateNewConnection } from "../Utils/validateConnection" +import { normalizedAuthInfo, computeChallengeResponse, validateNewConnection } from "../Utils/validate-connection" import { randomBytes } from "crypto" import { AuthenticationCredentials } from "../Types" @@ -78,7 +78,7 @@ const makeAuthSocket = (config: SocketConfig) => { } // will call state update to close connection socket?.end( - Boom.unauthorized('Logged Out') + new Boom('Logged Out', { statusCode: DisconnectReason.credentialsInvalidated }) ) authInfo = undefined } @@ -89,7 +89,7 @@ const makeAuthSocket = (config: SocketConfig) => { let listener: (item: BaileysEventMap['connection.update']) => void const timeout = waitInfinitely ? undefined : pendingRequestTimeoutMs if(timeout < 0) { - throw Boom.preconditionRequired('Connection Closed') + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) } await ( @@ -99,7 +99,7 @@ const makeAuthSocket = (config: SocketConfig) => { listener = ({ connection, lastDisconnect }) => { if(connection === 'open') resolve() else if(connection == 'close') { - reject(lastDisconnect.error || Boom.preconditionRequired('Connection Closed')) + reject(lastDisconnect.error || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) } } ev.on('connection.update', listener) @@ -153,7 +153,7 @@ const makeAuthSocket = (config: SocketConfig) => { } qrLoop(ttl) } - socketEvents.once('ws-open', async() => { + const onOpen = async() => { const canDoLogin = canLogin() const initQuery = (async () => { const {ref, ttl} = await socket.query({ @@ -185,7 +185,7 @@ const makeAuthSocket = (config: SocketConfig) => { logger.warn('Received login timeout req when state=open, ignoring...') return } - logger.debug('sending login request') + logger.info('sending login request') socket.sendMessage({ json, tag: loginTag @@ -220,21 +220,32 @@ const makeAuthSocket = (config: SocketConfig) => { response = await socket.waitForMessage('s2', true) } // validate the new connection - const {user, auth} = validateNewConnection(response[1], authInfo, curveKeys)// validate the connection + const {user, auth, phone} = validateNewConnection(response[1], authInfo, curveKeys)// validate the connection const isNewLogin = user.jid !== state.user?.jid authInfo = auth // update the keys so we can decrypt traffic socket.updateKeys({ encKey: auth.encKey, macKey: auth.macKey }) + logger.info({ user }, 'logged in') + updateState({ connection: 'open', phoneConnected: true, user, isNewLogin, + phoneInfo: phone, connectionTriesLeft: undefined, qr: undefined }) + ev.emit('credentials.update', auth) + } + socketEvents.once('ws-open', async() => { + try { + await onOpen() + } catch(error) { + socket.end(error) + } }) if(printQRInTerminal) { diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts index 68a611c..8324c8e 100644 --- a/src/Connection/chats.ts +++ b/src/Connection/chats.ts @@ -1,6 +1,493 @@ -import { SocketConfig } from "../Types"; +import BinaryNode from "../BinaryNode"; +import { EventEmitter } from 'events' +import { Chat, Contact, Presence, PresenceData, WABroadcastListInfo, SocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessage } from "../Types"; +import { debouncedTimeout, unixTimestampSeconds, whatsappID } from "../Utils/generics"; +import makeAuthSocket from "./auth"; +import { Attributes, BinaryNode as BinaryNodeBase } from "../BinaryNode/types"; const makeChatsSocket = (config: SocketConfig) => { + const { logger } = config + const sock = makeAuthSocket(config) + const { + ev, + socketEvents, + currentEpoch, + setQuery, + query, + sendMessage, + getState + } = sock + const chatsDebounceTimeout = debouncedTimeout(10_000, () => sendChatsQuery(1)) + + const sendChatsQuery = (epoch: number) => ( + sendMessage({ + json: new BinaryNode('query', {type: 'chat', epoch: epoch.toString()}), + binaryTag: [ WAMetric.queryChat, WAFlag.ignore ] + }) + ) + + const fetchImageUrl = async(jid: string) => { + const response = await query({ + json: ['query', 'ProfilePicThumb', jid], + expect200: true, + requiresPhoneConnection: false + }) + return response.eurl as string | undefined + } + + const executeChatModification = (node: BinaryNodeBase) => { + const { attributes } = node + const updateType = attributes.type + const jid = whatsappID(attributes?.jid) + + switch(updateType) { + case 'delete': + ev.emit('chats.delete', [jid]) + break + case 'clear': + if(node.data) { + const ids = (node.data as BinaryNode[]).map( + ({ attributes }) => attributes.index + ) + ev.emit('messages.delete', { jid, ids }) + } else { + ev.emit('messages.delete', { jid, all: true }) + } + break + case 'archive': + ev.emit('chats.update', [ { jid, archive: 'true' } ]) + break + case 'unarchive': + ev.emit('chats.update', [ { jid, archive: 'false' } ]) + break + case 'pin': + ev.emit('chats.update', [ { jid, pin: attributes.pin } ]) + break + case 'star': + case 'unstar': + const starred = updateType === 'star' + const updates: Partial[] = (node.data as BinaryNode[]).map( + ({ attributes }) => ({ + key: { + remoteJid: jid, + id: attributes.index, + fromMe: attributes.owner === 'true' + }, + starred + }) + ) + ev.emit('messages.update', updates) + break + default: + logger.warn({ node }, `received unrecognized chat update`) + break + } + } + + const applyingPresenceUpdate = (update: Attributes, chat: Partial) => { + chat.jid = whatsappID(update.id) + const jid = whatsappID(update.participant || update.id) + + if (jid.endsWith('@s.whatsapp.net')) { // if its a single chat + chat.presences = chat.presences || {} + + const presence = { } as PresenceData + + if(update.t) { + presence.lastSeen = +update.t + } + presence.lastKnownPresence = update.type as Presence + chat.presences[jid] = presence + + chat.presences = { + [jid]: presence + } + } + return chat + } + + ev.on('connection.update', async({ connection }) => { + if(connection !== 'open') return + try { + await Promise.all([ + sendMessage({ + json: new BinaryNode('query', {type: 'contacts', epoch: '1'}), + binaryTag: [ WAMetric.queryContact, WAFlag.ignore ] + }), + sendMessage({ + json: new BinaryNode('query', {type: 'status', epoch: '1'}), + binaryTag: [ WAMetric.queryStatus, WAFlag.ignore ] + }), + sendMessage({ + json: new BinaryNode('query', {type: 'quick_reply', epoch: '1'}), + binaryTag: [ WAMetric.queryQuickReply, WAFlag.ignore ] + }), + sendMessage({ + json: new BinaryNode('query', {type: 'label', epoch: '1'}), + binaryTag: [ WAMetric.queryLabel, WAFlag.ignore ] + }), + sendMessage({ + json: new BinaryNode('query', {type: 'emoji', epoch: '1'}), + binaryTag: [ WAMetric.queryEmoji, WAFlag.ignore ] + }), + sendMessage({ + json: new BinaryNode( + 'action', + { type: 'set', epoch: '1' }, + [ + new BinaryNode('presence', {type: 'available'}) + ] + ), + binaryTag: [ WAMetric.presence, WAFlag.available ] + }) + ]) + chatsDebounceTimeout.start() + + logger.debug('sent init queries') + } catch(error) { + logger.error(`error in sending init queries: ${error}`) + } + }) + // this persists through socket connections + // as conn & getSocket share the same eventemitter + socketEvents.on('CB:response,type:chat', async ({ data }: BinaryNode) => { + chatsDebounceTimeout.cancel() + if(Array.isArray(data)) { + const chats = data.map(({ attributes }) => { + return { + ...attributes, + jid: whatsappID(attributes.jid), + t: +attributes.t, + count: +attributes.count + } as Chat + }) + + logger.info(`got ${chats.length} chats`) + ev.emit('chats.upsert', { chats, type: 'set' }) + } + }) + // got all contacts from phone + socketEvents.on('CB:response,type:contacts', async ({ data }: BinaryNode) => { + if(Array.isArray(data)) { + const contacts = data.map(({ attributes }) => { + const contact = attributes as any as Contact + contact.jid = whatsappID(contact.jid) + return contact + }) + + logger.info(`got ${contacts.length} contacts`) + ev.emit('contacts.upsert', { contacts, type: 'set' }) + } + }) + // status updates + socketEvents.on('CB:Status,status', json => { + const jid = whatsappID(json[1].id) + ev.emit('contacts.update', [ { jid, status: json[1].status } ]) + }) + // User Profile Name Updates + socketEvents.on('CB:Conn,pushname', json => { + const { user, connection } = getState() + if(connection === 'open' && json[1].pushname !== user.name) { + user.name = json[1].pushname + ev.emit('connection.update', { user }) + } + }) + // read updates + socketEvents.on ('CB:action,,read', async ({ data }: BinaryNode) => { + if(Array.isArray(data)) { + const { attributes } = data[0] + + const update: Partial = { + jid: whatsappID(attributes.jid) + } + if (attributes.type === 'false') update.count = -1 + else update.count = 0 + + ev.emit('chats.update', [update]) + } + }) + + socketEvents.on('CB:Cmd,type:picture', async json => { + json = json[1] + const jid = whatsappID(json.jid) + const imgUrl = await fetchImageUrl(jid).catch(() => '') + + ev.emit('contacts.update', [ { jid, imgUrl } ]) + }) + + // chat archive, pin etc. + socketEvents.on('CB:action,,chat', ({ data }: BinaryNode) => { + if(Array.isArray(data)) { + const [node] = data + executeChatModification(node) + } + }) + + socketEvents.on ('CB:action,,user', json => { + const node = json[2][0] + if (node) { + const user = node[1] as Contact + user.jid = whatsappID(user.jid) + + ev.emit('contacts.upsert', { contacts: [user], type: 'upsert' }) + } + }) + + // presence updates + socketEvents.on('CB:Presence', json => { + const chat = applyingPresenceUpdate(json[1], { }) + ev.emit('chats.update', [ chat ]) + }) + + // blocklist updates + socketEvents.on('CB:Blocklist', json => { + json = json[1] + const blocklist = json.blocklist + ev.emit('blocklist.update', { blocklist, type: 'set' }) + }) + + return { + ...sock, + sendChatsQuery, + fetchImageUrl, + chatRead: async(jid: string, count: number, fromMessage: WAMessageKey) => { + if(count < 0) { + count = -2 + } + await setQuery ( + [ + new BinaryNode( + 'read', + { + jid, + count: count.toString(), + index: fromMessage.id, + owner: fromMessage.fromMe ? 'true' : 'false', + participant: fromMessage.participant + } + ) + ], + [ WAMetric.read, WAFlag.ignore ] + ) + ev.emit ('chats.update', [{ jid, count: count }]) + }, + /** + * Modify a given chat (archive, pin etc.) + * @param jid the ID of the person/group you are modifiying + */ + modifyChat: async(jid: string, modification: ChatModification) => { + let chatAttrs: Attributes = { jid: jid } + let data: BinaryNode[] | undefined = undefined + const stamp = unixTimestampSeconds() + + if('archive' in modification) { + chatAttrs.type = modification.archive ? 'archive' : 'unarchive' + } else if('pin' in modification) { + chatAttrs.type = 'pin' + if(typeof modification.pin === 'object') { + chatAttrs.previous = modification.pin.remove.toString() + } else { + chatAttrs.pin = stamp.toString() + } + } else if('mute' in modification) { + chatAttrs.type = 'mute' + if(typeof modification.mute === 'object') { + chatAttrs.previous = modification.mute.remove.toString() + } else { + chatAttrs.mute = (stamp + modification.mute).toString() + } + } else if('clear' in modification) { + chatAttrs.type = 'clear' + chatAttrs.modify_tag = Math.round(Math.random ()*1000000).toString() + if(modification.clear !== 'all') { + data = modification.clear.messages.map(({ id, fromMe }) => ( + new BinaryNode( + 'item', + { owner: (!!fromMe).toString(), index: id } + ) + )) + } + } else if('star' in modification) { + chatAttrs.type = modification.star.star ? 'star' : 'unstar' + data = modification.star.messages.map(({ id, fromMe }) => ( + new BinaryNode( + 'item', + { owner: (!!fromMe).toString(), index: id } + ) + )) + } + + const node = new BinaryNode('chat', chatAttrs, data) + const response = await setQuery ([node], [ WAMetric.chat, WAFlag.ignore ]) + // apply it and emit events + executeChatModification(node) + return response + }, + /** + * Query whether a given number is registered on WhatsApp + * @param str phone number/jid you want to check for + * @returns undefined if the number doesn't exists, otherwise the correctly formatted jid + */ + isOnWhatsApp: async (str: string) => { + const { status, jid, biz } = await query({ + json: ['query', 'exist', str], + requiresPhoneConnection: false + }) + if (status === 200) { + return { + exists: true, + jid: whatsappID(jid), + isBusiness: biz as boolean + } + } + }, + /** + * Tell someone about your presence -- online, typing, offline etc. + * @param jid the ID of the person/group who you are updating + * @param type your presence + */ + updatePresence: (jid: string | undefined, type: Presence) => ( + sendMessage({ + binaryTag: [WAMetric.presence, WAFlag[type]], // weird stuff WA does + json: new BinaryNode( + 'action', + { epoch: currentEpoch().toString(), type: 'set' }, + [ + new BinaryNode( + 'presence', + { type: type, to: jid } + ) + ] + ) + }) + ), + /** + * Request updates on the presence of a user + * this returns nothing, you'll receive updates in chats.update event + * */ + requestPresenceUpdate: async (jid: string) => ( + sendMessage({ json: ['action', 'presence', 'subscribe', jid] }) + ), + /** Query the status of the person (see groupMetadata() for groups) */ + getStatus: async(jid: string) => { + const status: { status: string } = await query({ json: ['query', 'Status', jid], requiresPhoneConnection: false }) + return status + }, + setStatus: async(status: string) => { + const response = await setQuery( + [ + new BinaryNode( + 'status', + {}, + Buffer.from (status, 'utf-8') + ) + ] + ) + ev.emit('contacts.update', [{ jid: getState().user!.jid, status }]) + return response + }, + /** Updates business profile. */ + updateBusinessProfile: async(profile: WABusinessProfile) => { + if (profile.business_hours?.config) { + profile.business_hours.business_config = profile.business_hours.config + delete profile.business_hours.config + } + const json = ['action', "editBusinessProfile", {...profile, v: 2}] + await query({ json, expect200: true, requiresPhoneConnection: true }) + }, + updateProfileName: async(name: string) => { + const response = (await setQuery( + [ + new BinaryNode( + 'profile', + { name } + ) + ] + )) as any as {status: number, pushname: string} + + if (response.status === 200) { + const user = { ...getState().user!, name } + ev.emit('connection.update', { user }) + ev.emit('contacts.update', [{ jid: user.jid, name }]) + } + return response + }, + /** Query broadcast list info */ + getBroadcastListInfo: (jid: string) => { + return query({ + json: ['query', 'contact', jid], + expect200: true, + requiresPhoneConnection: true + }) as Promise + }, + /** + * Update the profile picture + * @param jid + * @param img + */ + async updateProfilePicture (jid: string, img: Buffer) { + jid = whatsappID (jid) + const data = { img: Buffer.from([]), preview: Buffer.from([]) } //await generateProfilePicture(img) TODO + const tag = this.generateMessageTag () + const query = new BinaryNode( + 'picture', + { jid: jid, id: tag, type: 'set' }, + [ + new BinaryNode('image', {}, data.img), + new BinaryNode('preview', {}, data.preview) + ] + ) + const user = getState().user + const { eurl } = await this.setQuery ([query], [WAMetric.picture, 136], tag) as { eurl: string, status: number } + + if (jid === user.jid) { + user.imgUrl = eurl + ev.emit('connection.update', { user }) + } + ev.emit('contacts.update', [ { jid, imgUrl: eurl } ]) + }, + /** + * Add or remove user from blocklist + * @param jid the ID of the person who you are blocking/unblocking + * @param type type of operation + */ + blockUser: async(jid: string, type: 'add' | 'remove' = 'add') => { + const json = new BinaryNode( + 'block', + { type }, + [ new BinaryNode('user', { jid }) ] + ) + await setQuery ([json], [WAMetric.block, WAFlag.ignore]) + ev.emit('blocklist.update', { blocklist: [jid], type }) + }, + /** + * Query Business Profile (Useful for VCards) + * @param jid Business Jid + * @returns profile object or undefined if not business account + */ + getBusinessProfile: async(jid: string) => { + jid = whatsappID(jid) + const { + profiles: [{ + profile, + wid + }] + } = await query({ + json: [ + "query", "businessProfile", + [ { "wid": jid.replace('@s.whatsapp.net', '@c.us') } ], + 84 + ], + expect200: true, + requiresPhoneConnection: false, + }) + + return { + ...profile, + wid: whatsappID(wid) + } as WABusinessProfile + } + } } export default makeChatsSocket \ No newline at end of file diff --git a/src/Connection/groups.ts b/src/Connection/groups.ts new file mode 100644 index 0000000..552b7ff --- /dev/null +++ b/src/Connection/groups.ts @@ -0,0 +1,208 @@ +import BinaryNode from "../BinaryNode"; +import { EventEmitter } from 'events' +import { SocketConfig, GroupModificationResponse, ParticipantAction, GroupMetadata, WAFlag, WAMetric, WAGroupCreateResponse, GroupParticipant } from "../Types"; +import { generateMessageID, unixTimestampSeconds } from "../Utils/generics"; +import makeMessagesSocket from "./messages"; + +const makeGroupsSocket = (config: SocketConfig) => { + const { logger } = config + const sock = makeMessagesSocket(config) + const { + ev, + socketEvents, + query, + generateMessageTag, + currentEpoch, + setQuery, + getState + } = sock + + /** Generic function for group queries */ + const groupQuery = async(type: string, jid?: string, subject?: string, participants?: string[], additionalNodes?: BinaryNode[]) => { + const tag = generateMessageTag() + const result = await setQuery ([ + new BinaryNode( + 'group', + { + author: getState().user?.jid, + id: tag, + type: type, + jid: jid, + subject: subject, + }, + participants ? + participants.map(jid => ( + new BinaryNode('participant', { jid }) + )) : + additionalNodes + ) + ], [WAMetric.group, 136], tag) + return result + } + + /** Get the metadata of the group from WA */ + const groupMetadataFull = async (jid: string) => { + const metadata = await query({ + json: ['query', 'GroupMetadata', jid], + expect200: true + }) + metadata.participants = metadata.participants.map(p => ( + { ...p, id: undefined, jid: p.jid } + )) + return metadata as GroupMetadata + } + /** Get the metadata (works after you've left the group also) */ + const groupMetadataMinimal = async (jid: string) => { + const { attributes, data }:BinaryNode = await query({ + json: new BinaryNode( + 'query', + {type: 'group', jid: jid, epoch: currentEpoch().toString()} + ), + binaryTag: [WAMetric.group, WAFlag.ignore], + expect200: true + }) + const participants: GroupParticipant[] = [] + let desc: string | undefined + if(Array.isArray(data)) { + const nodes = data[0].data as BinaryNode[] + for(const item of nodes) { + if(item.header === 'participant') { + participants.push({ + jid: item.attributes.jid, + isAdmin: item.attributes.type === 'admin', + isSuperAdmin: false + }) + } else if(item.header === 'description') { + desc = (item.data as Buffer).toString('utf-8') + } + } + } + return { + id: jid, + owner: attributes?.creator, + creator: attributes?.creator, + creation: +attributes?.create, + subject: null, + desc, + participants + } as GroupMetadata + } + + socketEvents.on('CB:Chat,cmd:action', (json: BinaryNode) => { + /*const data = json[1].data + if (data) { + const emitGroupParticipantsUpdate = (action: WAParticipantAction) => this.emitParticipantsUpdate + (json[1].id, data[2].participants.map(whatsappID), action) + const emitGroupUpdate = (data: Partial) => this.emitGroupUpdate(json[1].id, data) + + switch (data[0]) { + case "promote": + emitGroupParticipantsUpdate('promote') + break + case "demote": + emitGroupParticipantsUpdate('demote') + break + case "desc_add": + emitGroupUpdate({ ...data[2], descOwner: data[1] }) + break + default: + this.logger.debug({ unhandled: true }, json) + break + } + }*/ + }) + + return { + ...sock, + groupMetadata: async(jid: string, minimal: boolean) => { + let result: GroupMetadata + + if(minimal) result = await groupMetadataMinimal(jid) + else result = await groupMetadataFull(jid) + + return result + }, + /** + * Create a group + * @param title like, the title of the group + * @param participants people to include in the group + */ + groupCreate: async (title: string, participants: string[]) => { + const response = await groupQuery('create', null, title, participants) as WAGroupCreateResponse + const gid = response.gid + let metadata: GroupMetadata + try { + metadata = await groupMetadataFull(gid) + } catch (error) { + logger.warn (`error in group creation: ${error}, switching gid & checking`) + // if metadata is not available + const comps = gid.replace ('@g.us', '').split ('-') + response.gid = `${comps[0]}-${+comps[1] + 1}@g.us` + + metadata = await groupMetadataFull(gid) + logger.warn (`group ID switched from ${gid} to ${response.gid}`) + } + ev.emit('chats.upsert', { + chats: [ + { + jid: response.gid, + name: title, + t: unixTimestampSeconds(), + count: 0 + } + ], + type: 'upsert' + }) + return response + }, + /** + * Leave a group + * @param jid the ID of the group + */ + groupLeave: async (jid: string) => { + await groupQuery('leave', jid) + ev.emit('chats.update', [ { jid, read_only: 'true' } ]) + }, + /** + * Update the subject of the group + * @param {string} jid the ID of the group + * @param {string} title the new title of the group + */ + groupUpdateSubject: async (jid: string, title: string) => { + await groupQuery('subject', jid, title) + ev.emit('chats.update', [ { jid, name: title } ]) + ev.emit('contacts.update', [ { jid, name: title } ]) + ev.emit('groups.update', [ { id: jid, subject: title } ]) + }, + /** + * Update the group description + * @param {string} jid the ID of the group + * @param {string} title the new title of the group + */ + groupUpdateDescription: async (jid: string, description: string) => { + const metadata = await groupMetadataFull(jid) + const node = new BinaryNode( + 'description', + {id: generateMessageID(), prev: metadata?.descId}, + Buffer.from (description, 'utf-8') + ) + const response = await groupQuery ('description', jid, null, null, [node]) + ev.emit('groups.update', [ { id: jid, desc: description } ]) + return response + }, + /** + * Update participants in the group + * @param jid the ID of the group + * @param participants the people to add + */ + groupParticipantsUpdate: async(jid: string, participants: string[], action: ParticipantAction) => { + const result: GroupModificationResponse = await groupQuery(action, jid, null, participants) + const jids = Object.keys(result.participants || {}) + ev.emit('group-participants.update', { jid, participants: jids, action }) + return jids + } + + } + +} +export default makeGroupsSocket \ No newline at end of file diff --git a/src/Connection/index.ts b/src/Connection/index.ts new file mode 100644 index 0000000..4fe93a9 --- /dev/null +++ b/src/Connection/index.ts @@ -0,0 +1,12 @@ +import { SocketConfig } from '../Types' +import { DEFAULT_CONNECTION_CONFIG } from '../Defaults' +import { EventEmitter } from 'events' +import * as Connection from './groups' +// export the last socket layer +const makeConnection = (config: Partial) => ( + Connection.default({ + ...DEFAULT_CONNECTION_CONFIG, + ...config + }) +) +export default makeConnection \ No newline at end of file diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts new file mode 100644 index 0000000..e6481e0 --- /dev/null +++ b/src/Connection/messages.ts @@ -0,0 +1,437 @@ +import BinaryNode from "../BinaryNode"; +import { Boom } from '@hapi/boom' +import { EventEmitter } from 'events' +import { Chat, Presence, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo } from "../Types"; +import { isGroupID, toNumber, whatsappID } from "../Utils/generics"; +import makeChatsSocket from "./chats"; +import { WA_DEFAULT_EPHEMERAL } from "../Defaults"; +import { generateWAMessage } from "../Utils/messages"; +import { decryptMediaMessageBuffer } from "../Utils/messages-media"; + +const STATUS_MAP = { + read: WAMessageStatus.READ, + message: WAMessageStatus.DELIVERY_ACK, + error: WAMessageStatus.ERROR +} as { [_: string]: WAMessageStatus } + +const makeMessagesSocket = (config: SocketConfig) => { + const { logger } = config + const sock = makeChatsSocket(config) + const { + ev, + socketEvents, + query, + sendMessage, + generateMessageTag, + currentEpoch, + setQuery, + getState + } = sock + + let mediaConn: Promise + const refreshMediaConn = async(forceGet = false) => { + let media = await mediaConn + if (!media || forceGet || (new Date().getTime()-media.fetchDate.getTime()) > media.ttl*1000) { + mediaConn = (async() => { + const {media_conn} = await query({ + json: ['query', 'mediaConn'], + requiresPhoneConnection: false + }) + media_conn.fetchDate = new Date() + return media_conn as MediaConnInfo + })() + } + return mediaConn + } + + const fetchMessagesFromWA = async( + jid: string, + count: number, + indexMessage?: { id?: string; fromMe?: boolean }, + mostRecentFirst: boolean = true + ) => { + const { data }:BinaryNode = await query({ + json: new BinaryNode( + 'query', + { + epoch: currentEpoch().toString(), + type: 'message', + jid: jid, + kind: mostRecentFirst ? 'before' : 'after', + count: count.toString(), + index: indexMessage?.id, + owner: indexMessage?.fromMe === false ? 'false' : 'true', + } + ), + binaryTag: [WAMetric.queryMessages, WAFlag.ignore], + expect200: false, + requiresPhoneConnection: true + }) + if(Array.isArray(data)) { + return data.map(data => data.data as WAMessage) + } + return [] + } + + const updateMediaMessage = async(message: WAMessage) => { + const content = message.message?.audioMessage || message.message?.videoMessage || message.message?.imageMessage || message.message?.stickerMessage || message.message?.documentMessage + if (!content) throw new Boom( + `given message ${message.key.id} is not a media message`, + { statusCode: 400, data: message } + ) + + const response = await query ({ + json: new BinaryNode( + 'query', + {type: 'media', index: message.key.id, owner: message.key.fromMe ? 'true' : 'false', jid: message.key.remoteJid, epoch: currentEpoch().toString()} + ), + binaryTag: [WAMetric.queryMedia, WAFlag.ignore], + expect200: true, + requiresPhoneConnection: true + }) + Object.keys(response[1]).forEach (key => content[key] = response[1][key]) // update message + + ev.emit('messages.upsert', { messages: [message], type: 'append' }) + + return response + } + + const onMessage = (message: WAMessage, type: MessageUpdateType | 'update') => { + const jid = message.key.remoteJid! + // store chat updates in this + const chatUpdate: Partial = { + jid, + t: +toNumber(message.messageTimestamp) + } + // add to count if the message isn't from me & there exists a message + if(!message.key.fromMe && message.message) { + chatUpdate.count = 1 + const participant = whatsappID(message.participant || jid) + chatUpdate.presences = { + [participant]: { + lastKnownPresence: Presence.available + } + } + } + + const ephemeralProtocolMsg = message.message?.ephemeralMessage?.message?.protocolMessage + if ( + ephemeralProtocolMsg && + ephemeralProtocolMsg.type === WAMessageProto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING + ) { + chatUpdate.eph_setting_ts = message.messageTimestamp.toString() + chatUpdate.ephemeral = ephemeralProtocolMsg.ephemeralExpiration.toString() + } + const protocolMessage = message.message?.protocolMessage + // if it's a message to delete another message + if (protocolMessage) { + switch (protocolMessage.type) { + case WAMessageProto.ProtocolMessage.ProtocolMessageType.REVOKE: + const key = protocolMessage.key + const messageStubType = WAMessageStubType.REVOKE + ev.emit('messages.update', [ { message: null, key, messageStubType } ]) + return + default: + break + } + } + + // check if the message is an action + if (message.messageStubType) { + const { user } = getState() + //let actor = whatsappID (message.participant) + let participants: string[] + const emitParticipantsUpdate = (action: ParticipantAction) => ( + ev.emit('group-participants.update', { jid, participants, action }) + ) + const emitGroupUpdate = (update: Partial) => { + ev.emit('groups.update', [ { id: jid, ...update } ]) + } + + switch (message.messageStubType) { + case WAMessageStubType.CHANGE_EPHEMERAL_SETTING: + chatUpdate.eph_setting_ts = message.messageTimestamp.toString() + chatUpdate.ephemeral = message.messageStubParameters[0] + break + case WAMessageStubType.GROUP_PARTICIPANT_LEAVE: + case WAMessageStubType.GROUP_PARTICIPANT_REMOVE: + participants = message.messageStubParameters.map (whatsappID) + emitParticipantsUpdate('remove') + // mark the chat read only if you left the group + if (participants.includes(user.jid)) { + chatUpdate.read_only = 'true' + } + break + case WAMessageStubType.GROUP_PARTICIPANT_ADD: + case WAMessageStubType.GROUP_PARTICIPANT_INVITE: + case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN: + participants = message.messageStubParameters.map (whatsappID) + if (participants.includes(user.jid)) { + chatUpdate.read_only = 'false' + } + emitParticipantsUpdate('add') + break + case WAMessageStubType.GROUP_CHANGE_ANNOUNCE: + const announce = message.messageStubParameters[0] === 'on' ? 'true' : 'false' + emitGroupUpdate({ announce }) + break + case WAMessageStubType.GROUP_CHANGE_RESTRICT: + const restrict = message.messageStubParameters[0] === 'on' ? 'true' : 'false' + emitGroupUpdate({ restrict }) + break + case WAMessageStubType.GROUP_CHANGE_SUBJECT: + case WAMessageStubType.GROUP_CREATE: + chatUpdate.name = message.messageStubParameters[0] + emitGroupUpdate({ subject: chatUpdate.name }) + break + } + } + + if(Object.keys(chatUpdate).length > 1) { + ev.emit('chats.update', [chatUpdate]) + } + if(type === 'update') { + ev.emit('messages.update', [message]) + } else { + ev.emit('messages.upsert', { messages: [message], type }) + } + } + + /** Query a string to check if it has a url, if it does, return WAUrlInfo */ + const generateUrlInfo = async(text: string) => { + const response = await query({ + json: new BinaryNode( + 'query', + {type: 'url', url: text, epoch: currentEpoch().toString()} + ), + binaryTag: [26, WAFlag.ignore], + expect200: true, + requiresPhoneConnection: false + }) + if(response[1]) { + response[1].jpegThumbnail = response[2] + } + return response[1] as WAUrlInfo + } + + /** Relay (send) a WAMessage; more advanced functionality to send a built WA Message, you may want to stick with sendMessage() */ + const relayWAMessage = async(message: WAMessage, { waitForAck } = { waitForAck: true }) => { + const json = new BinaryNode( + 'action', + { epoch: currentEpoch().toString(), type: 'relay' }, + [ new BinaryNode('message', {}, message) ] + ) + const flag = message.key.remoteJid === getState().user?.jid ? WAFlag.acknowledge : WAFlag.ignore // acknowledge when sending message to oneself + const mID = message.key.id + + message.status = WAMessageStatus.PENDING + const promise = query({ + json, + binaryTag: [WAMetric.message, flag], + tag: mID, + expect200: true, + requiresPhoneConnection: true + }) + + if(waitForAck) { + await promise + message.status = WAMessageStatus.SERVER_ACK + } else { + const emitUpdate = (status: WAMessageStatus) => { + message.status = status + ev.emit('messages.update', [ { key: message.key, status } ]) + } + promise + .then(() => emitUpdate(WAMessageStatus.SERVER_ACK)) + .catch(() => emitUpdate(WAMessageStatus.ERROR)) + } + + onMessage(message, 'append') + } + + // messages received + const messagesUpdate = ({ data }: BinaryNode, type: 'prepend' | 'last') => { + if(Array.isArray(data)) { + const messages: WAMessage[] = [] + for(let i = data.length-1; i >= 0;i--) { + messages.push(data[i].data as WAMessage) + } + ev.emit('messages.upsert', { messages, type }) + } + } + + socketEvents.on('CB:action,add:last', json => messagesUpdate(json, 'last')) + socketEvents.on('CB:action,add:unread', json => messagesUpdate(json, 'prepend')) + socketEvents.on('CB:action,add:before', json => messagesUpdate(json, 'prepend')) + + // new messages + socketEvents.on('CB:action,add:relay,message', ({data}: BinaryNode) => { + if(Array.isArray(data)) { + for(const { data: msg } of data) { + onMessage(msg as WAMessage, 'notify') + } + } + }) + // If a message has been updated (usually called when a video message gets its upload url, or live locations) + socketEvents.on ('CB:action,add:update,message', ({ data }: BinaryNode) => { + if(Array.isArray(data)) { + for(const { data: msg } of data) { + onMessage(msg as WAMessage, 'update') + } + } + }) + // message status updates + const onMessageStatusUpdate = ({ data }: BinaryNode) => { + if(Array.isArray(data)) { + for(const { attributes: json } of data) { + const key: WAMessageKey = { + remoteJid: whatsappID(json.jid), + id: json.index, + fromMe: json.owner === 'true' + } + const status = STATUS_MAP[json.type] + + if(status) { + ev.emit('messages.update', [ { key, status } ]) + } else { + logger.warn({ data }, 'got unknown status update for message') + } + } + } + } + socketEvents.on('CB:action,add:relay,received', onMessageStatusUpdate) + socketEvents.on('CB:action,,received', onMessageStatusUpdate) + + return { + ...sock, + relayWAMessage, + generateUrlInfo, + messageInfo: async(jid: string, messageID: string) => { + const { data }: BinaryNode = await query({ + json: new BinaryNode( + 'query', + {type: 'message_info', index: messageID, jid: jid, epoch: currentEpoch().toString()} + ), + binaryTag: [WAMetric.queryRead, WAFlag.ignore], + expect200: true, + requiresPhoneConnection: true + }) + const info: MessageInfo = {reads: [], deliveries: []} + if(Array.isArray(data)) { + for(const { header, attributes } of data) { + switch(header) { + case 'read': + info.reads.push(attributes as any) + break + case 'delivery': + info.deliveries.push(attributes as any) + break + } + } + } + return info + }, + downloadMediaMessage: async(message: WAMessage, type: 'buffer' | 'stream' = 'buffer') => { + let mContent = message.message?.ephemeralMessage?.message || message.message + if (!mContent) throw new Boom('No message present', { statusCode: 400, data: message }) + + const downloadMediaMessage = async () => { + const stream = await decryptMediaMessageBuffer(mContent) + if(type === 'buffer') { + let buffer = Buffer.from([]) + for await(const chunk of stream) { + buffer = Buffer.concat([buffer, chunk]) + } + return buffer + } + return stream + } + + try { + const result = await downloadMediaMessage() + return result + } catch (error) { + if(error instanceof Boom && error.output?.statusCode === 404) { // media needs to be updated + logger.info (`updating media of message: ${message.key.id}`) + + await updateMediaMessage(message) + + mContent = message.message?.ephemeralMessage?.message || message.message + const result = await downloadMediaMessage() + return result + } + throw error + } + }, + updateMediaMessage, + fetchMessagesFromWA, + searchMessages: async(txt: string, inJid: string | null, count: number, page: number) => { + const {data, attributes}: BinaryNode = await query({ + json: new BinaryNode( + 'query', + { + epoch: currentEpoch().toString(), + type: 'search', + search: txt, + count: count.toString(), + page: page.toString(), + jid: inJid + } + ), + binaryTag: [24, WAFlag.ignore], + expect200: true + }) // encrypt and send off + + const messages = Array.isArray(data) ? data.map(item => item.data as WAMessage) : [] + return { + last: attributes?.last === 'true', + messages + } + }, + sendWAMessage: async( + jid: string, + content: AnyMessageContent, + options: MiscMessageGenerationOptions & { waitForAck?: boolean } + ) => { + const userJid = getState().user?.jid + if( + typeof content === 'object' && + 'disappearingMessagesInChat' in content && + typeof content['disappearingMessagesInChat'] !== 'undefined' && + isGroupID(jid) + ) { + const { disappearingMessagesInChat } = content + const value = typeof disappearingMessagesInChat === 'boolean' ? + (disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : + disappearingMessagesInChat + const tag = generateMessageTag(true) + await setQuery([ + new BinaryNode( + 'group', + { id: tag, jid, type: 'prop', author: userJid }, + [ new BinaryNode('ephemeral', { value: value.toString() }) ] + ) + ], [WAMetric.group, WAFlag.other], tag) + } else { + const msg = await generateWAMessage( + jid, + content, + { + ...options, + userJid: userJid, + /*ephemeralOptions: chat?.ephemeral ? { + expiration: chat.ephemeral, + eph_setting_ts: chat.eph_setting_ts + } : undefined,*/ + getUrlInfo: generateUrlInfo, + getMediaOptions: refreshMediaConn + } + ) + await relayWAMessage(msg, { waitForAck: options.waitForAck }) + return msg + } + } + } +} + +export default makeMessagesSocket \ No newline at end of file diff --git a/src/Connection/socket.ts b/src/Connection/socket.ts index a7b3e6b..d86c072 100644 --- a/src/Connection/socket.ts +++ b/src/Connection/socket.ts @@ -1,4 +1,4 @@ -import Boom from "boom" +import { Boom } from '@hapi/boom' import EventEmitter from "events" import { STATUS_CODES } from "http" import { promisify } from "util" @@ -6,7 +6,7 @@ import WebSocket from "ws" import BinaryNode from "../BinaryNode" import { DisconnectReason, SocketConfig, SocketQueryOptions, SocketSendMessageOptions } from "../Types" import { aesEncrypt, hmacSign, promiseTimeout, unixTimestampSeconds } from "../Utils/generics" -import { decodeWAMessage } from "../Utils/decodeWAMessage" +import { decodeWAMessage } from "../Utils/decode-wa-message" import { WAFlag, WAMetric, WATag } from "../Types" import { DEFAULT_ORIGIN, DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, PHONE_CONNECTION_CB } from "../Defaults" @@ -284,7 +284,7 @@ export const makeSocket = ({ const waitForSocketOpen = async() => { if(ws.readyState === ws.OPEN) return if(ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { - throw Boom.preconditionRequired('Connection Closed') + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) } let onOpen: () => void let onClose: (err: Error) => void diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 79fc2d8..669ad7f 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -9,6 +9,11 @@ export const DEF_CALLBACK_PREFIX = 'CB:' export const DEF_TAG_PREFIX = 'TAG:' export const PHONE_CONNECTION_CB = 'CB:Pong' +export const WA_DEFAULT_EPHEMERAL = 7*24*60*60 + +/** from: https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url */ +export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi + export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { version: [2, 2123, 8], browser: Browsers.baileys('Chrome'), diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts new file mode 100644 index 0000000..33043e7 --- /dev/null +++ b/src/Store/in-memory-store.ts @@ -0,0 +1,163 @@ +import KeyedDB from "@adiwajshing/keyed-db" +import { Logger } from "pino" +import makeConnection from "../Connection" +import { BaileysEventEmitter, Chat, ConnectionState, Contact, WAMessage, WAMessageKey } from "../Types" + +export const waChatKey = (pin: boolean) => ({ + key: (c: Chat) => (pin ? (c.pin ? '1' : '0') : '') + (c.archive === 'true' ? '0' : '1') + c.t.toString(16).padStart(8, '0') + c.jid, + compare: (k1: string, k2: string) => k2.localeCompare (k1) +}) + +export type BaileysInMemoryStoreConfig = { + logger: Logger +} + +export default( + { logger }: BaileysInMemoryStoreConfig +) => { + const chats = new KeyedDB(waChatKey(true), c => c.jid) + const messages: { [_: string]: WAMessage[] } = {} + const contacts: { [_: string]: Contact } = {} + const state: ConnectionState = { + connection: 'close', + phoneConnected: false + } + + const messageIndex = (key: WAMessageKey) => { + const messageList = messages[key.remoteJid!] + if(messageList) { + const idx = messageList.findIndex(m => m.key.id === key.id) + if(idx >= 0) { + return { messageList, idx } + } + } + } + + const listen = (ev: BaileysEventEmitter) => { + ev.on('connection.update', update => { + Object.assign(state, update) + }) + ev.on('contacts.upsert', ({ contacts: newContacts, type }) => { + const oldContacts = new Set(Object.keys(contacts)) + for(const contact of newContacts) { + oldContacts.delete(contact.jid) + contacts[contact.jid] = Object.assign( + contacts[contact.jid] || {}, + contact + ) + } + if(type === 'set') { + for(const jid of oldContacts) { + delete contacts[jid] + } + logger.debug({ deletedContacts: oldContacts.size }, 'synced contacts') + } + }) + ev.on('contacts.update', updates => { + for(const update of updates) { + if(contacts[update.jid!]) { + Object.assign(contacts[update.jid!], update) + } else { + logger.debug({ update }, `got update for non-existant contact`) + } + } + }) + ev.on('chats.upsert', ({ chats: newChats, type }) => { + if(type === 'set') { + chats.clear() + } + for(const chat of newChats) { + chats.upsert(chat) + } + }) + ev.on('chats.update', updates => { + for(const update of updates) { + const result = chats.update(update.jid!, chat => { + Object.assign(chat, update) + }) + if(!result) { + logger.debug({ update }, `got update for non-existant chat`) + } + } + }) + ev.on('chats.delete', deletions => { + for(const item of deletions) { + chats.deleteById(item) + } + }) + ev.on('messages.upsert', ({ messages: newMessages, type }) => { + switch(type) { + case 'append': + case 'notify': + for(const msg of newMessages) { + const jid = msg.key.remoteJid! + const result = messageIndex(newMessages[0].key) + if(!result) { + if(!messages[jid]) { + messages[jid] = [] + } + messages[jid].push(msg) + } else { + result.messageList[result.idx] = msg + } + } + break + case 'last': + for(const msg of newMessages) { + const jid = msg.key.remoteJid! + if(!messages[jid]) { + messages[jid] = [] + } + const [lastItem] = messages[jid].slice(-1) + // reset message list + if(lastItem && lastItem.key.id !== msg.key.id) { + messages[jid] = [msg] + } + } + break + case 'prepend': + + break + } + }) + ev.on('messages.update', updates => { + for(const update of updates) { + const result = messageIndex(update.key!) + if(result) { + Object.assign(result.messageList[result.idx], update) + } else { + logger.debug({ update }, `got update for non-existant message`) + } + } + }) + ev.on('messages.delete', item => { + if('all' in item) { + messages[item.jid] = [] + } else { + const idSet = new Set(item.ids) + if(messages[item.jid]) { + messages[item.jid] = messages[item.jid].filter( + m => !idSet.has(m.key.id) + ) + } + } + }) + } + + return { + chats, + contacts, + messages, + listen, + fetchImageUrl: async(jid: string, sock: ReturnType) => { + const contact = contacts[jid] + if(!contact) { + return sock.fetchImageUrl(jid) + } + if(!contact.imgUrl) { + contact.imgUrl = await sock.fetchImageUrl(jid) + } + return contact.imgUrl + } + } +} \ No newline at end of file diff --git a/src/Store/index.ts b/src/Store/index.ts new file mode 100644 index 0000000..7e6ed66 --- /dev/null +++ b/src/Store/index.ts @@ -0,0 +1,2 @@ +import inMemoryStore from "./in-memory-store"; +export default inMemoryStore \ No newline at end of file diff --git a/src/Tests/_test.manual_tests.ts b/src/Tests/_test.manual_tests.ts new file mode 100644 index 0000000..367999a --- /dev/null +++ b/src/Tests/_test.manual_tests.ts @@ -0,0 +1,112 @@ + +describe ('Reconnects', () => { + const verifyConnectionOpen = async (conn: Connection) => { + expect((await conn.getState()).user).toBeDefined() + let failed = false + // check that the connection stays open + conn.ev.on('state.update', ({ connection, lastDisconnect }) => { + if(connection === 'close' && !!lastDisconnect.error) { + failed = true + } + }) + await delay (60*1000) + conn.close () + + expect(failed).toBe(false) + } + it('should dispose correctly on bad_session', async () => { + const conn = makeConnection({ + reconnectMode: 'on-any-error', + credentials: './auth_info.json', + maxRetries: 2, + connectCooldownMs: 500 + }) + let gotClose0 = false + let gotClose1 = false + + const openPromise = conn.open() + + conn.getSocket().ev.once('ws-close', () => { + gotClose0 = true + }) + conn.ev.on('state.update', ({ lastDisconnect }) => { + //@ts-ignore + if(lastDisconnect?.error?.output?.statusCode === DisconnectReason.badSession) { + gotClose1 = true + } + }) + setTimeout (() => conn.getSocket().ws.emit ('message', Buffer.from('some-tag,sdjjij1jo2ejo1je')), 1500) + await openPromise + + console.log('opened connection') + + await delay(1000) + conn.getSocket().ws.emit ('message', Buffer.from('some-tag,sdjjij1jo2ejo1je')) + + await delay(2000) + await conn.waitForConnection() + + conn.close() + + expect(gotClose0).toBe(true) + expect(gotClose1).toBe(true) + }, 20_000) + /** + * the idea is to test closing the connection at multiple points in the connection + * and see if the library cleans up resources correctly + */ + it('should cleanup correctly', async () => { + const conn = makeConnection({ + reconnectMode: 'on-any-error', + credentials: './auth_info.json' + }) + let timeoutMs = 100 + while (true) { + let tmout = setTimeout (() => { + conn.close() + }, timeoutMs) + try { + await conn.open() + clearTimeout (tmout) + break + } catch (error) { + + } + // exponentially increase the timeout disconnect + timeoutMs *= 2 + } + await verifyConnectionOpen(conn) + }, 120_000) + /** + * the idea is to test closing the connection at multiple points in the connection + * and see if the library cleans up resources correctly + */ + it('should disrupt connect loop', async () => { + const conn = makeConnection({ + reconnectMode: 'on-any-error', + credentials: './auth_info.json' + }) + + let timeout = 1000 + let tmout + const endConnection = async () => { + while (!conn.getSocket()) { + await delay(100) + } + conn.getSocket().end(Boom.preconditionRequired('conn close')) + + while (conn.getSocket()) { + await delay(100) + } + + timeout *= 2 + tmout = setTimeout (endConnection, timeout) + } + tmout = setTimeout (endConnection, timeout) + + await conn.open() + clearTimeout (tmout) + + await verifyConnectionOpen(conn) + }, 120_000) +}) \ No newline at end of file diff --git a/src/Tests/test.connect.ts b/src/Tests/test.connect.ts index 155f729..4903c2d 100644 --- a/src/Tests/test.connect.ts +++ b/src/Tests/test.connect.ts @@ -1,33 +1,31 @@ -import Boom from 'boom' +import { Boom } from '@hapi/boom' import P from 'pino' import BinaryNode from '../BinaryNode' -import makeConnection, { Connection, DisconnectReason } from '../makeConnection' -import { delay } from '../WAConnection/Utils' +import makeConnection from '../Connection' +import { delay } from '../Utils/generics' describe('QR Generation', () => { it('should generate QR', async () => { const QR_GENS = 1 - const {ev, open} = makeConnection({ + const {ev} = makeConnection({ maxRetries: 0, maxQRCodes: QR_GENS, logger: P({ level: 'trace' }) }) let calledQR = 0 - ev.removeAllListeners('qr') - ev.on('state.update', ({ qr }) => { + ev.on('connection.update', ({ qr }) => { if(qr) calledQR += 1 }) await expect(open()).rejects.toThrowError('Too many QR codes') - expect( - Object.keys(ev.eventNames()).filter(key => key.startsWith('TAG:')) - ).toHaveLength(0) expect(calledQR).toBeGreaterThanOrEqual(QR_GENS) }, 60_000) }) describe('Test Connect', () => { + const logger = P({ level: 'trace' }) + it('should connect', async () => { logger.info('please be ready to scan with your phone') @@ -36,33 +34,38 @@ describe('Test Connect', () => { logger, printQRInTerminal: true }) - await conn.open() + await conn.waitForConnection(true) const { user, isNewLogin } = await conn.getState() expect(user).toHaveProperty('jid') expect(user).toHaveProperty('name') expect(isNewLogin).toBe(true) - conn.close() + conn.end(undefined) }, 65_000) it('should restore session', async () => { - const conn = makeConnection({ + let conn = makeConnection({ printQRInTerminal: true, logger, }) - await conn.open() - conn.close() + await conn.waitForConnection(true) + conn.end(undefined) await delay(2500) - await conn.open() + conn = makeConnection({ + printQRInTerminal: true, + logger, + }) + await conn.waitForConnection(true) + const { user, isNewLogin, qr } = await conn.getState() expect(user).toHaveProperty('jid') expect(user).toHaveProperty('name') expect(isNewLogin).toBe(false) expect(qr).toBe(undefined) - conn.close() + conn.end(undefined) }, 65_000) it('should logout', async () => { @@ -70,7 +73,8 @@ describe('Test Connect', () => { printQRInTerminal: true, logger, }) - await conn.open() + await conn.waitForConnection(true) + const { user, qr } = await conn.getState() expect(user).toHaveProperty('jid') expect(user).toHaveProperty('name') @@ -83,118 +87,8 @@ describe('Test Connect', () => { credentials, logger }) - await expect(conn.open()).rejects.toThrowError('Unexpected error in login') + await expect( + conn.waitForConnection() + ).rejects.toThrowError('Unexpected error in login') }, 65_000) -}) - -describe ('Reconnects', () => { - const verifyConnectionOpen = async (conn: Connection) => { - expect((await conn.getState()).user).toBeDefined() - let failed = false - // check that the connection stays open - conn.ev.on('state.update', ({ connection, lastDisconnect }) => { - if(connection === 'close' && !!lastDisconnect.error) { - failed = true - } - }) - await delay (60*1000) - conn.close () - - expect(failed).toBe(false) - } - it('should dispose correctly on bad_session', async () => { - const conn = makeConnection({ - reconnectMode: 'on-any-error', - credentials: './auth_info.json', - maxRetries: 2, - connectCooldownMs: 500 - }) - let gotClose0 = false - let gotClose1 = false - - const openPromise = conn.open() - - conn.getSocket().ev.once('ws-close', () => { - gotClose0 = true - }) - conn.ev.on('state.update', ({ lastDisconnect }) => { - //@ts-ignore - if(lastDisconnect?.error?.output?.statusCode === DisconnectReason.badSession) { - gotClose1 = true - } - }) - setTimeout (() => conn.getSocket().ws.emit ('message', Buffer.from('some-tag,sdjjij1jo2ejo1je')), 1500) - await openPromise - - console.log('opened connection') - - await delay(1000) - conn.getSocket().ws.emit ('message', Buffer.from('some-tag,sdjjij1jo2ejo1je')) - - await delay(2000) - await conn.waitForConnection() - - conn.close() - - expect(gotClose0).toBe(true) - expect(gotClose1).toBe(true) - }, 20_000) - /** - * the idea is to test closing the connection at multiple points in the connection - * and see if the library cleans up resources correctly - */ - it('should cleanup correctly', async () => { - const conn = makeConnection({ - reconnectMode: 'on-any-error', - credentials: './auth_info.json' - }) - let timeoutMs = 100 - while (true) { - let tmout = setTimeout (() => { - conn.close() - }, timeoutMs) - try { - await conn.open() - clearTimeout (tmout) - break - } catch (error) { - - } - // exponentially increase the timeout disconnect - timeoutMs *= 2 - } - await verifyConnectionOpen(conn) - }, 120_000) - /** - * the idea is to test closing the connection at multiple points in the connection - * and see if the library cleans up resources correctly - */ - it('should disrupt connect loop', async () => { - const conn = makeConnection({ - reconnectMode: 'on-any-error', - credentials: './auth_info.json' - }) - - let timeout = 1000 - let tmout - const endConnection = async () => { - while (!conn.getSocket()) { - await delay(100) - } - conn.getSocket().end(Boom.preconditionRequired('conn close')) - - while (conn.getSocket()) { - await delay(100) - } - - timeout *= 2 - tmout = setTimeout (endConnection, timeout) - } - tmout = setTimeout (endConnection, timeout) - - await conn.open() - clearTimeout (tmout) - - await verifyConnectionOpen(conn) - }, 120_000) }) \ No newline at end of file diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 5e3ac08..8f285cb 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -1,7 +1,3 @@ -import type KeyedDB from "@adiwajshing/keyed-db"; -import type { proto } from '../../WAMessage/WAMessage' -import type { GroupMetadata } from "./GroupMetadata"; - /** set of statuses visible to other people; see updatePresence() in WhatsAppWeb.Send */ export enum Presence { unavailable = 'unavailable', // "offline" @@ -37,8 +33,25 @@ export interface Chat { ephemeral?: string // Baileys added properties - messages: KeyedDB - imgUrl?: string presences?: { [k: string]: PresenceData } - metadata?: GroupMetadata -} \ No newline at end of file +} + +export type ChatModification = + { archive: boolean } | + { + /** pin at current timestamp, or provide timestamp of pin to remove */ + pin: true | { remove: number } + } | + { + /** mute for duration, or provide timestamp of mute to remove*/ + mute: number | { remove: number } + } | + { + clear: 'all' | { messages: { id: string, fromMe?: boolean }[] } + } | + { + star: { + messages: { id: string, fromMe?: boolean }[], + star: boolean + } + } \ No newline at end of file diff --git a/src/Types/Contact.ts b/src/Types/Contact.ts index 2103534..cb24f02 100644 --- a/src/Types/Contact.ts +++ b/src/Types/Contact.ts @@ -12,4 +12,5 @@ export interface Contact { short?: string // Baileys Added imgUrl?: string + status?: string } \ No newline at end of file diff --git a/src/Types/GroupMetadata.ts b/src/Types/GroupMetadata.ts index 1d5a6c4..9aedf6d 100644 --- a/src/Types/GroupMetadata.ts +++ b/src/Types/GroupMetadata.ts @@ -2,6 +2,8 @@ import { Contact } from "./Contact"; export type GroupParticipant = (Contact & { isAdmin: boolean; isSuperAdmin: boolean }) +export type ParticipantAction = 'add' | 'remove' | 'promote' | 'demote' + export interface GroupMetadata { id: string owner: string @@ -16,4 +18,16 @@ export interface GroupMetadata { announce?: 'true' | 'false' // Baileys modified array participants: GroupParticipant[] +} + + +export interface WAGroupCreateResponse { + status: number + gid?: string + participants?: [{ [key: string]: any }] +} + +export interface GroupModificationResponse { + status: number + participants?: { [key: string]: any } } \ No newline at end of file diff --git a/src/Types/Message.ts b/src/Types/Message.ts new file mode 100644 index 0000000..476181b --- /dev/null +++ b/src/Types/Message.ts @@ -0,0 +1,135 @@ +import type { Agent } from "https" +import type { Logger } from "pino" +import type { URL } from "url" +import { proto } from '../../WAMessage/WAMessage' + +// export the WAMessage Prototypes +export { proto as WAMessageProto } +export type WAMessage = proto.WebMessageInfo +export type WAMessageContent = proto.IMessage +export type WAContactMessage = proto.ContactMessage +export type WAContactsArrayMessage = proto.ContactsArrayMessage +export type WAMessageKey = proto.IMessageKey +export type WATextMessage = proto.ExtendedTextMessage +export type WAContextInfo = proto.IContextInfo +export type WALocationMessage = proto.LocationMessage +export type WAGenericMediaMessage = proto.IVideoMessage | proto.IImageMessage | proto.IAudioMessage | proto.IDocumentMessage | proto.IStickerMessage +export import WAMessageStubType = proto.WebMessageInfo.WebMessageInfoStubType +export import WAMessageStatus = proto.WebMessageInfo.WebMessageInfoStatus +export type WAMediaUpload = Buffer | { url: URL | string } +/** Set of message types that are supported by the library */ +export type MessageType = keyof proto.Message + +export type MediaConnInfo = { + auth: string + ttl: number + hosts: { + hostname: string + }[] + fetchDate: Date +} + +/** Reverse stub type dictionary */ +export const WA_MESSAGE_STUB_TYPES = function () { + const types = WAMessageStubType + const dict: Record = {} + Object.keys(types).forEach(element => dict[ types[element] ] = element) + return dict +}() + +export interface WAUrlInfo { + 'canonical-url': string + 'matched-text': string + title: string + description: string + jpegThumbnail?: Buffer +} + +// types to generate WA messages +type Mentionable = { + /** list of jids that are mentioned in the accompanying text */ + mentions?: string[] +} +export type MediaType = 'image' | 'video' | 'sticker' | 'audio' | 'document' +export type AnyMediaMessageContent = ( + ({ + image: WAMediaUpload + caption?: string + jpegThumbnail?: string + } & Mentionable) | + ({ + video: WAMediaUpload + caption?: string + gifPlayback?: boolean + jpegThumbnail?: string + } & Mentionable) | { + audio: WAMediaUpload + /** if set to true, will send as a `voice note` */ + pttAudio?: boolean + /** optionally tell the duration of the audio */ + seconds?: number + } | { + sticker: WAMediaUpload + } | { + document: WAMediaUpload + mimetype: string + fileName?: string + }) & + { mimetype?: string } + +export type AnyRegularMessageContent = + string | + ({ + text: string + } + & Mentionable) | + AnyMediaMessageContent | + { + contacts: { + displayName?: string + contacts: WAContactMessage[] + } + } | + { + location: WALocationMessage + } + +export type AnyMessageContent = AnyRegularMessageContent | { + forward: WAMessage + force?: boolean +} | { + delete: WAMessageKey +} | { + disappearingMessagesInChat: boolean | number +} +export type MiscMessageGenerationOptions = { + /** Force message id */ + messageId?: string + /** optional, if you want to manually set the timestamp of the message */ + timestamp?: Date + /** the message you want to quote */ + quoted?: WAMessage +} +export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & { + userJid: string + ephemeralOptions?: { + expiration: number | string + eph_setting_ts: number | string + } +} +export type MediaGenerationOptions = { + logger?: Logger + agent?: Agent + getMediaOptions: (refresh: boolean) => Promise +} +export type MessageContentGenerationOptions = MediaGenerationOptions & { + getUrlInfo?: (text: string) => Promise +} +export type MessageGenerationOptions = MessageContentGenerationOptions & MessageGenerationOptionsFromContent + +export type MessageUpdateType = 'prepend' | 'append' | 'notify' | 'last' + +export interface MessageInfo { + reads: {jid: string, t: string}[] + deliveries: {jid: string, t: string}[] +} \ No newline at end of file diff --git a/src/Types/index.ts b/src/Types/index.ts index b16999b..efdd6c8 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -3,15 +3,21 @@ export * from './GroupMetadata' export * from './Chat' export * from './Contact' export * from './Store' +export * from './Message' import type EventEmitter from "events" import type { Agent } from "https" import type { Logger } from "pino" import type { URL } from "url" import type BinaryNode from "../BinaryNode" -import { AnyAuthenticationCredentials } from './Auth' +import { AnyAuthenticationCredentials, AuthenticationCredentials } from './Auth' +import { Chat } from './Chat' +import { Contact } from './Contact' import { ConnectionState } from './Store' +import { GroupMetadata, ParticipantAction } from './GroupMetadata' +import { MessageUpdateType, WAMessage } from './Message' + /** used for binary messages */ export enum WAMetric { debugLog = 1, @@ -117,7 +123,7 @@ export type SocketQueryOptions = SocketSendMessageOptions & { } export enum DisconnectReason { - connectionClosedIntentionally = 428, + connectionClosed = 428, connectionReplaced = 440, connectionLost = 408, timedOut = 408, @@ -131,6 +137,35 @@ export type WAInitResponse = { status: 200 } +export interface WABroadcastListInfo { + status: number + name: string + recipients?: {id: string}[] +} + + +type WABusinessHoursConfig = { + day_of_week: string + mode: string + open_time?: number + close_time?: number +} +export type WABusinessProfile = { + description: string + email: string + business_hours: { + timezone: string + config?: WABusinessHoursConfig[] + business_config?: WABusinessHoursConfig[] + } + website: string[] + categories: { + id: string + localized_display_name: string + }[] + wid?: string +} + export type QueryOptions = SocketQueryOptions & { waitForOpen?: boolean maxRetries?: number @@ -140,6 +175,23 @@ export type CurveKeyPair = { private: Uint8Array; public: Uint8Array } export type BaileysEventMap = { 'connection.update': Partial + 'credentials.update': AuthenticationCredentials + + 'chats.upsert': { chats: Chat[], type: 'set' | 'upsert' } + 'chats.update': Partial[] + 'chats.delete': string[] + + 'contacts.upsert': { contacts: Contact[], type: 'set' | 'upsert' } + 'contacts.update': Partial[] + + 'messages.delete': { jid: string, ids: string[] } | { jid: string, all: true } + 'messages.update': Partial[] + 'messages.upsert': { messages: WAMessage[], type: MessageUpdateType } + + 'groups.update': Partial[] + 'group-participants.update': { jid: string, participants: string[], action: ParticipantAction } + + 'blocklist.update': { blocklist: string[], type: 'add' | 'remove' | 'set' } } export interface BaileysEventEmitter extends EventEmitter { on(event: T, listener: (arg: BaileysEventMap[T]) => void): this diff --git a/src/Utils/decodeWAMessage.ts b/src/Utils/decode-wa-message.ts similarity index 98% rename from src/Utils/decodeWAMessage.ts rename to src/Utils/decode-wa-message.ts index c0d759c..a8e3e97 100644 --- a/src/Utils/decodeWAMessage.ts +++ b/src/Utils/decode-wa-message.ts @@ -1,4 +1,4 @@ -import Boom from "boom" +import { Boom } from '@hapi/boom' import BinaryNode from "../BinaryNode" import { aesDecrypt, hmacSign } from "./generics" import { DisconnectReason, WATag } from "../Types" diff --git a/src/Utils/generics.ts b/src/Utils/generics.ts index b524074..7fec9d1 100644 --- a/src/Utils/generics.ts +++ b/src/Utils/generics.ts @@ -1,4 +1,4 @@ -import Boom from 'boom' +import { Boom } from '@hapi/boom' import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes } from 'crypto' import HKDF from 'futoin-hkdf' import { platform, release } from 'os' diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts new file mode 100644 index 0000000..c8f3208 --- /dev/null +++ b/src/Utils/messages-media.ts @@ -0,0 +1,286 @@ +import type { Agent } from 'https' +import type { Logger } from 'pino' +import type { IAudioMetadata } from 'music-metadata' +import * as Crypto from 'crypto' +import { Readable, Transform } from 'stream' +import Jimp from 'jimp' +import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs' +import { exec } from 'child_process' +import { tmpdir } from 'os' +import HttpsProxyAgent from 'https-proxy-agent' +import { URL } from 'url' +import { MessageType, WAMessageContent, WAMessageProto, WAGenericMediaMessage, WAMediaUpload } from '../Types' +import got, { Options, Response } from 'got' +import { join } from 'path' +import { generateMessageID, hkdf } from './generics' +import { Boom } from '@hapi/boom' +import { MediaType } from '../Types' +import { DEFAULT_ORIGIN } from '../Defaults' + +export const hkdfInfoKey = (type: MediaType) => { + let hkdfInfo = type[0].toUpperCase() + type.slice(1) + return `WhatsApp ${hkdfInfo} Keys` +} +/** generates all the keys required to encrypt/decrypt & sign a media message */ +export function getMediaKeys(buffer, mediaType: MediaType) { + if (typeof buffer === 'string') { + buffer = Buffer.from(buffer.replace('data:;base64,', ''), 'base64') + } + // expand using HKDF to 112 bytes, also pass in the relevant app info + const expandedMediaKey = hkdf(buffer, 112, hkdfInfoKey(mediaType)) + return { + iv: expandedMediaKey.slice(0, 16), + cipherKey: expandedMediaKey.slice(16, 48), + macKey: expandedMediaKey.slice(48, 80), + } +} +/** Extracts video thumb using FFMPEG */ +const extractVideoThumb = async ( + path: string, + destPath: string, + time: string, + size: { width: number; height: number }, +) => + new Promise((resolve, reject) => { + const cmd = `ffmpeg -ss ${time} -i ${path} -y -s ${size.width}x${size.height} -vframes 1 -f image2 ${destPath}` + exec(cmd, (err) => { + if (err) reject(err) + else resolve() + }) + }) as Promise + +export const compressImage = async (bufferOrFilePath: Buffer | string) => { + const jimp = await Jimp.read(bufferOrFilePath as any) + const result = await jimp.resize(48, 48).getBufferAsync(Jimp.MIME_JPEG) + return result +} +export const generateProfilePicture = async (buffer: Buffer) => { + const jimp = await Jimp.read (buffer) + const min = Math.min(jimp.getWidth (), jimp.getHeight ()) + const cropped = jimp.crop (0, 0, min, min) + return { + img: await cropped.resize(640, 640).getBufferAsync (Jimp.MIME_JPEG), + preview: await cropped.resize(96, 96).getBufferAsync (Jimp.MIME_JPEG) + } +} +export const ProxyAgent = (host: string | URL) => HttpsProxyAgent(host) as any as Agent +/** gets the SHA256 of the given media message */ +export const mediaMessageSHA256B64 = (message: WAMessageContent) => { + const media = Object.values(message)[0] as WAGenericMediaMessage + return media?.fileSha256 && Buffer.from(media.fileSha256).toString ('base64') +} +export async function getAudioDuration (buffer: Buffer | string) { + const musicMetadata = await import ('music-metadata') + let metadata: IAudioMetadata + if(Buffer.isBuffer(buffer)) { + metadata = await musicMetadata.parseBuffer(buffer, null, { duration: true }) + } else { + const rStream = createReadStream(buffer) + metadata = await musicMetadata.parseStream(rStream, null, { duration: true }) + rStream.close() + } + return metadata.format.duration; +} +export const toReadable = (buffer: Buffer) => { + const readable = new Readable({ read: () => {} }) + readable.push(buffer) + readable.push(null) + return readable +} +export const getStream = async (item: WAMediaUpload) => { + if(Buffer.isBuffer(item)) return { stream: toReadable(item), type: 'buffer' } + if(item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) { + return { stream: await getGotStream(item.url), type: 'remote' } + } + return { stream: createReadStream(item.url), type: 'file' } +} +/** generates a thumbnail for a given media, if required */ +export async function generateThumbnail( + file: string, + mediaType: 'video' | 'image', + options: { + logger?: Logger + } +) { + let thumbnail: string + if(mediaType === 'image') { + const buff = await compressImage(file) + thumbnail = buff.toString('base64') + } else if(mediaType === 'video') { + const imgFilename = join(tmpdir(), generateMessageID() + '.jpg') + try { + await extractVideoThumb(file, imgFilename, '00:00:00', { width: 48, height: 48 }) + const buff = await fs.readFile(imgFilename) + thumbnail = buff.toString('base64') + + await fs.unlink(imgFilename) + } catch (err) { + options.logger?.debug('could not generate video thumb: ' + err) + } + } + return thumbnail +} +export const getGotStream = async(url: string | URL, options: Options & { isStream?: true } = {}) => { + const fetched = got.stream(url, { ...options, isStream: true }) + await new Promise((resolve, reject) => { + fetched.once('error', reject) + fetched.once('response', ({ statusCode }: Response) => { + if (statusCode >= 400) { + reject( + new Boom( + 'Invalid code (' + statusCode + ') returned', + { statusCode } + )) + } else { + resolve(undefined) + } + }) + }) + return fetched +} +export const encryptedStream = async(media: WAMediaUpload, mediaType: MediaType, saveOriginalFileIfRequired = true) => { + const { stream, type } = await getStream(media) + + const mediaKey = Crypto.randomBytes(32) + const {cipherKey, iv, macKey} = getMediaKeys(mediaKey, mediaType) + // random name + const encBodyPath = join(tmpdir(), mediaType + generateMessageID() + '.enc') + const encWriteStream = createWriteStream(encBodyPath) + let bodyPath: string + let writeStream: WriteStream + let didSaveToTmpPath = false + if(type === 'file') { + bodyPath = (media as any).url + } else if(saveOriginalFileIfRequired) { + bodyPath = join(tmpdir(), mediaType + generateMessageID()) + writeStream = createWriteStream(bodyPath) + didSaveToTmpPath = true + } + + let fileLength = 0 + const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv) + let hmac = Crypto.createHmac('sha256', macKey).update(iv) + let sha256Plain = Crypto.createHash('sha256') + let sha256Enc = Crypto.createHash('sha256') + + const onChunk = (buff: Buffer) => { + sha256Enc = sha256Enc.update(buff) + hmac = hmac.update(buff) + encWriteStream.write(buff) + } + for await(const data of stream) { + fileLength += data.length + sha256Plain = sha256Plain.update(data) + writeStream && writeStream.write(data) + onChunk(aes.update(data)) + } + onChunk(aes.final()) + + const mac = hmac.digest().slice(0, 10) + sha256Enc = sha256Enc.update(mac) + + const fileSha256 = sha256Plain.digest() + const fileEncSha256 = sha256Enc.digest() + + encWriteStream.write(mac) + encWriteStream.close() + + writeStream && writeStream.close() + + return { + mediaKey, + encBodyPath, + bodyPath, + mac, + fileEncSha256, + fileSha256, + fileLength, + didSaveToTmpPath + } +} +/** + * Decode a media message (video, image, document, audio) & return decrypted buffer + * @param message the media message you want to decode + */ +export async function decryptMediaMessageBuffer(message: WAMessageContent): Promise { + /* + One can infer media type from the key in the message + it is usually written as [mediaType]Message. Eg. imageMessage, audioMessage etc. + */ + const type = Object.keys(message)[0] as MessageType + if( + !type || + type === 'conversation' || + type === 'extendedTextMessage' + ) { + throw new Boom(`no media message for "${type}"`, { statusCode: 400 }) + } + if (type === 'locationMessage' || type === 'liveLocationMessage') { + const buffer = Buffer.from(message[type].jpegThumbnail) + const readable = new Readable({ read: () => {} }) + readable.push(buffer) + readable.push(null) + return readable + } + let messageContent: WAGenericMediaMessage + if (message.productMessage) { + const product = message.productMessage.product?.productImage + if (!product) throw new Boom('product has no image', { statusCode: 400 }) + messageContent = product + } else { + messageContent = message[type] + } + // download the message + const fetched = await getGotStream(messageContent.url, { + headers: { Origin: DEFAULT_ORIGIN } + }) + let remainingBytes = Buffer.from([]) + const { cipherKey, iv } = getMediaKeys(messageContent.mediaKey, type.replace('Message', '') as MediaType) + const aes = Crypto.createDecipheriv("aes-256-cbc", cipherKey, iv) + + const output = new Transform({ + transform(chunk, _, callback) { + let data = Buffer.concat([remainingBytes, chunk]) + const decryptLength = + Math.floor(data.length / 16) * 16 + remainingBytes = data.slice(decryptLength) + data = data.slice(0, decryptLength) + + try { + this.push(aes.update(data)) + callback() + } catch(error) { + callback(error) + } + }, + final(callback) { + try { + this.push(aes.final()) + callback() + } catch(error) { + callback(error) + } + }, + }) + return fetched.pipe(output, { end: true }) +} +export function extensionForMediaMessage(message: WAMessageContent) { + const getExtension = (mimetype: string) => mimetype.split(';')[0].split('/')[1] + const type = Object.keys(message)[0] as MessageType + let extension: string + if( + type === 'locationMessage' || + type === 'liveLocationMessage' || + type === 'productMessage' + ) { + extension = '.jpeg' + } else { + const messageContent = message[type] as + | WAMessageProto.VideoMessage + | WAMessageProto.ImageMessage + | WAMessageProto.AudioMessage + | WAMessageProto.DocumentMessage + extension = getExtension (messageContent.mimetype) + } + return extension +} \ No newline at end of file diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts new file mode 100644 index 0000000..5cf2202 --- /dev/null +++ b/src/Utils/messages.ts @@ -0,0 +1,355 @@ +import { Boom } from '@hapi/boom' +import { createReadStream, promises as fs } from "fs" +import got from "got" +import { DEFAULT_ORIGIN, URL_REGEX, WA_DEFAULT_EPHEMERAL } from "../Defaults" +import { + AnyMediaMessageContent, + AnyMessageContent, + MediaGenerationOptions, + MessageContentGenerationOptions, + MessageGenerationOptions, + MessageGenerationOptionsFromContent, + MessageType, + WAMediaUpload, + WAMessage, + WAMessageContent, + WAMessageProto, + WATextMessage, + MediaType, + WAMessageStatus +} from "../Types" +import { generateMessageID, unixTimestampSeconds, whatsappID } from "./generics" +import { encryptedStream, generateThumbnail, getAudioDuration } from "./messages-media" + +type MediaUploadData = { + media: WAMediaUpload + caption?: string + ptt?: boolean + seconds?: number + gifPlayback?: boolean + fileName?: string + jpegThumbnail?: string + mimetype?: string +} + +const MEDIA_PATH_MAP: { [T in MediaType]: string } = { + image: '/mms/image', + video: '/mms/video', + document: '/mms/document', + audio: '/mms/audio', + sticker: '/mms/image', +} as const + +const MIMETYPE_MAP: { [T in MediaType]: string } = { + image: 'image/jpeg', + video: 'video/mp4', + document: 'application/pdf', + audio: 'audio/ogg; codecs=opus', + sticker: 'image/webp', +} + +const MessageTypeProto = { + 'imageMessage': WAMessageProto.ImageMessage, + 'videoMessage': WAMessageProto.VideoMessage, + 'audioMessage': WAMessageProto.AudioMessage, + 'stickerMessage': WAMessageProto.StickerMessage, + 'documentMessage': WAMessageProto.DocumentMessage, +} + +const MEDIA_KEYS = Object.keys(MEDIA_PATH_MAP) as MediaType[] + +export const prepareWAMessageMedia = async( + message: AnyMediaMessageContent, + options: MediaGenerationOptions +) => { + let mediaType: typeof MEDIA_KEYS[number] + for(const key of MEDIA_KEYS) { + if(key in message) { + mediaType = key + } + } + const uploadData: MediaUploadData = { + ...message, + [mediaType]: undefined, + media: message[mediaType] + } + if(mediaType === 'document' && !uploadData.fileName) { + uploadData.fileName = 'file' + } + if(!uploadData.mimetype) { + uploadData.mimetype = MIMETYPE_MAP[mediaType] + } + const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined' + const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') && + !('jpegThumbnail' in uploadData) + const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation + const { + mediaKey, + encBodyPath, + bodyPath, + fileEncSha256, + fileSha256, + fileLength, + didSaveToTmpPath + } = await encryptedStream(uploadData.media, mediaType, requiresOriginalForSomeProcessing) + // url safe Base64 encode the SHA256 hash of the body + const fileEncSha256B64 = encodeURIComponent( + fileEncSha256.toString('base64') + .replace(/\+/g, '-') + .replace(/\//g, '_') + .replace(/\=+$/, '') + ) + try { + if(requiresThumbnailComputation) { + uploadData.jpegThumbnail = await generateThumbnail(bodyPath, mediaType as any, options) + } + if (requiresDurationComputation) { + uploadData.seconds = await getAudioDuration(bodyPath) + } + } catch (error) { + options.logger?.debug ({ error }, 'failed to obtain audio duration: ' + error.message) + } + // send a query JSON to obtain the url & auth token to upload our media + let uploadInfo = await options.getMediaOptions(false) + + let mediaUrl: string + for (let host of uploadInfo.hosts) { + const auth = encodeURIComponent(uploadInfo.auth) // the auth token + const url = `https://${host.hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` + + try { + const {body: responseText} = await got.post( + url, + { + headers: { + 'Content-Type': 'application/octet-stream', + 'Origin': DEFAULT_ORIGIN + }, + agent: { + https: options.agent + }, + body: createReadStream(encBodyPath) + } + ) + const result = JSON.parse(responseText) + mediaUrl = result?.url + + if (mediaUrl) break + else { + uploadInfo = await options.getMediaOptions(true) + throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) + } + } catch (error) { + const isLast = host.hostname === uploadInfo.hosts[uploadInfo.hosts.length-1].hostname + options.logger?.debug(`Error in uploading to ${host.hostname} (${error}) ${isLast ? '' : ', retrying...'}`) + } + } + if (!mediaUrl) { + throw new Boom( + 'Media upload failed on all hosts', + { statusCode: 500 } + ) + } + // remove tmp files + await Promise.all( + [ + fs.unlink(encBodyPath), + didSaveToTmpPath && bodyPath && fs.unlink(bodyPath) + ] + .filter(Boolean) + ) + delete uploadData.media + const content = { + [mediaType]: MessageTypeProto[mediaType].fromObject( + { + url: mediaUrl, + mediaKey, + fileEncSha256, + fileSha256, + fileLength, + ...uploadData + } + ) + } + return WAMessageProto.Message.fromObject(content) +} +export const prepareDisappearingMessageSettingContent = (ephemeralExpiration?: number) => { + ephemeralExpiration = ephemeralExpiration || 0 + const content: WAMessageContent = { + ephemeralMessage: { + message: { + protocolMessage: { + type: WAMessageProto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING, + ephemeralExpiration + } + } + } + } + return WAMessageProto.Message.fromObject(content) +} +/** + * Generate forwarded message content like WA does + * @param message the message to forward + * @param options.forceForward will show the message as forwarded even if it is from you + */ +export const generateForwardMessageContent = ( + message: WAMessage, + forceForward?: boolean +) => { + let content = message.message + if (!content) throw new Boom('no content in message', { statusCode: 400 }) + content = JSON.parse(JSON.stringify(content)) // hacky copy + + let key = Object.keys(content)[0] as MessageType + + let score = content[key].contextInfo?.forwardingScore || 0 + score += message.key.fromMe && !forceForward ? 0 : 1 + if (key === 'conversation') { + content.extendedTextMessage = { text: content[key] } + delete content.conversation + + key = 'extendedTextMessage' + } + if (score > 0) content[key].contextInfo = { forwardingScore: score, isForwarded: true } + else content[key].contextInfo = {} + + return content +} +export const generateWAMessageContent = async( + message: AnyMessageContent, + options: MessageContentGenerationOptions +) => { + let m: WAMessageContent = {} + if(typeof message === 'string') { + message = { text: message } + } + if('text' in message) { + const extContent = { ...message } as WATextMessage + if (!!options.getUrlInfo && message.text.match(URL_REGEX)) { + try { + const data = await options.getUrlInfo(message.text) + extContent.canonicalUrl = data['canonical-url'] + extContent.matchedText = data['matched-text'] + extContent.jpegThumbnail = data.jpegThumbnail + extContent.description = data.description + extContent.title = data.title + extContent.previewType = 0 + } catch (error) { // ignore if fails + + } + } + m.extendedTextMessage = WAMessageProto.ExtendedTextMessage.fromObject(extContent) + } else if('contacts' in message) { + const contactLen = message.contacts.contacts.length + if(!contactLen) { + throw new Boom('require atleast 1 contact', { statusCode: 400 }) + } + if(contactLen === 1) { + m.contactMessage = WAMessageProto.ContactMessage.fromObject(message.contacts.contacts[0]) + } + } else if('location' in message) { + m.locationMessage = WAMessageProto.LocationMessage.fromObject(message.location) + } else if('delete' in message) { + m.protocolMessage = { + key: message.delete, + type: WAMessageProto.ProtocolMessage.ProtocolMessageType.REVOKE + } + } else if('forward' in message) { + m = generateForwardMessageContent( + message.forward, + message.force + ) + } else if('disappearingMessagesInChat' in message) { + const exp = typeof message.disappearingMessagesInChat === 'boolean' ? + (message.disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : + message.disappearingMessagesInChat + m = prepareDisappearingMessageSettingContent(exp) + } else { + m = await prepareWAMessageMedia( + message, + options + ) + } + if('mentions' in message) { + const [messageType] = Object.keys(message) + message[messageType].contextInfo = message[messageType] || { } + message[messageType].contextInfo.mentionedJid = message.mentions + } + return WAMessageProto.Message.fromObject(m) +} +export const generateWAMessageFromContent = ( + jid: string, + message: WAMessageContent, + options: MessageGenerationOptionsFromContent +) => { + if (!options.timestamp) options.timestamp = new Date() // set timestamp to now + // prevent an annoying bug (WA doesn't accept sending messages with '@c.us') + jid = whatsappID(jid) + + const key = Object.keys(message)[0] + const timestamp = unixTimestampSeconds(options.timestamp) + const { quoted, userJid } = options + + if (quoted) { + const participant = quoted.key.fromMe ? userJid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid) + + message[key].contextInfo = message[key].contextInfo || { } + message[key].contextInfo.participant = participant + message[key].contextInfo.stanzaId = quoted.key.id + message[key].contextInfo.quotedMessage = quoted.message + + // if a participant is quoted, then it must be a group + // hence, remoteJid of group must also be entered + if (quoted.key.participant) { + message[key].contextInfo.remoteJid = quoted.key.remoteJid + } + } + if( + // if we want to send a disappearing message + !!options?.ephemeralOptions && + // and it's not a protocol message -- delete, toggle disappear message + key !== 'protocolMessage' && + // already not converted to disappearing message + key !== 'ephemeralMessage' + ) { + message[key].contextInfo = { + ...(message[key].contextInfo || {}), + expiration: options.ephemeralOptions.expiration || WA_DEFAULT_EPHEMERAL, + ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts.toString() + } + message = { + ephemeralMessage: { + message + } + } + } + message = WAMessageProto.Message.fromObject (message) + + const messageJSON = { + key: { + remoteJid: jid, + fromMe: true, + id: options?.messageId || generateMessageID(), + }, + message: message, + messageTimestamp: timestamp, + messageStubParameters: [], + participant: jid.includes('@g.us') ? userJid : undefined, + status: WAMessageStatus.PENDING + } + return WAMessageProto.WebMessageInfo.fromObject (messageJSON) +} +export const generateWAMessage = async( + jid: string, + content: AnyMessageContent, + options: MessageGenerationOptions, +) => ( + generateWAMessageFromContent( + jid, + await generateWAMessageContent( + content, + options + ), + options + ) +) \ No newline at end of file diff --git a/src/Utils/validateConnection.ts b/src/Utils/validate-connection.ts similarity index 99% rename from src/Utils/validateConnection.ts rename to src/Utils/validate-connection.ts index 94f7279..c3c542e 100644 --- a/src/Utils/validateConnection.ts +++ b/src/Utils/validate-connection.ts @@ -1,4 +1,4 @@ -import Boom from 'boom' +import {Boom} from '@hapi/boom' import * as Curve from 'curve25519-js' import type { Contact } from '../Types/Contact' import type { AnyAuthenticationCredentials, AuthenticationCredentials, CurveKeyPair } from "../Types" diff --git a/src/index.ts b/src/index.ts index 34a105f..9e38e6c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,8 @@ +import makeConnection from './Connection' + export * from '../WAMessage/WAMessage' -export * from './Binary/Constants' -export * from './Binary/Decoder' -export * from './Binary/Encoder' -export * from './WAConnection' +export * from './Utils/messages' +export * from './Types' +export * from './Store' + +export default makeConnection \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 81412e6..e584e8c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,18 +7,526 @@ resolved "https://registry.yarnpkg.com/@adiwajshing/keyed-db/-/keyed-db-0.2.4.tgz#2a09e88fce20b2672deb60a7750c5fe3ab0dfd99" integrity sha512-yprSnAtj80/VKuDqRcFFLDYltoNV8tChNwFfIgcf6PGD4sjzWIBgs08pRuTqGH5mk5wgL6PBRSsMCZqtZwzFEw== +"@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" + integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== + dependencies: + "@babel/highlight" "^7.14.5" + +"@babel/compat-data@^7.14.5": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08" + integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw== + +"@babel/core@^7.1.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.6.tgz#e0814ec1a950032ff16c13a2721de39a8416fcab" + integrity sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA== + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.14.5" + "@babel/helper-compilation-targets" "^7.14.5" + "@babel/helper-module-transforms" "^7.14.5" + "@babel/helpers" "^7.14.6" + "@babel/parser" "^7.14.6" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.5" + "@babel/types" "^7.14.5" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + source-map "^0.5.0" + +"@babel/generator@^7.14.5", "@babel/generator@^7.7.2": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.5.tgz#848d7b9f031caca9d0cd0af01b063f226f52d785" + integrity sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA== + dependencies: + "@babel/types" "^7.14.5" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-compilation-targets@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz#7a99c5d0967911e972fe2c3411f7d5b498498ecf" + integrity sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw== + dependencies: + "@babel/compat-data" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + browserslist "^4.16.6" + semver "^6.3.0" + +"@babel/helper-function-name@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4" + integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ== + dependencies: + "@babel/helper-get-function-arity" "^7.14.5" + "@babel/template" "^7.14.5" + "@babel/types" "^7.14.5" + +"@babel/helper-get-function-arity@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815" + integrity sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-hoist-variables@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d" + integrity sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-member-expression-to-functions@^7.14.5": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz#97e56244beb94211fe277bd818e3a329c66f7970" + integrity sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-module-imports@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3" + integrity sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-module-transforms@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz#7de42f10d789b423eb902ebd24031ca77cb1e10e" + integrity sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA== + dependencies: + "@babel/helper-module-imports" "^7.14.5" + "@babel/helper-replace-supers" "^7.14.5" + "@babel/helper-simple-access" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/helper-validator-identifier" "^7.14.5" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.5" + "@babel/types" "^7.14.5" + +"@babel/helper-optimise-call-expression@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c" + integrity sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" + integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== + +"@babel/helper-replace-supers@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz#0ecc0b03c41cd567b4024ea016134c28414abb94" + integrity sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.14.5" + "@babel/helper-optimise-call-expression" "^7.14.5" + "@babel/traverse" "^7.14.5" + "@babel/types" "^7.14.5" + +"@babel/helper-simple-access@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz#66ea85cf53ba0b4e588ba77fc813f53abcaa41c4" + integrity sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-split-export-declaration@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a" + integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-validator-identifier@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" + integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== + +"@babel/helper-validator-option@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" + integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== + +"@babel/helpers@^7.14.6": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.6.tgz#5b58306b95f1b47e2a0199434fa8658fa6c21635" + integrity sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA== + dependencies: + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.5" + "@babel/types" "^7.14.5" + +"@babel/highlight@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" + integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.14.7", "@babel/parser@^7.7.2": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595" + integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716" + integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/runtime@^7.7.2": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" - integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== dependencies: regenerator-runtime "^0.13.4" +"@babel/template@^7.14.5", "@babel/template@^7.3.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" + integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g== + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/parser" "^7.14.5" + "@babel/types" "^7.14.5" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.7.2": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753" + integrity sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ== + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.14.5" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-hoist-variables" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/parser" "^7.14.7" + "@babel/types" "^7.14.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.14.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff" + integrity sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.5" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@hapi/boom@^9.1.3": + version "9.1.3" + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.3.tgz#22cad56e39b7a4819161a99b1db19eaaa9b6cc6e" + integrity sha512-RlrGyZ603hE/eRTZtTltocRm50HHmrmL3kGOP0SQ9MasazlW1mt/fkv4C5P/6rnpFXjwld/POFX1C8tMZE3ldg== + dependencies: + "@hapi/hoek" "9.x.x" + "@hapi/bourne@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-2.0.0.tgz#5bb2193eb685c0007540ca61d166d4e1edaf918d" integrity sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg== +"@hapi/hoek@9.x.x": + version "9.2.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" + integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.0.6.tgz#3eb72ea80897495c3d73dd97aab7f26770e2260f" + integrity sha512-fMlIBocSHPZ3JxgWiDNW/KPj6s+YRd0hicb33IrmelCcjXo/pXPwvuiKFmZz+XuqI/1u7nbUK10zSsWL/1aegg== + dependencies: + "@jest/types" "^27.0.6" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^27.0.6" + jest-util "^27.0.6" + slash "^3.0.0" + +"@jest/core@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.0.6.tgz#c5f642727a0b3bf0f37c4b46c675372d0978d4a1" + integrity sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow== + dependencies: + "@jest/console" "^27.0.6" + "@jest/reporters" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.4" + jest-changed-files "^27.0.6" + jest-config "^27.0.6" + jest-haste-map "^27.0.6" + jest-message-util "^27.0.6" + jest-regex-util "^27.0.6" + jest-resolve "^27.0.6" + jest-resolve-dependencies "^27.0.6" + jest-runner "^27.0.6" + jest-runtime "^27.0.6" + jest-snapshot "^27.0.6" + jest-util "^27.0.6" + jest-validate "^27.0.6" + jest-watcher "^27.0.6" + micromatch "^4.0.4" + p-each-series "^2.1.0" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.0.6.tgz#ee293fe996db01d7d663b8108fa0e1ff436219d2" + integrity sha512-4XywtdhwZwCpPJ/qfAkqExRsERW+UaoSRStSHCCiQTUpoYdLukj+YJbQSFrZjhlUDRZeNiU9SFH0u7iNimdiIg== + dependencies: + "@jest/fake-timers" "^27.0.6" + "@jest/types" "^27.0.6" + "@types/node" "*" + jest-mock "^27.0.6" + +"@jest/fake-timers@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.0.6.tgz#cbad52f3fe6abe30e7acb8cd5fa3466b9588e3df" + integrity sha512-sqd+xTWtZ94l3yWDKnRTdvTeZ+A/V7SSKrxsrOKSqdyddb9CeNRF8fbhAU0D7ZJBpTTW2nbp6MftmKJDZfW2LQ== + dependencies: + "@jest/types" "^27.0.6" + "@sinonjs/fake-timers" "^7.0.2" + "@types/node" "*" + jest-message-util "^27.0.6" + jest-mock "^27.0.6" + jest-util "^27.0.6" + +"@jest/globals@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.0.6.tgz#48e3903f99a4650673d8657334d13c9caf0e8f82" + integrity sha512-DdTGCP606rh9bjkdQ7VvChV18iS7q0IMJVP1piwTWyWskol4iqcVwthZmoJEf7obE1nc34OpIyoVGPeqLC+ryw== + dependencies: + "@jest/environment" "^27.0.6" + "@jest/types" "^27.0.6" + expect "^27.0.6" + +"@jest/reporters@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.0.6.tgz#91e7f2d98c002ad5df94d5b5167c1eb0b9fd5b00" + integrity sha512-TIkBt09Cb2gptji3yJXb3EE+eVltW6BjO7frO7NEfjI9vSIYoISi5R3aI3KpEDXlB1xwB+97NXIqz84qYeYsfA== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.2.4" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^4.0.3" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.0.2" + jest-haste-map "^27.0.6" + jest-resolve "^27.0.6" + jest-util "^27.0.6" + jest-worker "^27.0.6" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^8.0.0" + +"@jest/source-map@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.0.6.tgz#be9e9b93565d49b0548b86e232092491fb60551f" + integrity sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.4" + source-map "^0.6.0" + +"@jest/test-result@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.0.6.tgz#3fa42015a14e4fdede6acd042ce98c7f36627051" + integrity sha512-ja/pBOMTufjX4JLEauLxE3LQBPaI2YjGFtXexRAjt1I/MbfNlMx0sytSX3tn5hSLzQsR3Qy2rd0hc1BWojtj9w== + dependencies: + "@jest/console" "^27.0.6" + "@jest/types" "^27.0.6" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.0.6.tgz#80a913ed7a1130545b1cd777ff2735dd3af5d34b" + integrity sha512-bISzNIApazYOlTHDum9PwW22NOyDa6VI31n6JucpjTVM0jD6JDgqEZ9+yn575nDdPF0+4csYDxNNW13NvFQGZA== + dependencies: + "@jest/test-result" "^27.0.6" + graceful-fs "^4.2.4" + jest-haste-map "^27.0.6" + jest-runtime "^27.0.6" + +"@jest/transform@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.0.6.tgz#189ad7107413208f7600f4719f81dd2f7278cc95" + integrity sha512-rj5Dw+mtIcntAUnMlW/Vju5mr73u8yg+irnHwzgtgoeI6cCPOvUwQ0D1uQtc/APmWgvRweEb1g05pkUpxH3iCA== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.0.6" + babel-plugin-istanbul "^6.0.0" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^27.0.6" + jest-regex-util "^27.0.6" + jest-util "^27.0.6" + micromatch "^4.0.4" + pirates "^4.0.1" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + +"@jest/types@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.0.6.tgz#9a992bc517e0c49f035938b8549719c2de40706b" + integrity sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + "@jimp/bmp@^0.16.1": version "0.16.1" resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.16.1.tgz#6e2da655b2ba22e721df0795423f34e92ef13768" @@ -363,9 +871,23 @@ integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= "@sindresorhus/is@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4" - integrity sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ== + version "4.0.1" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.1.tgz#d26729db850fa327b7cacc5522252194404226f5" + integrity sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g== + +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^7.0.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" + integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== + dependencies: + "@sinonjs/commons" "^1.7.0" "@szmarczak/http-timer@^4.0.5": version "4.0.5" @@ -379,10 +901,68 @@ resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.1.1.tgz#f0d92c12f87079ddfd1b29f614758b9696bc29e3" integrity sha512-XO6INPbZCxdprl+9qa/AAbFFOMzzwqYxpjPgLICrMD6C2FCw6qfJOPcBk6JqqPLSaZ/Qx87qn4rpPmPMwaAK6w== +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@tsconfig/node10@^1.0.7": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" + integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== + +"@tsconfig/node12@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" + integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== + +"@tsconfig/node14@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" + integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== + +"@tsconfig/node16@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.1.tgz#a6ca6a9a0ff366af433f42f5f0e124794ff6b8f1" + integrity sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA== + +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": + version "7.1.15" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.15.tgz#2ccfb1ad55a02c83f8e0ad327cbc332f55eb1024" + integrity sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.3.tgz#f456b4b2ce79137f768aa130d2423d2f0ccfaba5" + integrity sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" + integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== + dependencies: + "@babel/types" "^7.3.0" + "@types/cacheable-request@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" - integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz#c324da0197de0a98a2312156536ae262429ff6b9" + integrity sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA== dependencies: "@types/http-cache-semantics" "*" "@types/keyv" "*" @@ -390,28 +970,62 @@ "@types/responselike" "*" "@types/debug@^4.1.5": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd" - integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ== + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.6.tgz#0b7018723084918a865eff99249c490505df2163" + integrity sha512-7fDOJFA/x8B+sO1901BmHlf5dE1cxBU8mRXj8QOEDnn16hhGJv/IHxJtZhvsabZsIMn0eLIyeOKAeqSNJJYTpA== "@types/got@^9.6.11": - version "9.6.11" - resolved "https://registry.yarnpkg.com/@types/got/-/got-9.6.11.tgz#482b402cc5ee459481aeeadb08142ebb1a9afb26" - integrity sha512-dr3IiDNg5TDesGyuwTrN77E1Cd7DCdmCFtEfSGqr83jMMtcwhf/SGPbN2goY4JUWQfvxwY56+e5tjfi+oXeSdA== + version "9.6.12" + resolved "https://registry.yarnpkg.com/@types/got/-/got-9.6.12.tgz#fd42a6e1f5f64cd6bb422279b08c30bb5a15a56f" + integrity sha512-X4pj/HGHbXVLqTpKjA2ahI4rV/nNBc9mGO2I/0CgAra+F2dKgMXnENv2SRpemScBzBAI4vMelIVYViQxlSE6xA== dependencies: "@types/node" "*" "@types/tough-cookie" "*" form-data "^2.5.0" +"@types/graceful-fs@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + "@types/http-cache-semantics@*": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" - integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" + integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" + integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^26.0.24": + version "26.0.24" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a" + integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w== + dependencies: + jest-diff "^26.0.0" + pretty-format "^26.0.0" "@types/keyv@*": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" - integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== + version "3.1.2" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.2.tgz#5d97bb65526c20b6e0845f6b0d2ade4f28604ee5" + integrity sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg== dependencies: "@types/node" "*" @@ -420,25 +1034,20 @@ resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== -"@types/mocha@^7.0.2": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-7.0.2.tgz#b17f16cf933597e10d6d78eae3251e692ce8b0ce" - integrity sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w== +"@types/node@*", "@types/node@>=13.7.0": + version "16.0.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.0.1.tgz#70cedfda26af7a2ca073fdcc9beb2fff4aa693f8" + integrity sha512-hBOx4SUlEPKwRi6PrXuTGw1z6lz0fjsibcWCM378YxsSu/6+C30L6CR49zIBKHiwNWCYIcOLjg4OHKZaFeLAug== -"@types/node@*", "@types/node@^14.6.2": - version "14.14.37" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e" - integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw== - -"@types/node@^13.7.0": - version "13.13.48" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.48.tgz#46a3df718aed5217277f2395a682e055a487e341" - integrity sha512-z8wvSsgWQzkr4sVuMEEOvwMdOQjiRY2Y/ZW4fDfjfe3+TfQrZqFKOthBgk2RnVEmtOKrkwdZ7uTvsxTBLjKGDQ== +"@types/node@^14.6.2": + version "14.17.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.5.tgz#b59daf6a7ffa461b5648456ca59050ba8e40ed54" + integrity sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA== "@types/pino-pretty@*": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@types/pino-pretty/-/pino-pretty-4.7.0.tgz#e4a18541f8464d1cc48216f5593cc6a0e62dc2c3" - integrity sha512-fIZ+VXf9gJoJR4tiiM7G+j/bZkPoZEfFGzA4d8tAWCTpTVyvVaBwnmdLs3wEXYpMjw8eXulrOzNCjmGHT3FgHw== + version "4.7.1" + resolved "https://registry.yarnpkg.com/@types/pino-pretty/-/pino-pretty-4.7.1.tgz#2ce3f56f3cf4f9632374419d616ae2e6c933b935" + integrity sha512-l1ntNXdpVWsnPYUk5HyO5Lxfr38zLCgxVfEn/9Zhhm+nGF04/BiIou/m8XPwvoVZLV+livUo79VdHXMJPfUYxA== dependencies: "@types/pino" "*" @@ -450,19 +1059,24 @@ "@types/node" "*" "@types/pino@*", "@types/pino@^6.3.2": - version "6.3.7" - resolved "https://registry.yarnpkg.com/@types/pino/-/pino-6.3.7.tgz#0ccef98a159230cb3fa2589c7e8b00a7550a69f6" - integrity sha512-v7FdDXVEL0Zx1zcCf0cJZMojChnF+O0ujDKV1UdocsLuUhENjdtNIaanCZK1zRELp35x//bI2/IHtYUK0vmRvw== + version "6.3.9" + resolved "https://registry.yarnpkg.com/@types/pino/-/pino-6.3.9.tgz#dbbbd4a9a6b99935f5ed286c3d998ab83d260482" + integrity sha512-2/XV6adNNCLWnT2lJqcSn/OXrCxRFOY6yXYoofrLy5Ts5e8RHTJP1M4XEcCarQQMa6H6JISaa4GkrlGZwIP5aQ== dependencies: "@types/node" "*" "@types/pino-pretty" "*" "@types/pino-std-serializers" "*" "@types/sonic-boom" "*" +"@types/prettier@^2.1.5": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3" + integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog== + "@types/readable-stream@^2.3.9": - version "2.3.9" - resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.9.tgz#40a8349e6ace3afd2dd1b6d8e9b02945de4566a9" - integrity sha512-sqsgQqFT7HmQz/V5jH1O0fvQQnXAJO46Gg9LRO/JPfjmVmGUlcx831TZZO3Y3HtWhIkzf3kTsNT0Z0kzIhIvZw== + version "2.3.11" + resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.11.tgz#942bc4574a1d7ca4368cb9cb4352e3d2b4b51dea" + integrity sha512-0z+/apYJwKFz/RHp6mOMxz/y7xOvWPYPevuCEyAY3gXsjtaac02E26RvxA+I96rfvmVH/dEMGXNvyJfViR1FSQ== dependencies: "@types/node" "*" safe-buffer "*" @@ -481,32 +1095,69 @@ dependencies: "@types/node" "*" -"@types/strip-bom@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2" - integrity sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I= - -"@types/strip-json-comments@0.0.30": - version "0.0.30" - resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" - integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== "@types/tough-cookie@*": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d" - integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40" + integrity sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg== "@types/ws@^7.2.6": - version "7.4.1" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.1.tgz#49eacb15a0534663d53a36fbf5b4d98f5ae9a73a" - integrity sha512-ISCK1iFnR+jYv7+jLNX0wDqesZ/5RAeY3wUx6QaphmocphU61h+b+PHjS18TF4WIPTu/MMzxIq2PHr32o2TS5Q== + version "7.4.6" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.6.tgz#c4320845e43d45a7129bb32905e28781c71c1fff" + integrity sha512-ijZ1vzRawI7QoWnTNL8KpHixd2b2XVb9I9HAqI3triPsh1EC0xH0Eg6w2O3TKbDCgiNNlJqfrof6j4T2I+l9vw== dependencies: "@types/node" "*" -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== +"@types/yargs-parser@*": + version "20.2.1" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" + integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw== + +"@types/yargs@^15.0.0": + version "15.0.14" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" + integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== + dependencies: + "@types/yargs-parser" "*" + +"@types/yargs@^16.0.0": + version "16.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" + integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + dependencies: + "@types/yargs-parser" "*" + +abab@^2.0.3, abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.2.4: + version "8.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" + integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== agent-base@6: version "6.0.2" @@ -515,15 +1166,12 @@ agent-base@6: dependencies: debug "4" -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" ansi-regex@^5.0.0: version "5.0.0" @@ -544,12 +1192,17 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + any-base@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" integrity sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg== -anymatch@~3.1.1: +anymatch@^3.0.3: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -562,10 +1215,12 @@ arg@^4.1.0: resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" args@^5.0.1: version "5.0.1" @@ -577,26 +1232,6 @@ args@^5.0.1: leven "2.1.0" mri "1.1.4" -array-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" - integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= - -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= - -assert@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32" - integrity sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A== - dependencies: - es6-object-assign "^1.1.0" - is-nan "^1.2.1" - object-is "^1.0.1" - util "^0.12.0" - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -612,12 +1247,66 @@ atomic-sleep@^1.0.0: resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== -available-typed-arrays@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" - integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== +babel-jest@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.6.tgz#e99c6e0577da2655118e3608b68761a5a69bd0d8" + integrity sha512-iTJyYLNc4wRofASmofpOc5NK9QunwMk+TLFgGXsTFS8uEqmd8wdI7sga0FPe2oVH3b5Agt/EAK1QjPEuKL8VfA== dependencies: - array-filter "^1.0.0" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.0.0" + babel-preset-jest "^27.0.6" + chalk "^4.0.0" + graceful-fs "^4.2.4" + slash "^3.0.0" + +babel-plugin-istanbul@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" + integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^4.0.0" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz#f7c6b3d764af21cb4a2a1ab6870117dbde15b456" + integrity sha512-CewFeM9Vv2gM7Yr9n5eyyLVPRSiBnk6lKZRjgwYnGKSl9M14TMn2vkN02wTF04OGuSDLEzlWiMzvjXuW9mB6Gw== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz#909ef08e9f24a4679768be2f60a3df0856843f9d" + integrity sha512-WObA0/Biw2LrVVwZkF/2GqbOdzhKD6Fkdwhoy9ASIrOWr/zodcSpQh72JOkEn6NWyjmnPDjNSqaGN4KnpKzhXw== + dependencies: + babel-plugin-jest-hoist "^27.0.6" + babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: version "1.0.2" @@ -629,11 +1318,6 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - bmp-js@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" @@ -647,24 +1331,49 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@~3.0.2: +braces@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +browserslist@^4.16.6: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== + dependencies: + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" + escalade "^3.1.1" + node-releases "^1.1.71" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" buffer-equal@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs= -buffer-from@^1.0.0: +buffer-from@1.x, buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== @@ -683,50 +1392,44 @@ cacheable-lookup@^5.0.3: integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== cacheable-request@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" - integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw== + version "7.0.2" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" + integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== dependencies: clone-response "^1.0.2" get-stream "^5.1.0" http-cache-semantics "^4.0.0" keyv "^4.0.0" lowercase-keys "^2.0.0" - normalize-url "^4.1.0" + normalize-url "^6.0.1" responselike "^2.0.0" -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0: +camelcase@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== -chalk@2.4.2: +caniuse-lite@^1.0.30001219: + version "1.0.30001243" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz#d9250155c91e872186671c523f3ae50cfc94a3aa" + integrity sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA== + +chalk@2.4.2, chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -736,27 +1439,27 @@ chalk@2.4.2: supports-color "^5.3.0" chalk@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" -chokidar@3.5.1, chokidar@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.5.0" - optionalDependencies: - fsevents "~2.3.1" +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +ci-info@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6" + integrity sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A== + +cjs-module-lexer@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz#2fd46d9906a126965aa541345c499aaa18e8cd73" + integrity sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw== cliui@^7.0.2: version "7.0.4" @@ -774,6 +1477,16 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -798,12 +1511,17 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + colors@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -combined-stream@^1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -820,52 +1538,74 @@ content-type@^1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: - array-find-index "^1.0.1" + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" curve25519-js@^0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/curve25519-js/-/curve25519-js-0.0.4.tgz#e6ad967e8cd284590d657bbfc90d8b50e49ba060" integrity sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w== +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + dateformat@^4.5.1: version "4.5.1" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.5.1.tgz#c20e7a9ca77d147906b6dc2261a8be0a5bd2173c" integrity sha512-OD0TZ+B7yP7ZgpJf5K2DIbj3FZvFvxgFUuaqA/V5zTjAtAAXZ1E8bktHxmAGs4x5b7PflqA9LeQ84Og7wYtF7Q== -dateformat@~1.0.4-1.2.3: - version "1.0.12" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" - integrity sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk= - dependencies: - get-stdin "^4.0.1" - meow "^3.3.0" - -debug@4, debug@4.3.1, debug@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== dependencies: ms "2.1.2" -decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== +decimal.js@^10.2.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== decompress-response@^6.0.0: version "6.0.0" @@ -874,27 +1614,45 @@ decompress-response@^6.0.0: dependencies: mimic-response "^3.1.0" +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + defer-to-connect@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +diff-sequences@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" + integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== + +diff-sequences@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723" + integrity sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ== diff@^4.0.1: version "4.0.2" @@ -906,17 +1664,22 @@ dom-walk@^0.1.0: resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== -dotenv@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" - integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== - -dynamic-dedupe@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz#06e44c223f5e4e94d78ef9db23a6515ce2f962a1" - integrity sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE= +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== dependencies: - xtend "^4.0.0" + webidl-conversions "^5.0.0" + +electron-to-chromium@^1.3.723: + version "1.3.770" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.770.tgz#a9e705a73315f4900880622b3ab76cf1d7221b77" + integrity sha512-Kyh8DGK1KfEZuYKIHvuOmrKotsKZQ+qBkDIWHciE3QoFkxXB1KzPP+tfLilSHAfxTON0yYMnFCWkQtUOR7g6KQ== + +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== emoji-regex@^8.0.0: version "8.0.0" @@ -930,88 +1693,120 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -error-ex@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: - version "1.18.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" - integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.2" - is-callable "^1.2.3" - is-negative-zero "^2.0.1" - is-regex "^1.1.2" - is-string "^1.0.5" - object-inspect "^1.9.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.0" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es6-object-assign@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" - integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw= - escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + exif-parser@^0.1.12: version "0.1.12" resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922" integrity sha1-WKnS1ywCwfbwKg70qRZicrd2CSI= +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expect@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.0.6.tgz#a4d74fbe27222c718fff68ef49d78e26a8fd4c05" + integrity sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw== + dependencies: + "@jest/types" "^27.0.6" + ansi-styles "^5.0.0" + jest-get-type "^27.0.6" + jest-matcher-utils "^27.0.6" + jest-message-util "^27.0.6" + jest-regex-util "^27.0.6" + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + fast-redact@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.0.0.tgz#ac2f9e36c9f4976f5db9fb18c6ffbaf308cf316d" - integrity sha512-a/S/Hp6aoIjx7EmugtzLqXmcNsyFszqbt6qQ99BdG61QjBZF6shNis0BYR6TsZOQ1twYc0FN2Xdhwwbv6+KD0w== + version "3.0.1" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.0.1.tgz#d6015b971e933d03529b01333ba7f22c29961e92" + integrity sha512-kYpn4Y/valC9MdrISg47tZOpYBNoTXKgT9GYXFpHN/jYFs+lFkPoisY+LcBODdKVMY96ATzvzsWv+ES/4Kmufw== fast-safe-stringify@^2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== -file-type@^16.3.0: - version "16.3.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.3.0.tgz#f03af91db30f92cc9a0b335c0644c46101522f6d" - integrity sha512-ZA0hV64611vJT42ltw0T9IDwHApQuxRdrmQZWTeDmeAUtZBBVSQW3nSQqhhW1cAgpXgqcJvm410BYHXJQ9AymA== +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + +file-type@^16.5.0: + version "16.5.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.0.tgz#16a2626f3b33bac612f6e81e52216f3a7c8e12a2" + integrity sha512-OxgWA9tbL8N/WP00GD1z8O0MiwQKFyWRs1q+3FhjdvcGgKqwxcejyGWso3n4/IMU6DdwV+ARZ4A7TTnPkDcSiw== dependencies: readable-web-to-node-stream "^3.0.0" strtok3 "^6.0.3" token-types "^2.0.0" - typedarray-to-buffer "^3.1.5" file-type@^9.0.0: version "9.0.0" @@ -1025,37 +1820,19 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: - locate-path "^6.0.0" + locate-path "^5.0.0" path-exists "^4.0.0" -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - flatstr@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931" integrity sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw== -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= - form-data@^2.5.0: version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -1065,6 +1842,15 @@ form-data@^2.5.0: combined-stream "^1.0.6" mime-types "^2.1.12" +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -1080,7 +1866,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@~2.3.1: +fsevents@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -1091,28 +1877,24 @@ function-bind@^1.1.1: integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== futoin-hkdf@^1.3.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/futoin-hkdf/-/futoin-hkdf-1.3.3.tgz#6ee1c9c105dfa0995ba4f80633cf1c0c32defcb2" - integrity sha512-oR75fYk3B3X9/B02Y6vusrBKucrpC6VjxhRL+C6B7FwUpuSRHbhBNG3AZbcE/xPyJmEQWsyqUFp3VeNNbA3S7A== + version "1.4.2" + resolved "https://registry.yarnpkg.com/futoin-hkdf/-/futoin-hkdf-1.4.2.tgz#fd534e848e0e50339b8bfbd81250b09cbff10ba3" + integrity sha512-2BggwLEJOTfXzKq4Tl2bIT37p0IqqKkblH4e0cMp2sXTdmwg/ADBKMxvxaEytYYcgdxgng8+acsi3WgMVUl6CQ== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== get-stream@^5.1.0: version "5.2.0" @@ -1121,6 +1903,11 @@ get-stream@^5.1.0: dependencies: pump "^3.0.0" +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + gifwrap@^0.9.2: version "0.9.2" resolved "https://registry.yarnpkg.com/gifwrap/-/gifwrap-0.9.2.tgz#348e286e67d7cf57942172e1e6f05a71cee78489" @@ -1129,17 +1916,10 @@ gifwrap@^0.9.2: image-q "^1.1.1" omggif "^1.0.10" -glob-parent@~5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@7.1.6, glob@^7.0.0, glob@^7.1.3: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== +glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -1156,6 +1936,11 @@ global@~4.4.0: min-document "^2.19.0" process "^0.11.10" +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + got@^11.8.1: version "11.8.2" resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" @@ -1173,16 +1958,11 @@ got@^11.8.1: p-cancelable "^2.0.0" responselike "^2.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: +graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - handlebars@^4.7.7: version "4.7.7" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" @@ -1195,11 +1975,6 @@ handlebars@^4.7.7: optionalDependencies: uglify-js "^3.1.4" -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1210,11 +1985,6 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -1222,21 +1992,32 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== + dependencies: + whatwg-encoding "^1.0.5" -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== http-cache-semantics@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + http2-wrapper@^1.0.0-beta.5.2: version "1.0.3" resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" @@ -1253,6 +2034,18 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -1263,12 +2056,18 @@ image-q@^1.1.1: resolved "https://registry.yarnpkg.com/image-q/-/image-q-1.1.1.tgz#fc84099664460b90ca862d9300b6bfbbbfbf8056" integrity sha1-/IQJlmRGC5DKhi2TALa/u7+/gFY= -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= +import-local@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" + integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== dependencies: - repeating "^2.0.0" + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= inflight@^1.0.4: version "1.0.6" @@ -1288,69 +2087,20 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== -is-arguments@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" - integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== +is-ci@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994" + integrity sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ== dependencies: - call-bind "^1.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-bigint@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2" - integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" - integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== - dependencies: - call-bind "^1.0.0" - -is-callable@^1.1.4, is-callable@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" - integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== + ci-info "^3.1.1" is-core-module@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== + version "2.4.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" + integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== dependencies: has "^1.0.3" -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -1361,92 +2111,501 @@ is-function@^1.0.1: resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== -is-generator-function@^1.0.7: - version "1.0.8" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.8.tgz#dfb5c2b120e02b0a8d9d2c6806cd5621aa922f7b" - integrity sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ== - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-nan@^1.2.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" - integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - -is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - -is-number-object@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" - integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== -is-regex@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" - integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== - dependencies: - call-bind "^1.0.2" - has-symbols "^1.0.1" - -is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - -is-typed-array@^1.1.3: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e" - integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== - dependencies: - available-typed-arrays "^1.0.2" - call-bind "^1.0.2" - es-abstract "^1.18.0-next.2" - foreach "^2.0.5" - has-symbols "^1.0.1" +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= +istanbul-lib-coverage@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" + integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== + +istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" + integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== + dependencies: + "@babel/core" "^7.7.5" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" + integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" + integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.0.6.tgz#bed6183fcdea8a285482e3b50a9a7712d49a7a8b" + integrity sha512-BuL/ZDauaq5dumYh5y20sn4IISnf1P9A0TDswTxUi84ORGtVa86ApuBHqICL0vepqAnZiY6a7xeSPWv2/yy4eA== + dependencies: + "@jest/types" "^27.0.6" + execa "^5.0.0" + throat "^6.0.1" + +jest-circus@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.0.6.tgz#dd4df17c4697db6a2c232aaad4e9cec666926668" + integrity sha512-OJlsz6BBeX9qR+7O9lXefWoc2m9ZqcZ5Ohlzz0pTEAG4xMiZUJoacY8f4YDHxgk0oKYxj277AfOk9w6hZYvi1Q== + dependencies: + "@jest/environment" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/types" "^27.0.6" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.0.6" + is-generator-fn "^2.0.0" + jest-each "^27.0.6" + jest-matcher-utils "^27.0.6" + jest-message-util "^27.0.6" + jest-runtime "^27.0.6" + jest-snapshot "^27.0.6" + jest-util "^27.0.6" + pretty-format "^27.0.6" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + +jest-cli@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.0.6.tgz#d021e5f4d86d6a212450d4c7b86cb219f1e6864f" + integrity sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg== + dependencies: + "@jest/core" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/types" "^27.0.6" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.4" + import-local "^3.0.2" + jest-config "^27.0.6" + jest-util "^27.0.6" + jest-validate "^27.0.6" + prompts "^2.0.1" + yargs "^16.0.3" + +jest-config@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.0.6.tgz#119fb10f149ba63d9c50621baa4f1f179500277f" + integrity sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w== + dependencies: + "@babel/core" "^7.1.0" + "@jest/test-sequencer" "^27.0.6" + "@jest/types" "^27.0.6" + babel-jest "^27.0.6" + chalk "^4.0.0" + deepmerge "^4.2.2" + glob "^7.1.1" + graceful-fs "^4.2.4" + is-ci "^3.0.0" + jest-circus "^27.0.6" + jest-environment-jsdom "^27.0.6" + jest-environment-node "^27.0.6" + jest-get-type "^27.0.6" + jest-jasmine2 "^27.0.6" + jest-regex-util "^27.0.6" + jest-resolve "^27.0.6" + jest-runner "^27.0.6" + jest-util "^27.0.6" + jest-validate "^27.0.6" + micromatch "^4.0.4" + pretty-format "^27.0.6" + +jest-diff@^26.0.0: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" + integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== + dependencies: + chalk "^4.0.0" + diff-sequences "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-diff@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.0.6.tgz#4a7a19ee6f04ad70e0e3388f35829394a44c7b5e" + integrity sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg== + dependencies: + chalk "^4.0.0" + diff-sequences "^27.0.6" + jest-get-type "^27.0.6" + pretty-format "^27.0.6" + +jest-docblock@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.0.6.tgz#cc78266acf7fe693ca462cbbda0ea4e639e4e5f3" + integrity sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA== + dependencies: + detect-newline "^3.0.0" + +jest-each@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.0.6.tgz#cee117071b04060158dc8d9a66dc50ad40ef453b" + integrity sha512-m6yKcV3bkSWrUIjxkE9OC0mhBZZdhovIW5ergBYirqnkLXkyEn3oUUF/QZgyecA1cF1QFyTE8bRRl8Tfg1pfLA== + dependencies: + "@jest/types" "^27.0.6" + chalk "^4.0.0" + jest-get-type "^27.0.6" + jest-util "^27.0.6" + pretty-format "^27.0.6" + +jest-environment-jsdom@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.0.6.tgz#f66426c4c9950807d0a9f209c590ce544f73291f" + integrity sha512-FvetXg7lnXL9+78H+xUAsra3IeZRTiegA3An01cWeXBspKXUhAwMM9ycIJ4yBaR0L7HkoMPaZsozCLHh4T8fuw== + dependencies: + "@jest/environment" "^27.0.6" + "@jest/fake-timers" "^27.0.6" + "@jest/types" "^27.0.6" + "@types/node" "*" + jest-mock "^27.0.6" + jest-util "^27.0.6" + jsdom "^16.6.0" + +jest-environment-node@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.0.6.tgz#a6699b7ceb52e8d68138b9808b0c404e505f3e07" + integrity sha512-+Vi6yLrPg/qC81jfXx3IBlVnDTI6kmRr08iVa2hFCWmJt4zha0XW7ucQltCAPhSR0FEKEoJ3i+W4E6T0s9is0w== + dependencies: + "@jest/environment" "^27.0.6" + "@jest/fake-timers" "^27.0.6" + "@jest/types" "^27.0.6" + "@types/node" "*" + jest-mock "^27.0.6" + jest-util "^27.0.6" + +jest-get-type@^26.3.0: + version "26.3.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" + integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== + +jest-get-type@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.6.tgz#0eb5c7f755854279ce9b68a9f1a4122f69047cfe" + integrity sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg== + +jest-haste-map@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.0.6.tgz#4683a4e68f6ecaa74231679dca237279562c8dc7" + integrity sha512-4ldjPXX9h8doB2JlRzg9oAZ2p6/GpQUNAeiYXqcpmrKbP0Qev0wdZlxSMOmz8mPOEnt4h6qIzXFLDi8RScX/1w== + dependencies: + "@jest/types" "^27.0.6" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + jest-regex-util "^27.0.6" + jest-serializer "^27.0.6" + jest-util "^27.0.6" + jest-worker "^27.0.6" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + +jest-jasmine2@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.0.6.tgz#fd509a9ed3d92bd6edb68a779f4738b100655b37" + integrity sha512-cjpH2sBy+t6dvCeKBsHpW41mjHzXgsavaFMp+VWRf0eR4EW8xASk1acqmljFtK2DgyIECMv2yCdY41r2l1+4iA== + dependencies: + "@babel/traverse" "^7.1.0" + "@jest/environment" "^27.0.6" + "@jest/source-map" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/types" "^27.0.6" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + expect "^27.0.6" + is-generator-fn "^2.0.0" + jest-each "^27.0.6" + jest-matcher-utils "^27.0.6" + jest-message-util "^27.0.6" + jest-runtime "^27.0.6" + jest-snapshot "^27.0.6" + jest-util "^27.0.6" + pretty-format "^27.0.6" + throat "^6.0.1" + +jest-leak-detector@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.0.6.tgz#545854275f85450d4ef4b8fe305ca2a26450450f" + integrity sha512-2/d6n2wlH5zEcdctX4zdbgX8oM61tb67PQt4Xh8JFAIy6LRKUnX528HulkaG6nD5qDl5vRV1NXejCe1XRCH5gQ== + dependencies: + jest-get-type "^27.0.6" + pretty-format "^27.0.6" + +jest-matcher-utils@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz#2a8da1e86c620b39459f4352eaa255f0d43e39a9" + integrity sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA== + dependencies: + chalk "^4.0.0" + jest-diff "^27.0.6" + jest-get-type "^27.0.6" + pretty-format "^27.0.6" + +jest-message-util@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.0.6.tgz#158bcdf4785706492d164a39abca6a14da5ab8b5" + integrity sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.0.6" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" + micromatch "^4.0.4" + pretty-format "^27.0.6" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.0.6.tgz#0efdd40851398307ba16778728f6d34d583e3467" + integrity sha512-lzBETUoK8cSxts2NYXSBWT+EJNzmUVtVVwS1sU9GwE1DLCfGsngg+ZVSIe0yd0ZSm+y791esiuo+WSwpXJQ5Bw== + dependencies: + "@jest/types" "^27.0.6" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + +jest-regex-util@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.6.tgz#02e112082935ae949ce5d13b2675db3d8c87d9c5" + integrity sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ== + +jest-resolve-dependencies@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.6.tgz#3e619e0ef391c3ecfcf6ef4056207a3d2be3269f" + integrity sha512-mg9x9DS3BPAREWKCAoyg3QucCr0n6S8HEEsqRCKSPjPcu9HzRILzhdzY3imsLoZWeosEbJZz6TKasveczzpJZA== + dependencies: + "@jest/types" "^27.0.6" + jest-regex-util "^27.0.6" + jest-snapshot "^27.0.6" + +jest-resolve@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.0.6.tgz#e90f436dd4f8fbf53f58a91c42344864f8e55bff" + integrity sha512-yKmIgw2LgTh7uAJtzv8UFHGF7Dm7XfvOe/LQ3Txv101fLM8cx2h1QVwtSJ51Q/SCxpIiKfVn6G2jYYMDNHZteA== + dependencies: + "@jest/types" "^27.0.6" + chalk "^4.0.0" + escalade "^3.1.1" + graceful-fs "^4.2.4" + jest-pnp-resolver "^1.2.2" + jest-util "^27.0.6" + jest-validate "^27.0.6" + resolve "^1.20.0" + slash "^3.0.0" + +jest-runner@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.0.6.tgz#1325f45055539222bbc7256a6976e993ad2f9520" + integrity sha512-W3Bz5qAgaSChuivLn+nKOgjqNxM7O/9JOJoKDCqThPIg2sH/d4A/lzyiaFgnb9V1/w29Le11NpzTJSzga1vyYQ== + dependencies: + "@jest/console" "^27.0.6" + "@jest/environment" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.4" + jest-docblock "^27.0.6" + jest-environment-jsdom "^27.0.6" + jest-environment-node "^27.0.6" + jest-haste-map "^27.0.6" + jest-leak-detector "^27.0.6" + jest-message-util "^27.0.6" + jest-resolve "^27.0.6" + jest-runtime "^27.0.6" + jest-util "^27.0.6" + jest-worker "^27.0.6" + source-map-support "^0.5.6" + throat "^6.0.1" + +jest-runtime@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.0.6.tgz#45877cfcd386afdd4f317def551fc369794c27c9" + integrity sha512-BhvHLRVfKibYyqqEFkybsznKwhrsu7AWx2F3y9G9L95VSIN3/ZZ9vBpm/XCS2bS+BWz3sSeNGLzI3TVQ0uL85Q== + dependencies: + "@jest/console" "^27.0.6" + "@jest/environment" "^27.0.6" + "@jest/fake-timers" "^27.0.6" + "@jest/globals" "^27.0.6" + "@jest/source-map" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.4" + jest-haste-map "^27.0.6" + jest-message-util "^27.0.6" + jest-mock "^27.0.6" + jest-regex-util "^27.0.6" + jest-resolve "^27.0.6" + jest-snapshot "^27.0.6" + jest-util "^27.0.6" + jest-validate "^27.0.6" + slash "^3.0.0" + strip-bom "^4.0.0" + yargs "^16.0.3" + +jest-serializer@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.0.6.tgz#93a6c74e0132b81a2d54623251c46c498bb5bec1" + integrity sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.4" + +jest-snapshot@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.0.6.tgz#f4e6b208bd2e92e888344d78f0f650bcff05a4bf" + integrity sha512-NTHaz8He+ATUagUgE7C/UtFcRoHqR2Gc+KDfhQIyx+VFgwbeEMjeP+ILpUTLosZn/ZtbNdCF5LkVnN/l+V751A== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/parser" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.0.6" + graceful-fs "^4.2.4" + jest-diff "^27.0.6" + jest-get-type "^27.0.6" + jest-haste-map "^27.0.6" + jest-matcher-utils "^27.0.6" + jest-message-util "^27.0.6" + jest-resolve "^27.0.6" + jest-util "^27.0.6" + natural-compare "^1.4.0" + pretty-format "^27.0.6" + semver "^7.3.2" + +jest-util@^27.0.0, jest-util@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.0.6.tgz#e8e04eec159de2f4d5f57f795df9cdc091e50297" + integrity sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ== + dependencies: + "@jest/types" "^27.0.6" + "@types/node" "*" + chalk "^4.0.0" + graceful-fs "^4.2.4" + is-ci "^3.0.0" + picomatch "^2.2.3" + +jest-validate@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.0.6.tgz#930a527c7a951927df269f43b2dc23262457e2a6" + integrity sha512-yhZZOaMH3Zg6DC83n60pLmdU1DQE46DW+KLozPiPbSbPhlXXaiUTDlhHQhHFpaqIFRrInko1FHXjTRpjWRuWfA== + dependencies: + "@jest/types" "^27.0.6" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.0.6" + leven "^3.1.0" + pretty-format "^27.0.6" + +jest-watcher@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.0.6.tgz#89526f7f9edf1eac4e4be989bcb6dec6b8878d9c" + integrity sha512-/jIoKBhAP00/iMGnTwUBLgvxkn7vsOweDrOTSPzc7X9uOyUtJIDthQBTI1EXz90bdkrxorUZVhJwiB69gcHtYQ== + dependencies: + "@jest/test-result" "^27.0.6" + "@jest/types" "^27.0.6" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.0.6" + string-length "^4.0.1" + +jest-worker@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.6.tgz#a5fdb1e14ad34eb228cfe162d9f729cdbfa28aed" + integrity sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.0.6.tgz#10517b2a628f0409087fbf473db44777d7a04505" + integrity sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA== + dependencies: + "@jest/core" "^27.0.6" + import-local "^3.0.2" + jest-cli "^27.0.6" + jimp@^0.16.1: version "0.16.1" resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.16.1.tgz#192f851a30e5ca11112a3d0aa53137659a78ca7a" @@ -1473,18 +2632,69 @@ jpeg-js@0.4.2: resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.2.tgz#8b345b1ae4abde64c2da2fe67ea216a114ac279d" integrity sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw== -js-yaml@4.0.0: +js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" - integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q== + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: - argparse "^2.0.1" + argparse "^1.0.7" + esprima "^4.0.0" + +jsdom@^16.6.0: + version "16.6.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.6.0.tgz#f79b3786682065492a3da6a60a4695da983805ac" + integrity sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg== + dependencies: + abab "^2.0.5" + acorn "^8.2.4" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + form-data "^3.0.0" + html-encoding-sniffer "^2.0.1" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.5.0" + ws "^7.4.5" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== +json5@2.x, json5@^2.1.2, json5@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -1501,11 +2711,29 @@ keyv@^4.0.0: dependencies: json-buffer "3.0.1" +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + leven@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + load-bmfont@^1.3.1, load-bmfont@^1.4.0: version "1.4.1" resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.1.tgz#c0f5f4711a1e2ccff725a7b6078087ccfcddd3e9" @@ -1520,49 +2748,23 @@ load-bmfont@^1.3.1, load-bmfont@^1.4.0: xhr "^2.0.1" xtend "^4.0.0" -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" + p-locate "^4.1.0" -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash@^4.17.21: +lodash@4.x, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" - integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== - dependencies: - chalk "^4.0.0" - long@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - lowercase-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" @@ -1575,64 +2777,82 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + lunr@^2.3.9: version "2.3.9" resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== -make-error@^1.1.1: +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-error@1.x, make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" -marked@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.3.tgz#3551c4958c4da36897bda2a16812ef1399c8d6b0" - integrity sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA== +marked@~2.0.3: + version "2.0.7" + resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.7.tgz#bc5b857a09071b48ce82a1f7304913a993d4b7d1" + integrity sha512-BJXxkuIfJchcXOJWTT2DOL+yFWifFv2yGYOUzvXg8Qz610QKw+sHCvTMYwA+qWGhlA2uivBezChZ/pBy1tWdkQ== media-typer@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== -meow@^3.3.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -mime-db@1.47.0: - version "1.47.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" - integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== +micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.48.0: + version "1.48.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" + integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== mime-types@^2.1.12: - version "2.1.30" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" - integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== + version "2.1.31" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" + integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== dependencies: - mime-db "1.47.0" + mime-db "1.48.0" mime@^1.3.4: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + mimic-response@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" @@ -1650,18 +2870,23 @@ min-document@^2.19.0: dependencies: dom-walk "^0.1.0" -minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.4: +minimatch@^3.0.0, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" -minimist@^1.1.3, minimist@^1.2.5: +minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +mkdirp@1.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + mkdirp@^0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -1669,42 +2894,6 @@ mkdirp@^0.5.1: dependencies: minimist "^1.2.5" -mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mocha@^8.1.3: - version "8.3.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.3.2.tgz#53406f195fa86fbdebe71f8b1c6fb23221d69fcc" - integrity sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.1" - debug "4.3.1" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.6" - growl "1.10.5" - he "1.2.0" - js-yaml "4.0.0" - log-symbols "4.0.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.1.20" - serialize-javascript "5.0.1" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - wide-align "1.1.3" - workerpool "6.1.0" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - mri@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.4.tgz#7cb1dd1b9b40905f1fac053abe25b6720f44744a" @@ -1715,85 +2904,64 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - music-metadata@^7.4.1: - version "7.8.3" - resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-7.8.3.tgz#876c46f0c3f4cf27f40b2c0393463e6a71700f69" - integrity sha512-sF0oEmN88IJCuAR+1ZwyPqDvIrACddBJbWfRUQo3KZ6YN+V/EAex5AVWwlQxvY2XMcMJ+pPZEnALVnz9IXvU4A== + version "7.8.8" + resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-7.8.8.tgz#3f1c5a38eb54642a96f0d66fb9e704088fb8b427" + integrity sha512-NUtXW6FQA1fvBp4Q5o78Df6LHWqyny8bHxArJ79i5lr2N28jEd9HYyH09CAHKLjwiv58QLRa8r3P5nX36Spcxw== dependencies: content-type "^1.0.4" debug "^4.3.1" - file-type "^16.3.0" + file-type "^16.5.0" media-typer "^1.1.0" strtok3 "^6.0.8" token-types "^2.1.1" -nanoid@3.1.20: - version "3.1.20" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" - integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= neo-async@^2.6.0: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= -normalize-path@^3.0.0, normalize-path@~3.0.0: +node-modules-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" + integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= + +node-releases@^1.1.71: + version "1.1.73" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20" + integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg== + +normalize-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@^4.1.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" - integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== -object-assign@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-inspect@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" - integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== - -object-is@^1.0.1: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" + path-key "^3.0.0" -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" +nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== omggif@^1.0.10, omggif@^1.0.9: version "1.0.10" @@ -1807,6 +2975,13 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + onigasm@^2.2.5: version "2.2.5" resolved "https://registry.yarnpkg.com/onigasm/-/onigasm-2.2.5.tgz#cc4d2a79a0fa0b64caec1f4c7ea367585a676892" @@ -1814,24 +2989,46 @@ onigasm@^2.2.5: dependencies: lru-cache "^5.1.1" +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + p-cancelable@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.0.tgz#4d51c3b91f483d02a0d300765321fca393d758dd" - integrity sha512-HAZyB3ZodPo+BDpb4/Iu7Jv4P6cSazBz9ZM0ChhEXp70scx834aWCEjQRwgt41UzzejUAPdbqqONfRWTPYrPAQ== + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" +p-each-series@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" + integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: - p-limit "^3.0.2" + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@^1.0.5: version "1.0.11" @@ -1861,19 +3058,10 @@ parse-headers@^2.0.0: resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA== -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== path-exists@^4.0.0: version "4.0.0" @@ -1885,19 +3073,15 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" +path-parse@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== peek-readable@^3.1.3: version "3.1.3" @@ -1909,32 +3093,15 @@ phin@^2.9.1: resolved "https://registry.yarnpkg.com/phin/-/phin-2.9.3.tgz#f9b6ac10a035636fb65dfc576aaaa17b8743125c" integrity sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA== -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.2.3" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" - integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== - -pify@^2.0.0: +picomatch@^2.0.4, picomatch@^2.2.3: version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== pino-pretty@^4.3.0: - version "4.7.1" - resolved "https://registry.yarnpkg.com/pino-pretty/-/pino-pretty-4.7.1.tgz#499cf185e110399deae731221c899915c811bd1a" - integrity sha512-ILE5YBpur88FlZ0cr1BNqVjgG9fOoK+md3peqmcs7AC6oq7SNiaJioIcrykMxfNsuygMYjUJtvAcARRE9aRc9w== + version "4.8.0" + resolved "https://registry.yarnpkg.com/pino-pretty/-/pino-pretty-4.8.0.tgz#f2f3055bf222456217b14ffb04d8be0a0cc17fce" + integrity sha512-mhQfHG4rw5ZFpWL44m0Utjo4GC2+HMfdNvxyA8lLw0sIqn6fCf7uQe6dPckUcW/obly+OQHD7B/MTso6LNizYw== dependencies: "@hapi/bourne" "^2.0.0" args "^5.0.1" @@ -1945,6 +3112,7 @@ pino-pretty@^4.3.0: joycon "^2.2.5" pump "^3.0.0" readable-stream "^3.6.0" + rfdc "^1.3.0" split2 "^3.1.1" strip-json-comments "^3.1.1" @@ -1954,17 +3122,24 @@ pino-std-serializers@^3.1.0: integrity sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg== pino@^6.7.0: - version "6.11.2" - resolved "https://registry.yarnpkg.com/pino/-/pino-6.11.2.tgz#2f3d119c526651aab4ec3d280844785d52d0b690" - integrity sha512-bmzxwbrIPxQUlAuMkF4PWVErUGERU4z37HazlhflKFg08crsNE3fACGN6gPwg5xtKOK47Ux5cZm8YCuLV4wWJg== + version "6.11.3" + resolved "https://registry.yarnpkg.com/pino/-/pino-6.11.3.tgz#0c02eec6029d25e6794fdb6bbea367247d74bc29" + integrity sha512-drPtqkkSf0ufx2gaea3TryFiBHdNIdXKf5LN0hTM82SXI4xVIve2wLwNg92e1MT6m3jASLu6VO7eGY6+mmGeyw== dependencies: fast-redact "^3.0.0" fast-safe-stringify "^2.0.7" flatstr "^1.0.12" pino-std-serializers "^3.1.0" - quick-format-unescaped "4.0.1" + quick-format-unescaped "^4.0.3" sonic-boom "^1.0.2" +pirates@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" + integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== + dependencies: + node-modules-regexp "^1.0.0" + pixelmatch@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854" @@ -1972,11 +3147,43 @@ pixelmatch@^4.0.2: dependencies: pngjs "^3.0.0" +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + pngjs@^3.0.0, pngjs@^3.3.3: version "3.4.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +pretty-format@^26.0.0, pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== + dependencies: + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" + +pretty-format@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.0.6.tgz#ab770c47b2c6f893a21aefc57b75da63ef49a11f" + integrity sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ== + dependencies: + "@jest/types" "^27.0.6" + ansi-regex "^5.0.0" + ansi-styles "^5.0.0" + react-is "^17.0.1" + process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" @@ -1987,10 +3194,18 @@ progress@^2.0.3: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +prompts@^2.0.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.1.tgz#befd3b1195ba052f9fd2fde8a486c4e82ee77f61" + integrity sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + protobufjs@^6.10.1: - version "6.10.2" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.2.tgz#b9cb6bd8ec8f87514592ba3fdfd28e93f33a469b" - integrity sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ== + version "6.11.2" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b" + integrity sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -2003,9 +3218,14 @@ protobufjs@^6.10.1: "@protobufjs/pool" "^1.1.0" "@protobufjs/utf8" "^1.1.0" "@types/long" "^4.0.1" - "@types/node" "^13.7.0" + "@types/node" ">=13.7.0" long "^4.0.0" +psl@^1.1.33: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -2014,44 +3234,30 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" +punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + qrcode-terminal@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819" integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== -quick-format-unescaped@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.1.tgz#437a5ea1a0b61deb7605f8ab6a8fd3858dbeb701" - integrity sha512-RyYpQ6Q5/drsJyOhrWHYMWTedvjTIat+FTwv0K4yoUxzvekw2aRHMQJLlnvt8UantkZg2++bEzD9EdxXqkWf4A== +quick-format-unescaped@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.3.tgz#6d6b66b8207aa2b35eef12be1421bb24c428f652" + integrity sha512-MaL/oqh02mhEo5m5J2rwsVL23Iw2PEaGVHgT2vFt8AAsr0lfvQA5dpXo9TPu0rz7tSBdUPgkbam0j/fj5ZM8yg== quick-lru@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== readable-stream@^3.0.0, readable-stream@^3.6.0: version "3.6.0" @@ -2070,13 +3276,6 @@ readable-web-to-node-stream@^3.0.0: "@types/readable-stream" "^2.3.9" readable-stream "^3.6.0" -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== - dependencies: - picomatch "^2.2.1" - rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -2084,37 +3283,34 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: version "0.13.7" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= - dependencies: - is-finite "^1.0.0" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= resolve-alpn@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.1.1.tgz#4a006a7d533c81a5dd04681612090fde227cd6e1" - integrity sha512-0KbFjFPR2bnJhNx1t8Ad6RqVc8+QPJC4y561FYyC/Q/6OzB3fhUzB5PEgitYhPK6aifwR5gXBSnDMllaDWixGQ== + version "1.1.2" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.1.2.tgz#30b60cfbb0c0b8dc897940fe13fe255afcdd4d28" + integrity sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA== -resolve@^1.0.0, resolve@^1.1.6, resolve@^1.10.0: +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.1.6, resolve@^1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -2129,34 +3325,68 @@ responselike@^2.0.0: dependencies: lowercase-keys "^2.0.0" -rimraf@^2.6.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" -safe-buffer@*, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@*, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + sax@>=0.6.0: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -"semver@2 || 3 || 4 || 5": - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -serialize-javascript@5.0.1: +saxes@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" - integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== dependencies: - randombytes "^2.1.0" + xmlchars "^2.2.0" + +semver@7.x, semver@^7.3.2: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shelljs@^0.8.4: version "0.8.4" @@ -2168,18 +3398,29 @@ shelljs@^0.8.4: rechoir "^0.6.2" shiki@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.9.3.tgz#7bf7bcf3ed50ca525ec89cc09254abce4264d5ca" - integrity sha512-NEjg1mVbAUrzRv2eIcUt3TG7X9svX7l3n3F5/3OdFq+/BxUdmBOeKGiH4icZJBLHy354Shnj6sfBTemea2e7XA== + version "0.9.5" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.9.5.tgz#c8da81a05fbfd1810729c6873901a729a72ec541" + integrity sha512-XFn+rl3wIowDjzdr5DlHoHgQphXefgUTs2bNp/bZu4WF9gTrTLnKwio3f28VjiFG6Jpip7yQn/p4mMj6OrjrtQ== dependencies: + json5 "^2.2.0" onigasm "^2.2.5" - vscode-textmate "^5.2.0" + vscode-textmate "5.2.0" -signal-exit@^3.0.0: +signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + sonic-boom@^1.0.2: version "1.4.1" resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.4.1.tgz#d35d6a74076624f12e6f917ade7b9d75e918f53e" @@ -2188,7 +3429,7 @@ sonic-boom@^1.0.2: atomic-sleep "^1.0.0" flatstr "^1.0.12" -source-map-support@^0.5.12, source-map-support@^0.5.17: +source-map-support@^0.5.17, source-map-support@^0.5.6: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -2196,36 +3437,20 @@ source-map-support@^0.5.12, source-map-support@^0.5.17: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.6.0, source-map@^0.6.1: +source-map@^0.5.0: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.7" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" - integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== split2@^3.1.1: version "3.2.2" @@ -2234,13 +3459,25 @@ split2@^3.1.1: dependencies: readable-stream "^3.0.0" -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +stack-utils@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" + integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" + escape-string-regexp "^2.0.0" + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" string-width@^4.1.0, string-width@^4.2.0: version "4.2.2" @@ -2251,22 +3488,6 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -2274,13 +3495,6 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - strip-ansi@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" @@ -2288,35 +3502,21 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" -strip-bom@^2.0.0: +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= - dependencies: - get-stdin "^4.0.1" - -strip-json-comments@3.1.1, strip-json-comments@^3.1.1: +strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strip-json-comments@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - strtok3@^6.0.3, strtok3@^6.0.8: version "6.0.8" resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.0.8.tgz#c839157f615c10ba0f4ae35067dad9959eeca346" @@ -2326,13 +3526,6 @@ strtok3@^6.0.3, strtok3@^6.0.8: "@types/debug" "^4.1.5" peek-readable "^3.1.3" -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -2340,13 +3533,55 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.1.0: +supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + timm@^1.6.1: version "1.7.1" resolved "https://registry.yarnpkg.com/timm/-/timm-1.7.1.tgz#96bab60c7d45b5a10a8a4d0f0117c6b7e5aff76f" @@ -2357,6 +3592,16 @@ tinycolor2@^1.4.1: resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803" integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA== +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -2372,38 +3617,47 @@ token-types@^2.0.0, token-types@^2.1.1: "@tokenizer/token" "^0.1.1" ieee754 "^1.2.1" -tree-kill@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" - integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== - -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= - -ts-node-dev@^1.0.0: - version "1.1.6" - resolved "https://registry.yarnpkg.com/ts-node-dev/-/ts-node-dev-1.1.6.tgz#ee2113718cb5a92c1c8f4229123ad6afbeba01f8" - integrity sha512-RTUi7mHMNQospArGz07KiraQcdgUVNXKsgO2HAi7FoiyPMdTDqdniB6K1dqyaIxT7c9v/VpSbfBZPS6uVpaFLQ== +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== dependencies: - chokidar "^3.5.1" - dateformat "~1.0.4-1.2.3" - dynamic-dedupe "^0.3.0" - minimist "^1.2.5" - mkdirp "^1.0.4" - resolve "^1.0.0" - rimraf "^2.6.1" - source-map-support "^0.5.12" - tree-kill "^1.2.2" - ts-node "^9.0.0" - tsconfig "^7.0.0" + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" -ts-node@^9.0.0: - version "9.1.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" - integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== dependencies: + punycode "^2.1.1" + +ts-jest@^27.0.3: + version "27.0.3" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.0.3.tgz#808492f022296cde19390bb6ad627c8126bf93f8" + integrity sha512-U5rdMjnYam9Ucw+h0QvtNDbc5+88nxt7tbIvqaZUhFrfG4+SkWhMXjejCLVGcpILTPuV+H3W/GZDZrnZFpPeXw== + dependencies: + bs-logger "0.x" + buffer-from "1.x" + fast-json-stable-stringify "2.x" + jest-util "^27.0.0" + json5 "2.x" + lodash "4.x" + make-error "1.x" + mkdirp "1.x" + semver "7.x" + yargs-parser "20.x" + +ts-node@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.0.0.tgz#05f10b9a716b0b624129ad44f0ea05dac84ba3be" + integrity sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg== + dependencies: + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.1" arg "^4.1.0" create-require "^1.1.0" diff "^4.0.1" @@ -2411,15 +3665,22 @@ ts-node@^9.0.0: source-map-support "^0.5.17" yn "3.1.1" -tsconfig@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-7.0.0.tgz#84538875a4dc216e5c4a5432b3a4dec3d54e91b7" - integrity sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw== +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= dependencies: - "@types/strip-bom" "^3.0.0" - "@types/strip-json-comments" "0.0.30" - strip-bom "^3.0.0" - strip-json-comments "^2.0.0" + prelude-ls "~1.1.2" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== typedarray-to-buffer@^3.1.5: version "3.1.5" @@ -2428,47 +3689,42 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typedoc-default-themes@^0.12.9: +typedoc-default-themes@^0.12.10: version "0.12.10" resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz#614c4222fe642657f37693ea62cad4dafeddf843" integrity sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA== typedoc@^0.20.0-beta.27: - version "0.20.35" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.20.35.tgz#c36996098cbeb2ef63d9d7991262a071b98336a3" - integrity sha512-7sNca19LXg2hgyGHq3b33tQ1YFApmd8aBDEzWQ2ry4VDkw/NdFWkysGiGRY1QckDCB0gVH8+MlXA4K71IB3azg== + version "0.20.37" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.20.37.tgz#9b9417149cb815e3d569fc300b5d2c6e4e6c5d93" + integrity sha512-9+qDhdc4X00qTNOtii6QX2z7ndAeWVOso7w3MPSoSJdXlVhpwPfm1yEp4ooKuWA9fiQILR8FKkyjmeqa13hBbw== dependencies: colors "^1.4.0" fs-extra "^9.1.0" handlebars "^4.7.7" lodash "^4.17.21" lunr "^2.3.9" - marked "^2.0.1" + marked "~2.0.3" minimatch "^3.0.0" progress "^2.0.3" shelljs "^0.8.4" shiki "^0.9.3" - typedoc-default-themes "^0.12.9" + typedoc-default-themes "^0.12.10" typescript@^4.0.0: - version "4.2.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" - integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== + version "4.3.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" + integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== uglify-js@^3.1.4: - version "3.13.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.4.tgz#592588bb9f47ae03b24916e2471218d914955574" - integrity sha512-kv7fCkIXyQIilD5/yQy8O+uagsYIOt5cZvs890W40/e/rvjMSzJw81o9Bg0tkURxzZBROtDQhW2LFjOGoK3RZw== + version "3.13.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.10.tgz#a6bd0d28d38f592c3adb6b180ea6e07e1e540a8d" + integrity sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg== -unbox-primitive@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - which-boxed-primitive "^1.0.2" +universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== universalify@^2.0.0: version "2.0.0" @@ -2487,79 +3743,89 @@ util-deprecate@^1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util@^0.12.0: - version "0.12.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888" - integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog== +v8-to-istanbul@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz#4229f2a99e367f3f018fa1d5c2b8ec684667c69c" + integrity sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg== dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - safe-buffer "^5.1.2" - which-typed-array "^1.1.2" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" +vscode-textmate@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e" + integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ== -vscode-textmate@^5.2.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.4.0.tgz#4b25ffc1f14ac3a90faf9a388c67a01d24257cd7" - integrity sha512-c0Q4zYZkcLizeYJ3hNyaVUM2AA8KDhNCA3JvXY8CeZSJuBdAy3bAvSbv46RClC4P3dSO9BdwhnKEx2zOo6vP/w== - -which-boxed-primitive@^1.0.2: +w3c-hr-time@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" + browser-process-hrtime "^1.0.0" -which-typed-array@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff" - integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== dependencies: - available-typed-arrays "^1.0.2" - call-bind "^1.0.0" - es-abstract "^1.18.0-next.1" - foreach "^2.0.5" - function-bind "^1.1.1" - has-symbols "^1.0.1" - is-typed-array "^1.1.3" + xml-name-validator "^3.0.0" -which@2.0.2: +walker@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + +whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== + dependencies: + lodash "^4.7.0" + tr46 "^2.1.0" + webidl-conversions "^6.1.0" + +which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== wordwrap@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= -workerpool@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.0.tgz#a8e038b4c94569596852de7a8ea4228eefdeb37b" - integrity sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg== - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -2574,10 +3840,20 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@^7.3.1: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^7.3.1, ws@^7.4.5: + version "7.5.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.2.tgz#09cc8fea3bec1bc5ed44ef51b42f945be36900f6" + integrity sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ== xhr@^2.0.1: version "2.6.0" @@ -2589,6 +3865,11 @@ xhr@^2.0.1: parse-headers "^2.0.0" xtend "^4.0.0" +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + xml-parse-from-string@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" @@ -2607,6 +3888,11 @@ xmlbuilder@~11.0.0: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + xtend@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -2622,27 +3908,17 @@ yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-parser@^20.2.2: - version "20.2.7" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" - integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== +yargs-parser@20.x, yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0: +yargs@^16.0.3: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== @@ -2659,8 +3935,3 @@ yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 71e34fc5f8e4dc9ac72037026b21442b10dfeb3c Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 12 Jul 2021 23:50:08 +0530 Subject: [PATCH 003/311] Cleanup + add remaining utils --- src/Connection/auth.ts | 5 +- src/Connection/index.ts | 7 +- src/Connection/messages.ts | 37 +++++---- src/Connection/socket.ts | 3 +- src/Defaults/index.ts | 2 + src/Store/in-memory-store.ts | 130 +++++++++++++++++++++---------- src/Store/index.ts | 4 +- src/Store/ordered-dictionary.ts | 66 ++++++++++++++++ src/Types/Chat.ts | 3 +- src/Types/Message.ts | 26 +++++-- src/Types/index.ts | 2 + src/Utils/index.ts | 5 ++ src/Utils/messages.ts | 3 - src/Utils/validate-connection.ts | 12 ++- src/index.ts | 3 +- 15 files changed, 234 insertions(+), 74 deletions(-) create mode 100644 src/Store/ordered-dictionary.ts create mode 100644 src/Utils/index.ts diff --git a/src/Connection/auth.ts b/src/Connection/auth.ts index 87f42c2..8834191 100644 --- a/src/Connection/auth.ts +++ b/src/Connection/auth.ts @@ -3,8 +3,7 @@ import EventEmitter from "events" import * as Curve from 'curve25519-js' import { BaileysEventEmitter, BaileysEventMap, SocketConfig, CurveKeyPair, WAInitResponse, ConnectionState, DisconnectReason } from "../Types" import { makeSocket } from "./socket" -import { generateClientID, promiseTimeout } from "../Utils/generics" -import { normalizedAuthInfo, computeChallengeResponse, validateNewConnection } from "../Utils/validate-connection" +import { generateClientID, promiseTimeout, normalizedAuthInfo, computeChallengeResponse, validateNewConnection } from "../Utils" import { randomBytes } from "crypto" import { AuthenticationCredentials } from "../Types" @@ -106,7 +105,7 @@ const makeAuthSocket = (config: SocketConfig) => { } ) .finally(() => ( - ev.off('state.update', listener) + ev.off('connection.update', listener) )) ) } diff --git a/src/Connection/index.ts b/src/Connection/index.ts index 4fe93a9..6c3eedd 100644 --- a/src/Connection/index.ts +++ b/src/Connection/index.ts @@ -1,12 +1,15 @@ import { SocketConfig } from '../Types' import { DEFAULT_CONNECTION_CONFIG } from '../Defaults' import { EventEmitter } from 'events' -import * as Connection from './groups' +import _makeConnection from './groups' // export the last socket layer const makeConnection = (config: Partial) => ( - Connection.default({ + _makeConnection({ ...DEFAULT_CONNECTION_CONFIG, ...config }) ) + +export type Connection = ReturnType + export default makeConnection \ No newline at end of file diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index e6481e0..1b83d8b 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -1,12 +1,10 @@ import BinaryNode from "../BinaryNode"; import { Boom } from '@hapi/boom' import { EventEmitter } from 'events' -import { Chat, Presence, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo } from "../Types"; -import { isGroupID, toNumber, whatsappID } from "../Utils/generics"; +import { Chat, Presence, WAMessageCursor, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo } from "../Types"; +import { isGroupID, toNumber, whatsappID, generateWAMessage, decryptMediaMessageBuffer } from "../Utils"; import makeChatsSocket from "./chats"; import { WA_DEFAULT_EPHEMERAL } from "../Defaults"; -import { generateWAMessage } from "../Utils/messages"; -import { decryptMediaMessageBuffer } from "../Utils/messages-media"; const STATUS_MAP = { read: WAMessageStatus.READ, @@ -47,9 +45,12 @@ const makeMessagesSocket = (config: SocketConfig) => { const fetchMessagesFromWA = async( jid: string, count: number, - indexMessage?: { id?: string; fromMe?: boolean }, - mostRecentFirst: boolean = true + cursor?: WAMessageCursor ) => { + let key: WAMessageKey + if(cursor) { + key = 'before' in cursor ? cursor.before : cursor.after + } const { data }:BinaryNode = await query({ json: new BinaryNode( 'query', @@ -57,10 +58,10 @@ const makeMessagesSocket = (config: SocketConfig) => { epoch: currentEpoch().toString(), type: 'message', jid: jid, - kind: mostRecentFirst ? 'before' : 'after', + kind: !cursor || 'before' in cursor ? 'before' : 'after', count: count.toString(), - index: indexMessage?.id, - owner: indexMessage?.fromMe === false ? 'false' : 'true', + index: key?.id, + owner: key?.fromMe === false ? 'false' : 'true', } ), binaryTag: [WAMetric.queryMessages, WAFlag.ignore], @@ -91,7 +92,7 @@ const makeMessagesSocket = (config: SocketConfig) => { }) Object.keys(response[1]).forEach (key => content[key] = response[1][key]) // update message - ev.emit('messages.upsert', { messages: [message], type: 'append' }) + ev.emit('messages.update', [{ key: message.key, message: message.message }]) return response } @@ -365,6 +366,18 @@ const makeMessagesSocket = (config: SocketConfig) => { }, updateMediaMessage, fetchMessagesFromWA, + /** Load a single message specified by the ID */ + loadMessageFromWA: async(jid: string, id: string) => { + let message: WAMessage + + // load the message before the given message + let messages = (await fetchMessagesFromWA(jid, 1, { before: {id, fromMe: true} })) + if(!messages[0]) messages = (await fetchMessagesFromWA(jid, 1, { before: {id, fromMe: false} })) + // the message after the loaded message is the message required + const [actual] = await fetchMessagesFromWA(jid, 1, { after: messages[0] && messages[0].key }) + message = actual + return message + }, searchMessages: async(txt: string, inJid: string | null, count: number, page: number) => { const {data, attributes}: BinaryNode = await query({ json: new BinaryNode( @@ -419,10 +432,6 @@ const makeMessagesSocket = (config: SocketConfig) => { { ...options, userJid: userJid, - /*ephemeralOptions: chat?.ephemeral ? { - expiration: chat.ephemeral, - eph_setting_ts: chat.eph_setting_ts - } : undefined,*/ getUrlInfo: generateUrlInfo, getMediaOptions: refreshMediaConn } diff --git a/src/Connection/socket.ts b/src/Connection/socket.ts index d86c072..d6ae622 100644 --- a/src/Connection/socket.ts +++ b/src/Connection/socket.ts @@ -5,8 +5,7 @@ import { promisify } from "util" import WebSocket from "ws" import BinaryNode from "../BinaryNode" import { DisconnectReason, SocketConfig, SocketQueryOptions, SocketSendMessageOptions } from "../Types" -import { aesEncrypt, hmacSign, promiseTimeout, unixTimestampSeconds } from "../Utils/generics" -import { decodeWAMessage } from "../Utils/decode-wa-message" +import { aesEncrypt, hmacSign, promiseTimeout, unixTimestampSeconds, decodeWAMessage } from "../Utils" import { WAFlag, WAMetric, WATag } from "../Types" import { DEFAULT_ORIGIN, DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, PHONE_CONNECTION_CB } from "../Defaults" diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 669ad7f..caca01f 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -4,6 +4,8 @@ import { Browsers } from "../Utils/generics" export const UNAUTHORIZED_CODES = [401, 403, 419] +export const STORIES_JID = 'status@broadcast' + export const DEFAULT_ORIGIN = 'https://web.whatsapp.com' export const DEF_CALLBACK_PREFIX = 'CB:' export const DEF_TAG_PREFIX = 'TAG:' diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index 33043e7..5b092dc 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -1,39 +1,44 @@ import KeyedDB from "@adiwajshing/keyed-db" +import { Comparable } from "@adiwajshing/keyed-db/lib/Types" import { Logger } from "pino" -import makeConnection from "../Connection" -import { BaileysEventEmitter, Chat, ConnectionState, Contact, WAMessage, WAMessageKey } from "../Types" +import type { Connection } from "../Connection" +import type { BaileysEventEmitter, Chat, ConnectionState, Contact, WAMessage, WAMessageCursor } from "../Types" +import { toNumber } from "../Utils" +import makeOrderedDictionary from "./ordered-dictionary" export const waChatKey = (pin: boolean) => ({ key: (c: Chat) => (pin ? (c.pin ? '1' : '0') : '') + (c.archive === 'true' ? '0' : '1') + c.t.toString(16).padStart(8, '0') + c.jid, compare: (k1: string, k2: string) => k2.localeCompare (k1) }) +export const waMessageID = (m: WAMessage) => m.key.id + export type BaileysInMemoryStoreConfig = { + chatKey: Comparable logger: Logger } +const makeMessagesDictionary = () => makeOrderedDictionary(waMessageID) + export default( - { logger }: BaileysInMemoryStoreConfig + { logger, chatKey }: BaileysInMemoryStoreConfig ) => { - const chats = new KeyedDB(waChatKey(true), c => c.jid) - const messages: { [_: string]: WAMessage[] } = {} + + const chats = new KeyedDB(chatKey, c => c.jid) + const messages: { [_: string]: ReturnType } = {} const contacts: { [_: string]: Contact } = {} const state: ConnectionState = { connection: 'close', phoneConnected: false } - const messageIndex = (key: WAMessageKey) => { - const messageList = messages[key.remoteJid!] - if(messageList) { - const idx = messageList.findIndex(m => m.key.id === key.id) - if(idx >= 0) { - return { messageList, idx } - } - } + const assertMessageList = (jid: string) => { + if(!messages[jid]) messages[jid] = makeMessagesDictionary() + return messages[jid] } const listen = (ev: BaileysEventEmitter) => { + ev.on('connection.update', update => { Object.assign(state, update) }) @@ -91,55 +96,54 @@ export default( case 'notify': for(const msg of newMessages) { const jid = msg.key.remoteJid! - const result = messageIndex(newMessages[0].key) - if(!result) { - if(!messages[jid]) { - messages[jid] = [] - } - messages[jid].push(msg) - } else { - result.messageList[result.idx] = msg + const list = assertMessageList(jid) + list.upsert(msg, 'append') + + if(type === 'notify' && !chats.get(jid)) { + ev.emit('chats.upsert', { + chats: [ { jid, t: toNumber(msg.messageTimestamp), count: 1 } ], + type: 'upsert' + }) } } break case 'last': for(const msg of newMessages) { const jid = msg.key.remoteJid! - if(!messages[jid]) { - messages[jid] = [] - } - const [lastItem] = messages[jid].slice(-1) + const list = assertMessageList(jid) + const [lastItem] = list.array.slice(-1) // reset message list if(lastItem && lastItem.key.id !== msg.key.id) { - messages[jid] = [msg] + list.clear() + list.upsert(msg, 'append') } } break case 'prepend': - + for(const msg of newMessages) { + const jid = msg.key.remoteJid! + const list = assertMessageList(jid) + list.upsert(msg, 'prepend') + } break } }) ev.on('messages.update', updates => { for(const update of updates) { - const result = messageIndex(update.key!) - if(result) { - Object.assign(result.messageList[result.idx], update) - } else { + const list = assertMessageList(update.key.remoteJid) + const result = list.updateAssign(update) + if(!result) { logger.debug({ update }, `got update for non-existant message`) } } }) ev.on('messages.delete', item => { + const list = assertMessageList(item.jid) if('all' in item) { - messages[item.jid] = [] + list.clear() } else { const idSet = new Set(item.ids) - if(messages[item.jid]) { - messages[item.jid] = messages[item.jid].filter( - m => !idSet.has(m.key.id) - ) - } + list.filter(m => !idSet.has(m.key.id)) } }) } @@ -148,14 +152,60 @@ export default( chats, contacts, messages, + state, listen, - fetchImageUrl: async(jid: string, sock: ReturnType) => { + loadMessages: async(jid: string, count: number, cursor: WAMessageCursor, sock: Connection | undefined) => { + const list = assertMessageList(jid) + const retrieve = async(count: number, cursor: WAMessageCursor) => { + const result = await sock?.fetchMessagesFromWA(jid, count, cursor) + return result || [] + } + const mode = !cursor || 'before' in cursor ? 'before' : 'after' + const cursorKey = !!cursor ? ('before' in cursor ? cursor.before : cursor.after) : undefined + const cursorValue = cursorKey ? list.get(cursorKey.id) : undefined + + let messages: WAMessage[] + if(messages && mode ==='before' && (!cursorKey || cursorValue)) { + const msgIdx = messages.findIndex(m => m.key.id === cursorKey.id) + messages = list.array.slice(0, msgIdx) + + const diff = count - messages.length + if (diff < 0) { + messages = messages.slice(-count) // get the last X messages + } else if (diff > 0) { + const [fMessage] = messages + const extra = await retrieve (diff, { before: fMessage?.key || cursorKey }) + // add to DB + for(let i = extra.length-1; i >= 0;i--) { + list.upsert(extra[i], 'prepend') + } + } + } else messages = await retrieve(count, cursor) + + return messages + }, + loadMessage: async(jid: string, id: string, sock: Connection | undefined) => { + let message = messages[jid]?.get(id) + if(!message) { + message = await sock?.loadMessageFromWA(jid, id) + } + return message + }, + mostRecentMessage: async(jid: string, sock: Connection | undefined) => { + let message = messages[jid]?.array.slice(-1)[0] + if(!message) { + const [result] = await sock?.fetchMessagesFromWA(jid, 1, undefined) + message = result + } + return message + }, + fetchImageUrl: async(jid: string, sock: Connection | undefined) => { const contact = contacts[jid] if(!contact) { - return sock.fetchImageUrl(jid) + return sock?.fetchImageUrl(jid) } if(!contact.imgUrl) { - contact.imgUrl = await sock.fetchImageUrl(jid) + contact.imgUrl = await sock?.fetchImageUrl(jid) } return contact.imgUrl } diff --git a/src/Store/index.ts b/src/Store/index.ts index 7e6ed66..1bfc30c 100644 --- a/src/Store/index.ts +++ b/src/Store/index.ts @@ -1,2 +1,2 @@ -import inMemoryStore from "./in-memory-store"; -export default inMemoryStore \ No newline at end of file +import makeInMemoryStore from './in-memory-store' +export { makeInMemoryStore } \ No newline at end of file diff --git a/src/Store/ordered-dictionary.ts b/src/Store/ordered-dictionary.ts new file mode 100644 index 0000000..50272a0 --- /dev/null +++ b/src/Store/ordered-dictionary.ts @@ -0,0 +1,66 @@ + +const makeOrderedDictionary = function(idGetter: (item: T) => string) { + const array: T[] = [] + const dict: { [_: string]: T } = { } + + const get = (id: string) => dict[id] + + const update = (item: T) => { + const id = idGetter(item) + const idx = array.findIndex(i => idGetter(i) === id) + if(idx >= 0) { + array[idx] = item + dict[id] = item + } + return false + } + + const upsert = (item: T, mode: 'append' | 'prepend') => { + const id = idGetter(item) + if(get(id)) { + update(item) + } else { + if(mode === 'append') { + array.push(item) + } else { + array.splice(0, 0, item) + } + dict[id] = item + } + } + + const remove = (item: T) => { + const id = idGetter(item) + const idx = array.findIndex(i => idGetter(i) === id) + if(idx >= 0) { + array.splice(idx, 1) + delete dict[id] + return true + } + return false + } + + return { + array, + get, + upsert, + update, + remove, + updateAssign: (update: Partial) => { + const item = get(idGetter(update as any)) + if(item) { + Object.assign(item, update) + } + return false + }, + clear: () => { + array.splice(0, array.length) + Object.keys(dict).forEach(key => { delete dict[key] }) + }, + filter: (contain: (item: T) => boolean) => { + //const copy = + } + } +} +export default makeOrderedDictionary +//export type OrderedDictionary = ReturnType \ No newline at end of file diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 8f285cb..d35b929 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -54,4 +54,5 @@ export type ChatModification = messages: { id: string, fromMe?: boolean }[], star: boolean } - } \ No newline at end of file + } | + { delete: true } \ No newline at end of file diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 476181b..0c7e52d 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -78,7 +78,6 @@ export type AnyMediaMessageContent = ( { mimetype?: string } export type AnyRegularMessageContent = - string | ({ text: string } @@ -109,14 +108,15 @@ export type MiscMessageGenerationOptions = { timestamp?: Date /** the message you want to quote */ quoted?: WAMessage -} -export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & { - userJid: string + /** disappearing messages settings */ ephemeralOptions?: { expiration: number | string eph_setting_ts: number | string } } +export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & { + userJid: string +} export type MediaGenerationOptions = { logger?: Logger agent?: Agent @@ -132,4 +132,20 @@ export type MessageUpdateType = 'prepend' | 'append' | 'notify' | 'last' export interface MessageInfo { reads: {jid: string, t: string}[] deliveries: {jid: string, t: string}[] -} \ No newline at end of file +} + + +export interface MessageStatusUpdate { + from: string + to: string + /** Which participant caused the update (only for groups) */ + participant?: string + timestamp: Date + /** Message IDs read/delivered */ + ids: string[] + /** Status of the Message IDs */ + type: WAMessageStatus +} + + +export type WAMessageCursor = { before: WAMessageKey | undefined } | { after: WAMessageKey | undefined } \ No newline at end of file diff --git a/src/Types/index.ts b/src/Types/index.ts index efdd6c8..6da2733 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -195,5 +195,7 @@ export type BaileysEventMap = { } export interface BaileysEventEmitter extends EventEmitter { on(event: T, listener: (arg: BaileysEventMap[T]) => void): this + off(event: T, listener: (arg: BaileysEventMap[T]) => void): this + removeAllListeners(event: T): this emit(event: T, arg: BaileysEventMap[T]): boolean } \ No newline at end of file diff --git a/src/Utils/index.ts b/src/Utils/index.ts new file mode 100644 index 0000000..15973e8 --- /dev/null +++ b/src/Utils/index.ts @@ -0,0 +1,5 @@ +export * from './decode-wa-message' +export * from './generics' +export * from './messages' +export * from './messages-media' +export * from './validate-connection' \ No newline at end of file diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 5cf2202..0a7c39f 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -220,9 +220,6 @@ export const generateWAMessageContent = async( options: MessageContentGenerationOptions ) => { let m: WAMessageContent = {} - if(typeof message === 'string') { - message = { text: message } - } if('text' in message) { const extContent = { ...message } as WATextMessage if (!!options.getUrlInfo && message.text.match(URL_REGEX)) { diff --git a/src/Utils/validate-connection.ts b/src/Utils/validate-connection.ts index c3c542e..c506bd7 100644 --- a/src/Utils/validate-connection.ts +++ b/src/Utils/validate-connection.ts @@ -1,7 +1,7 @@ import {Boom} from '@hapi/boom' import * as Curve from 'curve25519-js' import type { Contact } from '../Types/Contact' -import type { AnyAuthenticationCredentials, AuthenticationCredentials, CurveKeyPair } from "../Types" +import type { AnyAuthenticationCredentials, AuthenticationCredentials, AuthenticationCredentialsBase64, CurveKeyPair } from "../Types" import { aesDecrypt, hkdf, hmacSign, whatsappID } from './generics' import { readFileSync } from 'fs' @@ -32,6 +32,16 @@ export const normalizedAuthInfo = (authInfo: AnyAuthenticationCredentials | stri } return authInfo as AuthenticationCredentials } + +export const base64EncodedAuthenticationCredentials = (creds: AnyAuthenticationCredentials) => { + const normalized = normalizedAuthInfo(creds) + return { + ...normalized, + encKey: normalized.encKey.toString('base64'), + macKey: normalized.macKey.toString('base64') + } as AuthenticationCredentialsBase64 +} + /** * Once the QR code is scanned and we can validate our connection, or we resolved the challenge when logging back in * @private diff --git a/src/index.ts b/src/index.ts index 9e38e6c..331f02b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,9 @@ import makeConnection from './Connection' export * from '../WAMessage/WAMessage' -export * from './Utils/messages' +export * from './Utils' export * from './Types' export * from './Store' +export * from './Defaults' export default makeConnection \ No newline at end of file From b372e36a2bd7c413fcf6556feccb9df2a8448a17 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 15 Jul 2021 23:41:58 +0530 Subject: [PATCH 004/311] store metadata --- src/Store/in-memory-store.ts | 41 +++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index 5b092dc..f4c6be3 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -2,7 +2,7 @@ import KeyedDB from "@adiwajshing/keyed-db" import { Comparable } from "@adiwajshing/keyed-db/lib/Types" import { Logger } from "pino" import type { Connection } from "../Connection" -import type { BaileysEventEmitter, Chat, ConnectionState, Contact, WAMessage, WAMessageCursor } from "../Types" +import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, WAMessage, WAMessageCursor } from "../Types" import { toNumber } from "../Utils" import makeOrderedDictionary from "./ordered-dictionary" @@ -27,6 +27,7 @@ export default( const chats = new KeyedDB(chatKey, c => c.jid) const messages: { [_: string]: ReturnType } = {} const contacts: { [_: string]: Contact } = {} + const groupMetadata: { [_: string]: GroupMetadata } = {} const state: ConnectionState = { connection: 'close', phoneConnected: false @@ -146,6 +147,38 @@ export default( list.filter(m => !idSet.has(m.key.id)) } }) + + ev.on('groups.update', updates => { + for(const update of updates) { + if(groupMetadata[update.id]) { + Object.assign(groupMetadata[update.id!], update) + } else { + logger.debug({ update }, `got update for non-existant group metadata`) + } + } + }) + + ev.on('group-participants.update', ({ jid, participants, action }) => { + const metadata = groupMetadata[jid] + if(metadata) { + switch(action) { + case 'add': + metadata.participants.push(...participants.map(jid => ({ jid, isAdmin: false, isSuperAdmin: false }))) + break + case 'demote': + case 'promote': + for(const participant of metadata.participants) { + if(participants.includes(participant.jid)) { + participant.isAdmin = action === 'promote' + } + } + break + case 'remove': + metadata.participants = metadata.participants.filter(p => !participants.includes(p.jid)) + break + } + } + }) } return { @@ -208,6 +241,12 @@ export default( contact.imgUrl = await sock?.fetchImageUrl(jid) } return contact.imgUrl + }, + fetchGroupMetadata: async(jid: string, sock: Connection | undefined) => { + if(!groupMetadata[jid]) { + groupMetadata[jid] = await sock?.groupMetadata(jid, chats.get(jid)?.read_only === 'true') + } + return groupMetadata[jid] } } } \ No newline at end of file From 753ecf099b67e284953caff7124eecb5ffc11fbd Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 16 Jul 2021 01:39:55 +0530 Subject: [PATCH 005/311] minor updates --- src/Connection/chats.ts | 2 +- src/Connection/messages.ts | 8 +++++--- src/Store/in-memory-store.ts | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts index 8324c8e..484c1e2 100644 --- a/src/Connection/chats.ts +++ b/src/Connection/chats.ts @@ -30,7 +30,7 @@ const makeChatsSocket = (config: SocketConfig) => { const fetchImageUrl = async(jid: string) => { const response = await query({ json: ['query', 'ProfilePicThumb', jid], - expect200: true, + expect200: false, requiresPhoneConnection: false }) return response.eurl as string | undefined diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index 1b83d8b..a39bd0d 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -222,8 +222,10 @@ const makeMessagesSocket = (config: SocketConfig) => { { epoch: currentEpoch().toString(), type: 'relay' }, [ new BinaryNode('message', {}, message) ] ) - const flag = message.key.remoteJid === getState().user?.jid ? WAFlag.acknowledge : WAFlag.ignore // acknowledge when sending message to oneself + const isMsgToMe = message.key.remoteJid === getState().user?.jid + const flag = isMsgToMe ? WAFlag.acknowledge : WAFlag.ignore // acknowledge when sending message to oneself const mID = message.key.id + const finalState = isMsgToMe ? WAMessageStatus.READ : WAMessageStatus.SERVER_ACK message.status = WAMessageStatus.PENDING const promise = query({ @@ -236,14 +238,14 @@ const makeMessagesSocket = (config: SocketConfig) => { if(waitForAck) { await promise - message.status = WAMessageStatus.SERVER_ACK + message.status = finalState } else { const emitUpdate = (status: WAMessageStatus) => { message.status = status ev.emit('messages.update', [ { key: message.key, status } ]) } promise - .then(() => emitUpdate(WAMessageStatus.SERVER_ACK)) + .then(() => emitUpdate(finalState)) .catch(() => emitUpdate(WAMessageStatus.ERROR)) } diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index f4c6be3..b6ca041 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -109,6 +109,7 @@ export default( } break case 'last': + logger.info('recv last message on all chats') for(const msg of newMessages) { const jid = msg.key.remoteJid! const list = assertMessageList(jid) @@ -185,6 +186,7 @@ export default( chats, contacts, messages, + groupMetadata, state, listen, loadMessages: async(jid: string, count: number, cursor: WAMessageCursor, sock: Connection | undefined) => { @@ -237,7 +239,7 @@ export default( if(!contact) { return sock?.fetchImageUrl(jid) } - if(!contact.imgUrl) { + if(typeof contact.imgUrl === 'undefined') { contact.imgUrl = await sock?.fetchImageUrl(jid) } return contact.imgUrl From f356fa1811fc0c6a2d3a3425e001655dc40e8075 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 16 Jul 2021 01:55:04 +0530 Subject: [PATCH 006/311] minor bug fixes --- src/Store/in-memory-store.ts | 2 +- src/Utils/messages.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index b6ca041..cda9c6e 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -115,7 +115,7 @@ export default( const list = assertMessageList(jid) const [lastItem] = list.array.slice(-1) // reset message list - if(lastItem && lastItem.key.id !== msg.key.id) { + if(lastItem?.key.id !== msg.key.id) { list.clear() list.upsert(msg, 'append') } diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 0a7c39f..9025e90 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -267,10 +267,10 @@ export const generateWAMessageContent = async( options ) } - if('mentions' in message) { - const [messageType] = Object.keys(message) - message[messageType].contextInfo = message[messageType] || { } - message[messageType].contextInfo.mentionedJid = message.mentions + if('mentions' in message && message.mentions?.length) { + const [messageType] = Object.keys(m) + m[messageType].contextInfo = m[messageType] || { } + m[messageType].contextInfo.mentionedJid = message.mentions } return WAMessageProto.Message.fromObject(m) } From e65f0606647fcff622360310af5e69edd169e84e Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 16 Jul 2021 23:48:43 +0530 Subject: [PATCH 007/311] update broadcast lists --- src/Connection/chats.ts | 10 +--------- src/Connection/groups.ts | 34 ++++++++++++++++++++++++++++++---- src/Store/in-memory-store.ts | 6 ++++++ src/Types/index.ts | 7 ------- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts index 484c1e2..a55719b 100644 --- a/src/Connection/chats.ts +++ b/src/Connection/chats.ts @@ -1,6 +1,6 @@ import BinaryNode from "../BinaryNode"; import { EventEmitter } from 'events' -import { Chat, Contact, Presence, PresenceData, WABroadcastListInfo, SocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessage } from "../Types"; +import { Chat, Contact, Presence, PresenceData, SocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessage } from "../Types"; import { debouncedTimeout, unixTimestampSeconds, whatsappID } from "../Utils/generics"; import makeAuthSocket from "./auth"; import { Attributes, BinaryNode as BinaryNodeBase } from "../BinaryNode/types"; @@ -413,14 +413,6 @@ const makeChatsSocket = (config: SocketConfig) => { } return response }, - /** Query broadcast list info */ - getBroadcastListInfo: (jid: string) => { - return query({ - json: ['query', 'contact', jid], - expect200: true, - requiresPhoneConnection: true - }) as Promise - }, /** * Update the profile picture * @param jid diff --git a/src/Connection/groups.ts b/src/Connection/groups.ts index 552b7ff..46c486b 100644 --- a/src/Connection/groups.ts +++ b/src/Connection/groups.ts @@ -1,7 +1,7 @@ import BinaryNode from "../BinaryNode"; import { EventEmitter } from 'events' import { SocketConfig, GroupModificationResponse, ParticipantAction, GroupMetadata, WAFlag, WAMetric, WAGroupCreateResponse, GroupParticipant } from "../Types"; -import { generateMessageID, unixTimestampSeconds } from "../Utils/generics"; +import { generateMessageID, unixTimestampSeconds, whatsappID } from "../Utils/generics"; import makeMessagesSocket from "./messages"; const makeGroupsSocket = (config: SocketConfig) => { @@ -47,8 +47,9 @@ const makeGroupsSocket = (config: SocketConfig) => { expect200: true }) metadata.participants = metadata.participants.map(p => ( - { ...p, id: undefined, jid: p.jid } + { ...p, id: undefined, jid: whatsappID(p.id) } )) + metadata.owner = whatsappID(metadata.owner) return metadata as GroupMetadata } /** Get the metadata (works after you've left the group also) */ @@ -153,7 +154,7 @@ const makeGroupsSocket = (config: SocketConfig) => { ], type: 'upsert' }) - return response + return metadata }, /** * Leave a group @@ -200,8 +201,33 @@ const makeGroupsSocket = (config: SocketConfig) => { const jids = Object.keys(result.participants || {}) ev.emit('group-participants.update', { jid, participants: jids, action }) return jids - } + }, + + /** Query broadcast list info */ + getBroadcastListInfo: async(jid: string) => { + interface WABroadcastListInfo { + status: number + name: string + recipients?: {id: string}[] + } + const result = await query({ + json: ['query', 'contact', jid], + expect200: true, + requiresPhoneConnection: true + }) as WABroadcastListInfo + + const metadata: GroupMetadata = { + subject: result.name, + id: jid, + creation: undefined, + owner: getState().user?.jid, + participants: result.recipients!.map(({id}) => ( + { jid: whatsappID(id), isAdmin: false, isSuperAdmin: false } + )) + } + return metadata + } } } diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index cda9c6e..5ca99fa 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -249,6 +249,12 @@ export default( groupMetadata[jid] = await sock?.groupMetadata(jid, chats.get(jid)?.read_only === 'true') } return groupMetadata[jid] + }, + fetchBroadcastListInfo: async(jid: string, sock: Connection | undefined) => { + if(!groupMetadata[jid]) { + groupMetadata[jid] = await sock?.getBroadcastListInfo(jid) + } + return groupMetadata[jid] } } } \ No newline at end of file diff --git a/src/Types/index.ts b/src/Types/index.ts index 6da2733..9127ae0 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -137,13 +137,6 @@ export type WAInitResponse = { status: 200 } -export interface WABroadcastListInfo { - status: number - name: string - recipients?: {id: string}[] -} - - type WABusinessHoursConfig = { day_of_week: string mode: string From 9ea23a2d12e1ffd799461b6f0ea8588e82dd0789 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 17 Jul 2021 00:23:07 +0530 Subject: [PATCH 008/311] bug fixes --- src/BinaryNode/encode.ts | 6 ++++-- src/Connection/chats.ts | 5 ++--- src/Connection/socket.ts | 8 ++++++-- src/Utils/messages.ts | 14 +++++++------- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/BinaryNode/encode.ts b/src/BinaryNode/encode.ts index 7fe785e..db29abf 100644 --- a/src/BinaryNode/encode.ts +++ b/src/BinaryNode/encode.ts @@ -92,8 +92,10 @@ const encode = ({ header, attributes, data }: BinaryNode, buffer: number[] = []) writeString(header) validAttributes.forEach((key) => { - writeString(key) - writeString(attributes[key]) + if(typeof attributes[key] === 'string') { + writeString(key) + writeString(attributes[key]) + } }) if(data instanceof proto.WebMessageInfo && !Buffer.isBuffer(data)) { diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts index a55719b..cb83450 100644 --- a/src/Connection/chats.ts +++ b/src/Connection/chats.ts @@ -263,14 +263,13 @@ const makeChatsSocket = (config: SocketConfig) => { jid, count: count.toString(), index: fromMessage.id, - owner: fromMessage.fromMe ? 'true' : 'false', - participant: fromMessage.participant + owner: fromMessage.fromMe ? 'true' : 'false' } ) ], [ WAMetric.read, WAFlag.ignore ] ) - ev.emit ('chats.update', [{ jid, count: count }]) + ev.emit ('chats.update', [{ jid, count: count < 0 ? -1 : 0 }]) }, /** * Modify a given chat (archive, pin etc.) diff --git a/src/Connection/socket.ts b/src/Connection/socket.ts index d6ae622..858ff3f 100644 --- a/src/Connection/socket.ts +++ b/src/Connection/socket.ts @@ -139,7 +139,7 @@ export const makeSocket = ({ /* Check if this is a response to a message we are expecting */ const l0 = json.header || json[0] || '' const l1 = json?.attributes || json?.[1] || { } - const l2 = ((json.data || json[2] || [])[0] || [])[0] || '' + const l2 = json?.data?.[0]?.header || json[2]?.[0] || '' Object.keys(l1).forEach(key => { anyTriggered = socketEvents.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, json) || anyTriggered @@ -347,7 +347,11 @@ export const makeSocket = ({ /** Generic function for action, set queries */ setQuery: async(nodes: BinaryNode[], binaryTag: WATag = [WAMetric.group, WAFlag.ignore], tag?: string) => ( query({ - json: ['action', { epoch: epoch.toString(), type: 'set' }, nodes], + json: new BinaryNode( + 'action', + { epoch: epoch.toString(), type: 'set' }, + nodes + ), binaryTag, tag, expect200: true, diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 9025e90..6bb1b4a 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -49,12 +49,12 @@ const MIMETYPE_MAP: { [T in MediaType]: string } = { } const MessageTypeProto = { - 'imageMessage': WAMessageProto.ImageMessage, - 'videoMessage': WAMessageProto.VideoMessage, - 'audioMessage': WAMessageProto.AudioMessage, - 'stickerMessage': WAMessageProto.StickerMessage, - 'documentMessage': WAMessageProto.DocumentMessage, -} + 'image': WAMessageProto.ImageMessage, + 'video': WAMessageProto.VideoMessage, + 'audio': WAMessageProto.AudioMessage, + 'sticker': WAMessageProto.StickerMessage, + 'document': WAMessageProto.DocumentMessage, +} as const const MEDIA_KEYS = Object.keys(MEDIA_PATH_MAP) as MediaType[] @@ -160,7 +160,7 @@ export const prepareWAMessageMedia = async( ) delete uploadData.media const content = { - [mediaType]: MessageTypeProto[mediaType].fromObject( + [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject( { url: mediaUrl, mediaKey, From bd86f95a9cf7b90814bf899e74eb734e43ba1628 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 17 Jul 2021 23:21:56 +0530 Subject: [PATCH 009/311] bug fixes --- src/Connection/chats.ts | 13 ++++++++++--- src/Connection/socket.ts | 15 ++++++--------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts index cb83450..00ffe36 100644 --- a/src/Connection/chats.ts +++ b/src/Connection/chats.ts @@ -79,6 +79,13 @@ const makeChatsSocket = (config: SocketConfig) => { ) ev.emit('messages.update', updates) break + case 'mute': + if(attributes.mute === '0') { + ev.emit('chats.update', [{ jid, mute: null }]) + } else { + ev.emit('chats.update', [{ jid, mute: attributes.mute }]) + } + break default: logger.warn({ node }, `received unrecognized chat update`) break @@ -251,7 +258,7 @@ const makeChatsSocket = (config: SocketConfig) => { ...sock, sendChatsQuery, fetchImageUrl, - chatRead: async(jid: string, count: number, fromMessage: WAMessageKey) => { + chatRead: async(fromMessage: WAMessageKey, count: number) => { if(count < 0) { count = -2 } @@ -260,7 +267,7 @@ const makeChatsSocket = (config: SocketConfig) => { new BinaryNode( 'read', { - jid, + jid: fromMessage.remoteJid, count: count.toString(), index: fromMessage.id, owner: fromMessage.fromMe ? 'true' : 'false' @@ -269,7 +276,7 @@ const makeChatsSocket = (config: SocketConfig) => { ], [ WAMetric.read, WAFlag.ignore ] ) - ev.emit ('chats.update', [{ jid, count: count < 0 ? -1 : 0 }]) + ev.emit ('chats.update', [{ jid: fromMessage.remoteJid, count: count < 0 ? -1 : 0 }]) }, /** * Modify a given chat (archive, pin etc.) diff --git a/src/Connection/socket.ts b/src/Connection/socket.ts index 858ff3f..2332fd5 100644 --- a/src/Connection/socket.ts +++ b/src/Connection/socket.ts @@ -256,7 +256,7 @@ export const makeSocket = ({ if(expect200 && Math.floor(responseStatusCode/100) !== 2) { const message = STATUS_CODES[responseStatusCode] || 'unknown' throw new Boom( - `Unexpected status in '${Object.values(json)[0] || 'query'}': ${message}(${responseStatusCode})`, + `Unexpected status in '${Array.isArray(json) ? json[0] : (json?.header || 'query')}': ${message}(${responseStatusCode})`, { data: { query: json, message }, statusCode: response.status } ) } @@ -345,19 +345,16 @@ export const makeSocket = ({ waitForMessage, query, /** Generic function for action, set queries */ - setQuery: async(nodes: BinaryNode[], binaryTag: WATag = [WAMetric.group, WAFlag.ignore], tag?: string) => ( - query({ - json: new BinaryNode( - 'action', - { epoch: epoch.toString(), type: 'set' }, - nodes - ), + setQuery: async(nodes: BinaryNode[], binaryTag: WATag = [WAMetric.group, WAFlag.ignore], tag?: string) => { + const json = new BinaryNode('action', { epoch: epoch.toString(), type: 'set' }, nodes) + return query({ + json, binaryTag, tag, expect200: true, requiresPhoneConnection: true }) as Promise<{ status: number }> - ), + }, currentEpoch: () => epoch, end } From 6751b5cc73fe951b8fd770d1993c1730099325b2 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 18 Jul 2021 17:27:23 +0530 Subject: [PATCH 010/311] make deps optional + bug fixes --- package.json | 6 +- src/Connection/auth.ts | 6 +- src/Connection/chats.ts | 10 +- src/Connection/groups.ts | 19 ++- src/Connection/socket.ts | 24 ++-- src/Store/in-memory-store.ts | 55 ++++----- src/Store/ordered-dictionary.ts | 1 + src/Types/index.ts | 9 +- yarn.lock | 204 +++++++++----------------------- 9 files changed, 122 insertions(+), 212 deletions(-) diff --git a/package.json b/package.json index bf4e3cd..b62abca 100644 --- a/package.json +++ b/package.json @@ -32,20 +32,18 @@ "url": "git@github.com:adiwajshing/baileys.git" }, "dependencies": { - "@adiwajshing/keyed-db": "^0.2.2", "@hapi/boom": "^9.1.3", "curve25519-js": "^0.0.4", "futoin-hkdf": "^1.3.2", "got": "^11.8.1", - "https-proxy-agent": "^5.0.0", "jimp": "^0.16.1", "music-metadata": "^7.4.1", "pino": "^6.7.0", - "pino-pretty": "^4.3.0", "protobufjs": "^6.10.1", "ws": "^7.3.1" }, "optionalDependencies": { + "@adiwajshing/keyed-db": "^0.2.4", "qrcode-terminal": "^0.12.0" }, "files": [ @@ -53,11 +51,13 @@ "WAMessage/*" ], "devDependencies": { + "@adiwajshing/keyed-db": "^0.2.4", "@types/got": "^9.6.11", "@types/jest": "^26.0.24", "@types/node": "^14.6.2", "@types/pino": "^6.3.2", "@types/ws": "^7.2.6", + "https-proxy-agent": "^5.0.0", "jest": "^27.0.6", "qrcode-terminal": "^0.12.0", "ts-jest": "^27.0.3", diff --git a/src/Connection/auth.ts b/src/Connection/auth.ts index 8834191..d6983ed 100644 --- a/src/Connection/auth.ts +++ b/src/Connection/auth.ts @@ -37,11 +37,11 @@ const makeAuthSocket = (config: SocketConfig) => { } } }) - const { socketEvents } = socket + const { ws } = socket let curveKeys: CurveKeyPair let initTimeout: NodeJS.Timeout // add close listener - socketEvents.on('ws-close', (error: Boom | Error) => { + ws.on('ws-close', (error: Boom | Error) => { logger.info({ error }, 'Closed connection to WhatsApp') initTimeout && clearTimeout(initTimeout) // if no reconnects occur @@ -239,7 +239,7 @@ const makeAuthSocket = (config: SocketConfig) => { }) ev.emit('credentials.update', auth) } - socketEvents.once('ws-open', async() => { + ws.once('open', async() => { try { await onOpen() } catch(error) { diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts index 00ffe36..ed4a1a2 100644 --- a/src/Connection/chats.ts +++ b/src/Connection/chats.ts @@ -156,8 +156,6 @@ const makeChatsSocket = (config: SocketConfig) => { logger.error(`error in sending init queries: ${error}`) } }) - // this persists through socket connections - // as conn & getSocket share the same eventemitter socketEvents.on('CB:response,type:chat', async ({ data }: BinaryNode) => { chatsDebounceTimeout.cancel() if(Array.isArray(data)) { @@ -171,7 +169,7 @@ const makeChatsSocket = (config: SocketConfig) => { }) logger.info(`got ${chats.length} chats`) - ev.emit('chats.upsert', { chats, type: 'set' }) + ev.emit('chats.set', { chats }) } }) // got all contacts from phone @@ -184,7 +182,7 @@ const makeChatsSocket = (config: SocketConfig) => { }) logger.info(`got ${contacts.length} contacts`) - ev.emit('contacts.upsert', { contacts, type: 'set' }) + ev.emit('contacts.set', { contacts }) } }) // status updates @@ -237,7 +235,7 @@ const makeChatsSocket = (config: SocketConfig) => { const user = node[1] as Contact user.jid = whatsappID(user.jid) - ev.emit('contacts.upsert', { contacts: [user], type: 'upsert' }) + ev.emit('contacts.upsert', [user]) } }) @@ -251,7 +249,7 @@ const makeChatsSocket = (config: SocketConfig) => { socketEvents.on('CB:Blocklist', json => { json = json[1] const blocklist = json.blocklist - ev.emit('blocklist.update', { blocklist, type: 'set' }) + ev.emit('blocklist.set', { blocklist }) }) return { diff --git a/src/Connection/groups.ts b/src/Connection/groups.ts index 46c486b..86540c8 100644 --- a/src/Connection/groups.ts +++ b/src/Connection/groups.ts @@ -143,17 +143,14 @@ const makeGroupsSocket = (config: SocketConfig) => { metadata = await groupMetadataFull(gid) logger.warn (`group ID switched from ${gid} to ${response.gid}`) } - ev.emit('chats.upsert', { - chats: [ - { - jid: response.gid, - name: title, - t: unixTimestampSeconds(), - count: 0 - } - ], - type: 'upsert' - }) + ev.emit('chats.upsert', [ + { + jid: response.gid, + name: title, + t: unixTimestampSeconds(), + count: 0 + } + ]) return metadata }, /** diff --git a/src/Connection/socket.ts b/src/Connection/socket.ts index 2332fd5..739768a 100644 --- a/src/Connection/socket.ts +++ b/src/Connection/socket.ts @@ -95,6 +95,8 @@ export const makeSocket = ({ return tag } const end = (error: Error | undefined) => { + logger.debug({ error }, 'connection closed') + ws.removeAllListeners('close') ws.removeAllListeners('error') ws.removeAllListeners('open') @@ -105,9 +107,11 @@ export const makeSocket = ({ clearPhoneCheckInterval() if(ws.readyState !== ws.CLOSED && ws.readyState !== ws.CLOSING) { - socketEvents.emit('ws-close', error) try { ws.close() } catch { } } + ws.emit('ws-close', error) + // so it cannot be re-emitted + ws.removeAllListeners('ws-close') } const onMessageRecieved = (message: string | Buffer) => { if(message[0] === '!') { @@ -221,7 +225,8 @@ export const makeSocket = ({ onErr = err => reject(err || new Boom('Connection Closed', { statusCode: 429 })) socketEvents.on(`TAG:${tag}`, onRecv) - socketEvents.on('ws-close', onErr) // if the socket closes, you'll never receive the message + ws.on('close', onErr) // if the socket closes, you'll never receive the message + ws.on('error', onErr) }, ) return result as any @@ -230,7 +235,8 @@ export const makeSocket = ({ cancelPhoneChecker && cancelPhoneChecker() socketEvents.off(`TAG:${tag}`, onRecv) - socketEvents.off(`ws-close`, onErr) + ws.off('close', onErr) // if the socket closes, you'll never receive the message + ws.off('error', onErr) } } /** @@ -290,21 +296,21 @@ export const makeSocket = ({ await new Promise((resolve, reject) => { onOpen = () => resolve(undefined) onClose = reject - socketEvents.on('ws-open', onOpen) - socketEvents.on('ws-close', onClose) + ws.on('open', onOpen) + ws.on('close', onClose) + ws.on('error', onClose) }) .finally(() => { - socketEvents.off('ws-open', onOpen) - socketEvents.off('ws-close', onClose) + socketEvents.off('open', onOpen) + socketEvents.off('close', onClose) + socketEvents.off('error', onClose) }) } ws.on('message', onMessageRecieved) ws.on('open', () => { startKeepAliveRequest() - logger.info('Opened WS connection to WhatsApp Web') - socketEvents.emit('ws-open') }) ws.on('error', end) ws.on('close', () => end(new Boom('Connection Terminated', { statusCode: DisconnectReason.connectionLost }))) diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index 5ca99fa..d11ecd8 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -1,6 +1,6 @@ -import KeyedDB from "@adiwajshing/keyed-db" -import { Comparable } from "@adiwajshing/keyed-db/lib/Types" -import { Logger } from "pino" +import type KeyedDB from "@adiwajshing/keyed-db" +import type { Comparable } from "@adiwajshing/keyed-db/lib/Types" +import type { Logger } from "pino" import type { Connection } from "../Connection" import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, WAMessage, WAMessageCursor } from "../Types" import { toNumber } from "../Utils" @@ -23,8 +23,8 @@ const makeMessagesDictionary = () => makeOrderedDictionary(waMessageID) export default( { logger, chatKey }: BaileysInMemoryStoreConfig ) => { - - const chats = new KeyedDB(chatKey, c => c.jid) + const KeyedDBConstructor = require('@adiwajshing/keyed-db').default as new (...args: any[]) => KeyedDB + const chats = new KeyedDBConstructor(chatKey, c => c.jid) const messages: { [_: string]: ReturnType } = {} const contacts: { [_: string]: Contact } = {} const groupMetadata: { [_: string]: GroupMetadata } = {} @@ -39,11 +39,8 @@ export default( } const listen = (ev: BaileysEventEmitter) => { - - ev.on('connection.update', update => { - Object.assign(state, update) - }) - ev.on('contacts.upsert', ({ contacts: newContacts, type }) => { + + const contactsUpsert = (newContacts: Contact[]) => { const oldContacts = new Set(Object.keys(contacts)) for(const contact of newContacts) { oldContacts.delete(contact.jid) @@ -52,12 +49,18 @@ export default( contact ) } - if(type === 'set') { - for(const jid of oldContacts) { - delete contacts[jid] - } - logger.debug({ deletedContacts: oldContacts.size }, 'synced contacts') + return oldContacts + } + + ev.on('connection.update', update => { + Object.assign(state, update) + }) + ev.on('contacts.set', ({ contacts: newContacts }) => { + const oldContacts = contactsUpsert(newContacts) + for(const jid of oldContacts) { + delete contacts[jid] } + logger.debug({ deletedContacts: oldContacts.size }, 'synced contacts') }) ev.on('contacts.update', updates => { for(const update of updates) { @@ -68,13 +71,11 @@ export default( } } }) - ev.on('chats.upsert', ({ chats: newChats, type }) => { - if(type === 'set') { - chats.clear() - } - for(const chat of newChats) { - chats.upsert(chat) - } + ev.on('chats.upsert', newChats => { + chats.upsert(...newChats) + }) + ev.on('chats.set', ({ chats: newChats }) => { + chats.upsert(...newChats) }) ev.on('chats.update', updates => { for(const update of updates) { @@ -101,10 +102,9 @@ export default( list.upsert(msg, 'append') if(type === 'notify' && !chats.get(jid)) { - ev.emit('chats.upsert', { - chats: [ { jid, t: toNumber(msg.messageTimestamp), count: 1 } ], - type: 'upsert' - }) + ev.emit('chats.upsert', [ + { jid, t: toNumber(msg.messageTimestamp), count: 1 } + ]) } } break @@ -135,9 +135,10 @@ export default( const list = assertMessageList(update.key.remoteJid) const result = list.updateAssign(update) if(!result) { - logger.debug({ update }, `got update for non-existant message`) + logger.debug({ update }, `got update for non-existent message`) } } + }) ev.on('messages.delete', item => { const list = assertMessageList(item.jid) diff --git a/src/Store/ordered-dictionary.ts b/src/Store/ordered-dictionary.ts index 50272a0..d1ce2ad 100644 --- a/src/Store/ordered-dictionary.ts +++ b/src/Store/ordered-dictionary.ts @@ -50,6 +50,7 @@ const makeOrderedDictionary = function(idGetter: (item: T) => string) { const item = get(idGetter(update as any)) if(item) { Object.assign(item, update) + return true } return false }, diff --git a/src/Types/index.ts b/src/Types/index.ts index 9127ae0..7091a1c 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -170,11 +170,13 @@ export type BaileysEventMap = { 'connection.update': Partial 'credentials.update': AuthenticationCredentials - 'chats.upsert': { chats: Chat[], type: 'set' | 'upsert' } + 'chats.set': { chats: Chat[] } + 'chats.upsert': Chat[] 'chats.update': Partial[] 'chats.delete': string[] - 'contacts.upsert': { contacts: Contact[], type: 'set' | 'upsert' } + 'contacts.set': { contacts: Contact[] } + 'contacts.upsert': Contact[] 'contacts.update': Partial[] 'messages.delete': { jid: string, ids: string[] } | { jid: string, all: true } @@ -184,7 +186,8 @@ export type BaileysEventMap = { 'groups.update': Partial[] 'group-participants.update': { jid: string, participants: string[], action: ParticipantAction } - 'blocklist.update': { blocklist: string[], type: 'add' | 'remove' | 'set' } + 'blocklist.set': { blocklist: string[] } + 'blocklist.update': { blocklist: string[], type: 'add' | 'remove' } } export interface BaileysEventEmitter extends EventEmitter { on(event: T, listener: (arg: BaileysEventMap[T]) => void): this diff --git a/yarn.lock b/yarn.lock index e584e8c..afcc087 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@adiwajshing/keyed-db@^0.2.2": +"@adiwajshing/keyed-db@^0.2.4": version "0.2.4" resolved "https://registry.yarnpkg.com/@adiwajshing/keyed-db/-/keyed-db-0.2.4.tgz#2a09e88fce20b2672deb60a7750c5fe3ab0dfd99" integrity sha512-yprSnAtj80/VKuDqRcFFLDYltoNV8tChNwFfIgcf6PGD4sjzWIBgs08pRuTqGH5mk5wgL6PBRSsMCZqtZwzFEw== @@ -321,11 +321,6 @@ dependencies: "@hapi/hoek" "9.x.x" -"@hapi/bourne@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-2.0.0.tgz#5bb2193eb685c0007540ca61d166d4e1edaf918d" - integrity sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg== - "@hapi/hoek@9.x.x": version "9.2.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" @@ -890,9 +885,9 @@ "@sinonjs/commons" "^1.7.0" "@szmarczak/http-timer@^4.0.5": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" - integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== dependencies: defer-to-connect "^2.0.0" @@ -969,11 +964,6 @@ "@types/node" "*" "@types/responselike" "*" -"@types/debug@^4.1.5": - version "4.1.6" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.6.tgz#0b7018723084918a865eff99249c490505df2163" - integrity sha512-7fDOJFA/x8B+sO1901BmHlf5dE1cxBU8mRXj8QOEDnn16hhGJv/IHxJtZhvsabZsIMn0eLIyeOKAeqSNJJYTpA== - "@types/got@^9.6.11": version "9.6.12" resolved "https://registry.yarnpkg.com/@types/got/-/got-9.6.12.tgz#fd42a6e1f5f64cd6bb422279b08c30bb5a15a56f" @@ -1035,9 +1025,9 @@ integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== "@types/node@*", "@types/node@>=13.7.0": - version "16.0.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.0.1.tgz#70cedfda26af7a2ca073fdcc9beb2fff4aa693f8" - integrity sha512-hBOx4SUlEPKwRi6PrXuTGw1z6lz0fjsibcWCM378YxsSu/6+C30L6CR49zIBKHiwNWCYIcOLjg4OHKZaFeLAug== + version "16.3.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.3.3.tgz#0c30adff37bbbc7a50eb9b58fae2a504d0d88038" + integrity sha512-8h7k1YgQKxKXWckzFCMfsIwn0Y61UK6tlD6y2lOb3hTOIMlK3t9/QwHOhc81TwU+RMf0As5fj7NPjroERCnejQ== "@types/node@^14.6.2": version "14.17.5" @@ -1073,14 +1063,6 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3" integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog== -"@types/readable-stream@^2.3.9": - version "2.3.11" - resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.11.tgz#942bc4574a1d7ca4368cb9cb4352e3d2b4b51dea" - integrity sha512-0z+/apYJwKFz/RHp6mOMxz/y7xOvWPYPevuCEyAY3gXsjtaac02E26RvxA+I96rfvmVH/dEMGXNvyJfViR1FSQ== - dependencies: - "@types/node" "*" - safe-buffer "*" - "@types/responselike@*", "@types/responselike@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" @@ -1222,16 +1204,6 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -args@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/args/-/args-5.0.1.tgz#4bf298df90a4799a09521362c579278cc2fdd761" - integrity sha512-1kqmFCFsPffavQFGt8OxJdIcETti99kySRUPMpOhaGjL6mRJn8HFU1OxKY5bMqfZKUwTQc1mZkAjmGYaVOHFtQ== - dependencies: - camelcase "5.0.0" - chalk "2.4.2" - leven "2.1.0" - mri "1.1.4" - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1409,11 +1381,6 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" - integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== - camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -1425,11 +1392,11 @@ camelcase@^6.2.0: integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== caniuse-lite@^1.0.30001219: - version "1.0.30001243" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz#d9250155c91e872186671c523f3ae50cfc94a3aa" - integrity sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA== + version "1.0.30001245" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz#45b941bbd833cb0fa53861ff2bae746b3c6ca5d4" + integrity sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA== -chalk@2.4.2, chalk@^2.0.0: +chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1457,9 +1424,9 @@ ci-info@^3.1.1: integrity sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A== cjs-module-lexer@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz#2fd46d9906a126965aa541345c499aaa18e8cd73" - integrity sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw== + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== cliui@^7.0.2: version "7.0.4" @@ -1590,11 +1557,6 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" -dateformat@^4.5.1: - version "4.5.1" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.5.1.tgz#c20e7a9ca77d147906b6dc2261a8be0a5bd2173c" - integrity sha512-OD0TZ+B7yP7ZgpJf5K2DIbj3FZvFvxgFUuaqA/V5zTjAtAAXZ1E8bktHxmAGs4x5b7PflqA9LeQ84Og7wYtF7Q== - debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: version "4.3.2" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" @@ -1672,9 +1634,9 @@ domexception@^2.0.1: webidl-conversions "^5.0.0" electron-to-chromium@^1.3.723: - version "1.3.770" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.770.tgz#a9e705a73315f4900880622b3ab76cf1d7221b77" - integrity sha512-Kyh8DGK1KfEZuYKIHvuOmrKotsKZQ+qBkDIWHciE3QoFkxXB1KzPP+tfLilSHAfxTON0yYMnFCWkQtUOR7g6KQ== + version "1.3.779" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.779.tgz#de55492a756deec63424f89fbe62aec9776f0e6d" + integrity sha512-nreave0y/1Qhmo8XtO6C/LpawNyC6U26+q7d814/e+tIqUK073pM+4xW7WUXyqCRa5K4wdxHmNMBAi8ap9nEew== emittery@^0.8.1: version "0.8.1" @@ -1787,10 +1749,10 @@ fast-redact@^3.0.0: resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.0.1.tgz#d6015b971e933d03529b01333ba7f22c29961e92" integrity sha512-kYpn4Y/valC9MdrISg47tZOpYBNoTXKgT9GYXFpHN/jYFs+lFkPoisY+LcBODdKVMY96ATzvzsWv+ES/4Kmufw== -fast-safe-stringify@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" - integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== +fast-safe-stringify@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz#dc2af48c46cf712b683e849b2bbd446b32de936f" + integrity sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag== fb-watchman@^2.0.0: version "2.0.1" @@ -1800,9 +1762,9 @@ fb-watchman@^2.0.0: bser "2.1.1" file-type@^16.5.0: - version "16.5.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.0.tgz#16a2626f3b33bac612f6e81e52216f3a7c8e12a2" - integrity sha512-OxgWA9tbL8N/WP00GD1z8O0MiwQKFyWRs1q+3FhjdvcGgKqwxcejyGWso3n4/IMU6DdwV+ARZ4A7TTnPkDcSiw== + version "16.5.1" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.1.tgz#dd697dc5c3a2f4db63af746f38a6322e5e7bc6a5" + integrity sha512-Pi1G43smrCy82Q3be3sfKaeS5uHdfj905dP88YqhroG6TYbVY2ljTdDXeXqa6Cn5nOk6znOjWM2uZptA8vH/qQ== dependencies: readable-web-to-node-stream "^3.0.0" strtok3 "^6.0.3" @@ -2095,9 +2057,9 @@ is-ci@^3.0.0: ci-info "^3.1.1" is-core-module@^2.2.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" - integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== + version "2.5.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.5.0.tgz#f754843617c70bfd29b7bd87327400cda5c18491" + integrity sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg== dependencies: has "^1.0.3" @@ -2617,16 +2579,6 @@ jimp@^0.16.1: "@jimp/types" "^0.16.1" regenerator-runtime "^0.13.3" -jmespath@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" - integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= - -joycon@^2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/joycon/-/joycon-2.2.5.tgz#8d4cf4cbb2544d7b7583c216fcdfec19f6be1615" - integrity sha512-YqvUxoOcVPnCp0VU1/56f+iKSdvIRJYPznH22BdXV3xMk75SFXhWeJkZ8C9XxUWt1b5x2X1SxuFygW1U0FmkEQ== - jpeg-js@0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.2.tgz#8b345b1ae4abde64c2da2fe67ea216a114ac279d" @@ -2716,11 +2668,6 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -leven@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" - integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= - leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -2894,11 +2841,6 @@ mkdirp@^0.5.1: dependencies: minimist "^1.2.5" -mri@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.4.tgz#7cb1dd1b9b40905f1fac053abe25b6720f44744a" - integrity sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -3083,10 +3025,10 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -peek-readable@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-3.1.3.tgz#932480d46cf6aa553c46c68566c4fb69a82cd2b1" - integrity sha512-mpAcysyRJxmICBcBa5IXH7SZPvWkcghm6Fk8RekoS3v+BpbSzlZzuWbMx+GXrlUwESi9qHar4nVEZNMKylIHvg== +peek-readable@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.0.0.tgz#b024ef391c86136eba0ae9df3ff4f966a09e9a7e" + integrity sha512-kLbU4cz6h86poGVBKgAVMpFmD47nX04fPPQNKnv9fuj+IJZYkEBjsYAVu5nDbZWx0ZsWwWlMzeG90zQa5KLBaA== phin@^2.9.1: version "2.9.3" @@ -3098,36 +3040,18 @@ picomatch@^2.0.4, picomatch@^2.2.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== -pino-pretty@^4.3.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/pino-pretty/-/pino-pretty-4.8.0.tgz#f2f3055bf222456217b14ffb04d8be0a0cc17fce" - integrity sha512-mhQfHG4rw5ZFpWL44m0Utjo4GC2+HMfdNvxyA8lLw0sIqn6fCf7uQe6dPckUcW/obly+OQHD7B/MTso6LNizYw== - dependencies: - "@hapi/bourne" "^2.0.0" - args "^5.0.1" - chalk "^4.0.0" - dateformat "^4.5.1" - fast-safe-stringify "^2.0.7" - jmespath "^0.15.0" - joycon "^2.2.5" - pump "^3.0.0" - readable-stream "^3.6.0" - rfdc "^1.3.0" - split2 "^3.1.1" - strip-json-comments "^3.1.1" - pino-std-serializers@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz#b56487c402d882eb96cd67c257868016b61ad671" integrity sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg== pino@^6.7.0: - version "6.11.3" - resolved "https://registry.yarnpkg.com/pino/-/pino-6.11.3.tgz#0c02eec6029d25e6794fdb6bbea367247d74bc29" - integrity sha512-drPtqkkSf0ufx2gaea3TryFiBHdNIdXKf5LN0hTM82SXI4xVIve2wLwNg92e1MT6m3jASLu6VO7eGY6+mmGeyw== + version "6.12.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-6.12.0.tgz#2281521620d70eeff519039467352d656f46735e" + integrity sha512-5NGopOcUusGuklGHVVv9az0Hv/Dj3urHhD3G+zhl5pBGIRYAeGCi/Ej6YCl16Q2ko28cmYiJz+/qRoJiwy62Rw== dependencies: fast-redact "^3.0.0" - fast-safe-stringify "^2.0.7" + fast-safe-stringify "^2.0.8" flatstr "^1.0.12" pino-std-serializers "^3.1.0" quick-format-unescaped "^4.0.3" @@ -3259,7 +3183,7 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -readable-stream@^3.0.0, readable-stream@^3.6.0: +readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -3269,11 +3193,10 @@ readable-stream@^3.0.0, readable-stream@^3.6.0: util-deprecate "^1.0.1" readable-web-to-node-stream@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.1.tgz#3f619b1bc5dd73a4cfe5c5f9b4f6faba55dff845" - integrity sha512-4zDC6CvjUyusN7V0QLsXVB7pJCD9+vtrM9bYDRv6uBQ+SKfx36rp5AFNPRgh9auKRul/a1iFZJYXcCbwRL+SaA== + version "3.0.2" + resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" + integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== dependencies: - "@types/readable-stream" "^2.3.9" readable-stream "^3.6.0" rechoir@^0.6.2: @@ -3325,11 +3248,6 @@ responselike@^2.0.0: dependencies: lowercase-keys "^2.0.0" -rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - rimraf@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -3337,16 +3255,16 @@ rimraf@^3.0.0: dependencies: glob "^7.1.3" -safe-buffer@*, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -3452,13 +3370,6 @@ source-map@^0.7.3: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== -split2@^3.1.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" - integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== - dependencies: - readable-stream "^3.0.0" - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -3512,19 +3423,12 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - strtok3@^6.0.3, strtok3@^6.0.8: - version "6.0.8" - resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.0.8.tgz#c839157f615c10ba0f4ae35067dad9959eeca346" - integrity sha512-QLgv+oiXwXgCgp2PdPPa+Jpp4D9imK9e/0BsyfeFMr6QL6wMVqoVn9+OXQ9I7MZbmUzN6lmitTJ09uwS2OmGcw== + version "6.2.0" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.2.0.tgz#7c24e74a9a24c7f2b976e4469654d459e6795d91" + integrity sha512-hBbPN4+f9fypbfTs0NImALgzYcb6k/blFr2mJVX6bUOmJCbXe/trDHdIC+Ir5XUXRMGFvq487ecwLitDoHVoew== dependencies: - "@tokenizer/token" "^0.1.1" - "@types/debug" "^4.1.5" - peek-readable "^3.1.3" + peek-readable "^4.0.0" supports-color@^5.3.0: version "5.5.0" @@ -3650,9 +3554,9 @@ ts-jest@^27.0.3: yargs-parser "20.x" ts-node@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.0.0.tgz#05f10b9a716b0b624129ad44f0ea05dac84ba3be" - integrity sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg== + version "10.1.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.1.0.tgz#e656d8ad3b61106938a867f69c39a8ba6efc966e" + integrity sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA== dependencies: "@tsconfig/node10" "^1.0.7" "@tsconfig/node12" "^1.0.7" @@ -3851,9 +3755,9 @@ write-file-atomic@^3.0.0: typedarray-to-buffer "^3.1.5" ws@^7.3.1, ws@^7.4.5: - version "7.5.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.2.tgz#09cc8fea3bec1bc5ed44ef51b42f945be36900f6" - integrity sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ== + version "7.5.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" + integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== xhr@^2.0.1: version "2.6.0" From 8a5e6489c01e625d713d860e955dabb5e79097ce Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 18 Jul 2021 21:41:50 +0530 Subject: [PATCH 011/311] patch messages.update --- src/Connection/chats.ts | 6 +++--- src/Connection/messages.ts | 16 +++++++++++----- src/Store/in-memory-store.ts | 10 +++++----- src/Store/ordered-dictionary.ts | 6 ++++-- src/Types/Message.ts | 1 + src/Types/index.ts | 4 ++-- 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts index ed4a1a2..1394c90 100644 --- a/src/Connection/chats.ts +++ b/src/Connection/chats.ts @@ -1,6 +1,6 @@ import BinaryNode from "../BinaryNode"; import { EventEmitter } from 'events' -import { Chat, Contact, Presence, PresenceData, SocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessage } from "../Types"; +import { Chat, Contact, Presence, PresenceData, SocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessage, WAMessageUpdate } from "../Types"; import { debouncedTimeout, unixTimestampSeconds, whatsappID } from "../Utils/generics"; import makeAuthSocket from "./auth"; import { Attributes, BinaryNode as BinaryNodeBase } from "../BinaryNode/types"; @@ -67,14 +67,14 @@ const makeChatsSocket = (config: SocketConfig) => { case 'star': case 'unstar': const starred = updateType === 'star' - const updates: Partial[] = (node.data as BinaryNode[]).map( + const updates: WAMessageUpdate[] = (node.data as BinaryNode[]).map( ({ attributes }) => ({ key: { remoteJid: jid, id: attributes.index, fromMe: attributes.owner === 'true' }, - starred + update: { starred } }) ) ev.emit('messages.update', updates) diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index a39bd0d..3c00471 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -92,7 +92,7 @@ const makeMessagesSocket = (config: SocketConfig) => { }) Object.keys(response[1]).forEach (key => content[key] = response[1][key]) // update message - ev.emit('messages.update', [{ key: message.key, message: message.message }]) + ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]) return response } @@ -130,7 +130,13 @@ const makeMessagesSocket = (config: SocketConfig) => { case WAMessageProto.ProtocolMessage.ProtocolMessageType.REVOKE: const key = protocolMessage.key const messageStubType = WAMessageStubType.REVOKE - ev.emit('messages.update', [ { message: null, key, messageStubType } ]) + ev.emit('messages.update', [ + { + // the key of the deleted message is updated + update: { message: null, key: message.key, messageStubType }, + key + } + ]) return default: break @@ -192,7 +198,7 @@ const makeMessagesSocket = (config: SocketConfig) => { ev.emit('chats.update', [chatUpdate]) } if(type === 'update') { - ev.emit('messages.update', [message]) + ev.emit('messages.update', [ { update: message, key: message.key } ]) } else { ev.emit('messages.upsert', { messages: [message], type }) } @@ -242,7 +248,7 @@ const makeMessagesSocket = (config: SocketConfig) => { } else { const emitUpdate = (status: WAMessageStatus) => { message.status = status - ev.emit('messages.update', [ { key: message.key, status } ]) + ev.emit('messages.update', [ { key: message.key, update: { status } } ]) } promise .then(() => emitUpdate(finalState)) @@ -295,7 +301,7 @@ const makeMessagesSocket = (config: SocketConfig) => { const status = STATUS_MAP[json.type] if(status) { - ev.emit('messages.update', [ { key, status } ]) + ev.emit('messages.update', [ { key, update: { status } } ]) } else { logger.warn({ data }, 'got unknown status update for message') } diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index d11ecd8..af06358 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -131,9 +131,9 @@ export default( } }) ev.on('messages.update', updates => { - for(const update of updates) { - const list = assertMessageList(update.key.remoteJid) - const result = list.updateAssign(update) + for(const { update, key } of updates) { + const list = assertMessageList(key.remoteJid) + const result = list.updateAssign(key.id, update) if(!result) { logger.debug({ update }, `got update for non-existent message`) } @@ -201,8 +201,8 @@ export default( const cursorValue = cursorKey ? list.get(cursorKey.id) : undefined let messages: WAMessage[] - if(messages && mode ==='before' && (!cursorKey || cursorValue)) { - const msgIdx = messages.findIndex(m => m.key.id === cursorKey.id) + if(list && mode === 'before' && (!cursorKey || cursorValue)) { + const msgIdx = list.array.findIndex(m => m.key.id === cursorKey.id) messages = list.array.slice(0, msgIdx) const diff = count - messages.length diff --git a/src/Store/ordered-dictionary.ts b/src/Store/ordered-dictionary.ts index d1ce2ad..fb6cd7e 100644 --- a/src/Store/ordered-dictionary.ts +++ b/src/Store/ordered-dictionary.ts @@ -46,10 +46,12 @@ const makeOrderedDictionary = function(idGetter: (item: T) => string) { upsert, update, remove, - updateAssign: (update: Partial) => { - const item = get(idGetter(update as any)) + updateAssign: (id: string, update: Partial) => { + const item = get(id) if(item) { Object.assign(item, update) + delete dict[id] + dict[id] = item return true } return false diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 0c7e52d..43905f6 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -147,5 +147,6 @@ export interface MessageStatusUpdate { type: WAMessageStatus } +export type WAMessageUpdate = { update: Partial, key: proto.IMessageKey } export type WAMessageCursor = { before: WAMessageKey | undefined } | { after: WAMessageKey | undefined } \ No newline at end of file diff --git a/src/Types/index.ts b/src/Types/index.ts index 7091a1c..ab1f493 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -16,7 +16,7 @@ import { Contact } from './Contact' import { ConnectionState } from './Store' import { GroupMetadata, ParticipantAction } from './GroupMetadata' -import { MessageUpdateType, WAMessage } from './Message' +import { MessageUpdateType, WAMessage, WAMessageKey, WAMessageUpdate } from './Message' /** used for binary messages */ export enum WAMetric { @@ -180,7 +180,7 @@ export type BaileysEventMap = { 'contacts.update': Partial[] 'messages.delete': { jid: string, ids: string[] } | { jid: string, all: true } - 'messages.update': Partial[] + 'messages.update': WAMessageUpdate[] 'messages.upsert': { messages: WAMessage[], type: MessageUpdateType } 'groups.update': Partial[] From cd127dbca9a8d2f3a6be652b5a223a16598c94d4 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 18 Jul 2021 22:12:35 +0530 Subject: [PATCH 012/311] fix undefined error on messages fetch --- src/Store/in-memory-store.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index af06358..34cc7ca 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -202,8 +202,12 @@ export default( let messages: WAMessage[] if(list && mode === 'before' && (!cursorKey || cursorValue)) { - const msgIdx = list.array.findIndex(m => m.key.id === cursorKey.id) - messages = list.array.slice(0, msgIdx) + if(cursorValue) { + const msgIdx = list.array.findIndex(m => m.key.id === cursorKey.id) + messages = list.array.slice(0, msgIdx) + } else { + messages = list.array + } const diff = count - messages.length if (diff < 0) { From 5f8106d4e06d8dfc7b3e7dc7c7df733b2f4c62b7 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 20 Jul 2021 20:03:53 +0530 Subject: [PATCH 013/311] store fixes --- src/Store/in-memory-store.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index 34cc7ca..8fe94fd 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -208,17 +208,18 @@ export default( } else { messages = list.array } - const diff = count - messages.length if (diff < 0) { messages = messages.slice(-count) // get the last X messages } else if (diff > 0) { const [fMessage] = messages - const extra = await retrieve (diff, { before: fMessage?.key || cursorKey }) + const cursor = { before: fMessage?.key || cursorKey } + const extra = await retrieve (diff, cursor) // add to DB for(let i = extra.length-1; i >= 0;i--) { list.upsert(extra[i], 'prepend') } + messages.splice(0, 0, ...extra) } } else messages = await retrieve(count, cursor) From 5c4a317213b216e3df4180fcfdb147589da0c0ae Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 29 Jul 2021 13:34:02 +0530 Subject: [PATCH 014/311] update proto + message info --- WAMessage/WAMessage.d.ts | 11489 ++++++++++- WAMessage/WAMessage.js | 35199 ++++++++++++++++++++++++++++----- src/Connection/messages.ts | 47 +- src/Store/in-memory-store.ts | 35 +- src/Types/Message.ts | 22 +- src/Types/index.ts | 5 +- 6 files changed, 41116 insertions(+), 5681 deletions(-) diff --git a/WAMessage/WAMessage.d.ts b/WAMessage/WAMessage.d.ts index ab2ea9d..51d9d1b 100644 --- a/WAMessage/WAMessage.d.ts +++ b/WAMessage/WAMessage.d.ts @@ -2,1128 +2,7181 @@ import * as $protobuf from "protobufjs"; /** Namespace proto. */ export namespace proto { - /** Properties of a WebFeatures. */ - interface IWebFeatures { + /** Properties of an AppVersion. */ + interface IAppVersion { - /** WebFeatures labelsDisplay */ - labelsDisplay?: (proto.WebFeatures.WebFeaturesFlag|null); + /** AppVersion primary */ + primary?: (number|null); - /** WebFeatures voipIndividualOutgoing */ - voipIndividualOutgoing?: (proto.WebFeatures.WebFeaturesFlag|null); + /** AppVersion secondary */ + secondary?: (number|null); - /** WebFeatures groupsV3 */ - groupsV3?: (proto.WebFeatures.WebFeaturesFlag|null); + /** AppVersion tertiary */ + tertiary?: (number|null); - /** WebFeatures groupsV3Create */ - groupsV3Create?: (proto.WebFeatures.WebFeaturesFlag|null); + /** AppVersion quaternary */ + quaternary?: (number|null); - /** WebFeatures changeNumberV2 */ - changeNumberV2?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures queryStatusV3Thumbnail */ - queryStatusV3Thumbnail?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures liveLocations */ - liveLocations?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures queryVname */ - queryVname?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures voipIndividualIncoming */ - voipIndividualIncoming?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures quickRepliesQuery */ - quickRepliesQuery?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures payments */ - payments?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures stickerPackQuery */ - stickerPackQuery?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures liveLocationsFinal */ - liveLocationsFinal?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures labelsEdit */ - labelsEdit?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures mediaUpload */ - mediaUpload?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures mediaUploadRichQuickReplies */ - mediaUploadRichQuickReplies?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures vnameV2 */ - vnameV2?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures videoPlaybackUrl */ - videoPlaybackUrl?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures statusRanking */ - statusRanking?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures voipIndividualVideo */ - voipIndividualVideo?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures thirdPartyStickers */ - thirdPartyStickers?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures frequentlyForwardedSetting */ - frequentlyForwardedSetting?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures groupsV4JoinPermission */ - groupsV4JoinPermission?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures recentStickers */ - recentStickers?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures catalog */ - catalog?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures starredStickers */ - starredStickers?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures voipGroupCall */ - voipGroupCall?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures templateMessage */ - templateMessage?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures templateMessageInteractivity */ - templateMessageInteractivity?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures ephemeralMessages */ - ephemeralMessages?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures e2ENotificationSync */ - e2ENotificationSync?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures recentStickersV2 */ - recentStickersV2?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures syncdRelease1 */ - syncdRelease1?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures recentStickersV3 */ - recentStickersV3?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures userNotice */ - userNotice?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures syncdRelease11 */ - syncdRelease11?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures support */ - support?: (proto.WebFeatures.WebFeaturesFlag|null); + /** AppVersion quinary */ + quinary?: (number|null); } - /** Represents a WebFeatures. */ - class WebFeatures implements IWebFeatures { + /** Represents an AppVersion. */ + class AppVersion implements IAppVersion { /** - * Constructs a new WebFeatures. + * Constructs a new AppVersion. * @param [properties] Properties to set */ - constructor(properties?: proto.IWebFeatures); + constructor(properties?: proto.IAppVersion); - /** WebFeatures labelsDisplay. */ - public labelsDisplay: proto.WebFeatures.WebFeaturesFlag; + /** AppVersion primary. */ + public primary: number; - /** WebFeatures voipIndividualOutgoing. */ - public voipIndividualOutgoing: proto.WebFeatures.WebFeaturesFlag; + /** AppVersion secondary. */ + public secondary: number; - /** WebFeatures groupsV3. */ - public groupsV3: proto.WebFeatures.WebFeaturesFlag; + /** AppVersion tertiary. */ + public tertiary: number; - /** WebFeatures groupsV3Create. */ - public groupsV3Create: proto.WebFeatures.WebFeaturesFlag; + /** AppVersion quaternary. */ + public quaternary: number; - /** WebFeatures changeNumberV2. */ - public changeNumberV2: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures queryStatusV3Thumbnail. */ - public queryStatusV3Thumbnail: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures liveLocations. */ - public liveLocations: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures queryVname. */ - public queryVname: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures voipIndividualIncoming. */ - public voipIndividualIncoming: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures quickRepliesQuery. */ - public quickRepliesQuery: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures payments. */ - public payments: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures stickerPackQuery. */ - public stickerPackQuery: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures liveLocationsFinal. */ - public liveLocationsFinal: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures labelsEdit. */ - public labelsEdit: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures mediaUpload. */ - public mediaUpload: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures mediaUploadRichQuickReplies. */ - public mediaUploadRichQuickReplies: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures vnameV2. */ - public vnameV2: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures videoPlaybackUrl. */ - public videoPlaybackUrl: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures statusRanking. */ - public statusRanking: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures voipIndividualVideo. */ - public voipIndividualVideo: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures thirdPartyStickers. */ - public thirdPartyStickers: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures frequentlyForwardedSetting. */ - public frequentlyForwardedSetting: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures groupsV4JoinPermission. */ - public groupsV4JoinPermission: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures recentStickers. */ - public recentStickers: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures catalog. */ - public catalog: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures starredStickers. */ - public starredStickers: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures voipGroupCall. */ - public voipGroupCall: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures templateMessage. */ - public templateMessage: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures templateMessageInteractivity. */ - public templateMessageInteractivity: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures ephemeralMessages. */ - public ephemeralMessages: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures e2ENotificationSync. */ - public e2ENotificationSync: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures recentStickersV2. */ - public recentStickersV2: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures syncdRelease1. */ - public syncdRelease1: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures recentStickersV3. */ - public recentStickersV3: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures userNotice. */ - public userNotice: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures syncdRelease11. */ - public syncdRelease11: proto.WebFeatures.WebFeaturesFlag; - - /** WebFeatures support. */ - public support: proto.WebFeatures.WebFeaturesFlag; + /** AppVersion quinary. */ + public quinary: number; /** - * Creates a new WebFeatures instance using the specified properties. + * Creates a new AppVersion instance using the specified properties. * @param [properties] Properties to set - * @returns WebFeatures instance + * @returns AppVersion instance */ - public static create(properties?: proto.IWebFeatures): proto.WebFeatures; + public static create(properties?: proto.IAppVersion): proto.AppVersion; /** - * Encodes the specified WebFeatures message. Does not implicitly {@link proto.WebFeatures.verify|verify} messages. - * @param message WebFeatures message or plain object to encode + * Encodes the specified AppVersion message. Does not implicitly {@link proto.AppVersion.verify|verify} messages. + * @param message AppVersion message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encode(message: proto.IWebFeatures, writer?: $protobuf.Writer): $protobuf.Writer; + public static encode(message: proto.IAppVersion, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Encodes the specified WebFeatures message, length delimited. Does not implicitly {@link proto.WebFeatures.verify|verify} messages. - * @param message WebFeatures message or plain object to encode + * Encodes the specified AppVersion message, length delimited. Does not implicitly {@link proto.AppVersion.verify|verify} messages. + * @param message AppVersion message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encodeDelimited(message: proto.IWebFeatures, writer?: $protobuf.Writer): $protobuf.Writer; + public static encodeDelimited(message: proto.IAppVersion, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Decodes a WebFeatures message from the specified reader or buffer. + * Decodes an AppVersion message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns WebFeatures + * @returns AppVersion * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WebFeatures; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.AppVersion; /** - * Decodes a WebFeatures message from the specified reader or buffer, length delimited. + * Decodes an AppVersion message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns WebFeatures + * @returns AppVersion * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WebFeatures; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.AppVersion; /** - * Verifies a WebFeatures message. + * Verifies an AppVersion message. * @param message Plain object to verify * @returns `null` if valid, otherwise the reason why it is not */ public static verify(message: { [k: string]: any }): (string|null); /** - * Creates a WebFeatures message from a plain object. Also converts values to their respective internal types. + * Creates an AppVersion message from a plain object. Also converts values to their respective internal types. * @param object Plain object - * @returns WebFeatures + * @returns AppVersion */ - public static fromObject(object: { [k: string]: any }): proto.WebFeatures; + public static fromObject(object: { [k: string]: any }): proto.AppVersion; /** - * Creates a plain object from a WebFeatures message. Also converts values to other types if specified. - * @param message WebFeatures + * Creates a plain object from an AppVersion message. Also converts values to other types if specified. + * @param message AppVersion * @param [options] Conversion options * @returns Plain object */ - public static toObject(message: proto.WebFeatures, options?: $protobuf.IConversionOptions): { [k: string]: any }; + public static toObject(message: proto.AppVersion, options?: $protobuf.IConversionOptions): { [k: string]: any }; /** - * Converts this WebFeatures to JSON. + * Converts this AppVersion to JSON. * @returns JSON object */ public toJSON(): { [k: string]: any }; } - namespace WebFeatures { + /** Properties of a UserAgent. */ + interface IUserAgent { - /** WebFeaturesFlag enum. */ - enum WebFeaturesFlag { - NOT_STARTED = 0, - FORCE_UPGRADE = 1, - DEVELOPMENT = 2, - PRODUCTION = 3 - } + /** UserAgent platform */ + platform?: (proto.UserAgent.UserAgentPlatform|null); + + /** UserAgent appVersion */ + appVersion?: (proto.IAppVersion|null); + + /** UserAgent mcc */ + mcc?: (string|null); + + /** UserAgent mnc */ + mnc?: (string|null); + + /** UserAgent osVersion */ + osVersion?: (string|null); + + /** UserAgent manufacturer */ + manufacturer?: (string|null); + + /** UserAgent device */ + device?: (string|null); + + /** UserAgent osBuildNumber */ + osBuildNumber?: (string|null); + + /** UserAgent phoneId */ + phoneId?: (string|null); + + /** UserAgent releaseChannel */ + releaseChannel?: (proto.UserAgent.UserAgentReleaseChannel|null); + + /** UserAgent localeLanguageIso6391 */ + localeLanguageIso6391?: (string|null); + + /** UserAgent localeCountryIso31661Alpha2 */ + localeCountryIso31661Alpha2?: (string|null); + + /** UserAgent deviceBoard */ + deviceBoard?: (string|null); } - /** Properties of a NotificationMessageInfo. */ - interface INotificationMessageInfo { - - /** NotificationMessageInfo key */ - key?: (proto.IMessageKey|null); - - /** NotificationMessageInfo message */ - message?: (proto.IMessage|null); - - /** NotificationMessageInfo messageTimestamp */ - messageTimestamp?: (number|Long|null); - - /** NotificationMessageInfo participant */ - participant?: (string|null); - } - - /** Represents a NotificationMessageInfo. */ - class NotificationMessageInfo implements INotificationMessageInfo { + /** Represents a UserAgent. */ + class UserAgent implements IUserAgent { /** - * Constructs a new NotificationMessageInfo. + * Constructs a new UserAgent. * @param [properties] Properties to set */ - constructor(properties?: proto.INotificationMessageInfo); + constructor(properties?: proto.IUserAgent); - /** NotificationMessageInfo key. */ - public key?: (proto.IMessageKey|null); + /** UserAgent platform. */ + public platform: proto.UserAgent.UserAgentPlatform; - /** NotificationMessageInfo message. */ - public message?: (proto.IMessage|null); + /** UserAgent appVersion. */ + public appVersion?: (proto.IAppVersion|null); - /** NotificationMessageInfo messageTimestamp. */ - public messageTimestamp: (number|Long); + /** UserAgent mcc. */ + public mcc: string; - /** NotificationMessageInfo participant. */ - public participant: string; + /** UserAgent mnc. */ + public mnc: string; + + /** UserAgent osVersion. */ + public osVersion: string; + + /** UserAgent manufacturer. */ + public manufacturer: string; + + /** UserAgent device. */ + public device: string; + + /** UserAgent osBuildNumber. */ + public osBuildNumber: string; + + /** UserAgent phoneId. */ + public phoneId: string; + + /** UserAgent releaseChannel. */ + public releaseChannel: proto.UserAgent.UserAgentReleaseChannel; + + /** UserAgent localeLanguageIso6391. */ + public localeLanguageIso6391: string; + + /** UserAgent localeCountryIso31661Alpha2. */ + public localeCountryIso31661Alpha2: string; + + /** UserAgent deviceBoard. */ + public deviceBoard: string; /** - * Creates a new NotificationMessageInfo instance using the specified properties. + * Creates a new UserAgent instance using the specified properties. * @param [properties] Properties to set - * @returns NotificationMessageInfo instance + * @returns UserAgent instance */ - public static create(properties?: proto.INotificationMessageInfo): proto.NotificationMessageInfo; + public static create(properties?: proto.IUserAgent): proto.UserAgent; /** - * Encodes the specified NotificationMessageInfo message. Does not implicitly {@link proto.NotificationMessageInfo.verify|verify} messages. - * @param message NotificationMessageInfo message or plain object to encode + * Encodes the specified UserAgent message. Does not implicitly {@link proto.UserAgent.verify|verify} messages. + * @param message UserAgent message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encode(message: proto.INotificationMessageInfo, writer?: $protobuf.Writer): $protobuf.Writer; + public static encode(message: proto.IUserAgent, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Encodes the specified NotificationMessageInfo message, length delimited. Does not implicitly {@link proto.NotificationMessageInfo.verify|verify} messages. - * @param message NotificationMessageInfo message or plain object to encode + * Encodes the specified UserAgent message, length delimited. Does not implicitly {@link proto.UserAgent.verify|verify} messages. + * @param message UserAgent message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encodeDelimited(message: proto.INotificationMessageInfo, writer?: $protobuf.Writer): $protobuf.Writer; + public static encodeDelimited(message: proto.IUserAgent, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Decodes a NotificationMessageInfo message from the specified reader or buffer. + * Decodes a UserAgent message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns NotificationMessageInfo + * @returns UserAgent * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.NotificationMessageInfo; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.UserAgent; /** - * Decodes a NotificationMessageInfo message from the specified reader or buffer, length delimited. + * Decodes a UserAgent message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns NotificationMessageInfo + * @returns UserAgent * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.NotificationMessageInfo; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.UserAgent; /** - * Verifies a NotificationMessageInfo message. + * Verifies a UserAgent message. * @param message Plain object to verify * @returns `null` if valid, otherwise the reason why it is not */ public static verify(message: { [k: string]: any }): (string|null); /** - * Creates a NotificationMessageInfo message from a plain object. Also converts values to their respective internal types. + * Creates a UserAgent message from a plain object. Also converts values to their respective internal types. * @param object Plain object - * @returns NotificationMessageInfo + * @returns UserAgent */ - public static fromObject(object: { [k: string]: any }): proto.NotificationMessageInfo; + public static fromObject(object: { [k: string]: any }): proto.UserAgent; /** - * Creates a plain object from a NotificationMessageInfo message. Also converts values to other types if specified. - * @param message NotificationMessageInfo + * Creates a plain object from a UserAgent message. Also converts values to other types if specified. + * @param message UserAgent * @param [options] Conversion options * @returns Plain object */ - public static toObject(message: proto.NotificationMessageInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + public static toObject(message: proto.UserAgent, options?: $protobuf.IConversionOptions): { [k: string]: any }; /** - * Converts this NotificationMessageInfo to JSON. + * Converts this UserAgent to JSON. * @returns JSON object */ public toJSON(): { [k: string]: any }; } - /** Properties of a WebNotificationsInfo. */ - interface IWebNotificationsInfo { + namespace UserAgent { - /** WebNotificationsInfo timestamp */ - timestamp?: (number|Long|null); + /** UserAgentPlatform enum. */ + enum UserAgentPlatform { + ANDROID = 0, + IOS = 1, + WINDOWS_PHONE = 2, + BLACKBERRY = 3, + BLACKBERRYX = 4, + S40 = 5, + S60 = 6, + PYTHON_CLIENT = 7, + TIZEN = 8, + ENTERPRISE = 9, + SMB_ANDROID = 10, + KAIOS = 11, + SMB_IOS = 12, + WINDOWS = 13, + WEB = 14, + PORTAL = 15, + GREEN_ANDROID = 16, + GREEN_IPHONE = 17, + BLUE_ANDROID = 18, + BLUE_IPHONE = 19, + FBLITE_ANDROID = 20, + MLITE_ANDROID = 21, + IGLITE_ANDROID = 22, + PAGE = 23, + MACOS = 24, + VR = 25 + } - /** WebNotificationsInfo unreadChats */ - unreadChats?: (number|null); - - /** WebNotificationsInfo notifyMessageCount */ - notifyMessageCount?: (number|null); - - /** WebNotificationsInfo notifyMessages */ - notifyMessages?: (proto.IWebMessageInfo[]|null); + /** UserAgentReleaseChannel enum. */ + enum UserAgentReleaseChannel { + RELEASE = 0, + BETA = 1, + ALPHA = 2, + DEBUG = 3 + } } - /** Represents a WebNotificationsInfo. */ - class WebNotificationsInfo implements IWebNotificationsInfo { + /** Properties of a WebdPayload. */ + interface IWebdPayload { + + /** WebdPayload usesParticipantInKey */ + usesParticipantInKey?: (boolean|null); + + /** WebdPayload supportsStarredMessages */ + supportsStarredMessages?: (boolean|null); + + /** WebdPayload supportsDocumentMessages */ + supportsDocumentMessages?: (boolean|null); + + /** WebdPayload supportsUrlMessages */ + supportsUrlMessages?: (boolean|null); + + /** WebdPayload supportsMediaRetry */ + supportsMediaRetry?: (boolean|null); + + /** WebdPayload supportsE2EImage */ + supportsE2EImage?: (boolean|null); + + /** WebdPayload supportsE2EVideo */ + supportsE2EVideo?: (boolean|null); + + /** WebdPayload supportsE2EAudio */ + supportsE2EAudio?: (boolean|null); + + /** WebdPayload supportsE2EDocument */ + supportsE2EDocument?: (boolean|null); + + /** WebdPayload documentTypes */ + documentTypes?: (string|null); + + /** WebdPayload features */ + features?: (Uint8Array|null); + } + + /** Represents a WebdPayload. */ + class WebdPayload implements IWebdPayload { /** - * Constructs a new WebNotificationsInfo. + * Constructs a new WebdPayload. * @param [properties] Properties to set */ - constructor(properties?: proto.IWebNotificationsInfo); + constructor(properties?: proto.IWebdPayload); - /** WebNotificationsInfo timestamp. */ - public timestamp: (number|Long); + /** WebdPayload usesParticipantInKey. */ + public usesParticipantInKey: boolean; - /** WebNotificationsInfo unreadChats. */ - public unreadChats: number; + /** WebdPayload supportsStarredMessages. */ + public supportsStarredMessages: boolean; - /** WebNotificationsInfo notifyMessageCount. */ - public notifyMessageCount: number; + /** WebdPayload supportsDocumentMessages. */ + public supportsDocumentMessages: boolean; - /** WebNotificationsInfo notifyMessages. */ - public notifyMessages: proto.IWebMessageInfo[]; + /** WebdPayload supportsUrlMessages. */ + public supportsUrlMessages: boolean; + + /** WebdPayload supportsMediaRetry. */ + public supportsMediaRetry: boolean; + + /** WebdPayload supportsE2EImage. */ + public supportsE2EImage: boolean; + + /** WebdPayload supportsE2EVideo. */ + public supportsE2EVideo: boolean; + + /** WebdPayload supportsE2EAudio. */ + public supportsE2EAudio: boolean; + + /** WebdPayload supportsE2EDocument. */ + public supportsE2EDocument: boolean; + + /** WebdPayload documentTypes. */ + public documentTypes: string; + + /** WebdPayload features. */ + public features: Uint8Array; /** - * Creates a new WebNotificationsInfo instance using the specified properties. + * Creates a new WebdPayload instance using the specified properties. * @param [properties] Properties to set - * @returns WebNotificationsInfo instance + * @returns WebdPayload instance */ - public static create(properties?: proto.IWebNotificationsInfo): proto.WebNotificationsInfo; + public static create(properties?: proto.IWebdPayload): proto.WebdPayload; /** - * Encodes the specified WebNotificationsInfo message. Does not implicitly {@link proto.WebNotificationsInfo.verify|verify} messages. - * @param message WebNotificationsInfo message or plain object to encode + * Encodes the specified WebdPayload message. Does not implicitly {@link proto.WebdPayload.verify|verify} messages. + * @param message WebdPayload message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encode(message: proto.IWebNotificationsInfo, writer?: $protobuf.Writer): $protobuf.Writer; + public static encode(message: proto.IWebdPayload, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Encodes the specified WebNotificationsInfo message, length delimited. Does not implicitly {@link proto.WebNotificationsInfo.verify|verify} messages. - * @param message WebNotificationsInfo message or plain object to encode + * Encodes the specified WebdPayload message, length delimited. Does not implicitly {@link proto.WebdPayload.verify|verify} messages. + * @param message WebdPayload message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encodeDelimited(message: proto.IWebNotificationsInfo, writer?: $protobuf.Writer): $protobuf.Writer; + public static encodeDelimited(message: proto.IWebdPayload, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Decodes a WebNotificationsInfo message from the specified reader or buffer. + * Decodes a WebdPayload message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns WebNotificationsInfo + * @returns WebdPayload * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WebNotificationsInfo; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WebdPayload; /** - * Decodes a WebNotificationsInfo message from the specified reader or buffer, length delimited. + * Decodes a WebdPayload message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns WebNotificationsInfo + * @returns WebdPayload * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WebNotificationsInfo; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WebdPayload; /** - * Verifies a WebNotificationsInfo message. + * Verifies a WebdPayload message. * @param message Plain object to verify * @returns `null` if valid, otherwise the reason why it is not */ public static verify(message: { [k: string]: any }): (string|null); /** - * Creates a WebNotificationsInfo message from a plain object. Also converts values to their respective internal types. + * Creates a WebdPayload message from a plain object. Also converts values to their respective internal types. * @param object Plain object - * @returns WebNotificationsInfo + * @returns WebdPayload */ - public static fromObject(object: { [k: string]: any }): proto.WebNotificationsInfo; + public static fromObject(object: { [k: string]: any }): proto.WebdPayload; /** - * Creates a plain object from a WebNotificationsInfo message. Also converts values to other types if specified. - * @param message WebNotificationsInfo + * Creates a plain object from a WebdPayload message. Also converts values to other types if specified. + * @param message WebdPayload * @param [options] Conversion options * @returns Plain object */ - public static toObject(message: proto.WebNotificationsInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + public static toObject(message: proto.WebdPayload, options?: $protobuf.IConversionOptions): { [k: string]: any }; /** - * Converts this WebNotificationsInfo to JSON. + * Converts this WebdPayload to JSON. * @returns JSON object */ public toJSON(): { [k: string]: any }; } - /** Properties of a PaymentInfo. */ - interface IPaymentInfo { + /** Properties of a WebInfo. */ + interface IWebInfo { - /** PaymentInfo currencyDeprecated */ - currencyDeprecated?: (proto.PaymentInfo.PaymentInfoCurrency|null); + /** WebInfo refToken */ + refToken?: (string|null); - /** PaymentInfo amount1000 */ - amount1000?: (number|Long|null); + /** WebInfo version */ + version?: (string|null); - /** PaymentInfo receiverJid */ - receiverJid?: (string|null); + /** WebInfo webdPayload */ + webdPayload?: (proto.IWebdPayload|null); - /** PaymentInfo status */ - status?: (proto.PaymentInfo.PaymentInfoStatus|null); - - /** PaymentInfo transactionTimestamp */ - transactionTimestamp?: (number|Long|null); - - /** PaymentInfo requestMessageKey */ - requestMessageKey?: (proto.IMessageKey|null); - - /** PaymentInfo expiryTimestamp */ - expiryTimestamp?: (number|Long|null); - - /** PaymentInfo futureproofed */ - futureproofed?: (boolean|null); - - /** PaymentInfo currency */ - currency?: (string|null); - - /** PaymentInfo txnStatus */ - txnStatus?: (proto.PaymentInfo.PaymentInfoTxnStatus|null); + /** WebInfo webSubPlatform */ + webSubPlatform?: (proto.WebInfo.WebInfoWebSubPlatform|null); } - /** Represents a PaymentInfo. */ - class PaymentInfo implements IPaymentInfo { + /** Represents a WebInfo. */ + class WebInfo implements IWebInfo { /** - * Constructs a new PaymentInfo. + * Constructs a new WebInfo. * @param [properties] Properties to set */ - constructor(properties?: proto.IPaymentInfo); + constructor(properties?: proto.IWebInfo); - /** PaymentInfo currencyDeprecated. */ - public currencyDeprecated: proto.PaymentInfo.PaymentInfoCurrency; + /** WebInfo refToken. */ + public refToken: string; - /** PaymentInfo amount1000. */ - public amount1000: (number|Long); + /** WebInfo version. */ + public version: string; - /** PaymentInfo receiverJid. */ - public receiverJid: string; + /** WebInfo webdPayload. */ + public webdPayload?: (proto.IWebdPayload|null); - /** PaymentInfo status. */ - public status: proto.PaymentInfo.PaymentInfoStatus; - - /** PaymentInfo transactionTimestamp. */ - public transactionTimestamp: (number|Long); - - /** PaymentInfo requestMessageKey. */ - public requestMessageKey?: (proto.IMessageKey|null); - - /** PaymentInfo expiryTimestamp. */ - public expiryTimestamp: (number|Long); - - /** PaymentInfo futureproofed. */ - public futureproofed: boolean; - - /** PaymentInfo currency. */ - public currency: string; - - /** PaymentInfo txnStatus. */ - public txnStatus: proto.PaymentInfo.PaymentInfoTxnStatus; + /** WebInfo webSubPlatform. */ + public webSubPlatform: proto.WebInfo.WebInfoWebSubPlatform; /** - * Creates a new PaymentInfo instance using the specified properties. + * Creates a new WebInfo instance using the specified properties. * @param [properties] Properties to set - * @returns PaymentInfo instance + * @returns WebInfo instance */ - public static create(properties?: proto.IPaymentInfo): proto.PaymentInfo; + public static create(properties?: proto.IWebInfo): proto.WebInfo; /** - * Encodes the specified PaymentInfo message. Does not implicitly {@link proto.PaymentInfo.verify|verify} messages. - * @param message PaymentInfo message or plain object to encode + * Encodes the specified WebInfo message. Does not implicitly {@link proto.WebInfo.verify|verify} messages. + * @param message WebInfo message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encode(message: proto.IPaymentInfo, writer?: $protobuf.Writer): $protobuf.Writer; + public static encode(message: proto.IWebInfo, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Encodes the specified PaymentInfo message, length delimited. Does not implicitly {@link proto.PaymentInfo.verify|verify} messages. - * @param message PaymentInfo message or plain object to encode + * Encodes the specified WebInfo message, length delimited. Does not implicitly {@link proto.WebInfo.verify|verify} messages. + * @param message WebInfo message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encodeDelimited(message: proto.IPaymentInfo, writer?: $protobuf.Writer): $protobuf.Writer; + public static encodeDelimited(message: proto.IWebInfo, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Decodes a PaymentInfo message from the specified reader or buffer. + * Decodes a WebInfo message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns PaymentInfo + * @returns WebInfo * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PaymentInfo; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WebInfo; /** - * Decodes a PaymentInfo message from the specified reader or buffer, length delimited. + * Decodes a WebInfo message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns PaymentInfo + * @returns WebInfo * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PaymentInfo; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WebInfo; /** - * Verifies a PaymentInfo message. + * Verifies a WebInfo message. * @param message Plain object to verify * @returns `null` if valid, otherwise the reason why it is not */ public static verify(message: { [k: string]: any }): (string|null); /** - * Creates a PaymentInfo message from a plain object. Also converts values to their respective internal types. + * Creates a WebInfo message from a plain object. Also converts values to their respective internal types. * @param object Plain object - * @returns PaymentInfo + * @returns WebInfo */ - public static fromObject(object: { [k: string]: any }): proto.PaymentInfo; + public static fromObject(object: { [k: string]: any }): proto.WebInfo; /** - * Creates a plain object from a PaymentInfo message. Also converts values to other types if specified. - * @param message PaymentInfo + * Creates a plain object from a WebInfo message. Also converts values to other types if specified. + * @param message WebInfo * @param [options] Conversion options * @returns Plain object */ - public static toObject(message: proto.PaymentInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + public static toObject(message: proto.WebInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; /** - * Converts this PaymentInfo to JSON. + * Converts this WebInfo to JSON. * @returns JSON object */ public toJSON(): { [k: string]: any }; } - namespace PaymentInfo { + namespace WebInfo { - /** PaymentInfoCurrency enum. */ - enum PaymentInfoCurrency { - UNKNOWN_CURRENCY = 0, - INR = 1 - } - - /** PaymentInfoStatus enum. */ - enum PaymentInfoStatus { - UNKNOWN_STATUS = 0, - PROCESSING = 1, - SENT = 2, - NEED_TO_ACCEPT = 3, - COMPLETE = 4, - COULD_NOT_COMPLETE = 5, - REFUNDED = 6, - EXPIRED = 7, - REJECTED = 8, - CANCELLED = 9, - WAITING_FOR_PAYER = 10, - WAITING = 11 - } - - /** PaymentInfoTxnStatus enum. */ - enum PaymentInfoTxnStatus { - UNKNOWN = 0, - PENDING_SETUP = 1, - PENDING_RECEIVER_SETUP = 2, - INIT = 3, - SUCCESS = 4, - COMPLETED = 5, - FAILED = 6, - FAILED_RISK = 7, - FAILED_PROCESSING = 8, - FAILED_RECEIVER_PROCESSING = 9, - FAILED_DA = 10, - FAILED_DA_FINAL = 11, - REFUNDED_TXN = 12, - REFUND_FAILED = 13, - REFUND_FAILED_PROCESSING = 14, - REFUND_FAILED_DA = 15, - EXPIRED_TXN = 16, - AUTH_CANCELED = 17, - AUTH_CANCEL_FAILED_PROCESSING = 18, - AUTH_CANCEL_FAILED = 19, - COLLECT_INIT = 20, - COLLECT_SUCCESS = 21, - COLLECT_FAILED = 22, - COLLECT_FAILED_RISK = 23, - COLLECT_REJECTED = 24, - COLLECT_EXPIRED = 25, - COLLECT_CANCELED = 26, - COLLECT_CANCELLING = 27 + /** WebInfoWebSubPlatform enum. */ + enum WebInfoWebSubPlatform { + WEB_BROWSER = 0, + APP_STORE = 1, + WIN_STORE = 2, + DARWIN = 3, + WIN32 = 4 } } - /** Properties of a WebMessageInfo. */ - interface IWebMessageInfo { + /** Properties of a DNSSource. */ + interface IDNSSource { - /** WebMessageInfo key */ - key: proto.IMessageKey; + /** DNSSource dnsMethod */ + dnsMethod?: (proto.DNSSource.DNSSourceDNSResolutionMethod|null); - /** WebMessageInfo message */ - message?: (proto.IMessage|null); + /** DNSSource appCached */ + appCached?: (boolean|null); + } - /** WebMessageInfo messageTimestamp */ - messageTimestamp?: (number|Long|null); + /** Represents a DNSSource. */ + class DNSSource implements IDNSSource { - /** WebMessageInfo status */ - status?: (proto.WebMessageInfo.WebMessageInfoStatus|null); + /** + * Constructs a new DNSSource. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IDNSSource); - /** WebMessageInfo participant */ - participant?: (string|null); + /** DNSSource dnsMethod. */ + public dnsMethod: proto.DNSSource.DNSSourceDNSResolutionMethod; - /** WebMessageInfo ignore */ - ignore?: (boolean|null); + /** DNSSource appCached. */ + public appCached: boolean; - /** WebMessageInfo starred */ - starred?: (boolean|null); + /** + * Creates a new DNSSource instance using the specified properties. + * @param [properties] Properties to set + * @returns DNSSource instance + */ + public static create(properties?: proto.IDNSSource): proto.DNSSource; - /** WebMessageInfo broadcast */ - broadcast?: (boolean|null); + /** + * Encodes the specified DNSSource message. Does not implicitly {@link proto.DNSSource.verify|verify} messages. + * @param message DNSSource message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IDNSSource, writer?: $protobuf.Writer): $protobuf.Writer; - /** WebMessageInfo pushName */ + /** + * Encodes the specified DNSSource message, length delimited. Does not implicitly {@link proto.DNSSource.verify|verify} messages. + * @param message DNSSource message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IDNSSource, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a DNSSource message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns DNSSource + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DNSSource; + + /** + * Decodes a DNSSource message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns DNSSource + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DNSSource; + + /** + * Verifies a DNSSource message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a DNSSource message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns DNSSource + */ + public static fromObject(object: { [k: string]: any }): proto.DNSSource; + + /** + * Creates a plain object from a DNSSource message. Also converts values to other types if specified. + * @param message DNSSource + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.DNSSource, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this DNSSource to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace DNSSource { + + /** DNSSourceDNSResolutionMethod enum. */ + enum DNSSourceDNSResolutionMethod { + SYSTEM = 0, + GOOGLE = 1, + HARDCODED = 2, + OVERRIDE = 3, + FALLBACK = 4 + } + } + + /** Properties of a CompanionRegData. */ + interface ICompanionRegData { + + /** CompanionRegData eRegid */ + eRegid?: (Uint8Array|null); + + /** CompanionRegData eKeytype */ + eKeytype?: (Uint8Array|null); + + /** CompanionRegData eIdent */ + eIdent?: (Uint8Array|null); + + /** CompanionRegData eSkeyId */ + eSkeyId?: (Uint8Array|null); + + /** CompanionRegData eSkeyVal */ + eSkeyVal?: (Uint8Array|null); + + /** CompanionRegData eSkeySig */ + eSkeySig?: (Uint8Array|null); + + /** CompanionRegData buildHash */ + buildHash?: (Uint8Array|null); + + /** CompanionRegData companionProps */ + companionProps?: (Uint8Array|null); + } + + /** Represents a CompanionRegData. */ + class CompanionRegData implements ICompanionRegData { + + /** + * Constructs a new CompanionRegData. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ICompanionRegData); + + /** CompanionRegData eRegid. */ + public eRegid: Uint8Array; + + /** CompanionRegData eKeytype. */ + public eKeytype: Uint8Array; + + /** CompanionRegData eIdent. */ + public eIdent: Uint8Array; + + /** CompanionRegData eSkeyId. */ + public eSkeyId: Uint8Array; + + /** CompanionRegData eSkeyVal. */ + public eSkeyVal: Uint8Array; + + /** CompanionRegData eSkeySig. */ + public eSkeySig: Uint8Array; + + /** CompanionRegData buildHash. */ + public buildHash: Uint8Array; + + /** CompanionRegData companionProps. */ + public companionProps: Uint8Array; + + /** + * Creates a new CompanionRegData instance using the specified properties. + * @param [properties] Properties to set + * @returns CompanionRegData instance + */ + public static create(properties?: proto.ICompanionRegData): proto.CompanionRegData; + + /** + * Encodes the specified CompanionRegData message. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages. + * @param message CompanionRegData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ICompanionRegData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified CompanionRegData message, length delimited. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages. + * @param message CompanionRegData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ICompanionRegData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a CompanionRegData message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns CompanionRegData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.CompanionRegData; + + /** + * Decodes a CompanionRegData message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns CompanionRegData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.CompanionRegData; + + /** + * Verifies a CompanionRegData message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a CompanionRegData message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns CompanionRegData + */ + public static fromObject(object: { [k: string]: any }): proto.CompanionRegData; + + /** + * Creates a plain object from a CompanionRegData message. Also converts values to other types if specified. + * @param message CompanionRegData + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.CompanionRegData, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this CompanionRegData to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ClientPayload. */ + interface IClientPayload { + + /** ClientPayload username */ + username?: (number|Long|null); + + /** ClientPayload passive */ + passive?: (boolean|null); + + /** ClientPayload clientFeatures */ + clientFeatures?: (proto.ClientPayload.ClientPayloadClientFeature[]|null); + + /** ClientPayload userAgent */ + userAgent?: (proto.IUserAgent|null); + + /** ClientPayload webInfo */ + webInfo?: (proto.IWebInfo|null); + + /** ClientPayload pushName */ pushName?: (string|null); - /** WebMessageInfo mediaCiphertextSha256 */ - mediaCiphertextSha256?: (Uint8Array|null); + /** ClientPayload sessionId */ + sessionId?: (number|null); - /** WebMessageInfo multicast */ - multicast?: (boolean|null); + /** ClientPayload shortConnect */ + shortConnect?: (boolean|null); - /** WebMessageInfo urlText */ - urlText?: (boolean|null); + /** ClientPayload iosAppExtension */ + iosAppExtension?: (proto.ClientPayload.ClientPayloadIOSAppExtension|null); - /** WebMessageInfo urlNumber */ - urlNumber?: (boolean|null); + /** ClientPayload connectType */ + connectType?: (proto.ClientPayload.ClientPayloadConnectType|null); - /** WebMessageInfo messageStubType */ - messageStubType?: (proto.WebMessageInfo.WebMessageInfoStubType|null); + /** ClientPayload connectReason */ + connectReason?: (proto.ClientPayload.ClientPayloadConnectReason|null); - /** WebMessageInfo clearMedia */ - clearMedia?: (boolean|null); + /** ClientPayload shards */ + shards?: (number[]|null); - /** WebMessageInfo messageStubParameters */ - messageStubParameters?: (string[]|null); + /** ClientPayload dnsSource */ + dnsSource?: (proto.IDNSSource|null); - /** WebMessageInfo duration */ - duration?: (number|null); + /** ClientPayload connectAttemptCount */ + connectAttemptCount?: (number|null); - /** WebMessageInfo labels */ - labels?: (string[]|null); + /** ClientPayload agent */ + agent?: (number|null); - /** WebMessageInfo paymentInfo */ - paymentInfo?: (proto.IPaymentInfo|null); + /** ClientPayload device */ + device?: (number|null); - /** WebMessageInfo finalLiveLocation */ - finalLiveLocation?: (proto.ILiveLocationMessage|null); + /** ClientPayload regData */ + regData?: (proto.ICompanionRegData|null); - /** WebMessageInfo quotedPaymentInfo */ - quotedPaymentInfo?: (proto.IPaymentInfo|null); + /** ClientPayload product */ + product?: (proto.ClientPayload.ClientPayloadProduct|null); - /** WebMessageInfo ephemeralStartTimestamp */ - ephemeralStartTimestamp?: (number|Long|null); + /** ClientPayload fbCat */ + fbCat?: (Uint8Array|null); - /** WebMessageInfo ephemeralDuration */ - ephemeralDuration?: (number|null); + /** ClientPayload fbUserAgent */ + fbUserAgent?: (Uint8Array|null); - /** WebMessageInfo ephemeralOffToOn */ - ephemeralOffToOn?: (boolean|null); - - /** WebMessageInfo ephemeralOutOfSync */ - ephemeralOutOfSync?: (boolean|null); - - /** WebMessageInfo bizPrivacyStatus */ - bizPrivacyStatus?: (proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus|null); - - /** WebMessageInfo verifiedBizName */ - verifiedBizName?: (string|null); + /** ClientPayload oc */ + oc?: (boolean|null); } - /** Represents a WebMessageInfo. */ - class WebMessageInfo implements IWebMessageInfo { + /** Represents a ClientPayload. */ + class ClientPayload implements IClientPayload { /** - * Constructs a new WebMessageInfo. + * Constructs a new ClientPayload. * @param [properties] Properties to set */ - constructor(properties?: proto.IWebMessageInfo); + constructor(properties?: proto.IClientPayload); - /** WebMessageInfo key. */ - public key: proto.IMessageKey; + /** ClientPayload username. */ + public username: (number|Long); - /** WebMessageInfo message. */ - public message?: (proto.IMessage|null); + /** ClientPayload passive. */ + public passive: boolean; - /** WebMessageInfo messageTimestamp. */ - public messageTimestamp: (number|Long); + /** ClientPayload clientFeatures. */ + public clientFeatures: proto.ClientPayload.ClientPayloadClientFeature[]; - /** WebMessageInfo status. */ - public status: proto.WebMessageInfo.WebMessageInfoStatus; + /** ClientPayload userAgent. */ + public userAgent?: (proto.IUserAgent|null); - /** WebMessageInfo participant. */ - public participant: string; + /** ClientPayload webInfo. */ + public webInfo?: (proto.IWebInfo|null); - /** WebMessageInfo ignore. */ - public ignore: boolean; - - /** WebMessageInfo starred. */ - public starred: boolean; - - /** WebMessageInfo broadcast. */ - public broadcast: boolean; - - /** WebMessageInfo pushName. */ + /** ClientPayload pushName. */ public pushName: string; - /** WebMessageInfo mediaCiphertextSha256. */ - public mediaCiphertextSha256: Uint8Array; + /** ClientPayload sessionId. */ + public sessionId: number; - /** WebMessageInfo multicast. */ - public multicast: boolean; + /** ClientPayload shortConnect. */ + public shortConnect: boolean; - /** WebMessageInfo urlText. */ - public urlText: boolean; + /** ClientPayload iosAppExtension. */ + public iosAppExtension: proto.ClientPayload.ClientPayloadIOSAppExtension; - /** WebMessageInfo urlNumber. */ - public urlNumber: boolean; + /** ClientPayload connectType. */ + public connectType: proto.ClientPayload.ClientPayloadConnectType; - /** WebMessageInfo messageStubType. */ - public messageStubType: proto.WebMessageInfo.WebMessageInfoStubType; + /** ClientPayload connectReason. */ + public connectReason: proto.ClientPayload.ClientPayloadConnectReason; - /** WebMessageInfo clearMedia. */ - public clearMedia: boolean; + /** ClientPayload shards. */ + public shards: number[]; - /** WebMessageInfo messageStubParameters. */ - public messageStubParameters: string[]; + /** ClientPayload dnsSource. */ + public dnsSource?: (proto.IDNSSource|null); - /** WebMessageInfo duration. */ - public duration: number; + /** ClientPayload connectAttemptCount. */ + public connectAttemptCount: number; - /** WebMessageInfo labels. */ - public labels: string[]; + /** ClientPayload agent. */ + public agent: number; - /** WebMessageInfo paymentInfo. */ - public paymentInfo?: (proto.IPaymentInfo|null); + /** ClientPayload device. */ + public device: number; - /** WebMessageInfo finalLiveLocation. */ - public finalLiveLocation?: (proto.ILiveLocationMessage|null); + /** ClientPayload regData. */ + public regData?: (proto.ICompanionRegData|null); - /** WebMessageInfo quotedPaymentInfo. */ - public quotedPaymentInfo?: (proto.IPaymentInfo|null); + /** ClientPayload product. */ + public product: proto.ClientPayload.ClientPayloadProduct; - /** WebMessageInfo ephemeralStartTimestamp. */ - public ephemeralStartTimestamp: (number|Long); + /** ClientPayload fbCat. */ + public fbCat: Uint8Array; - /** WebMessageInfo ephemeralDuration. */ - public ephemeralDuration: number; + /** ClientPayload fbUserAgent. */ + public fbUserAgent: Uint8Array; - /** WebMessageInfo ephemeralOffToOn. */ - public ephemeralOffToOn: boolean; - - /** WebMessageInfo ephemeralOutOfSync. */ - public ephemeralOutOfSync: boolean; - - /** WebMessageInfo bizPrivacyStatus. */ - public bizPrivacyStatus: proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus; - - /** WebMessageInfo verifiedBizName. */ - public verifiedBizName: string; + /** ClientPayload oc. */ + public oc: boolean; /** - * Creates a new WebMessageInfo instance using the specified properties. + * Creates a new ClientPayload instance using the specified properties. * @param [properties] Properties to set - * @returns WebMessageInfo instance + * @returns ClientPayload instance */ - public static create(properties?: proto.IWebMessageInfo): proto.WebMessageInfo; + public static create(properties?: proto.IClientPayload): proto.ClientPayload; /** - * Encodes the specified WebMessageInfo message. Does not implicitly {@link proto.WebMessageInfo.verify|verify} messages. - * @param message WebMessageInfo message or plain object to encode + * Encodes the specified ClientPayload message. Does not implicitly {@link proto.ClientPayload.verify|verify} messages. + * @param message ClientPayload message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encode(message: proto.IWebMessageInfo, writer?: $protobuf.Writer): $protobuf.Writer; + public static encode(message: proto.IClientPayload, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Encodes the specified WebMessageInfo message, length delimited. Does not implicitly {@link proto.WebMessageInfo.verify|verify} messages. - * @param message WebMessageInfo message or plain object to encode + * Encodes the specified ClientPayload message, length delimited. Does not implicitly {@link proto.ClientPayload.verify|verify} messages. + * @param message ClientPayload message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encodeDelimited(message: proto.IWebMessageInfo, writer?: $protobuf.Writer): $protobuf.Writer; + public static encodeDelimited(message: proto.IClientPayload, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Decodes a WebMessageInfo message from the specified reader or buffer. + * Decodes a ClientPayload message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns WebMessageInfo + * @returns ClientPayload * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WebMessageInfo; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ClientPayload; /** - * Decodes a WebMessageInfo message from the specified reader or buffer, length delimited. + * Decodes a ClientPayload message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns WebMessageInfo + * @returns ClientPayload * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WebMessageInfo; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ClientPayload; /** - * Verifies a WebMessageInfo message. + * Verifies a ClientPayload message. * @param message Plain object to verify * @returns `null` if valid, otherwise the reason why it is not */ public static verify(message: { [k: string]: any }): (string|null); /** - * Creates a WebMessageInfo message from a plain object. Also converts values to their respective internal types. + * Creates a ClientPayload message from a plain object. Also converts values to their respective internal types. * @param object Plain object - * @returns WebMessageInfo + * @returns ClientPayload */ - public static fromObject(object: { [k: string]: any }): proto.WebMessageInfo; + public static fromObject(object: { [k: string]: any }): proto.ClientPayload; /** - * Creates a plain object from a WebMessageInfo message. Also converts values to other types if specified. - * @param message WebMessageInfo + * Creates a plain object from a ClientPayload message. Also converts values to other types if specified. + * @param message ClientPayload * @param [options] Conversion options * @returns Plain object */ - public static toObject(message: proto.WebMessageInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + public static toObject(message: proto.ClientPayload, options?: $protobuf.IConversionOptions): { [k: string]: any }; /** - * Converts this WebMessageInfo to JSON. + * Converts this ClientPayload to JSON. * @returns JSON object */ public toJSON(): { [k: string]: any }; } - namespace WebMessageInfo { + namespace ClientPayload { - /** WebMessageInfoStatus enum. */ - enum WebMessageInfoStatus { - ERROR = 0, - PENDING = 1, - SERVER_ACK = 2, - DELIVERY_ACK = 3, - READ = 4, - PLAYED = 5 + /** ClientPayloadClientFeature enum. */ + enum ClientPayloadClientFeature { + NONE = 0 } - /** WebMessageInfoStubType enum. */ - enum WebMessageInfoStubType { + /** ClientPayloadIOSAppExtension enum. */ + enum ClientPayloadIOSAppExtension { + SHARE_EXTENSION = 0, + SERVICE_EXTENSION = 1, + INTENTS_EXTENSION = 2 + } + + /** ClientPayloadConnectType enum. */ + enum ClientPayloadConnectType { + CELLULAR_UNKNOWN = 0, + WIFI_UNKNOWN = 1, + CELLULAR_EDGE = 100, + CELLULAR_IDEN = 101, + CELLULAR_UMTS = 102, + CELLULAR_EVDO = 103, + CELLULAR_GPRS = 104, + CELLULAR_HSDPA = 105, + CELLULAR_HSUPA = 106, + CELLULAR_HSPA = 107, + CELLULAR_CDMA = 108, + CELLULAR_1XRTT = 109, + CELLULAR_EHRPD = 110, + CELLULAR_LTE = 111, + CELLULAR_HSPAP = 112 + } + + /** ClientPayloadConnectReason enum. */ + enum ClientPayloadConnectReason { + PUSH = 0, + USER_ACTIVATED = 1, + SCHEDULED = 2, + ERROR_RECONNECT = 3, + NETWORK_SWITCH = 4, + PING_RECONNECT = 5 + } + + /** ClientPayloadProduct enum. */ + enum ClientPayloadProduct { + WHATSAPP = 0, + MESSENGER = 1 + } + } + + /** Properties of a NoiseCertificate. */ + interface INoiseCertificate { + + /** NoiseCertificate details */ + details?: (Uint8Array|null); + + /** NoiseCertificate signature */ + signature?: (Uint8Array|null); + } + + /** Represents a NoiseCertificate. */ + class NoiseCertificate implements INoiseCertificate { + + /** + * Constructs a new NoiseCertificate. + * @param [properties] Properties to set + */ + constructor(properties?: proto.INoiseCertificate); + + /** NoiseCertificate details. */ + public details: Uint8Array; + + /** NoiseCertificate signature. */ + public signature: Uint8Array; + + /** + * Creates a new NoiseCertificate instance using the specified properties. + * @param [properties] Properties to set + * @returns NoiseCertificate instance + */ + public static create(properties?: proto.INoiseCertificate): proto.NoiseCertificate; + + /** + * Encodes the specified NoiseCertificate message. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages. + * @param message NoiseCertificate message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.INoiseCertificate, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified NoiseCertificate message, length delimited. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages. + * @param message NoiseCertificate message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.INoiseCertificate, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a NoiseCertificate message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns NoiseCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.NoiseCertificate; + + /** + * Decodes a NoiseCertificate message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns NoiseCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.NoiseCertificate; + + /** + * Verifies a NoiseCertificate message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a NoiseCertificate message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns NoiseCertificate + */ + public static fromObject(object: { [k: string]: any }): proto.NoiseCertificate; + + /** + * Creates a plain object from a NoiseCertificate message. Also converts values to other types if specified. + * @param message NoiseCertificate + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.NoiseCertificate, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this NoiseCertificate to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ClientHello. */ + interface IClientHello { + + /** ClientHello ephemeral */ + ephemeral?: (Uint8Array|null); + + /** ClientHello static */ + "static"?: (Uint8Array|null); + + /** ClientHello payload */ + payload?: (Uint8Array|null); + } + + /** Represents a ClientHello. */ + class ClientHello implements IClientHello { + + /** + * Constructs a new ClientHello. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IClientHello); + + /** ClientHello ephemeral. */ + public ephemeral: Uint8Array; + + /** ClientHello static. */ + public static: Uint8Array; + + /** ClientHello payload. */ + public payload: Uint8Array; + + /** + * Creates a new ClientHello instance using the specified properties. + * @param [properties] Properties to set + * @returns ClientHello instance + */ + public static create(properties?: proto.IClientHello): proto.ClientHello; + + /** + * Encodes the specified ClientHello message. Does not implicitly {@link proto.ClientHello.verify|verify} messages. + * @param message ClientHello message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IClientHello, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ClientHello message, length delimited. Does not implicitly {@link proto.ClientHello.verify|verify} messages. + * @param message ClientHello message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IClientHello, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ClientHello message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ClientHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ClientHello; + + /** + * Decodes a ClientHello message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ClientHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ClientHello; + + /** + * Verifies a ClientHello message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ClientHello message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ClientHello + */ + public static fromObject(object: { [k: string]: any }): proto.ClientHello; + + /** + * Creates a plain object from a ClientHello message. Also converts values to other types if specified. + * @param message ClientHello + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ClientHello, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ClientHello to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ServerHello. */ + interface IServerHello { + + /** ServerHello ephemeral */ + ephemeral?: (Uint8Array|null); + + /** ServerHello static */ + "static"?: (Uint8Array|null); + + /** ServerHello payload */ + payload?: (Uint8Array|null); + } + + /** Represents a ServerHello. */ + class ServerHello implements IServerHello { + + /** + * Constructs a new ServerHello. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IServerHello); + + /** ServerHello ephemeral. */ + public ephemeral: Uint8Array; + + /** ServerHello static. */ + public static: Uint8Array; + + /** ServerHello payload. */ + public payload: Uint8Array; + + /** + * Creates a new ServerHello instance using the specified properties. + * @param [properties] Properties to set + * @returns ServerHello instance + */ + public static create(properties?: proto.IServerHello): proto.ServerHello; + + /** + * Encodes the specified ServerHello message. Does not implicitly {@link proto.ServerHello.verify|verify} messages. + * @param message ServerHello message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IServerHello, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ServerHello message, length delimited. Does not implicitly {@link proto.ServerHello.verify|verify} messages. + * @param message ServerHello message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IServerHello, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ServerHello message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ServerHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ServerHello; + + /** + * Decodes a ServerHello message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ServerHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ServerHello; + + /** + * Verifies a ServerHello message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ServerHello message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ServerHello + */ + public static fromObject(object: { [k: string]: any }): proto.ServerHello; + + /** + * Creates a plain object from a ServerHello message. Also converts values to other types if specified. + * @param message ServerHello + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ServerHello, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ServerHello to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ClientFinish. */ + interface IClientFinish { + + /** ClientFinish static */ + "static"?: (Uint8Array|null); + + /** ClientFinish payload */ + payload?: (Uint8Array|null); + } + + /** Represents a ClientFinish. */ + class ClientFinish implements IClientFinish { + + /** + * Constructs a new ClientFinish. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IClientFinish); + + /** ClientFinish static. */ + public static: Uint8Array; + + /** ClientFinish payload. */ + public payload: Uint8Array; + + /** + * Creates a new ClientFinish instance using the specified properties. + * @param [properties] Properties to set + * @returns ClientFinish instance + */ + public static create(properties?: proto.IClientFinish): proto.ClientFinish; + + /** + * Encodes the specified ClientFinish message. Does not implicitly {@link proto.ClientFinish.verify|verify} messages. + * @param message ClientFinish message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IClientFinish, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ClientFinish message, length delimited. Does not implicitly {@link proto.ClientFinish.verify|verify} messages. + * @param message ClientFinish message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IClientFinish, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ClientFinish message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ClientFinish + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ClientFinish; + + /** + * Decodes a ClientFinish message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ClientFinish + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ClientFinish; + + /** + * Verifies a ClientFinish message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ClientFinish message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ClientFinish + */ + public static fromObject(object: { [k: string]: any }): proto.ClientFinish; + + /** + * Creates a plain object from a ClientFinish message. Also converts values to other types if specified. + * @param message ClientFinish + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ClientFinish, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ClientFinish to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HandshakeMessage. */ + interface IHandshakeMessage { + + /** HandshakeMessage clientHello */ + clientHello?: (proto.IClientHello|null); + + /** HandshakeMessage serverHello */ + serverHello?: (proto.IServerHello|null); + + /** HandshakeMessage clientFinish */ + clientFinish?: (proto.IClientFinish|null); + } + + /** Represents a HandshakeMessage. */ + class HandshakeMessage implements IHandshakeMessage { + + /** + * Constructs a new HandshakeMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHandshakeMessage); + + /** HandshakeMessage clientHello. */ + public clientHello?: (proto.IClientHello|null); + + /** HandshakeMessage serverHello. */ + public serverHello?: (proto.IServerHello|null); + + /** HandshakeMessage clientFinish. */ + public clientFinish?: (proto.IClientFinish|null); + + /** + * Creates a new HandshakeMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns HandshakeMessage instance + */ + public static create(properties?: proto.IHandshakeMessage): proto.HandshakeMessage; + + /** + * Encodes the specified HandshakeMessage message. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages. + * @param message HandshakeMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHandshakeMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HandshakeMessage message, length delimited. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages. + * @param message HandshakeMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHandshakeMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HandshakeMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HandshakeMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HandshakeMessage; + + /** + * Decodes a HandshakeMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HandshakeMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HandshakeMessage; + + /** + * Verifies a HandshakeMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HandshakeMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HandshakeMessage + */ + public static fromObject(object: { [k: string]: any }): proto.HandshakeMessage; + + /** + * Creates a plain object from a HandshakeMessage message. Also converts values to other types if specified. + * @param message HandshakeMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HandshakeMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HandshakeMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a BizIdentityInfo. */ + interface IBizIdentityInfo { + + /** BizIdentityInfo vlevel */ + vlevel?: (proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue|null); + + /** BizIdentityInfo vnameCert */ + vnameCert?: (proto.IVerifiedNameCertificate|null); + + /** BizIdentityInfo signed */ + signed?: (boolean|null); + + /** BizIdentityInfo revoked */ + revoked?: (boolean|null); + + /** BizIdentityInfo hostStorage */ + hostStorage?: (proto.BizIdentityInfo.BizIdentityInfoHostStorageType|null); + + /** BizIdentityInfo actualActors */ + actualActors?: (proto.BizIdentityInfo.BizIdentityInfoActualActorsType|null); + + /** BizIdentityInfo privacyModeTs */ + privacyModeTs?: (number|Long|null); + } + + /** Represents a BizIdentityInfo. */ + class BizIdentityInfo implements IBizIdentityInfo { + + /** + * Constructs a new BizIdentityInfo. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IBizIdentityInfo); + + /** BizIdentityInfo vlevel. */ + public vlevel: proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue; + + /** BizIdentityInfo vnameCert. */ + public vnameCert?: (proto.IVerifiedNameCertificate|null); + + /** BizIdentityInfo signed. */ + public signed: boolean; + + /** BizIdentityInfo revoked. */ + public revoked: boolean; + + /** BizIdentityInfo hostStorage. */ + public hostStorage: proto.BizIdentityInfo.BizIdentityInfoHostStorageType; + + /** BizIdentityInfo actualActors. */ + public actualActors: proto.BizIdentityInfo.BizIdentityInfoActualActorsType; + + /** BizIdentityInfo privacyModeTs. */ + public privacyModeTs: (number|Long); + + /** + * Creates a new BizIdentityInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns BizIdentityInfo instance + */ + public static create(properties?: proto.IBizIdentityInfo): proto.BizIdentityInfo; + + /** + * Encodes the specified BizIdentityInfo message. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages. + * @param message BizIdentityInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IBizIdentityInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified BizIdentityInfo message, length delimited. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages. + * @param message BizIdentityInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IBizIdentityInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a BizIdentityInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns BizIdentityInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.BizIdentityInfo; + + /** + * Decodes a BizIdentityInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns BizIdentityInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.BizIdentityInfo; + + /** + * Verifies a BizIdentityInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a BizIdentityInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns BizIdentityInfo + */ + public static fromObject(object: { [k: string]: any }): proto.BizIdentityInfo; + + /** + * Creates a plain object from a BizIdentityInfo message. Also converts values to other types if specified. + * @param message BizIdentityInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.BizIdentityInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this BizIdentityInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace BizIdentityInfo { + + /** BizIdentityInfoVerifiedLevelValue enum. */ + enum BizIdentityInfoVerifiedLevelValue { UNKNOWN = 0, - REVOKE = 1, - CIPHERTEXT = 2, - FUTUREPROOF = 3, - NON_VERIFIED_TRANSITION = 4, - UNVERIFIED_TRANSITION = 5, - VERIFIED_TRANSITION = 6, - VERIFIED_LOW_UNKNOWN = 7, - VERIFIED_HIGH = 8, - VERIFIED_INITIAL_UNKNOWN = 9, - VERIFIED_INITIAL_LOW = 10, - VERIFIED_INITIAL_HIGH = 11, - VERIFIED_TRANSITION_ANY_TO_NONE = 12, - VERIFIED_TRANSITION_ANY_TO_HIGH = 13, - VERIFIED_TRANSITION_HIGH_TO_LOW = 14, - VERIFIED_TRANSITION_HIGH_TO_UNKNOWN = 15, - VERIFIED_TRANSITION_UNKNOWN_TO_LOW = 16, - VERIFIED_TRANSITION_LOW_TO_UNKNOWN = 17, - VERIFIED_TRANSITION_NONE_TO_LOW = 18, - VERIFIED_TRANSITION_NONE_TO_UNKNOWN = 19, - GROUP_CREATE = 20, - GROUP_CHANGE_SUBJECT = 21, - GROUP_CHANGE_ICON = 22, - GROUP_CHANGE_INVITE_LINK = 23, - GROUP_CHANGE_DESCRIPTION = 24, - GROUP_CHANGE_RESTRICT = 25, - GROUP_CHANGE_ANNOUNCE = 26, - GROUP_PARTICIPANT_ADD = 27, - GROUP_PARTICIPANT_REMOVE = 28, - GROUP_PARTICIPANT_PROMOTE = 29, - GROUP_PARTICIPANT_DEMOTE = 30, - GROUP_PARTICIPANT_INVITE = 31, - GROUP_PARTICIPANT_LEAVE = 32, - GROUP_PARTICIPANT_CHANGE_NUMBER = 33, - BROADCAST_CREATE = 34, - BROADCAST_ADD = 35, - BROADCAST_REMOVE = 36, - GENERIC_NOTIFICATION = 37, - E2E_IDENTITY_CHANGED = 38, - E2E_ENCRYPTED = 39, - CALL_MISSED_VOICE = 40, - CALL_MISSED_VIDEO = 41, - INDIVIDUAL_CHANGE_NUMBER = 42, - GROUP_DELETE = 43, - GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE = 44, - CALL_MISSED_GROUP_VOICE = 45, - CALL_MISSED_GROUP_VIDEO = 46, - PAYMENT_CIPHERTEXT = 47, - PAYMENT_FUTUREPROOF = 48, - PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED = 49, - PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED = 50, - PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED = 51, - PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP = 52, - PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP = 53, - PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER = 54, - PAYMENT_ACTION_SEND_PAYMENT_REMINDER = 55, - PAYMENT_ACTION_SEND_PAYMENT_INVITATION = 56, - PAYMENT_ACTION_REQUEST_DECLINED = 57, - PAYMENT_ACTION_REQUEST_EXPIRED = 58, - PAYMENT_ACTION_REQUEST_CANCELLED = 59, - BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM = 60, - BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP = 61, - BIZ_INTRO_TOP = 62, - BIZ_INTRO_BOTTOM = 63, - BIZ_NAME_CHANGE = 64, - BIZ_MOVE_TO_CONSUMER_APP = 65, - BIZ_TWO_TIER_MIGRATION_TOP = 66, - BIZ_TWO_TIER_MIGRATION_BOTTOM = 67, - OVERSIZED = 68, - GROUP_CHANGE_NO_FREQUENTLY_FORWARDED = 69, - GROUP_V4_ADD_INVITE_SENT = 70, - GROUP_PARTICIPANT_ADD_REQUEST_JOIN = 71, - CHANGE_EPHEMERAL_SETTING = 72, - E2E_DEVICE_CHANGED = 73, - VIEWED_ONCE = 74, - E2E_ENCRYPTED_NOW = 75, - BLUE_MSG_BSP_FB_TO_BSP_PREMISE = 76, - BLUE_MSG_BSP_FB_TO_SELF_FB = 77, - BLUE_MSG_BSP_FB_TO_SELF_PREMISE = 78, - BLUE_MSG_BSP_FB_UNVERIFIED = 79, - BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED = 80, - BLUE_MSG_BSP_FB_VERIFIED = 81, - BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED = 82, - BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE = 83, - BLUE_MSG_BSP_PREMISE_UNVERIFIED = 84, - BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED = 85, - BLUE_MSG_BSP_PREMISE_VERIFIED = 86, - BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED = 87, - BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED = 88, - BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED = 89, - BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED = 90, - BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED = 91, - BLUE_MSG_SELF_FB_TO_BSP_PREMISE = 92, - BLUE_MSG_SELF_FB_TO_SELF_PREMISE = 93, - BLUE_MSG_SELF_FB_UNVERIFIED = 94, - BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED = 95, - BLUE_MSG_SELF_FB_VERIFIED = 96, - BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED = 97, - BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE = 98, - BLUE_MSG_SELF_PREMISE_UNVERIFIED = 99, - BLUE_MSG_SELF_PREMISE_VERIFIED = 100, - BLUE_MSG_TO_BSP_FB = 101, - BLUE_MSG_TO_CONSUMER = 102, - BLUE_MSG_TO_SELF_FB = 103, - BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED = 104, - BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED = 105, - BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED = 106, - BLUE_MSG_UNVERIFIED_TO_VERIFIED = 107, - BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED = 108, - BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED = 109, - BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED = 110, - BLUE_MSG_VERIFIED_TO_UNVERIFIED = 111, - BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED = 112, - BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED = 113, - BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED = 114, - BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED = 115, - BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED = 116, - BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED = 117, - E2E_IDENTITY_UNAVAILABLE = 118 + LOW = 1, + HIGH = 2 } - /** WebMessageInfoBizPrivacyStatus enum. */ - enum WebMessageInfoBizPrivacyStatus { - E2EE = 0, - FB = 2, - BSP = 1, - BSP_AND_FB = 3 + /** BizIdentityInfoHostStorageType enum. */ + enum BizIdentityInfoHostStorageType { + ON_PREMISE = 0, + FACEBOOK = 1 } + + /** BizIdentityInfoActualActorsType enum. */ + enum BizIdentityInfoActualActorsType { + SELF = 0, + BSP = 1 + } + } + + /** Properties of a BizAccountLinkInfo. */ + interface IBizAccountLinkInfo { + + /** BizAccountLinkInfo whatsappBizAcctFbid */ + whatsappBizAcctFbid?: (number|Long|null); + + /** BizAccountLinkInfo whatsappAcctNumber */ + whatsappAcctNumber?: (string|null); + + /** BizAccountLinkInfo issueTime */ + issueTime?: (number|Long|null); + + /** BizAccountLinkInfo hostStorage */ + hostStorage?: (proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType|null); + + /** BizAccountLinkInfo accountType */ + accountType?: (proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType|null); + } + + /** Represents a BizAccountLinkInfo. */ + class BizAccountLinkInfo implements IBizAccountLinkInfo { + + /** + * Constructs a new BizAccountLinkInfo. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IBizAccountLinkInfo); + + /** BizAccountLinkInfo whatsappBizAcctFbid. */ + public whatsappBizAcctFbid: (number|Long); + + /** BizAccountLinkInfo whatsappAcctNumber. */ + public whatsappAcctNumber: string; + + /** BizAccountLinkInfo issueTime. */ + public issueTime: (number|Long); + + /** BizAccountLinkInfo hostStorage. */ + public hostStorage: proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType; + + /** BizAccountLinkInfo accountType. */ + public accountType: proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType; + + /** + * Creates a new BizAccountLinkInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns BizAccountLinkInfo instance + */ + public static create(properties?: proto.IBizAccountLinkInfo): proto.BizAccountLinkInfo; + + /** + * Encodes the specified BizAccountLinkInfo message. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages. + * @param message BizAccountLinkInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IBizAccountLinkInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified BizAccountLinkInfo message, length delimited. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages. + * @param message BizAccountLinkInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IBizAccountLinkInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a BizAccountLinkInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns BizAccountLinkInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.BizAccountLinkInfo; + + /** + * Decodes a BizAccountLinkInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns BizAccountLinkInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.BizAccountLinkInfo; + + /** + * Verifies a BizAccountLinkInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a BizAccountLinkInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns BizAccountLinkInfo + */ + public static fromObject(object: { [k: string]: any }): proto.BizAccountLinkInfo; + + /** + * Creates a plain object from a BizAccountLinkInfo message. Also converts values to other types if specified. + * @param message BizAccountLinkInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.BizAccountLinkInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this BizAccountLinkInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace BizAccountLinkInfo { + + /** BizAccountLinkInfoHostStorageType enum. */ + enum BizAccountLinkInfoHostStorageType { + ON_PREMISE = 0, + FACEBOOK = 1 + } + + /** BizAccountLinkInfoAccountType enum. */ + enum BizAccountLinkInfoAccountType { + ENTERPRISE = 0, + PAGE = 1 + } + } + + /** Properties of a BizAccountPayload. */ + interface IBizAccountPayload { + + /** BizAccountPayload vnameCert */ + vnameCert?: (proto.IVerifiedNameCertificate|null); + + /** BizAccountPayload bizAcctLinkInfo */ + bizAcctLinkInfo?: (Uint8Array|null); + } + + /** Represents a BizAccountPayload. */ + class BizAccountPayload implements IBizAccountPayload { + + /** + * Constructs a new BizAccountPayload. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IBizAccountPayload); + + /** BizAccountPayload vnameCert. */ + public vnameCert?: (proto.IVerifiedNameCertificate|null); + + /** BizAccountPayload bizAcctLinkInfo. */ + public bizAcctLinkInfo: Uint8Array; + + /** + * Creates a new BizAccountPayload instance using the specified properties. + * @param [properties] Properties to set + * @returns BizAccountPayload instance + */ + public static create(properties?: proto.IBizAccountPayload): proto.BizAccountPayload; + + /** + * Encodes the specified BizAccountPayload message. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages. + * @param message BizAccountPayload message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IBizAccountPayload, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified BizAccountPayload message, length delimited. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages. + * @param message BizAccountPayload message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IBizAccountPayload, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a BizAccountPayload message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns BizAccountPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.BizAccountPayload; + + /** + * Decodes a BizAccountPayload message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns BizAccountPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.BizAccountPayload; + + /** + * Verifies a BizAccountPayload message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a BizAccountPayload message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns BizAccountPayload + */ + public static fromObject(object: { [k: string]: any }): proto.BizAccountPayload; + + /** + * Creates a plain object from a BizAccountPayload message. Also converts values to other types if specified. + * @param message BizAccountPayload + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.BizAccountPayload, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this BizAccountPayload to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a VerifiedNameCertificate. */ + interface IVerifiedNameCertificate { + + /** VerifiedNameCertificate details */ + details?: (Uint8Array|null); + + /** VerifiedNameCertificate signature */ + signature?: (Uint8Array|null); + + /** VerifiedNameCertificate serverSignature */ + serverSignature?: (Uint8Array|null); + } + + /** Represents a VerifiedNameCertificate. */ + class VerifiedNameCertificate implements IVerifiedNameCertificate { + + /** + * Constructs a new VerifiedNameCertificate. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IVerifiedNameCertificate); + + /** VerifiedNameCertificate details. */ + public details: Uint8Array; + + /** VerifiedNameCertificate signature. */ + public signature: Uint8Array; + + /** VerifiedNameCertificate serverSignature. */ + public serverSignature: Uint8Array; + + /** + * Creates a new VerifiedNameCertificate instance using the specified properties. + * @param [properties] Properties to set + * @returns VerifiedNameCertificate instance + */ + public static create(properties?: proto.IVerifiedNameCertificate): proto.VerifiedNameCertificate; + + /** + * Encodes the specified VerifiedNameCertificate message. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages. + * @param message VerifiedNameCertificate message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IVerifiedNameCertificate, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified VerifiedNameCertificate message, length delimited. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages. + * @param message VerifiedNameCertificate message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IVerifiedNameCertificate, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a VerifiedNameCertificate message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns VerifiedNameCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.VerifiedNameCertificate; + + /** + * Decodes a VerifiedNameCertificate message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns VerifiedNameCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.VerifiedNameCertificate; + + /** + * Verifies a VerifiedNameCertificate message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a VerifiedNameCertificate message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns VerifiedNameCertificate + */ + public static fromObject(object: { [k: string]: any }): proto.VerifiedNameCertificate; + + /** + * Creates a plain object from a VerifiedNameCertificate message. Also converts values to other types if specified. + * @param message VerifiedNameCertificate + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.VerifiedNameCertificate, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this VerifiedNameCertificate to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a LocalizedName. */ + interface ILocalizedName { + + /** LocalizedName lg */ + lg?: (string|null); + + /** LocalizedName lc */ + lc?: (string|null); + + /** LocalizedName verifiedName */ + verifiedName?: (string|null); + } + + /** Represents a LocalizedName. */ + class LocalizedName implements ILocalizedName { + + /** + * Constructs a new LocalizedName. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ILocalizedName); + + /** LocalizedName lg. */ + public lg: string; + + /** LocalizedName lc. */ + public lc: string; + + /** LocalizedName verifiedName. */ + public verifiedName: string; + + /** + * Creates a new LocalizedName instance using the specified properties. + * @param [properties] Properties to set + * @returns LocalizedName instance + */ + public static create(properties?: proto.ILocalizedName): proto.LocalizedName; + + /** + * Encodes the specified LocalizedName message. Does not implicitly {@link proto.LocalizedName.verify|verify} messages. + * @param message LocalizedName message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ILocalizedName, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified LocalizedName message, length delimited. Does not implicitly {@link proto.LocalizedName.verify|verify} messages. + * @param message LocalizedName message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ILocalizedName, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a LocalizedName message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns LocalizedName + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.LocalizedName; + + /** + * Decodes a LocalizedName message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns LocalizedName + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.LocalizedName; + + /** + * Verifies a LocalizedName message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a LocalizedName message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns LocalizedName + */ + public static fromObject(object: { [k: string]: any }): proto.LocalizedName; + + /** + * Creates a plain object from a LocalizedName message. Also converts values to other types if specified. + * @param message LocalizedName + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.LocalizedName, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this LocalizedName to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncActionData. */ + interface ISyncActionData { + + /** SyncActionData index */ + index?: (Uint8Array|null); + + /** SyncActionData value */ + value?: (proto.ISyncActionValue|null); + + /** SyncActionData padding */ + padding?: (Uint8Array|null); + + /** SyncActionData version */ + version?: (number|null); + } + + /** Represents a SyncActionData. */ + class SyncActionData implements ISyncActionData { + + /** + * Constructs a new SyncActionData. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncActionData); + + /** SyncActionData index. */ + public index: Uint8Array; + + /** SyncActionData value. */ + public value?: (proto.ISyncActionValue|null); + + /** SyncActionData padding. */ + public padding: Uint8Array; + + /** SyncActionData version. */ + public version: number; + + /** + * Creates a new SyncActionData instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncActionData instance + */ + public static create(properties?: proto.ISyncActionData): proto.SyncActionData; + + /** + * Encodes the specified SyncActionData message. Does not implicitly {@link proto.SyncActionData.verify|verify} messages. + * @param message SyncActionData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncActionData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncActionData message, length delimited. Does not implicitly {@link proto.SyncActionData.verify|verify} messages. + * @param message SyncActionData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncActionData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncActionData message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncActionData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncActionData; + + /** + * Decodes a SyncActionData message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncActionData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncActionData; + + /** + * Verifies a SyncActionData message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncActionData message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncActionData + */ + public static fromObject(object: { [k: string]: any }): proto.SyncActionData; + + /** + * Creates a plain object from a SyncActionData message. Also converts values to other types if specified. + * @param message SyncActionData + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncActionData, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncActionData to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a StarAction. */ + interface IStarAction { + + /** StarAction starred */ + starred?: (boolean|null); + } + + /** Represents a StarAction. */ + class StarAction implements IStarAction { + + /** + * Constructs a new StarAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IStarAction); + + /** StarAction starred. */ + public starred: boolean; + + /** + * Creates a new StarAction instance using the specified properties. + * @param [properties] Properties to set + * @returns StarAction instance + */ + public static create(properties?: proto.IStarAction): proto.StarAction; + + /** + * Encodes the specified StarAction message. Does not implicitly {@link proto.StarAction.verify|verify} messages. + * @param message StarAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IStarAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified StarAction message, length delimited. Does not implicitly {@link proto.StarAction.verify|verify} messages. + * @param message StarAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IStarAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a StarAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns StarAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.StarAction; + + /** + * Decodes a StarAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns StarAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.StarAction; + + /** + * Verifies a StarAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a StarAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns StarAction + */ + public static fromObject(object: { [k: string]: any }): proto.StarAction; + + /** + * Creates a plain object from a StarAction message. Also converts values to other types if specified. + * @param message StarAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.StarAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this StarAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ContactAction. */ + interface IContactAction { + + /** ContactAction fullName */ + fullName?: (string|null); + + /** ContactAction firstName */ + firstName?: (string|null); + } + + /** Represents a ContactAction. */ + class ContactAction implements IContactAction { + + /** + * Constructs a new ContactAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IContactAction); + + /** ContactAction fullName. */ + public fullName: string; + + /** ContactAction firstName. */ + public firstName: string; + + /** + * Creates a new ContactAction instance using the specified properties. + * @param [properties] Properties to set + * @returns ContactAction instance + */ + public static create(properties?: proto.IContactAction): proto.ContactAction; + + /** + * Encodes the specified ContactAction message. Does not implicitly {@link proto.ContactAction.verify|verify} messages. + * @param message ContactAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IContactAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ContactAction message, length delimited. Does not implicitly {@link proto.ContactAction.verify|verify} messages. + * @param message ContactAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IContactAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ContactAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ContactAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ContactAction; + + /** + * Decodes a ContactAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ContactAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ContactAction; + + /** + * Verifies a ContactAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ContactAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ContactAction + */ + public static fromObject(object: { [k: string]: any }): proto.ContactAction; + + /** + * Creates a plain object from a ContactAction message. Also converts values to other types if specified. + * @param message ContactAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ContactAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ContactAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a MuteAction. */ + interface IMuteAction { + + /** MuteAction muted */ + muted?: (boolean|null); + + /** MuteAction muteEndTimestamp */ + muteEndTimestamp?: (number|Long|null); + } + + /** Represents a MuteAction. */ + class MuteAction implements IMuteAction { + + /** + * Constructs a new MuteAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMuteAction); + + /** MuteAction muted. */ + public muted: boolean; + + /** MuteAction muteEndTimestamp. */ + public muteEndTimestamp: (number|Long); + + /** + * Creates a new MuteAction instance using the specified properties. + * @param [properties] Properties to set + * @returns MuteAction instance + */ + public static create(properties?: proto.IMuteAction): proto.MuteAction; + + /** + * Encodes the specified MuteAction message. Does not implicitly {@link proto.MuteAction.verify|verify} messages. + * @param message MuteAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMuteAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MuteAction message, length delimited. Does not implicitly {@link proto.MuteAction.verify|verify} messages. + * @param message MuteAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMuteAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MuteAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MuteAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MuteAction; + + /** + * Decodes a MuteAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MuteAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MuteAction; + + /** + * Verifies a MuteAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MuteAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MuteAction + */ + public static fromObject(object: { [k: string]: any }): proto.MuteAction; + + /** + * Creates a plain object from a MuteAction message. Also converts values to other types if specified. + * @param message MuteAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MuteAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MuteAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a PinAction. */ + interface IPinAction { + + /** PinAction pinned */ + pinned?: (boolean|null); + } + + /** Represents a PinAction. */ + class PinAction implements IPinAction { + + /** + * Constructs a new PinAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPinAction); + + /** PinAction pinned. */ + public pinned: boolean; + + /** + * Creates a new PinAction instance using the specified properties. + * @param [properties] Properties to set + * @returns PinAction instance + */ + public static create(properties?: proto.IPinAction): proto.PinAction; + + /** + * Encodes the specified PinAction message. Does not implicitly {@link proto.PinAction.verify|verify} messages. + * @param message PinAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPinAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified PinAction message, length delimited. Does not implicitly {@link proto.PinAction.verify|verify} messages. + * @param message PinAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPinAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a PinAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns PinAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PinAction; + + /** + * Decodes a PinAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns PinAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PinAction; + + /** + * Verifies a PinAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a PinAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns PinAction + */ + public static fromObject(object: { [k: string]: any }): proto.PinAction; + + /** + * Creates a plain object from a PinAction message. Also converts values to other types if specified. + * @param message PinAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.PinAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this PinAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SecurityNotificationSetting. */ + interface ISecurityNotificationSetting { + + /** SecurityNotificationSetting showNotification */ + showNotification?: (boolean|null); + } + + /** Represents a SecurityNotificationSetting. */ + class SecurityNotificationSetting implements ISecurityNotificationSetting { + + /** + * Constructs a new SecurityNotificationSetting. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISecurityNotificationSetting); + + /** SecurityNotificationSetting showNotification. */ + public showNotification: boolean; + + /** + * Creates a new SecurityNotificationSetting instance using the specified properties. + * @param [properties] Properties to set + * @returns SecurityNotificationSetting instance + */ + public static create(properties?: proto.ISecurityNotificationSetting): proto.SecurityNotificationSetting; + + /** + * Encodes the specified SecurityNotificationSetting message. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages. + * @param message SecurityNotificationSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISecurityNotificationSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SecurityNotificationSetting message, length delimited. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages. + * @param message SecurityNotificationSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISecurityNotificationSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SecurityNotificationSetting message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SecurityNotificationSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SecurityNotificationSetting; + + /** + * Decodes a SecurityNotificationSetting message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SecurityNotificationSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SecurityNotificationSetting; + + /** + * Verifies a SecurityNotificationSetting message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SecurityNotificationSetting message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SecurityNotificationSetting + */ + public static fromObject(object: { [k: string]: any }): proto.SecurityNotificationSetting; + + /** + * Creates a plain object from a SecurityNotificationSetting message. Also converts values to other types if specified. + * @param message SecurityNotificationSetting + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SecurityNotificationSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SecurityNotificationSetting to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a PushNameSetting. */ + interface IPushNameSetting { + + /** PushNameSetting name */ + name?: (string|null); + } + + /** Represents a PushNameSetting. */ + class PushNameSetting implements IPushNameSetting { + + /** + * Constructs a new PushNameSetting. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPushNameSetting); + + /** PushNameSetting name. */ + public name: string; + + /** + * Creates a new PushNameSetting instance using the specified properties. + * @param [properties] Properties to set + * @returns PushNameSetting instance + */ + public static create(properties?: proto.IPushNameSetting): proto.PushNameSetting; + + /** + * Encodes the specified PushNameSetting message. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages. + * @param message PushNameSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPushNameSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified PushNameSetting message, length delimited. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages. + * @param message PushNameSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPushNameSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a PushNameSetting message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns PushNameSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PushNameSetting; + + /** + * Decodes a PushNameSetting message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns PushNameSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PushNameSetting; + + /** + * Verifies a PushNameSetting message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a PushNameSetting message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns PushNameSetting + */ + public static fromObject(object: { [k: string]: any }): proto.PushNameSetting; + + /** + * Creates a plain object from a PushNameSetting message. Also converts values to other types if specified. + * @param message PushNameSetting + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.PushNameSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this PushNameSetting to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a LocaleSetting. */ + interface ILocaleSetting { + + /** LocaleSetting locale */ + locale?: (string|null); + } + + /** Represents a LocaleSetting. */ + class LocaleSetting implements ILocaleSetting { + + /** + * Constructs a new LocaleSetting. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ILocaleSetting); + + /** LocaleSetting locale. */ + public locale: string; + + /** + * Creates a new LocaleSetting instance using the specified properties. + * @param [properties] Properties to set + * @returns LocaleSetting instance + */ + public static create(properties?: proto.ILocaleSetting): proto.LocaleSetting; + + /** + * Encodes the specified LocaleSetting message. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages. + * @param message LocaleSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ILocaleSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified LocaleSetting message, length delimited. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages. + * @param message LocaleSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ILocaleSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a LocaleSetting message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns LocaleSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.LocaleSetting; + + /** + * Decodes a LocaleSetting message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns LocaleSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.LocaleSetting; + + /** + * Verifies a LocaleSetting message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a LocaleSetting message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns LocaleSetting + */ + public static fromObject(object: { [k: string]: any }): proto.LocaleSetting; + + /** + * Creates a plain object from a LocaleSetting message. Also converts values to other types if specified. + * @param message LocaleSetting + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.LocaleSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this LocaleSetting to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a QuickReplyAction. */ + interface IQuickReplyAction { + + /** QuickReplyAction shortcut */ + shortcut?: (string|null); + + /** QuickReplyAction message */ + message?: (string|null); + + /** QuickReplyAction keywords */ + keywords?: (string[]|null); + + /** QuickReplyAction count */ + count?: (number|null); + + /** QuickReplyAction deleted */ + deleted?: (boolean|null); + } + + /** Represents a QuickReplyAction. */ + class QuickReplyAction implements IQuickReplyAction { + + /** + * Constructs a new QuickReplyAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IQuickReplyAction); + + /** QuickReplyAction shortcut. */ + public shortcut: string; + + /** QuickReplyAction message. */ + public message: string; + + /** QuickReplyAction keywords. */ + public keywords: string[]; + + /** QuickReplyAction count. */ + public count: number; + + /** QuickReplyAction deleted. */ + public deleted: boolean; + + /** + * Creates a new QuickReplyAction instance using the specified properties. + * @param [properties] Properties to set + * @returns QuickReplyAction instance + */ + public static create(properties?: proto.IQuickReplyAction): proto.QuickReplyAction; + + /** + * Encodes the specified QuickReplyAction message. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages. + * @param message QuickReplyAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IQuickReplyAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified QuickReplyAction message, length delimited. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages. + * @param message QuickReplyAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IQuickReplyAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a QuickReplyAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns QuickReplyAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.QuickReplyAction; + + /** + * Decodes a QuickReplyAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns QuickReplyAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.QuickReplyAction; + + /** + * Verifies a QuickReplyAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a QuickReplyAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns QuickReplyAction + */ + public static fromObject(object: { [k: string]: any }): proto.QuickReplyAction; + + /** + * Creates a plain object from a QuickReplyAction message. Also converts values to other types if specified. + * @param message QuickReplyAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.QuickReplyAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this QuickReplyAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a LabelAssociationAction. */ + interface ILabelAssociationAction { + + /** LabelAssociationAction labeled */ + labeled?: (boolean|null); + } + + /** Represents a LabelAssociationAction. */ + class LabelAssociationAction implements ILabelAssociationAction { + + /** + * Constructs a new LabelAssociationAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ILabelAssociationAction); + + /** LabelAssociationAction labeled. */ + public labeled: boolean; + + /** + * Creates a new LabelAssociationAction instance using the specified properties. + * @param [properties] Properties to set + * @returns LabelAssociationAction instance + */ + public static create(properties?: proto.ILabelAssociationAction): proto.LabelAssociationAction; + + /** + * Encodes the specified LabelAssociationAction message. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages. + * @param message LabelAssociationAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ILabelAssociationAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified LabelAssociationAction message, length delimited. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages. + * @param message LabelAssociationAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ILabelAssociationAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a LabelAssociationAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns LabelAssociationAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.LabelAssociationAction; + + /** + * Decodes a LabelAssociationAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns LabelAssociationAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.LabelAssociationAction; + + /** + * Verifies a LabelAssociationAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a LabelAssociationAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns LabelAssociationAction + */ + public static fromObject(object: { [k: string]: any }): proto.LabelAssociationAction; + + /** + * Creates a plain object from a LabelAssociationAction message. Also converts values to other types if specified. + * @param message LabelAssociationAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.LabelAssociationAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this LabelAssociationAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a LabelEditAction. */ + interface ILabelEditAction { + + /** LabelEditAction name */ + name?: (string|null); + + /** LabelEditAction color */ + color?: (number|null); + + /** LabelEditAction predefinedId */ + predefinedId?: (number|null); + + /** LabelEditAction deleted */ + deleted?: (boolean|null); + } + + /** Represents a LabelEditAction. */ + class LabelEditAction implements ILabelEditAction { + + /** + * Constructs a new LabelEditAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ILabelEditAction); + + /** LabelEditAction name. */ + public name: string; + + /** LabelEditAction color. */ + public color: number; + + /** LabelEditAction predefinedId. */ + public predefinedId: number; + + /** LabelEditAction deleted. */ + public deleted: boolean; + + /** + * Creates a new LabelEditAction instance using the specified properties. + * @param [properties] Properties to set + * @returns LabelEditAction instance + */ + public static create(properties?: proto.ILabelEditAction): proto.LabelEditAction; + + /** + * Encodes the specified LabelEditAction message. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages. + * @param message LabelEditAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ILabelEditAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified LabelEditAction message, length delimited. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages. + * @param message LabelEditAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ILabelEditAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a LabelEditAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns LabelEditAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.LabelEditAction; + + /** + * Decodes a LabelEditAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns LabelEditAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.LabelEditAction; + + /** + * Verifies a LabelEditAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a LabelEditAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns LabelEditAction + */ + public static fromObject(object: { [k: string]: any }): proto.LabelEditAction; + + /** + * Creates a plain object from a LabelEditAction message. Also converts values to other types if specified. + * @param message LabelEditAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.LabelEditAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this LabelEditAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RecentStickerWeightsAction. */ + interface IRecentStickerWeightsAction { + + /** RecentStickerWeightsAction weights */ + weights?: (proto.IRecentStickerWeight[]|null); + } + + /** Represents a RecentStickerWeightsAction. */ + class RecentStickerWeightsAction implements IRecentStickerWeightsAction { + + /** + * Constructs a new RecentStickerWeightsAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IRecentStickerWeightsAction); + + /** RecentStickerWeightsAction weights. */ + public weights: proto.IRecentStickerWeight[]; + + /** + * Creates a new RecentStickerWeightsAction instance using the specified properties. + * @param [properties] Properties to set + * @returns RecentStickerWeightsAction instance + */ + public static create(properties?: proto.IRecentStickerWeightsAction): proto.RecentStickerWeightsAction; + + /** + * Encodes the specified RecentStickerWeightsAction message. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages. + * @param message RecentStickerWeightsAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IRecentStickerWeightsAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RecentStickerWeightsAction message, length delimited. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages. + * @param message RecentStickerWeightsAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IRecentStickerWeightsAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RecentStickerWeightsAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RecentStickerWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentStickerWeightsAction; + + /** + * Decodes a RecentStickerWeightsAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RecentStickerWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentStickerWeightsAction; + + /** + * Verifies a RecentStickerWeightsAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RecentStickerWeightsAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RecentStickerWeightsAction + */ + public static fromObject(object: { [k: string]: any }): proto.RecentStickerWeightsAction; + + /** + * Creates a plain object from a RecentStickerWeightsAction message. Also converts values to other types if specified. + * @param message RecentStickerWeightsAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.RecentStickerWeightsAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RecentStickerWeightsAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RecentStickerMetadata. */ + interface IRecentStickerMetadata { + + /** RecentStickerMetadata directPath */ + directPath?: (string|null); + + /** RecentStickerMetadata encFilehash */ + encFilehash?: (string|null); + + /** RecentStickerMetadata mediaKey */ + mediaKey?: (string|null); + + /** RecentStickerMetadata stanzaId */ + stanzaId?: (string|null); + + /** RecentStickerMetadata chatJid */ + chatJid?: (string|null); + + /** RecentStickerMetadata participant */ + participant?: (string|null); + + /** RecentStickerMetadata isSentByMe */ + isSentByMe?: (boolean|null); + } + + /** Represents a RecentStickerMetadata. */ + class RecentStickerMetadata implements IRecentStickerMetadata { + + /** + * Constructs a new RecentStickerMetadata. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IRecentStickerMetadata); + + /** RecentStickerMetadata directPath. */ + public directPath: string; + + /** RecentStickerMetadata encFilehash. */ + public encFilehash: string; + + /** RecentStickerMetadata mediaKey. */ + public mediaKey: string; + + /** RecentStickerMetadata stanzaId. */ + public stanzaId: string; + + /** RecentStickerMetadata chatJid. */ + public chatJid: string; + + /** RecentStickerMetadata participant. */ + public participant: string; + + /** RecentStickerMetadata isSentByMe. */ + public isSentByMe: boolean; + + /** + * Creates a new RecentStickerMetadata instance using the specified properties. + * @param [properties] Properties to set + * @returns RecentStickerMetadata instance + */ + public static create(properties?: proto.IRecentStickerMetadata): proto.RecentStickerMetadata; + + /** + * Encodes the specified RecentStickerMetadata message. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages. + * @param message RecentStickerMetadata message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IRecentStickerMetadata, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RecentStickerMetadata message, length delimited. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages. + * @param message RecentStickerMetadata message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IRecentStickerMetadata, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RecentStickerMetadata message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RecentStickerMetadata + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentStickerMetadata; + + /** + * Decodes a RecentStickerMetadata message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RecentStickerMetadata + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentStickerMetadata; + + /** + * Verifies a RecentStickerMetadata message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RecentStickerMetadata message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RecentStickerMetadata + */ + public static fromObject(object: { [k: string]: any }): proto.RecentStickerMetadata; + + /** + * Creates a plain object from a RecentStickerMetadata message. Also converts values to other types if specified. + * @param message RecentStickerMetadata + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.RecentStickerMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RecentStickerMetadata to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RecentEmojiWeightsAction. */ + interface IRecentEmojiWeightsAction { + + /** RecentEmojiWeightsAction weights */ + weights?: (proto.IRecentEmojiWeight[]|null); + } + + /** Represents a RecentEmojiWeightsAction. */ + class RecentEmojiWeightsAction implements IRecentEmojiWeightsAction { + + /** + * Constructs a new RecentEmojiWeightsAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IRecentEmojiWeightsAction); + + /** RecentEmojiWeightsAction weights. */ + public weights: proto.IRecentEmojiWeight[]; + + /** + * Creates a new RecentEmojiWeightsAction instance using the specified properties. + * @param [properties] Properties to set + * @returns RecentEmojiWeightsAction instance + */ + public static create(properties?: proto.IRecentEmojiWeightsAction): proto.RecentEmojiWeightsAction; + + /** + * Encodes the specified RecentEmojiWeightsAction message. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages. + * @param message RecentEmojiWeightsAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IRecentEmojiWeightsAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RecentEmojiWeightsAction message, length delimited. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages. + * @param message RecentEmojiWeightsAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IRecentEmojiWeightsAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RecentEmojiWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentEmojiWeightsAction; + + /** + * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RecentEmojiWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentEmojiWeightsAction; + + /** + * Verifies a RecentEmojiWeightsAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RecentEmojiWeightsAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RecentEmojiWeightsAction + */ + public static fromObject(object: { [k: string]: any }): proto.RecentEmojiWeightsAction; + + /** + * Creates a plain object from a RecentEmojiWeightsAction message. Also converts values to other types if specified. + * @param message RecentEmojiWeightsAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.RecentEmojiWeightsAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RecentEmojiWeightsAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an ArchiveChatAction. */ + interface IArchiveChatAction { + + /** ArchiveChatAction archived */ + archived?: (boolean|null); + + /** ArchiveChatAction messageRange */ + messageRange?: (proto.ISyncActionMessageRange|null); + } + + /** Represents an ArchiveChatAction. */ + class ArchiveChatAction implements IArchiveChatAction { + + /** + * Constructs a new ArchiveChatAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IArchiveChatAction); + + /** ArchiveChatAction archived. */ + public archived: boolean; + + /** ArchiveChatAction messageRange. */ + public messageRange?: (proto.ISyncActionMessageRange|null); + + /** + * Creates a new ArchiveChatAction instance using the specified properties. + * @param [properties] Properties to set + * @returns ArchiveChatAction instance + */ + public static create(properties?: proto.IArchiveChatAction): proto.ArchiveChatAction; + + /** + * Encodes the specified ArchiveChatAction message. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages. + * @param message ArchiveChatAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IArchiveChatAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ArchiveChatAction message, length delimited. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages. + * @param message ArchiveChatAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IArchiveChatAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an ArchiveChatAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ArchiveChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ArchiveChatAction; + + /** + * Decodes an ArchiveChatAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ArchiveChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ArchiveChatAction; + + /** + * Verifies an ArchiveChatAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an ArchiveChatAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ArchiveChatAction + */ + public static fromObject(object: { [k: string]: any }): proto.ArchiveChatAction; + + /** + * Creates a plain object from an ArchiveChatAction message. Also converts values to other types if specified. + * @param message ArchiveChatAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ArchiveChatAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ArchiveChatAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a DeleteMessageForMeAction. */ + interface IDeleteMessageForMeAction { + + /** DeleteMessageForMeAction deleteMedia */ + deleteMedia?: (boolean|null); + + /** DeleteMessageForMeAction messageTimestamp */ + messageTimestamp?: (number|Long|null); + } + + /** Represents a DeleteMessageForMeAction. */ + class DeleteMessageForMeAction implements IDeleteMessageForMeAction { + + /** + * Constructs a new DeleteMessageForMeAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IDeleteMessageForMeAction); + + /** DeleteMessageForMeAction deleteMedia. */ + public deleteMedia: boolean; + + /** DeleteMessageForMeAction messageTimestamp. */ + public messageTimestamp: (number|Long); + + /** + * Creates a new DeleteMessageForMeAction instance using the specified properties. + * @param [properties] Properties to set + * @returns DeleteMessageForMeAction instance + */ + public static create(properties?: proto.IDeleteMessageForMeAction): proto.DeleteMessageForMeAction; + + /** + * Encodes the specified DeleteMessageForMeAction message. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages. + * @param message DeleteMessageForMeAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IDeleteMessageForMeAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified DeleteMessageForMeAction message, length delimited. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages. + * @param message DeleteMessageForMeAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IDeleteMessageForMeAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a DeleteMessageForMeAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns DeleteMessageForMeAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DeleteMessageForMeAction; + + /** + * Decodes a DeleteMessageForMeAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns DeleteMessageForMeAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DeleteMessageForMeAction; + + /** + * Verifies a DeleteMessageForMeAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a DeleteMessageForMeAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns DeleteMessageForMeAction + */ + public static fromObject(object: { [k: string]: any }): proto.DeleteMessageForMeAction; + + /** + * Creates a plain object from a DeleteMessageForMeAction message. Also converts values to other types if specified. + * @param message DeleteMessageForMeAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.DeleteMessageForMeAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this DeleteMessageForMeAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a MarkChatAsReadAction. */ + interface IMarkChatAsReadAction { + + /** MarkChatAsReadAction read */ + read?: (boolean|null); + + /** MarkChatAsReadAction messageRange */ + messageRange?: (proto.ISyncActionMessageRange|null); + } + + /** Represents a MarkChatAsReadAction. */ + class MarkChatAsReadAction implements IMarkChatAsReadAction { + + /** + * Constructs a new MarkChatAsReadAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMarkChatAsReadAction); + + /** MarkChatAsReadAction read. */ + public read: boolean; + + /** MarkChatAsReadAction messageRange. */ + public messageRange?: (proto.ISyncActionMessageRange|null); + + /** + * Creates a new MarkChatAsReadAction instance using the specified properties. + * @param [properties] Properties to set + * @returns MarkChatAsReadAction instance + */ + public static create(properties?: proto.IMarkChatAsReadAction): proto.MarkChatAsReadAction; + + /** + * Encodes the specified MarkChatAsReadAction message. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages. + * @param message MarkChatAsReadAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMarkChatAsReadAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MarkChatAsReadAction message, length delimited. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages. + * @param message MarkChatAsReadAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMarkChatAsReadAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MarkChatAsReadAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MarkChatAsReadAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MarkChatAsReadAction; + + /** + * Decodes a MarkChatAsReadAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MarkChatAsReadAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MarkChatAsReadAction; + + /** + * Verifies a MarkChatAsReadAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MarkChatAsReadAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MarkChatAsReadAction + */ + public static fromObject(object: { [k: string]: any }): proto.MarkChatAsReadAction; + + /** + * Creates a plain object from a MarkChatAsReadAction message. Also converts values to other types if specified. + * @param message MarkChatAsReadAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MarkChatAsReadAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MarkChatAsReadAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ClearChatAction. */ + interface IClearChatAction { + + /** ClearChatAction messageRange */ + messageRange?: (proto.ISyncActionMessageRange|null); + } + + /** Represents a ClearChatAction. */ + class ClearChatAction implements IClearChatAction { + + /** + * Constructs a new ClearChatAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IClearChatAction); + + /** ClearChatAction messageRange. */ + public messageRange?: (proto.ISyncActionMessageRange|null); + + /** + * Creates a new ClearChatAction instance using the specified properties. + * @param [properties] Properties to set + * @returns ClearChatAction instance + */ + public static create(properties?: proto.IClearChatAction): proto.ClearChatAction; + + /** + * Encodes the specified ClearChatAction message. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages. + * @param message ClearChatAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IClearChatAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ClearChatAction message, length delimited. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages. + * @param message ClearChatAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IClearChatAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ClearChatAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ClearChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ClearChatAction; + + /** + * Decodes a ClearChatAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ClearChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ClearChatAction; + + /** + * Verifies a ClearChatAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ClearChatAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ClearChatAction + */ + public static fromObject(object: { [k: string]: any }): proto.ClearChatAction; + + /** + * Creates a plain object from a ClearChatAction message. Also converts values to other types if specified. + * @param message ClearChatAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ClearChatAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ClearChatAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a DeleteChatAction. */ + interface IDeleteChatAction { + + /** DeleteChatAction messageRange */ + messageRange?: (proto.ISyncActionMessageRange|null); + } + + /** Represents a DeleteChatAction. */ + class DeleteChatAction implements IDeleteChatAction { + + /** + * Constructs a new DeleteChatAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IDeleteChatAction); + + /** DeleteChatAction messageRange. */ + public messageRange?: (proto.ISyncActionMessageRange|null); + + /** + * Creates a new DeleteChatAction instance using the specified properties. + * @param [properties] Properties to set + * @returns DeleteChatAction instance + */ + public static create(properties?: proto.IDeleteChatAction): proto.DeleteChatAction; + + /** + * Encodes the specified DeleteChatAction message. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages. + * @param message DeleteChatAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IDeleteChatAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified DeleteChatAction message, length delimited. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages. + * @param message DeleteChatAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IDeleteChatAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a DeleteChatAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns DeleteChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DeleteChatAction; + + /** + * Decodes a DeleteChatAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns DeleteChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DeleteChatAction; + + /** + * Verifies a DeleteChatAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a DeleteChatAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns DeleteChatAction + */ + public static fromObject(object: { [k: string]: any }): proto.DeleteChatAction; + + /** + * Creates a plain object from a DeleteChatAction message. Also converts values to other types if specified. + * @param message DeleteChatAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.DeleteChatAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this DeleteChatAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an UnarchiveChatsSetting. */ + interface IUnarchiveChatsSetting { + + /** UnarchiveChatsSetting unarchiveChats */ + unarchiveChats?: (boolean|null); + } + + /** Represents an UnarchiveChatsSetting. */ + class UnarchiveChatsSetting implements IUnarchiveChatsSetting { + + /** + * Constructs a new UnarchiveChatsSetting. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IUnarchiveChatsSetting); + + /** UnarchiveChatsSetting unarchiveChats. */ + public unarchiveChats: boolean; + + /** + * Creates a new UnarchiveChatsSetting instance using the specified properties. + * @param [properties] Properties to set + * @returns UnarchiveChatsSetting instance + */ + public static create(properties?: proto.IUnarchiveChatsSetting): proto.UnarchiveChatsSetting; + + /** + * Encodes the specified UnarchiveChatsSetting message. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages. + * @param message UnarchiveChatsSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IUnarchiveChatsSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified UnarchiveChatsSetting message, length delimited. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages. + * @param message UnarchiveChatsSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IUnarchiveChatsSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an UnarchiveChatsSetting message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns UnarchiveChatsSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.UnarchiveChatsSetting; + + /** + * Decodes an UnarchiveChatsSetting message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns UnarchiveChatsSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.UnarchiveChatsSetting; + + /** + * Verifies an UnarchiveChatsSetting message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an UnarchiveChatsSetting message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns UnarchiveChatsSetting + */ + public static fromObject(object: { [k: string]: any }): proto.UnarchiveChatsSetting; + + /** + * Creates a plain object from an UnarchiveChatsSetting message. Also converts values to other types if specified. + * @param message UnarchiveChatsSetting + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.UnarchiveChatsSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this UnarchiveChatsSetting to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncActionMessageRange. */ + interface ISyncActionMessageRange { + + /** SyncActionMessageRange lastMessageTimestamp */ + lastMessageTimestamp?: (number|Long|null); + + /** SyncActionMessageRange lastSystemMessageTimestamp */ + lastSystemMessageTimestamp?: (number|Long|null); + + /** SyncActionMessageRange messages */ + messages?: (proto.ISyncActionMessage[]|null); + } + + /** Represents a SyncActionMessageRange. */ + class SyncActionMessageRange implements ISyncActionMessageRange { + + /** + * Constructs a new SyncActionMessageRange. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncActionMessageRange); + + /** SyncActionMessageRange lastMessageTimestamp. */ + public lastMessageTimestamp: (number|Long); + + /** SyncActionMessageRange lastSystemMessageTimestamp. */ + public lastSystemMessageTimestamp: (number|Long); + + /** SyncActionMessageRange messages. */ + public messages: proto.ISyncActionMessage[]; + + /** + * Creates a new SyncActionMessageRange instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncActionMessageRange instance + */ + public static create(properties?: proto.ISyncActionMessageRange): proto.SyncActionMessageRange; + + /** + * Encodes the specified SyncActionMessageRange message. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages. + * @param message SyncActionMessageRange message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncActionMessageRange, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncActionMessageRange message, length delimited. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages. + * @param message SyncActionMessageRange message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncActionMessageRange, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncActionMessageRange message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncActionMessageRange + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncActionMessageRange; + + /** + * Decodes a SyncActionMessageRange message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncActionMessageRange + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncActionMessageRange; + + /** + * Verifies a SyncActionMessageRange message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncActionMessageRange message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncActionMessageRange + */ + public static fromObject(object: { [k: string]: any }): proto.SyncActionMessageRange; + + /** + * Creates a plain object from a SyncActionMessageRange message. Also converts values to other types if specified. + * @param message SyncActionMessageRange + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncActionMessageRange, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncActionMessageRange to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncActionMessage. */ + interface ISyncActionMessage { + + /** SyncActionMessage key */ + key?: (proto.IMessageKey|null); + + /** SyncActionMessage timestamp */ + timestamp?: (number|Long|null); + } + + /** Represents a SyncActionMessage. */ + class SyncActionMessage implements ISyncActionMessage { + + /** + * Constructs a new SyncActionMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncActionMessage); + + /** SyncActionMessage key. */ + public key?: (proto.IMessageKey|null); + + /** SyncActionMessage timestamp. */ + public timestamp: (number|Long); + + /** + * Creates a new SyncActionMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncActionMessage instance + */ + public static create(properties?: proto.ISyncActionMessage): proto.SyncActionMessage; + + /** + * Encodes the specified SyncActionMessage message. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages. + * @param message SyncActionMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncActionMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncActionMessage message, length delimited. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages. + * @param message SyncActionMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncActionMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncActionMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncActionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncActionMessage; + + /** + * Decodes a SyncActionMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncActionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncActionMessage; + + /** + * Verifies a SyncActionMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncActionMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncActionMessage + */ + public static fromObject(object: { [k: string]: any }): proto.SyncActionMessage; + + /** + * Creates a plain object from a SyncActionMessage message. Also converts values to other types if specified. + * @param message SyncActionMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncActionMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncActionMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a KeyExpiration. */ + interface IKeyExpiration { + + /** KeyExpiration expiredKeyEpoch */ + expiredKeyEpoch?: (number|null); + } + + /** Represents a KeyExpiration. */ + class KeyExpiration implements IKeyExpiration { + + /** + * Constructs a new KeyExpiration. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IKeyExpiration); + + /** KeyExpiration expiredKeyEpoch. */ + public expiredKeyEpoch: number; + + /** + * Creates a new KeyExpiration instance using the specified properties. + * @param [properties] Properties to set + * @returns KeyExpiration instance + */ + public static create(properties?: proto.IKeyExpiration): proto.KeyExpiration; + + /** + * Encodes the specified KeyExpiration message. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages. + * @param message KeyExpiration message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IKeyExpiration, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified KeyExpiration message, length delimited. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages. + * @param message KeyExpiration message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IKeyExpiration, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a KeyExpiration message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns KeyExpiration + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.KeyExpiration; + + /** + * Decodes a KeyExpiration message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns KeyExpiration + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.KeyExpiration; + + /** + * Verifies a KeyExpiration message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a KeyExpiration message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns KeyExpiration + */ + public static fromObject(object: { [k: string]: any }): proto.KeyExpiration; + + /** + * Creates a plain object from a KeyExpiration message. Also converts values to other types if specified. + * @param message KeyExpiration + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.KeyExpiration, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this KeyExpiration to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncActionValue. */ + interface ISyncActionValue { + + /** SyncActionValue timestamp */ + timestamp?: (number|Long|null); + + /** SyncActionValue starAction */ + starAction?: (proto.IStarAction|null); + + /** SyncActionValue contactAction */ + contactAction?: (proto.IContactAction|null); + + /** SyncActionValue muteAction */ + muteAction?: (proto.IMuteAction|null); + + /** SyncActionValue pinAction */ + pinAction?: (proto.IPinAction|null); + + /** SyncActionValue securityNotificationSetting */ + securityNotificationSetting?: (proto.ISecurityNotificationSetting|null); + + /** SyncActionValue pushNameSetting */ + pushNameSetting?: (proto.IPushNameSetting|null); + + /** SyncActionValue quickReplyAction */ + quickReplyAction?: (proto.IQuickReplyAction|null); + + /** SyncActionValue recentStickerWeightsAction */ + recentStickerWeightsAction?: (proto.IRecentStickerWeightsAction|null); + + /** SyncActionValue recentStickerMetadata */ + recentStickerMetadata?: (proto.IRecentStickerMetadata|null); + + /** SyncActionValue recentEmojiWeightsAction */ + recentEmojiWeightsAction?: (proto.IRecentEmojiWeightsAction|null); + + /** SyncActionValue labelEditAction */ + labelEditAction?: (proto.ILabelEditAction|null); + + /** SyncActionValue labelAssociationAction */ + labelAssociationAction?: (proto.ILabelAssociationAction|null); + + /** SyncActionValue localeSetting */ + localeSetting?: (proto.ILocaleSetting|null); + + /** SyncActionValue archiveChatAction */ + archiveChatAction?: (proto.IArchiveChatAction|null); + + /** SyncActionValue deleteMessageForMeAction */ + deleteMessageForMeAction?: (proto.IDeleteMessageForMeAction|null); + + /** SyncActionValue keyExpiration */ + keyExpiration?: (proto.IKeyExpiration|null); + + /** SyncActionValue markChatAsReadAction */ + markChatAsReadAction?: (proto.IMarkChatAsReadAction|null); + + /** SyncActionValue clearChatAction */ + clearChatAction?: (proto.IClearChatAction|null); + + /** SyncActionValue deleteChatAction */ + deleteChatAction?: (proto.IDeleteChatAction|null); + + /** SyncActionValue unarchiveChatsSetting */ + unarchiveChatsSetting?: (proto.IUnarchiveChatsSetting|null); + } + + /** Represents a SyncActionValue. */ + class SyncActionValue implements ISyncActionValue { + + /** + * Constructs a new SyncActionValue. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncActionValue); + + /** SyncActionValue timestamp. */ + public timestamp: (number|Long); + + /** SyncActionValue starAction. */ + public starAction?: (proto.IStarAction|null); + + /** SyncActionValue contactAction. */ + public contactAction?: (proto.IContactAction|null); + + /** SyncActionValue muteAction. */ + public muteAction?: (proto.IMuteAction|null); + + /** SyncActionValue pinAction. */ + public pinAction?: (proto.IPinAction|null); + + /** SyncActionValue securityNotificationSetting. */ + public securityNotificationSetting?: (proto.ISecurityNotificationSetting|null); + + /** SyncActionValue pushNameSetting. */ + public pushNameSetting?: (proto.IPushNameSetting|null); + + /** SyncActionValue quickReplyAction. */ + public quickReplyAction?: (proto.IQuickReplyAction|null); + + /** SyncActionValue recentStickerWeightsAction. */ + public recentStickerWeightsAction?: (proto.IRecentStickerWeightsAction|null); + + /** SyncActionValue recentStickerMetadata. */ + public recentStickerMetadata?: (proto.IRecentStickerMetadata|null); + + /** SyncActionValue recentEmojiWeightsAction. */ + public recentEmojiWeightsAction?: (proto.IRecentEmojiWeightsAction|null); + + /** SyncActionValue labelEditAction. */ + public labelEditAction?: (proto.ILabelEditAction|null); + + /** SyncActionValue labelAssociationAction. */ + public labelAssociationAction?: (proto.ILabelAssociationAction|null); + + /** SyncActionValue localeSetting. */ + public localeSetting?: (proto.ILocaleSetting|null); + + /** SyncActionValue archiveChatAction. */ + public archiveChatAction?: (proto.IArchiveChatAction|null); + + /** SyncActionValue deleteMessageForMeAction. */ + public deleteMessageForMeAction?: (proto.IDeleteMessageForMeAction|null); + + /** SyncActionValue keyExpiration. */ + public keyExpiration?: (proto.IKeyExpiration|null); + + /** SyncActionValue markChatAsReadAction. */ + public markChatAsReadAction?: (proto.IMarkChatAsReadAction|null); + + /** SyncActionValue clearChatAction. */ + public clearChatAction?: (proto.IClearChatAction|null); + + /** SyncActionValue deleteChatAction. */ + public deleteChatAction?: (proto.IDeleteChatAction|null); + + /** SyncActionValue unarchiveChatsSetting. */ + public unarchiveChatsSetting?: (proto.IUnarchiveChatsSetting|null); + + /** + * Creates a new SyncActionValue instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncActionValue instance + */ + public static create(properties?: proto.ISyncActionValue): proto.SyncActionValue; + + /** + * Encodes the specified SyncActionValue message. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages. + * @param message SyncActionValue message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncActionValue, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncActionValue message, length delimited. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages. + * @param message SyncActionValue message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncActionValue, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncActionValue message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncActionValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncActionValue; + + /** + * Decodes a SyncActionValue message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncActionValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncActionValue; + + /** + * Verifies a SyncActionValue message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncActionValue message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncActionValue + */ + public static fromObject(object: { [k: string]: any }): proto.SyncActionValue; + + /** + * Creates a plain object from a SyncActionValue message. Also converts values to other types if specified. + * @param message SyncActionValue + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncActionValue, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncActionValue to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RecentEmojiWeight. */ + interface IRecentEmojiWeight { + + /** RecentEmojiWeight emoji */ + emoji?: (string|null); + + /** RecentEmojiWeight weight */ + weight?: (number|null); + } + + /** Represents a RecentEmojiWeight. */ + class RecentEmojiWeight implements IRecentEmojiWeight { + + /** + * Constructs a new RecentEmojiWeight. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IRecentEmojiWeight); + + /** RecentEmojiWeight emoji. */ + public emoji: string; + + /** RecentEmojiWeight weight. */ + public weight: number; + + /** + * Creates a new RecentEmojiWeight instance using the specified properties. + * @param [properties] Properties to set + * @returns RecentEmojiWeight instance + */ + public static create(properties?: proto.IRecentEmojiWeight): proto.RecentEmojiWeight; + + /** + * Encodes the specified RecentEmojiWeight message. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages. + * @param message RecentEmojiWeight message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IRecentEmojiWeight, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RecentEmojiWeight message, length delimited. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages. + * @param message RecentEmojiWeight message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IRecentEmojiWeight, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RecentEmojiWeight message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RecentEmojiWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentEmojiWeight; + + /** + * Decodes a RecentEmojiWeight message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RecentEmojiWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentEmojiWeight; + + /** + * Verifies a RecentEmojiWeight message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RecentEmojiWeight message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RecentEmojiWeight + */ + public static fromObject(object: { [k: string]: any }): proto.RecentEmojiWeight; + + /** + * Creates a plain object from a RecentEmojiWeight message. Also converts values to other types if specified. + * @param message RecentEmojiWeight + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.RecentEmojiWeight, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RecentEmojiWeight to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RecentStickerWeight. */ + interface IRecentStickerWeight { + + /** RecentStickerWeight filehash */ + filehash?: (string|null); + + /** RecentStickerWeight weight */ + weight?: (number|null); + } + + /** Represents a RecentStickerWeight. */ + class RecentStickerWeight implements IRecentStickerWeight { + + /** + * Constructs a new RecentStickerWeight. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IRecentStickerWeight); + + /** RecentStickerWeight filehash. */ + public filehash: string; + + /** RecentStickerWeight weight. */ + public weight: number; + + /** + * Creates a new RecentStickerWeight instance using the specified properties. + * @param [properties] Properties to set + * @returns RecentStickerWeight instance + */ + public static create(properties?: proto.IRecentStickerWeight): proto.RecentStickerWeight; + + /** + * Encodes the specified RecentStickerWeight message. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages. + * @param message RecentStickerWeight message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IRecentStickerWeight, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RecentStickerWeight message, length delimited. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages. + * @param message RecentStickerWeight message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IRecentStickerWeight, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RecentStickerWeight message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RecentStickerWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentStickerWeight; + + /** + * Decodes a RecentStickerWeight message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RecentStickerWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentStickerWeight; + + /** + * Verifies a RecentStickerWeight message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RecentStickerWeight message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RecentStickerWeight + */ + public static fromObject(object: { [k: string]: any }): proto.RecentStickerWeight; + + /** + * Creates a plain object from a RecentStickerWeight message. Also converts values to other types if specified. + * @param message RecentStickerWeight + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.RecentStickerWeight, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RecentStickerWeight to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdPatch. */ + interface ISyncdPatch { + + /** SyncdPatch version */ + version?: (proto.ISyncdVersion|null); + + /** SyncdPatch mutations */ + mutations?: (proto.ISyncdMutation[]|null); + + /** SyncdPatch externalMutations */ + externalMutations?: (proto.IExternalBlobReference|null); + + /** SyncdPatch snapshotMac */ + snapshotMac?: (Uint8Array|null); + + /** SyncdPatch patchMac */ + patchMac?: (Uint8Array|null); + + /** SyncdPatch keyId */ + keyId?: (proto.IKeyId|null); + + /** SyncdPatch exitCode */ + exitCode?: (proto.IExitCode|null); + + /** SyncdPatch deviceIndex */ + deviceIndex?: (number|null); + } + + /** Represents a SyncdPatch. */ + class SyncdPatch implements ISyncdPatch { + + /** + * Constructs a new SyncdPatch. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdPatch); + + /** SyncdPatch version. */ + public version?: (proto.ISyncdVersion|null); + + /** SyncdPatch mutations. */ + public mutations: proto.ISyncdMutation[]; + + /** SyncdPatch externalMutations. */ + public externalMutations?: (proto.IExternalBlobReference|null); + + /** SyncdPatch snapshotMac. */ + public snapshotMac: Uint8Array; + + /** SyncdPatch patchMac. */ + public patchMac: Uint8Array; + + /** SyncdPatch keyId. */ + public keyId?: (proto.IKeyId|null); + + /** SyncdPatch exitCode. */ + public exitCode?: (proto.IExitCode|null); + + /** SyncdPatch deviceIndex. */ + public deviceIndex: number; + + /** + * Creates a new SyncdPatch instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdPatch instance + */ + public static create(properties?: proto.ISyncdPatch): proto.SyncdPatch; + + /** + * Encodes the specified SyncdPatch message. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages. + * @param message SyncdPatch message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdPatch, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdPatch message, length delimited. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages. + * @param message SyncdPatch message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdPatch, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdPatch message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdPatch + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdPatch; + + /** + * Decodes a SyncdPatch message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdPatch + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdPatch; + + /** + * Verifies a SyncdPatch message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdPatch message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdPatch + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdPatch; + + /** + * Creates a plain object from a SyncdPatch message. Also converts values to other types if specified. + * @param message SyncdPatch + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdPatch, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdPatch to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdMutation. */ + interface ISyncdMutation { + + /** SyncdMutation operation */ + operation?: (proto.SyncdMutation.SyncdMutationSyncdOperation|null); + + /** SyncdMutation record */ + record?: (proto.ISyncdRecord|null); + } + + /** Represents a SyncdMutation. */ + class SyncdMutation implements ISyncdMutation { + + /** + * Constructs a new SyncdMutation. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdMutation); + + /** SyncdMutation operation. */ + public operation: proto.SyncdMutation.SyncdMutationSyncdOperation; + + /** SyncdMutation record. */ + public record?: (proto.ISyncdRecord|null); + + /** + * Creates a new SyncdMutation instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdMutation instance + */ + public static create(properties?: proto.ISyncdMutation): proto.SyncdMutation; + + /** + * Encodes the specified SyncdMutation message. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages. + * @param message SyncdMutation message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdMutation, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdMutation message, length delimited. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages. + * @param message SyncdMutation message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdMutation, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdMutation message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdMutation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdMutation; + + /** + * Decodes a SyncdMutation message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdMutation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdMutation; + + /** + * Verifies a SyncdMutation message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdMutation message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdMutation + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdMutation; + + /** + * Creates a plain object from a SyncdMutation message. Also converts values to other types if specified. + * @param message SyncdMutation + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdMutation, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdMutation to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace SyncdMutation { + + /** SyncdMutationSyncdOperation enum. */ + enum SyncdMutationSyncdOperation { + SET = 0, + REMOVE = 1 + } + } + + /** Properties of a SyncdMutations. */ + interface ISyncdMutations { + + /** SyncdMutations mutations */ + mutations?: (proto.ISyncdMutation[]|null); + } + + /** Represents a SyncdMutations. */ + class SyncdMutations implements ISyncdMutations { + + /** + * Constructs a new SyncdMutations. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdMutations); + + /** SyncdMutations mutations. */ + public mutations: proto.ISyncdMutation[]; + + /** + * Creates a new SyncdMutations instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdMutations instance + */ + public static create(properties?: proto.ISyncdMutations): proto.SyncdMutations; + + /** + * Encodes the specified SyncdMutations message. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages. + * @param message SyncdMutations message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdMutations, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdMutations message, length delimited. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages. + * @param message SyncdMutations message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdMutations, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdMutations message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdMutations + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdMutations; + + /** + * Decodes a SyncdMutations message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdMutations + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdMutations; + + /** + * Verifies a SyncdMutations message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdMutations message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdMutations + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdMutations; + + /** + * Creates a plain object from a SyncdMutations message. Also converts values to other types if specified. + * @param message SyncdMutations + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdMutations, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdMutations to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdSnapshot. */ + interface ISyncdSnapshot { + + /** SyncdSnapshot version */ + version?: (proto.ISyncdVersion|null); + + /** SyncdSnapshot records */ + records?: (proto.ISyncdRecord[]|null); + + /** SyncdSnapshot mac */ + mac?: (Uint8Array|null); + + /** SyncdSnapshot keyId */ + keyId?: (proto.IKeyId|null); + } + + /** Represents a SyncdSnapshot. */ + class SyncdSnapshot implements ISyncdSnapshot { + + /** + * Constructs a new SyncdSnapshot. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdSnapshot); + + /** SyncdSnapshot version. */ + public version?: (proto.ISyncdVersion|null); + + /** SyncdSnapshot records. */ + public records: proto.ISyncdRecord[]; + + /** SyncdSnapshot mac. */ + public mac: Uint8Array; + + /** SyncdSnapshot keyId. */ + public keyId?: (proto.IKeyId|null); + + /** + * Creates a new SyncdSnapshot instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdSnapshot instance + */ + public static create(properties?: proto.ISyncdSnapshot): proto.SyncdSnapshot; + + /** + * Encodes the specified SyncdSnapshot message. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages. + * @param message SyncdSnapshot message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdSnapshot, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdSnapshot message, length delimited. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages. + * @param message SyncdSnapshot message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdSnapshot, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdSnapshot message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdSnapshot + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdSnapshot; + + /** + * Decodes a SyncdSnapshot message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdSnapshot + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdSnapshot; + + /** + * Verifies a SyncdSnapshot message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdSnapshot message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdSnapshot + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdSnapshot; + + /** + * Creates a plain object from a SyncdSnapshot message. Also converts values to other types if specified. + * @param message SyncdSnapshot + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdSnapshot, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdSnapshot to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an ExternalBlobReference. */ + interface IExternalBlobReference { + + /** ExternalBlobReference mediaKey */ + mediaKey?: (Uint8Array|null); + + /** ExternalBlobReference directPath */ + directPath?: (string|null); + + /** ExternalBlobReference handle */ + handle?: (string|null); + + /** ExternalBlobReference fileSizeBytes */ + fileSizeBytes?: (number|Long|null); + + /** ExternalBlobReference fileSha256 */ + fileSha256?: (Uint8Array|null); + + /** ExternalBlobReference fileEncSha256 */ + fileEncSha256?: (Uint8Array|null); + } + + /** Represents an ExternalBlobReference. */ + class ExternalBlobReference implements IExternalBlobReference { + + /** + * Constructs a new ExternalBlobReference. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IExternalBlobReference); + + /** ExternalBlobReference mediaKey. */ + public mediaKey: Uint8Array; + + /** ExternalBlobReference directPath. */ + public directPath: string; + + /** ExternalBlobReference handle. */ + public handle: string; + + /** ExternalBlobReference fileSizeBytes. */ + public fileSizeBytes: (number|Long); + + /** ExternalBlobReference fileSha256. */ + public fileSha256: Uint8Array; + + /** ExternalBlobReference fileEncSha256. */ + public fileEncSha256: Uint8Array; + + /** + * Creates a new ExternalBlobReference instance using the specified properties. + * @param [properties] Properties to set + * @returns ExternalBlobReference instance + */ + public static create(properties?: proto.IExternalBlobReference): proto.ExternalBlobReference; + + /** + * Encodes the specified ExternalBlobReference message. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages. + * @param message ExternalBlobReference message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IExternalBlobReference, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ExternalBlobReference message, length delimited. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages. + * @param message ExternalBlobReference message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IExternalBlobReference, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an ExternalBlobReference message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ExternalBlobReference + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ExternalBlobReference; + + /** + * Decodes an ExternalBlobReference message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ExternalBlobReference + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ExternalBlobReference; + + /** + * Verifies an ExternalBlobReference message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an ExternalBlobReference message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ExternalBlobReference + */ + public static fromObject(object: { [k: string]: any }): proto.ExternalBlobReference; + + /** + * Creates a plain object from an ExternalBlobReference message. Also converts values to other types if specified. + * @param message ExternalBlobReference + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ExternalBlobReference, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ExternalBlobReference to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdRecord. */ + interface ISyncdRecord { + + /** SyncdRecord index */ + index?: (proto.ISyncdIndex|null); + + /** SyncdRecord value */ + value?: (proto.ISyncdValue|null); + + /** SyncdRecord keyId */ + keyId?: (proto.IKeyId|null); + } + + /** Represents a SyncdRecord. */ + class SyncdRecord implements ISyncdRecord { + + /** + * Constructs a new SyncdRecord. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdRecord); + + /** SyncdRecord index. */ + public index?: (proto.ISyncdIndex|null); + + /** SyncdRecord value. */ + public value?: (proto.ISyncdValue|null); + + /** SyncdRecord keyId. */ + public keyId?: (proto.IKeyId|null); + + /** + * Creates a new SyncdRecord instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdRecord instance + */ + public static create(properties?: proto.ISyncdRecord): proto.SyncdRecord; + + /** + * Encodes the specified SyncdRecord message. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages. + * @param message SyncdRecord message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdRecord, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdRecord message, length delimited. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages. + * @param message SyncdRecord message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdRecord, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdRecord message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdRecord + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdRecord; + + /** + * Decodes a SyncdRecord message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdRecord + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdRecord; + + /** + * Verifies a SyncdRecord message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdRecord message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdRecord + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdRecord; + + /** + * Creates a plain object from a SyncdRecord message. Also converts values to other types if specified. + * @param message SyncdRecord + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdRecord, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdRecord to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a KeyId. */ + interface IKeyId { + + /** KeyId id */ + id?: (Uint8Array|null); + } + + /** Represents a KeyId. */ + class KeyId implements IKeyId { + + /** + * Constructs a new KeyId. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IKeyId); + + /** KeyId id. */ + public id: Uint8Array; + + /** + * Creates a new KeyId instance using the specified properties. + * @param [properties] Properties to set + * @returns KeyId instance + */ + public static create(properties?: proto.IKeyId): proto.KeyId; + + /** + * Encodes the specified KeyId message. Does not implicitly {@link proto.KeyId.verify|verify} messages. + * @param message KeyId message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IKeyId, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified KeyId message, length delimited. Does not implicitly {@link proto.KeyId.verify|verify} messages. + * @param message KeyId message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IKeyId, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a KeyId message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns KeyId + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.KeyId; + + /** + * Decodes a KeyId message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns KeyId + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.KeyId; + + /** + * Verifies a KeyId message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a KeyId message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns KeyId + */ + public static fromObject(object: { [k: string]: any }): proto.KeyId; + + /** + * Creates a plain object from a KeyId message. Also converts values to other types if specified. + * @param message KeyId + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.KeyId, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this KeyId to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdValue. */ + interface ISyncdValue { + + /** SyncdValue blob */ + blob?: (Uint8Array|null); + } + + /** Represents a SyncdValue. */ + class SyncdValue implements ISyncdValue { + + /** + * Constructs a new SyncdValue. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdValue); + + /** SyncdValue blob. */ + public blob: Uint8Array; + + /** + * Creates a new SyncdValue instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdValue instance + */ + public static create(properties?: proto.ISyncdValue): proto.SyncdValue; + + /** + * Encodes the specified SyncdValue message. Does not implicitly {@link proto.SyncdValue.verify|verify} messages. + * @param message SyncdValue message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdValue, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdValue message, length delimited. Does not implicitly {@link proto.SyncdValue.verify|verify} messages. + * @param message SyncdValue message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdValue, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdValue message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdValue; + + /** + * Decodes a SyncdValue message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdValue; + + /** + * Verifies a SyncdValue message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdValue message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdValue + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdValue; + + /** + * Creates a plain object from a SyncdValue message. Also converts values to other types if specified. + * @param message SyncdValue + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdValue, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdValue to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdIndex. */ + interface ISyncdIndex { + + /** SyncdIndex blob */ + blob?: (Uint8Array|null); + } + + /** Represents a SyncdIndex. */ + class SyncdIndex implements ISyncdIndex { + + /** + * Constructs a new SyncdIndex. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdIndex); + + /** SyncdIndex blob. */ + public blob: Uint8Array; + + /** + * Creates a new SyncdIndex instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdIndex instance + */ + public static create(properties?: proto.ISyncdIndex): proto.SyncdIndex; + + /** + * Encodes the specified SyncdIndex message. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages. + * @param message SyncdIndex message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdIndex, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdIndex message, length delimited. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages. + * @param message SyncdIndex message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdIndex, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdIndex message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdIndex + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdIndex; + + /** + * Decodes a SyncdIndex message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdIndex + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdIndex; + + /** + * Verifies a SyncdIndex message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdIndex message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdIndex + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdIndex; + + /** + * Creates a plain object from a SyncdIndex message. Also converts values to other types if specified. + * @param message SyncdIndex + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdIndex, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdIndex to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an ExitCode. */ + interface IExitCode { + + /** ExitCode code */ + code?: (number|Long|null); + + /** ExitCode text */ + text?: (string|null); + } + + /** Represents an ExitCode. */ + class ExitCode implements IExitCode { + + /** + * Constructs a new ExitCode. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IExitCode); + + /** ExitCode code. */ + public code: (number|Long); + + /** ExitCode text. */ + public text: string; + + /** + * Creates a new ExitCode instance using the specified properties. + * @param [properties] Properties to set + * @returns ExitCode instance + */ + public static create(properties?: proto.IExitCode): proto.ExitCode; + + /** + * Encodes the specified ExitCode message. Does not implicitly {@link proto.ExitCode.verify|verify} messages. + * @param message ExitCode message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IExitCode, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ExitCode message, length delimited. Does not implicitly {@link proto.ExitCode.verify|verify} messages. + * @param message ExitCode message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IExitCode, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an ExitCode message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ExitCode + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ExitCode; + + /** + * Decodes an ExitCode message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ExitCode + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ExitCode; + + /** + * Verifies an ExitCode message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an ExitCode message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ExitCode + */ + public static fromObject(object: { [k: string]: any }): proto.ExitCode; + + /** + * Creates a plain object from an ExitCode message. Also converts values to other types if specified. + * @param message ExitCode + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ExitCode, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ExitCode to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdVersion. */ + interface ISyncdVersion { + + /** SyncdVersion version */ + version?: (number|Long|null); + } + + /** Represents a SyncdVersion. */ + class SyncdVersion implements ISyncdVersion { + + /** + * Constructs a new SyncdVersion. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdVersion); + + /** SyncdVersion version. */ + public version: (number|Long); + + /** + * Creates a new SyncdVersion instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdVersion instance + */ + public static create(properties?: proto.ISyncdVersion): proto.SyncdVersion; + + /** + * Encodes the specified SyncdVersion message. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages. + * @param message SyncdVersion message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdVersion, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdVersion message, length delimited. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages. + * @param message SyncdVersion message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdVersion, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdVersion message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdVersion + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdVersion; + + /** + * Decodes a SyncdVersion message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdVersion + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdVersion; + + /** + * Verifies a SyncdVersion message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdVersion message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdVersion + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdVersion; + + /** + * Creates a plain object from a SyncdVersion message. Also converts values to other types if specified. + * @param message SyncdVersion + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdVersion, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdVersion to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ServerErrorReceipt. */ + interface IServerErrorReceipt { + + /** ServerErrorReceipt stanzaId */ + stanzaId?: (string|null); + } + + /** Represents a ServerErrorReceipt. */ + class ServerErrorReceipt implements IServerErrorReceipt { + + /** + * Constructs a new ServerErrorReceipt. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IServerErrorReceipt); + + /** ServerErrorReceipt stanzaId. */ + public stanzaId: string; + + /** + * Creates a new ServerErrorReceipt instance using the specified properties. + * @param [properties] Properties to set + * @returns ServerErrorReceipt instance + */ + public static create(properties?: proto.IServerErrorReceipt): proto.ServerErrorReceipt; + + /** + * Encodes the specified ServerErrorReceipt message. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages. + * @param message ServerErrorReceipt message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IServerErrorReceipt, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ServerErrorReceipt message, length delimited. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages. + * @param message ServerErrorReceipt message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IServerErrorReceipt, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ServerErrorReceipt message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ServerErrorReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ServerErrorReceipt; + + /** + * Decodes a ServerErrorReceipt message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ServerErrorReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ServerErrorReceipt; + + /** + * Verifies a ServerErrorReceipt message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ServerErrorReceipt message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ServerErrorReceipt + */ + public static fromObject(object: { [k: string]: any }): proto.ServerErrorReceipt; + + /** + * Creates a plain object from a ServerErrorReceipt message. Also converts values to other types if specified. + * @param message ServerErrorReceipt + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ServerErrorReceipt, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ServerErrorReceipt to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a MediaRetryNotification. */ + interface IMediaRetryNotification { + + /** MediaRetryNotification stanzaId */ + stanzaId?: (string|null); + + /** MediaRetryNotification directPath */ + directPath?: (string|null); + + /** MediaRetryNotification result */ + result?: (proto.MediaRetryNotification.MediaRetryNotificationResultType|null); + } + + /** Represents a MediaRetryNotification. */ + class MediaRetryNotification implements IMediaRetryNotification { + + /** + * Constructs a new MediaRetryNotification. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMediaRetryNotification); + + /** MediaRetryNotification stanzaId. */ + public stanzaId: string; + + /** MediaRetryNotification directPath. */ + public directPath: string; + + /** MediaRetryNotification result. */ + public result: proto.MediaRetryNotification.MediaRetryNotificationResultType; + + /** + * Creates a new MediaRetryNotification instance using the specified properties. + * @param [properties] Properties to set + * @returns MediaRetryNotification instance + */ + public static create(properties?: proto.IMediaRetryNotification): proto.MediaRetryNotification; + + /** + * Encodes the specified MediaRetryNotification message. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages. + * @param message MediaRetryNotification message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMediaRetryNotification, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MediaRetryNotification message, length delimited. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages. + * @param message MediaRetryNotification message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMediaRetryNotification, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MediaRetryNotification message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MediaRetryNotification + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MediaRetryNotification; + + /** + * Decodes a MediaRetryNotification message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MediaRetryNotification + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MediaRetryNotification; + + /** + * Verifies a MediaRetryNotification message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MediaRetryNotification message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MediaRetryNotification + */ + public static fromObject(object: { [k: string]: any }): proto.MediaRetryNotification; + + /** + * Creates a plain object from a MediaRetryNotification message. Also converts values to other types if specified. + * @param message MediaRetryNotification + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MediaRetryNotification, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MediaRetryNotification to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace MediaRetryNotification { + + /** MediaRetryNotificationResultType enum. */ + enum MediaRetryNotificationResultType { + GENERAL_ERROR = 0, + SUCCESS = 1, + NOT_FOUND = 2, + DECRYPTION_ERROR = 3 + } + } + + /** Properties of a MsgOpaqueData. */ + interface IMsgOpaqueData { + + /** MsgOpaqueData body */ + body?: (string|null); + + /** MsgOpaqueData caption */ + caption?: (string|null); + + /** MsgOpaqueData clientUrl */ + clientUrl?: (string|null); + + /** MsgOpaqueData lng */ + lng?: (number|null); + + /** MsgOpaqueData lat */ + lat?: (number|null); + + /** MsgOpaqueData paymentAmount1000 */ + paymentAmount1000?: (number|null); + + /** MsgOpaqueData paymentNoteMsgBody */ + paymentNoteMsgBody?: (string|null); + + /** MsgOpaqueData canonicalUrl */ + canonicalUrl?: (string|null); + + /** MsgOpaqueData matchedText */ + matchedText?: (string|null); + + /** MsgOpaqueData title */ + title?: (string|null); + + /** MsgOpaqueData description */ + description?: (string|null); + } + + /** Represents a MsgOpaqueData. */ + class MsgOpaqueData implements IMsgOpaqueData { + + /** + * Constructs a new MsgOpaqueData. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMsgOpaqueData); + + /** MsgOpaqueData body. */ + public body: string; + + /** MsgOpaqueData caption. */ + public caption: string; + + /** MsgOpaqueData clientUrl. */ + public clientUrl: string; + + /** MsgOpaqueData lng. */ + public lng: number; + + /** MsgOpaqueData lat. */ + public lat: number; + + /** MsgOpaqueData paymentAmount1000. */ + public paymentAmount1000: number; + + /** MsgOpaqueData paymentNoteMsgBody. */ + public paymentNoteMsgBody: string; + + /** MsgOpaqueData canonicalUrl. */ + public canonicalUrl: string; + + /** MsgOpaqueData matchedText. */ + public matchedText: string; + + /** MsgOpaqueData title. */ + public title: string; + + /** MsgOpaqueData description. */ + public description: string; + + /** + * Creates a new MsgOpaqueData instance using the specified properties. + * @param [properties] Properties to set + * @returns MsgOpaqueData instance + */ + public static create(properties?: proto.IMsgOpaqueData): proto.MsgOpaqueData; + + /** + * Encodes the specified MsgOpaqueData message. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages. + * @param message MsgOpaqueData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMsgOpaqueData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MsgOpaqueData message, length delimited. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages. + * @param message MsgOpaqueData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMsgOpaqueData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MsgOpaqueData message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MsgOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MsgOpaqueData; + + /** + * Decodes a MsgOpaqueData message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MsgOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MsgOpaqueData; + + /** + * Verifies a MsgOpaqueData message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MsgOpaqueData message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MsgOpaqueData + */ + public static fromObject(object: { [k: string]: any }): proto.MsgOpaqueData; + + /** + * Creates a plain object from a MsgOpaqueData message. Also converts values to other types if specified. + * @param message MsgOpaqueData + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MsgOpaqueData, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MsgOpaqueData to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a MsgRowOpaqueData. */ + interface IMsgRowOpaqueData { + + /** MsgRowOpaqueData currentMsg */ + currentMsg?: (proto.IMsgOpaqueData|null); + + /** MsgRowOpaqueData quotedMsg */ + quotedMsg?: (proto.IMsgOpaqueData|null); + } + + /** Represents a MsgRowOpaqueData. */ + class MsgRowOpaqueData implements IMsgRowOpaqueData { + + /** + * Constructs a new MsgRowOpaqueData. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMsgRowOpaqueData); + + /** MsgRowOpaqueData currentMsg. */ + public currentMsg?: (proto.IMsgOpaqueData|null); + + /** MsgRowOpaqueData quotedMsg. */ + public quotedMsg?: (proto.IMsgOpaqueData|null); + + /** + * Creates a new MsgRowOpaqueData instance using the specified properties. + * @param [properties] Properties to set + * @returns MsgRowOpaqueData instance + */ + public static create(properties?: proto.IMsgRowOpaqueData): proto.MsgRowOpaqueData; + + /** + * Encodes the specified MsgRowOpaqueData message. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages. + * @param message MsgRowOpaqueData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMsgRowOpaqueData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MsgRowOpaqueData message, length delimited. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages. + * @param message MsgRowOpaqueData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMsgRowOpaqueData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MsgRowOpaqueData message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MsgRowOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MsgRowOpaqueData; + + /** + * Decodes a MsgRowOpaqueData message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MsgRowOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MsgRowOpaqueData; + + /** + * Verifies a MsgRowOpaqueData message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MsgRowOpaqueData message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MsgRowOpaqueData + */ + public static fromObject(object: { [k: string]: any }): proto.MsgRowOpaqueData; + + /** + * Creates a plain object from a MsgRowOpaqueData message. Also converts values to other types if specified. + * @param message MsgRowOpaqueData + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MsgRowOpaqueData, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MsgRowOpaqueData to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Pushname. */ + interface IPushname { + + /** Pushname id */ + id?: (string|null); + + /** Pushname pushname */ + pushname?: (string|null); + } + + /** Represents a Pushname. */ + class Pushname implements IPushname { + + /** + * Constructs a new Pushname. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPushname); + + /** Pushname id. */ + public id: string; + + /** Pushname pushname. */ + public pushname: string; + + /** + * Creates a new Pushname instance using the specified properties. + * @param [properties] Properties to set + * @returns Pushname instance + */ + public static create(properties?: proto.IPushname): proto.Pushname; + + /** + * Encodes the specified Pushname message. Does not implicitly {@link proto.Pushname.verify|verify} messages. + * @param message Pushname message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPushname, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Pushname message, length delimited. Does not implicitly {@link proto.Pushname.verify|verify} messages. + * @param message Pushname message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPushname, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Pushname message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Pushname + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Pushname; + + /** + * Decodes a Pushname message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Pushname + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Pushname; + + /** + * Verifies a Pushname message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Pushname message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Pushname + */ + public static fromObject(object: { [k: string]: any }): proto.Pushname; + + /** + * Creates a plain object from a Pushname message. Also converts values to other types if specified. + * @param message Pushname + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Pushname, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Pushname to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HistorySyncMsg. */ + interface IHistorySyncMsg { + + /** HistorySyncMsg message */ + message?: (proto.IWebMessageInfo|null); + + /** HistorySyncMsg msgOrderId */ + msgOrderId?: (number|Long|null); + } + + /** Represents a HistorySyncMsg. */ + class HistorySyncMsg implements IHistorySyncMsg { + + /** + * Constructs a new HistorySyncMsg. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHistorySyncMsg); + + /** HistorySyncMsg message. */ + public message?: (proto.IWebMessageInfo|null); + + /** HistorySyncMsg msgOrderId. */ + public msgOrderId: (number|Long); + + /** + * Creates a new HistorySyncMsg instance using the specified properties. + * @param [properties] Properties to set + * @returns HistorySyncMsg instance + */ + public static create(properties?: proto.IHistorySyncMsg): proto.HistorySyncMsg; + + /** + * Encodes the specified HistorySyncMsg message. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages. + * @param message HistorySyncMsg message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHistorySyncMsg, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HistorySyncMsg message, length delimited. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages. + * @param message HistorySyncMsg message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHistorySyncMsg, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HistorySyncMsg message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HistorySyncMsg + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HistorySyncMsg; + + /** + * Decodes a HistorySyncMsg message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HistorySyncMsg + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HistorySyncMsg; + + /** + * Verifies a HistorySyncMsg message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HistorySyncMsg message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HistorySyncMsg + */ + public static fromObject(object: { [k: string]: any }): proto.HistorySyncMsg; + + /** + * Creates a plain object from a HistorySyncMsg message. Also converts values to other types if specified. + * @param message HistorySyncMsg + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HistorySyncMsg, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HistorySyncMsg to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Conversation. */ + interface IConversation { + + /** Conversation id */ + id: string; + + /** Conversation messages */ + messages?: (proto.IHistorySyncMsg[]|null); + + /** Conversation newJid */ + newJid?: (string|null); + + /** Conversation oldJid */ + oldJid?: (string|null); + + /** Conversation lastMsgTimestamp */ + lastMsgTimestamp?: (number|Long|null); + + /** Conversation unreadCount */ + unreadCount?: (number|null); + + /** Conversation readOnly */ + readOnly?: (boolean|null); + + /** Conversation endOfHistoryTransfer */ + endOfHistoryTransfer?: (boolean|null); + + /** Conversation ephemeralExpiration */ + ephemeralExpiration?: (number|null); + + /** Conversation ephemeralSettingTimestamp */ + ephemeralSettingTimestamp?: (number|Long|null); + + /** Conversation endOfHistoryTransferType */ + endOfHistoryTransferType?: (proto.Conversation.ConversationEndOfHistoryTransferType|null); + + /** Conversation conversationTimestamp */ + conversationTimestamp?: (number|Long|null); + + /** Conversation name */ + name?: (string|null); + + /** Conversation pHash */ + pHash?: (string|null); + + /** Conversation notSpam */ + notSpam?: (boolean|null); + } + + /** Represents a Conversation. */ + class Conversation implements IConversation { + + /** + * Constructs a new Conversation. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IConversation); + + /** Conversation id. */ + public id: string; + + /** Conversation messages. */ + public messages: proto.IHistorySyncMsg[]; + + /** Conversation newJid. */ + public newJid: string; + + /** Conversation oldJid. */ + public oldJid: string; + + /** Conversation lastMsgTimestamp. */ + public lastMsgTimestamp: (number|Long); + + /** Conversation unreadCount. */ + public unreadCount: number; + + /** Conversation readOnly. */ + public readOnly: boolean; + + /** Conversation endOfHistoryTransfer. */ + public endOfHistoryTransfer: boolean; + + /** Conversation ephemeralExpiration. */ + public ephemeralExpiration: number; + + /** Conversation ephemeralSettingTimestamp. */ + public ephemeralSettingTimestamp: (number|Long); + + /** Conversation endOfHistoryTransferType. */ + public endOfHistoryTransferType: proto.Conversation.ConversationEndOfHistoryTransferType; + + /** Conversation conversationTimestamp. */ + public conversationTimestamp: (number|Long); + + /** Conversation name. */ + public name: string; + + /** Conversation pHash. */ + public pHash: string; + + /** Conversation notSpam. */ + public notSpam: boolean; + + /** + * Creates a new Conversation instance using the specified properties. + * @param [properties] Properties to set + * @returns Conversation instance + */ + public static create(properties?: proto.IConversation): proto.Conversation; + + /** + * Encodes the specified Conversation message. Does not implicitly {@link proto.Conversation.verify|verify} messages. + * @param message Conversation message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IConversation, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Conversation message, length delimited. Does not implicitly {@link proto.Conversation.verify|verify} messages. + * @param message Conversation message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IConversation, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Conversation message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Conversation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Conversation; + + /** + * Decodes a Conversation message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Conversation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Conversation; + + /** + * Verifies a Conversation message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Conversation message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Conversation + */ + public static fromObject(object: { [k: string]: any }): proto.Conversation; + + /** + * Creates a plain object from a Conversation message. Also converts values to other types if specified. + * @param message Conversation + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Conversation, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Conversation to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace Conversation { + + /** ConversationEndOfHistoryTransferType enum. */ + enum ConversationEndOfHistoryTransferType { + COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY = 0, + COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY = 1 + } + } + + /** Properties of a HistorySync. */ + interface IHistorySync { + + /** HistorySync syncType */ + syncType: proto.HistorySync.HistorySyncHistorySyncType; + + /** HistorySync conversations */ + conversations?: (proto.IConversation[]|null); + + /** HistorySync statusV3Messages */ + statusV3Messages?: (proto.IWebMessageInfo[]|null); + + /** HistorySync chunkOrder */ + chunkOrder?: (number|null); + + /** HistorySync progress */ + progress?: (number|null); + + /** HistorySync pushnames */ + pushnames?: (proto.IPushname[]|null); + } + + /** Represents a HistorySync. */ + class HistorySync implements IHistorySync { + + /** + * Constructs a new HistorySync. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHistorySync); + + /** HistorySync syncType. */ + public syncType: proto.HistorySync.HistorySyncHistorySyncType; + + /** HistorySync conversations. */ + public conversations: proto.IConversation[]; + + /** HistorySync statusV3Messages. */ + public statusV3Messages: proto.IWebMessageInfo[]; + + /** HistorySync chunkOrder. */ + public chunkOrder: number; + + /** HistorySync progress. */ + public progress: number; + + /** HistorySync pushnames. */ + public pushnames: proto.IPushname[]; + + /** + * Creates a new HistorySync instance using the specified properties. + * @param [properties] Properties to set + * @returns HistorySync instance + */ + public static create(properties?: proto.IHistorySync): proto.HistorySync; + + /** + * Encodes the specified HistorySync message. Does not implicitly {@link proto.HistorySync.verify|verify} messages. + * @param message HistorySync message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHistorySync, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HistorySync message, length delimited. Does not implicitly {@link proto.HistorySync.verify|verify} messages. + * @param message HistorySync message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHistorySync, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HistorySync message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HistorySync + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HistorySync; + + /** + * Decodes a HistorySync message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HistorySync + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HistorySync; + + /** + * Verifies a HistorySync message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HistorySync message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HistorySync + */ + public static fromObject(object: { [k: string]: any }): proto.HistorySync; + + /** + * Creates a plain object from a HistorySync message. Also converts values to other types if specified. + * @param message HistorySync + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HistorySync, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HistorySync to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace HistorySync { + + /** HistorySyncHistorySyncType enum. */ + enum HistorySyncHistorySyncType { + INITIAL_BOOTSTRAP = 0, + INITIAL_STATUS_V3 = 1, + FULL = 2, + RECENT = 3, + PUSH_NAME = 4 + } + } + + /** Properties of an EphemeralSetting. */ + interface IEphemeralSetting { + + /** EphemeralSetting duration */ + duration?: (number|null); + + /** EphemeralSetting timestamp */ + timestamp?: (number|Long|null); + } + + /** Represents an EphemeralSetting. */ + class EphemeralSetting implements IEphemeralSetting { + + /** + * Constructs a new EphemeralSetting. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IEphemeralSetting); + + /** EphemeralSetting duration. */ + public duration: number; + + /** EphemeralSetting timestamp. */ + public timestamp: (number|Long); + + /** + * Creates a new EphemeralSetting instance using the specified properties. + * @param [properties] Properties to set + * @returns EphemeralSetting instance + */ + public static create(properties?: proto.IEphemeralSetting): proto.EphemeralSetting; + + /** + * Encodes the specified EphemeralSetting message. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. + * @param message EphemeralSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IEphemeralSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified EphemeralSetting message, length delimited. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. + * @param message EphemeralSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IEphemeralSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an EphemeralSetting message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns EphemeralSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.EphemeralSetting; + + /** + * Decodes an EphemeralSetting message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns EphemeralSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.EphemeralSetting; + + /** + * Verifies an EphemeralSetting message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an EphemeralSetting message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns EphemeralSetting + */ + public static fromObject(object: { [k: string]: any }): proto.EphemeralSetting; + + /** + * Creates a plain object from an EphemeralSetting message. Also converts values to other types if specified. + * @param message EphemeralSetting + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.EphemeralSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this EphemeralSetting to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a PaymentBackground. */ + interface IPaymentBackground { + + /** PaymentBackground id */ + id?: (string|null); + + /** PaymentBackground fileLength */ + fileLength?: (string|null); + + /** PaymentBackground width */ + width?: (number|null); + + /** PaymentBackground height */ + height?: (number|null); + + /** PaymentBackground mimetype */ + mimetype?: (string|null); + + /** PaymentBackground placeholderArgb */ + placeholderArgb?: (number|null); + + /** PaymentBackground textArgb */ + textArgb?: (number|null); + + /** PaymentBackground subtextArgb */ + subtextArgb?: (number|null); + } + + /** Represents a PaymentBackground. */ + class PaymentBackground implements IPaymentBackground { + + /** + * Constructs a new PaymentBackground. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPaymentBackground); + + /** PaymentBackground id. */ + public id: string; + + /** PaymentBackground fileLength. */ + public fileLength: string; + + /** PaymentBackground width. */ + public width: number; + + /** PaymentBackground height. */ + public height: number; + + /** PaymentBackground mimetype. */ + public mimetype: string; + + /** PaymentBackground placeholderArgb. */ + public placeholderArgb: number; + + /** PaymentBackground textArgb. */ + public textArgb: number; + + /** PaymentBackground subtextArgb. */ + public subtextArgb: number; + + /** + * Creates a new PaymentBackground instance using the specified properties. + * @param [properties] Properties to set + * @returns PaymentBackground instance + */ + public static create(properties?: proto.IPaymentBackground): proto.PaymentBackground; + + /** + * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @param message PaymentBackground message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @param message PaymentBackground message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a PaymentBackground message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns PaymentBackground + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PaymentBackground; + + /** + * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns PaymentBackground + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PaymentBackground; + + /** + * Verifies a PaymentBackground message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns PaymentBackground + */ + public static fromObject(object: { [k: string]: any }): proto.PaymentBackground; + + /** + * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. + * @param message PaymentBackground + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.PaymentBackground, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this PaymentBackground to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Money. */ + interface IMoney { + + /** Money value */ + value?: (number|Long|null); + + /** Money offset */ + offset?: (number|null); + + /** Money currencyCode */ + currencyCode?: (string|null); + } + + /** Represents a Money. */ + class Money implements IMoney { + + /** + * Constructs a new Money. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMoney); + + /** Money value. */ + public value: (number|Long); + + /** Money offset. */ + public offset: number; + + /** Money currencyCode. */ + public currencyCode: string; + + /** + * Creates a new Money instance using the specified properties. + * @param [properties] Properties to set + * @returns Money instance + */ + public static create(properties?: proto.IMoney): proto.Money; + + /** + * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. + * @param message Money message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. + * @param message Money message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Money message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Money; + + /** + * Decodes a Money message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Money; + + /** + * Verifies a Money message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Money message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Money + */ + public static fromObject(object: { [k: string]: any }): proto.Money; + + /** + * Creates a plain object from a Money message. Also converts values to other types if specified. + * @param message Money + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Money, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Money to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; } /** Properties of a HydratedQuickReplyButton. */ @@ -2233,6 +8286,222 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + /** Properties of a DeviceListMetadata. */ + interface IDeviceListMetadata { + + /** DeviceListMetadata senderKeyHash */ + senderKeyHash?: (Uint8Array|null); + + /** DeviceListMetadata senderTimestamp */ + senderTimestamp?: (number|Long|null); + + /** DeviceListMetadata senderKeyIndexes */ + senderKeyIndexes?: (number[]|null); + + /** DeviceListMetadata recipientKeyHash */ + recipientKeyHash?: (Uint8Array|null); + + /** DeviceListMetadata recipientTimestamp */ + recipientTimestamp?: (number|Long|null); + + /** DeviceListMetadata recipientKeyIndexes */ + recipientKeyIndexes?: (number[]|null); + } + + /** Represents a DeviceListMetadata. */ + class DeviceListMetadata implements IDeviceListMetadata { + + /** + * Constructs a new DeviceListMetadata. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IDeviceListMetadata); + + /** DeviceListMetadata senderKeyHash. */ + public senderKeyHash: Uint8Array; + + /** DeviceListMetadata senderTimestamp. */ + public senderTimestamp: (number|Long); + + /** DeviceListMetadata senderKeyIndexes. */ + public senderKeyIndexes: number[]; + + /** DeviceListMetadata recipientKeyHash. */ + public recipientKeyHash: Uint8Array; + + /** DeviceListMetadata recipientTimestamp. */ + public recipientTimestamp: (number|Long); + + /** DeviceListMetadata recipientKeyIndexes. */ + public recipientKeyIndexes: number[]; + + /** + * Creates a new DeviceListMetadata instance using the specified properties. + * @param [properties] Properties to set + * @returns DeviceListMetadata instance + */ + public static create(properties?: proto.IDeviceListMetadata): proto.DeviceListMetadata; + + /** + * Encodes the specified DeviceListMetadata message. Does not implicitly {@link proto.DeviceListMetadata.verify|verify} messages. + * @param message DeviceListMetadata message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IDeviceListMetadata, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified DeviceListMetadata message, length delimited. Does not implicitly {@link proto.DeviceListMetadata.verify|verify} messages. + * @param message DeviceListMetadata message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IDeviceListMetadata, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a DeviceListMetadata message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns DeviceListMetadata + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DeviceListMetadata; + + /** + * Decodes a DeviceListMetadata message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns DeviceListMetadata + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DeviceListMetadata; + + /** + * Verifies a DeviceListMetadata message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a DeviceListMetadata message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns DeviceListMetadata + */ + public static fromObject(object: { [k: string]: any }): proto.DeviceListMetadata; + + /** + * Creates a plain object from a DeviceListMetadata message. Also converts values to other types if specified. + * @param message DeviceListMetadata + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.DeviceListMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this DeviceListMetadata to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a MessageContextInfo. */ + interface IMessageContextInfo { + + /** MessageContextInfo deviceListMetadata */ + deviceListMetadata?: (proto.IDeviceListMetadata|null); + + /** MessageContextInfo deviceListMetadataVersion */ + deviceListMetadataVersion?: (number|null); + } + + /** Represents a MessageContextInfo. */ + class MessageContextInfo implements IMessageContextInfo { + + /** + * Constructs a new MessageContextInfo. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMessageContextInfo); + + /** MessageContextInfo deviceListMetadata. */ + public deviceListMetadata?: (proto.IDeviceListMetadata|null); + + /** MessageContextInfo deviceListMetadataVersion. */ + public deviceListMetadataVersion: number; + + /** + * Creates a new MessageContextInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns MessageContextInfo instance + */ + public static create(properties?: proto.IMessageContextInfo): proto.MessageContextInfo; + + /** + * Encodes the specified MessageContextInfo message. Does not implicitly {@link proto.MessageContextInfo.verify|verify} messages. + * @param message MessageContextInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMessageContextInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MessageContextInfo message, length delimited. Does not implicitly {@link proto.MessageContextInfo.verify|verify} messages. + * @param message MessageContextInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMessageContextInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MessageContextInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MessageContextInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MessageContextInfo; + + /** + * Decodes a MessageContextInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MessageContextInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MessageContextInfo; + + /** + * Verifies a MessageContextInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MessageContextInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MessageContextInfo + */ + public static fromObject(object: { [k: string]: any }): proto.MessageContextInfo; + + /** + * Creates a plain object from a MessageContextInfo message. Also converts values to other types if specified. + * @param message MessageContextInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MessageContextInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MessageContextInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of an AdReplyInfo. */ interface IAdReplyInfo { @@ -2549,6 +8818,15 @@ export namespace proto { /** ContextInfo externalAdReply */ externalAdReply?: (proto.IExternalAdReplyInfo|null); + + /** ContextInfo entryPointConversionSource */ + entryPointConversionSource?: (string|null); + + /** ContextInfo entryPointConversionApp */ + entryPointConversionApp?: (string|null); + + /** ContextInfo entryPointConversionDelaySeconds */ + entryPointConversionDelaySeconds?: (number|null); } /** Represents a ContextInfo. */ @@ -2608,6 +8886,15 @@ export namespace proto { /** ContextInfo externalAdReply. */ public externalAdReply?: (proto.IExternalAdReplyInfo|null); + /** ContextInfo entryPointConversionSource. */ + public entryPointConversionSource: string; + + /** ContextInfo entryPointConversionApp. */ + public entryPointConversionApp: string; + + /** ContextInfo entryPointConversionDelaySeconds. */ + public entryPointConversionDelaySeconds: number; + /** * Creates a new ContextInfo instance using the specified properties. * @param [properties] Properties to set @@ -2843,6 +9130,15 @@ export namespace proto { /** ImageMessage viewOnce */ viewOnce?: (boolean|null); + + /** ImageMessage thumbnailDirectPath */ + thumbnailDirectPath?: (string|null); + + /** ImageMessage thumbnailSha256 */ + thumbnailSha256?: (Uint8Array|null); + + /** ImageMessage thumbnailEncSha256 */ + thumbnailEncSha256?: (Uint8Array|null); } /** Represents an ImageMessage. */ @@ -2920,6 +9216,15 @@ export namespace proto { /** ImageMessage viewOnce. */ public viewOnce: boolean; + /** ImageMessage thumbnailDirectPath. */ + public thumbnailDirectPath: string; + + /** ImageMessage thumbnailSha256. */ + public thumbnailSha256: Uint8Array; + + /** ImageMessage thumbnailEncSha256. */ + public thumbnailEncSha256: Uint8Array; + /** * Creates a new ImageMessage instance using the specified properties. * @param [properties] Properties to set @@ -2991,6 +9296,159 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + /** Properties of an InvoiceMessage. */ + interface IInvoiceMessage { + + /** InvoiceMessage note */ + note?: (string|null); + + /** InvoiceMessage token */ + token?: (string|null); + + /** InvoiceMessage attachmentType */ + attachmentType?: (proto.InvoiceMessage.InvoiceMessageAttachmentType|null); + + /** InvoiceMessage attachmentMimetype */ + attachmentMimetype?: (string|null); + + /** InvoiceMessage attachmentMediaKey */ + attachmentMediaKey?: (Uint8Array|null); + + /** InvoiceMessage attachmentMediaKeyTimestamp */ + attachmentMediaKeyTimestamp?: (number|Long|null); + + /** InvoiceMessage attachmentFileSha256 */ + attachmentFileSha256?: (Uint8Array|null); + + /** InvoiceMessage attachmentFileEncSha256 */ + attachmentFileEncSha256?: (Uint8Array|null); + + /** InvoiceMessage attachmentDirectPath */ + attachmentDirectPath?: (string|null); + + /** InvoiceMessage attachmentJpegThumbnail */ + attachmentJpegThumbnail?: (Uint8Array|null); + } + + /** Represents an InvoiceMessage. */ + class InvoiceMessage implements IInvoiceMessage { + + /** + * Constructs a new InvoiceMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IInvoiceMessage); + + /** InvoiceMessage note. */ + public note: string; + + /** InvoiceMessage token. */ + public token: string; + + /** InvoiceMessage attachmentType. */ + public attachmentType: proto.InvoiceMessage.InvoiceMessageAttachmentType; + + /** InvoiceMessage attachmentMimetype. */ + public attachmentMimetype: string; + + /** InvoiceMessage attachmentMediaKey. */ + public attachmentMediaKey: Uint8Array; + + /** InvoiceMessage attachmentMediaKeyTimestamp. */ + public attachmentMediaKeyTimestamp: (number|Long); + + /** InvoiceMessage attachmentFileSha256. */ + public attachmentFileSha256: Uint8Array; + + /** InvoiceMessage attachmentFileEncSha256. */ + public attachmentFileEncSha256: Uint8Array; + + /** InvoiceMessage attachmentDirectPath. */ + public attachmentDirectPath: string; + + /** InvoiceMessage attachmentJpegThumbnail. */ + public attachmentJpegThumbnail: Uint8Array; + + /** + * Creates a new InvoiceMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns InvoiceMessage instance + */ + public static create(properties?: proto.IInvoiceMessage): proto.InvoiceMessage; + + /** + * Encodes the specified InvoiceMessage message. Does not implicitly {@link proto.InvoiceMessage.verify|verify} messages. + * @param message InvoiceMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IInvoiceMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified InvoiceMessage message, length delimited. Does not implicitly {@link proto.InvoiceMessage.verify|verify} messages. + * @param message InvoiceMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IInvoiceMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an InvoiceMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns InvoiceMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.InvoiceMessage; + + /** + * Decodes an InvoiceMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns InvoiceMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.InvoiceMessage; + + /** + * Verifies an InvoiceMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an InvoiceMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns InvoiceMessage + */ + public static fromObject(object: { [k: string]: any }): proto.InvoiceMessage; + + /** + * Creates a plain object from an InvoiceMessage message. Also converts values to other types if specified. + * @param message InvoiceMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.InvoiceMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this InvoiceMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace InvoiceMessage { + + /** InvoiceMessageAttachmentType enum. */ + enum InvoiceMessageAttachmentType { + IMAGE = 0, + PDF = 1 + } + } + /** Properties of a ContactMessage. */ interface IContactMessage { @@ -3287,6 +9745,27 @@ export namespace proto { /** ExtendedTextMessage doNotPlayInline */ doNotPlayInline?: (boolean|null); + + /** ExtendedTextMessage thumbnailDirectPath */ + thumbnailDirectPath?: (string|null); + + /** ExtendedTextMessage thumbnailSha256 */ + thumbnailSha256?: (Uint8Array|null); + + /** ExtendedTextMessage thumbnailEncSha256 */ + thumbnailEncSha256?: (Uint8Array|null); + + /** ExtendedTextMessage mediaKey */ + mediaKey?: (Uint8Array|null); + + /** ExtendedTextMessage mediaKeyTimestamp */ + mediaKeyTimestamp?: (number|Long|null); + + /** ExtendedTextMessage thumbnailHeight */ + thumbnailHeight?: (number|null); + + /** ExtendedTextMessage thumbnailWidth */ + thumbnailWidth?: (number|null); } /** Represents an ExtendedTextMessage. */ @@ -3334,6 +9813,27 @@ export namespace proto { /** ExtendedTextMessage doNotPlayInline. */ public doNotPlayInline: boolean; + /** ExtendedTextMessage thumbnailDirectPath. */ + public thumbnailDirectPath: string; + + /** ExtendedTextMessage thumbnailSha256. */ + public thumbnailSha256: Uint8Array; + + /** ExtendedTextMessage thumbnailEncSha256. */ + public thumbnailEncSha256: Uint8Array; + + /** ExtendedTextMessage mediaKey. */ + public mediaKey: Uint8Array; + + /** ExtendedTextMessage mediaKeyTimestamp. */ + public mediaKeyTimestamp: (number|Long); + + /** ExtendedTextMessage thumbnailHeight. */ + public thumbnailHeight: number; + + /** ExtendedTextMessage thumbnailWidth. */ + public thumbnailWidth: number; + /** * Creates a new ExtendedTextMessage instance using the specified properties. * @param [properties] Properties to set @@ -3837,6 +10337,15 @@ export namespace proto { /** VideoMessage viewOnce */ viewOnce?: (boolean|null); + + /** VideoMessage thumbnailDirectPath */ + thumbnailDirectPath?: (string|null); + + /** VideoMessage thumbnailSha256 */ + thumbnailSha256?: (Uint8Array|null); + + /** VideoMessage thumbnailEncSha256 */ + thumbnailEncSha256?: (Uint8Array|null); } /** Represents a VideoMessage. */ @@ -3905,6 +10414,15 @@ export namespace proto { /** VideoMessage viewOnce. */ public viewOnce: boolean; + /** VideoMessage thumbnailDirectPath. */ + public thumbnailDirectPath: string; + + /** VideoMessage thumbnailSha256. */ + public thumbnailSha256: Uint8Array; + + /** VideoMessage thumbnailEncSha256. */ + public thumbnailEncSha256: Uint8Array; + /** * Creates a new VideoMessage instance using the specified properties. * @param [properties] Properties to set @@ -3991,6 +10509,15 @@ export namespace proto { /** Call callKey */ callKey?: (Uint8Array|null); + + /** Call conversionSource */ + conversionSource?: (string|null); + + /** Call conversionData */ + conversionData?: (Uint8Array|null); + + /** Call conversionDelaySeconds */ + conversionDelaySeconds?: (number|null); } /** Represents a Call. */ @@ -4005,6 +10532,15 @@ export namespace proto { /** Call callKey. */ public callKey: Uint8Array; + /** Call conversionSource. */ + public conversionSource: string; + + /** Call conversionData. */ + public conversionData: Uint8Array; + + /** Call conversionDelaySeconds. */ + public conversionDelaySeconds: number; + /** * Creates a new Call instance using the specified properties. * @param [properties] Properties to set @@ -4198,6 +10734,9 @@ export namespace proto { /** ProtocolMessage initialSecurityNotificationSettingSync */ initialSecurityNotificationSettingSync?: (proto.IInitialSecurityNotificationSettingSync|null); + + /** ProtocolMessage appStateFatalExceptionNotification */ + appStateFatalExceptionNotification?: (proto.IAppStateFatalExceptionNotification|null); } /** Represents a ProtocolMessage. */ @@ -4233,6 +10772,9 @@ export namespace proto { /** ProtocolMessage initialSecurityNotificationSettingSync. */ public initialSecurityNotificationSettingSync?: (proto.IInitialSecurityNotificationSettingSync|null); + /** ProtocolMessage appStateFatalExceptionNotification. */ + public appStateFatalExceptionNotification?: (proto.IAppStateFatalExceptionNotification|null); + /** * Creates a new ProtocolMessage instance using the specified properties. * @param [properties] Properties to set @@ -4315,7 +10857,8 @@ export namespace proto { APP_STATE_SYNC_KEY_SHARE = 6, APP_STATE_SYNC_KEY_REQUEST = 7, MSG_FANOUT_BACKFILL_REQUEST = 8, - INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC = 9 + INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC = 9, + APP_STATE_FATAL_EXCEPTION_NOTIFICATION = 10 } } @@ -4458,7 +11001,8 @@ export namespace proto { INITIAL_BOOTSTRAP = 0, INITIAL_STATUS_V3 = 1, FULL = 2, - RECENT = 3 + RECENT = 3, + PUSH_NAME = 4 } } @@ -4656,6 +11200,9 @@ export namespace proto { /** AppStateSyncKeyFingerprint currentIndex */ currentIndex?: (number|null); + + /** AppStateSyncKeyFingerprint deviceIndexes */ + deviceIndexes?: (number[]|null); } /** Represents an AppStateSyncKeyFingerprint. */ @@ -4673,6 +11220,9 @@ export namespace proto { /** AppStateSyncKeyFingerprint currentIndex. */ public currentIndex: number; + /** AppStateSyncKeyFingerprint deviceIndexes. */ + public deviceIndexes: number[]; + /** * Creates a new AppStateSyncKeyFingerprint instance using the specified properties. * @param [properties] Properties to set @@ -5026,6 +11576,102 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + /** Properties of an AppStateFatalExceptionNotification. */ + interface IAppStateFatalExceptionNotification { + + /** AppStateFatalExceptionNotification collectionNames */ + collectionNames?: (string[]|null); + + /** AppStateFatalExceptionNotification timestamp */ + timestamp?: (number|Long|null); + } + + /** Represents an AppStateFatalExceptionNotification. */ + class AppStateFatalExceptionNotification implements IAppStateFatalExceptionNotification { + + /** + * Constructs a new AppStateFatalExceptionNotification. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IAppStateFatalExceptionNotification); + + /** AppStateFatalExceptionNotification collectionNames. */ + public collectionNames: string[]; + + /** AppStateFatalExceptionNotification timestamp. */ + public timestamp: (number|Long); + + /** + * Creates a new AppStateFatalExceptionNotification instance using the specified properties. + * @param [properties] Properties to set + * @returns AppStateFatalExceptionNotification instance + */ + public static create(properties?: proto.IAppStateFatalExceptionNotification): proto.AppStateFatalExceptionNotification; + + /** + * Encodes the specified AppStateFatalExceptionNotification message. Does not implicitly {@link proto.AppStateFatalExceptionNotification.verify|verify} messages. + * @param message AppStateFatalExceptionNotification message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IAppStateFatalExceptionNotification, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified AppStateFatalExceptionNotification message, length delimited. Does not implicitly {@link proto.AppStateFatalExceptionNotification.verify|verify} messages. + * @param message AppStateFatalExceptionNotification message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IAppStateFatalExceptionNotification, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an AppStateFatalExceptionNotification message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns AppStateFatalExceptionNotification + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.AppStateFatalExceptionNotification; + + /** + * Decodes an AppStateFatalExceptionNotification message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns AppStateFatalExceptionNotification + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.AppStateFatalExceptionNotification; + + /** + * Verifies an AppStateFatalExceptionNotification message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an AppStateFatalExceptionNotification message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns AppStateFatalExceptionNotification + */ + public static fromObject(object: { [k: string]: any }): proto.AppStateFatalExceptionNotification; + + /** + * Creates a plain object from an AppStateFatalExceptionNotification message. Also converts values to other types if specified. + * @param message AppStateFatalExceptionNotification + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.AppStateFatalExceptionNotification, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this AppStateFatalExceptionNotification to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of an InitialSecurityNotificationSettingSync. */ interface IInitialSecurityNotificationSettingSync { @@ -5900,6 +12546,9 @@ export namespace proto { /** SendPaymentMessage requestMessageKey */ requestMessageKey?: (proto.IMessageKey|null); + + /** SendPaymentMessage background */ + background?: (proto.IPaymentBackground|null); } /** Represents a SendPaymentMessage. */ @@ -5917,6 +12566,9 @@ export namespace proto { /** SendPaymentMessage requestMessageKey. */ public requestMessageKey?: (proto.IMessageKey|null); + /** SendPaymentMessage background. */ + public background?: (proto.IPaymentBackground|null); + /** * Creates a new SendPaymentMessage instance using the specified properties. * @param [properties] Properties to set @@ -6005,6 +12657,12 @@ export namespace proto { /** RequestPaymentMessage expiryTimestamp */ expiryTimestamp?: (number|Long|null); + + /** RequestPaymentMessage amount */ + amount?: (proto.IMoney|null); + + /** RequestPaymentMessage background */ + background?: (proto.IPaymentBackground|null); } /** Represents a RequestPaymentMessage. */ @@ -6031,6 +12689,12 @@ export namespace proto { /** RequestPaymentMessage expiryTimestamp. */ public expiryTimestamp: (number|Long); + /** RequestPaymentMessage amount. */ + public amount?: (proto.IMoney|null); + + /** RequestPaymentMessage background. */ + public background?: (proto.IPaymentBackground|null); + /** * Creates a new RequestPaymentMessage instance using the specified properties. * @param [properties] Properties to set @@ -6282,6 +12946,113 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + /** Properties of a PaymentInviteMessage. */ + interface IPaymentInviteMessage { + + /** PaymentInviteMessage serviceType */ + serviceType?: (proto.PaymentInviteMessage.PaymentInviteMessageServiceType|null); + + /** PaymentInviteMessage expiryTimestamp */ + expiryTimestamp?: (number|Long|null); + } + + /** Represents a PaymentInviteMessage. */ + class PaymentInviteMessage implements IPaymentInviteMessage { + + /** + * Constructs a new PaymentInviteMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPaymentInviteMessage); + + /** PaymentInviteMessage serviceType. */ + public serviceType: proto.PaymentInviteMessage.PaymentInviteMessageServiceType; + + /** PaymentInviteMessage expiryTimestamp. */ + public expiryTimestamp: (number|Long); + + /** + * Creates a new PaymentInviteMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns PaymentInviteMessage instance + */ + public static create(properties?: proto.IPaymentInviteMessage): proto.PaymentInviteMessage; + + /** + * Encodes the specified PaymentInviteMessage message. Does not implicitly {@link proto.PaymentInviteMessage.verify|verify} messages. + * @param message PaymentInviteMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPaymentInviteMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified PaymentInviteMessage message, length delimited. Does not implicitly {@link proto.PaymentInviteMessage.verify|verify} messages. + * @param message PaymentInviteMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPaymentInviteMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a PaymentInviteMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns PaymentInviteMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PaymentInviteMessage; + + /** + * Decodes a PaymentInviteMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns PaymentInviteMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PaymentInviteMessage; + + /** + * Verifies a PaymentInviteMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a PaymentInviteMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns PaymentInviteMessage + */ + public static fromObject(object: { [k: string]: any }): proto.PaymentInviteMessage; + + /** + * Creates a plain object from a PaymentInviteMessage message. Also converts values to other types if specified. + * @param message PaymentInviteMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.PaymentInviteMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this PaymentInviteMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace PaymentInviteMessage { + + /** PaymentInviteMessageServiceType enum. */ + enum PaymentInviteMessageServiceType { + UNKNOWN = 0, + FBPAY = 1, + NOVI = 2, + UPI = 3 + } + } + /** Properties of a LiveLocationMessage. */ interface ILiveLocationMessage { @@ -6791,7 +13562,7 @@ export namespace proto { public documentMessage?: (proto.IDocumentMessage|null); /** HydratedFourRowTemplate hydratedTitleText. */ - public hydratedTitleText: string; + public hydratedTitleText?: (string|null); /** HydratedFourRowTemplate imageMessage. */ public imageMessage?: (proto.IImageMessage|null); @@ -7229,6 +14000,9 @@ export namespace proto { /** ProductSnapshot firstImageId */ firstImageId?: (string|null); + + /** ProductSnapshot salePriceAmount1000 */ + salePriceAmount1000?: (number|Long|null); } /** Represents a ProductSnapshot. */ @@ -7270,6 +14044,9 @@ export namespace proto { /** ProductSnapshot firstImageId. */ public firstImageId: string; + /** ProductSnapshot salePriceAmount1000. */ + public salePriceAmount1000: (number|Long); + /** * Creates a new ProductSnapshot instance using the specified properties. * @param [properties] Properties to set @@ -7479,6 +14256,12 @@ export namespace proto { /** OrderMessage token */ token?: (string|null); + /** OrderMessage totalAmount1000 */ + totalAmount1000?: (number|Long|null); + + /** OrderMessage totalCurrencyCode */ + totalCurrencyCode?: (string|null); + /** OrderMessage contextInfo */ contextInfo?: (proto.IContextInfo|null); } @@ -7519,6 +14302,12 @@ export namespace proto { /** OrderMessage token. */ public token: string; + /** OrderMessage totalAmount1000. */ + public totalAmount1000: (number|Long); + + /** OrderMessage totalCurrencyCode. */ + public totalCurrencyCode: string; + /** OrderMessage contextInfo. */ public contextInfo?: (proto.IContextInfo|null); @@ -7804,6 +14593,390 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + /** Properties of a Product. */ + interface IProduct { + + /** Product productId */ + productId?: (string|null); + } + + /** Represents a Product. */ + class Product implements IProduct { + + /** + * Constructs a new Product. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IProduct); + + /** Product productId. */ + public productId: string; + + /** + * Creates a new Product instance using the specified properties. + * @param [properties] Properties to set + * @returns Product instance + */ + public static create(properties?: proto.IProduct): proto.Product; + + /** + * Encodes the specified Product message. Does not implicitly {@link proto.Product.verify|verify} messages. + * @param message Product message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IProduct, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Product message, length delimited. Does not implicitly {@link proto.Product.verify|verify} messages. + * @param message Product message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IProduct, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Product message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Product + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Product; + + /** + * Decodes a Product message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Product + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Product; + + /** + * Verifies a Product message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Product message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Product + */ + public static fromObject(object: { [k: string]: any }): proto.Product; + + /** + * Creates a plain object from a Product message. Also converts values to other types if specified. + * @param message Product + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Product, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Product to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ProductSection. */ + interface IProductSection { + + /** ProductSection title */ + title?: (string|null); + + /** ProductSection products */ + products?: (proto.IProduct[]|null); + } + + /** Represents a ProductSection. */ + class ProductSection implements IProductSection { + + /** + * Constructs a new ProductSection. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IProductSection); + + /** ProductSection title. */ + public title: string; + + /** ProductSection products. */ + public products: proto.IProduct[]; + + /** + * Creates a new ProductSection instance using the specified properties. + * @param [properties] Properties to set + * @returns ProductSection instance + */ + public static create(properties?: proto.IProductSection): proto.ProductSection; + + /** + * Encodes the specified ProductSection message. Does not implicitly {@link proto.ProductSection.verify|verify} messages. + * @param message ProductSection message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IProductSection, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ProductSection message, length delimited. Does not implicitly {@link proto.ProductSection.verify|verify} messages. + * @param message ProductSection message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IProductSection, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ProductSection message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ProductSection + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ProductSection; + + /** + * Decodes a ProductSection message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ProductSection + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ProductSection; + + /** + * Verifies a ProductSection message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ProductSection message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ProductSection + */ + public static fromObject(object: { [k: string]: any }): proto.ProductSection; + + /** + * Creates a plain object from a ProductSection message. Also converts values to other types if specified. + * @param message ProductSection + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ProductSection, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ProductSection to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ProductListHeaderImage. */ + interface IProductListHeaderImage { + + /** ProductListHeaderImage productId */ + productId?: (string|null); + + /** ProductListHeaderImage jpegThumbnail */ + jpegThumbnail?: (Uint8Array|null); + } + + /** Represents a ProductListHeaderImage. */ + class ProductListHeaderImage implements IProductListHeaderImage { + + /** + * Constructs a new ProductListHeaderImage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IProductListHeaderImage); + + /** ProductListHeaderImage productId. */ + public productId: string; + + /** ProductListHeaderImage jpegThumbnail. */ + public jpegThumbnail: Uint8Array; + + /** + * Creates a new ProductListHeaderImage instance using the specified properties. + * @param [properties] Properties to set + * @returns ProductListHeaderImage instance + */ + public static create(properties?: proto.IProductListHeaderImage): proto.ProductListHeaderImage; + + /** + * Encodes the specified ProductListHeaderImage message. Does not implicitly {@link proto.ProductListHeaderImage.verify|verify} messages. + * @param message ProductListHeaderImage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IProductListHeaderImage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ProductListHeaderImage message, length delimited. Does not implicitly {@link proto.ProductListHeaderImage.verify|verify} messages. + * @param message ProductListHeaderImage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IProductListHeaderImage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ProductListHeaderImage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ProductListHeaderImage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ProductListHeaderImage; + + /** + * Decodes a ProductListHeaderImage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ProductListHeaderImage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ProductListHeaderImage; + + /** + * Verifies a ProductListHeaderImage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ProductListHeaderImage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ProductListHeaderImage + */ + public static fromObject(object: { [k: string]: any }): proto.ProductListHeaderImage; + + /** + * Creates a plain object from a ProductListHeaderImage message. Also converts values to other types if specified. + * @param message ProductListHeaderImage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ProductListHeaderImage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ProductListHeaderImage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ProductListInfo. */ + interface IProductListInfo { + + /** ProductListInfo productSections */ + productSections?: (proto.IProductSection[]|null); + + /** ProductListInfo headerImage */ + headerImage?: (proto.IProductListHeaderImage|null); + + /** ProductListInfo businessOwnerJid */ + businessOwnerJid?: (string|null); + } + + /** Represents a ProductListInfo. */ + class ProductListInfo implements IProductListInfo { + + /** + * Constructs a new ProductListInfo. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IProductListInfo); + + /** ProductListInfo productSections. */ + public productSections: proto.IProductSection[]; + + /** ProductListInfo headerImage. */ + public headerImage?: (proto.IProductListHeaderImage|null); + + /** ProductListInfo businessOwnerJid. */ + public businessOwnerJid: string; + + /** + * Creates a new ProductListInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns ProductListInfo instance + */ + public static create(properties?: proto.IProductListInfo): proto.ProductListInfo; + + /** + * Encodes the specified ProductListInfo message. Does not implicitly {@link proto.ProductListInfo.verify|verify} messages. + * @param message ProductListInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IProductListInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ProductListInfo message, length delimited. Does not implicitly {@link proto.ProductListInfo.verify|verify} messages. + * @param message ProductListInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IProductListInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ProductListInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ProductListInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ProductListInfo; + + /** + * Decodes a ProductListInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ProductListInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ProductListInfo; + + /** + * Verifies a ProductListInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ProductListInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ProductListInfo + */ + public static fromObject(object: { [k: string]: any }): proto.ProductListInfo; + + /** + * Creates a plain object from a ProductListInfo message. Also converts values to other types if specified. + * @param message ProductListInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ProductListInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ProductListInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of a ListMessage. */ interface IListMessage { @@ -7821,6 +14994,15 @@ export namespace proto { /** ListMessage sections */ sections?: (proto.ISection[]|null); + + /** ListMessage productListInfo */ + productListInfo?: (proto.IProductListInfo|null); + + /** ListMessage footerText */ + footerText?: (string|null); + + /** ListMessage contextInfo */ + contextInfo?: (proto.IContextInfo|null); } /** Represents a ListMessage. */ @@ -7847,6 +15029,15 @@ export namespace proto { /** ListMessage sections. */ public sections: proto.ISection[]; + /** ListMessage productListInfo. */ + public productListInfo?: (proto.IProductListInfo|null); + + /** ListMessage footerText. */ + public footerText: string; + + /** ListMessage contextInfo. */ + public contextInfo?: (proto.IContextInfo|null); + /** * Creates a new ListMessage instance using the specified properties. * @param [properties] Properties to set @@ -7923,7 +15114,8 @@ export namespace proto { /** ListMessageListType enum. */ enum ListMessageListType { UNKNOWN = 0, - SINGLE_SELECT = 1 + SINGLE_SELECT = 1, + PRODUCT_LIST = 2 } } @@ -8020,8 +15212,8 @@ export namespace proto { /** Properties of a ListResponseMessage. */ interface IListResponseMessage { - /** ListResponseMessage selectedDisplayText */ - selectedDisplayText?: (string|null); + /** ListResponseMessage title */ + title?: (string|null); /** ListResponseMessage listType */ listType?: (proto.ListResponseMessage.ListResponseMessageListType|null); @@ -8031,6 +15223,9 @@ export namespace proto { /** ListResponseMessage contextInfo */ contextInfo?: (proto.IContextInfo|null); + + /** ListResponseMessage description */ + description?: (string|null); } /** Represents a ListResponseMessage. */ @@ -8042,8 +15237,8 @@ export namespace proto { */ constructor(properties?: proto.IListResponseMessage); - /** ListResponseMessage selectedDisplayText. */ - public selectedDisplayText: string; + /** ListResponseMessage title. */ + public title: string; /** ListResponseMessage listType. */ public listType: proto.ListResponseMessage.ListResponseMessageListType; @@ -8054,6 +15249,9 @@ export namespace proto { /** ListResponseMessage contextInfo. */ public contextInfo?: (proto.IContextInfo|null); + /** ListResponseMessage description. */ + public description: string; + /** * Creates a new ListResponseMessage instance using the specified properties. * @param [properties] Properties to set @@ -8260,108 +15458,6 @@ export namespace proto { public toJSON(): { [k: string]: any }; } - /** Properties of an EphemeralSetting. */ - interface IEphemeralSetting { - - /** EphemeralSetting chatJid */ - chatJid?: (string|null); - - /** EphemeralSetting ephemeralExpiration */ - ephemeralExpiration?: (number|null); - - /** EphemeralSetting ephemeralSettingTimestamp */ - ephemeralSettingTimestamp?: (number|Long|null); - } - - /** Represents an EphemeralSetting. */ - class EphemeralSetting implements IEphemeralSetting { - - /** - * Constructs a new EphemeralSetting. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IEphemeralSetting); - - /** EphemeralSetting chatJid. */ - public chatJid: string; - - /** EphemeralSetting ephemeralExpiration. */ - public ephemeralExpiration: number; - - /** EphemeralSetting ephemeralSettingTimestamp. */ - public ephemeralSettingTimestamp: (number|Long); - - /** - * Creates a new EphemeralSetting instance using the specified properties. - * @param [properties] Properties to set - * @returns EphemeralSetting instance - */ - public static create(properties?: proto.IEphemeralSetting): proto.EphemeralSetting; - - /** - * Encodes the specified EphemeralSetting message. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. - * @param message EphemeralSetting message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IEphemeralSetting, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified EphemeralSetting message, length delimited. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. - * @param message EphemeralSetting message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IEphemeralSetting, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes an EphemeralSetting message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns EphemeralSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.EphemeralSetting; - - /** - * Decodes an EphemeralSetting message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns EphemeralSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.EphemeralSetting; - - /** - * Verifies an EphemeralSetting message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates an EphemeralSetting message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns EphemeralSetting - */ - public static fromObject(object: { [k: string]: any }): proto.EphemeralSetting; - - /** - * Creates a plain object from an EphemeralSetting message. Also converts values to other types if specified. - * @param message EphemeralSetting - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.EphemeralSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this EphemeralSetting to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - /** Properties of a DeviceSentMessage. */ interface IDeviceSentMessage { @@ -8373,9 +15469,6 @@ export namespace proto { /** DeviceSentMessage phash */ phash?: (string|null); - - /** DeviceSentMessage broadcastEphemeralSettings */ - broadcastEphemeralSettings?: (proto.IEphemeralSetting[]|null); } /** Represents a DeviceSentMessage. */ @@ -8396,9 +15489,6 @@ export namespace proto { /** DeviceSentMessage phash. */ public phash: string; - /** DeviceSentMessage broadcastEphemeralSettings. */ - public broadcastEphemeralSettings: proto.IEphemeralSetting[]; - /** * Creates a new DeviceSentMessage instance using the specified properties. * @param [properties] Properties to set @@ -8560,6 +15650,591 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + /** Properties of a ButtonText. */ + interface IButtonText { + + /** ButtonText displayText */ + displayText?: (string|null); + } + + /** Represents a ButtonText. */ + class ButtonText implements IButtonText { + + /** + * Constructs a new ButtonText. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IButtonText); + + /** ButtonText displayText. */ + public displayText: string; + + /** + * Creates a new ButtonText instance using the specified properties. + * @param [properties] Properties to set + * @returns ButtonText instance + */ + public static create(properties?: proto.IButtonText): proto.ButtonText; + + /** + * Encodes the specified ButtonText message. Does not implicitly {@link proto.ButtonText.verify|verify} messages. + * @param message ButtonText message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IButtonText, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ButtonText message, length delimited. Does not implicitly {@link proto.ButtonText.verify|verify} messages. + * @param message ButtonText message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IButtonText, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ButtonText message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ButtonText + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ButtonText; + + /** + * Decodes a ButtonText message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ButtonText + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ButtonText; + + /** + * Verifies a ButtonText message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ButtonText message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ButtonText + */ + public static fromObject(object: { [k: string]: any }): proto.ButtonText; + + /** + * Creates a plain object from a ButtonText message. Also converts values to other types if specified. + * @param message ButtonText + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ButtonText, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ButtonText to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a NativeFlowInfo. */ + interface INativeFlowInfo { + + /** NativeFlowInfo name */ + name?: (string|null); + + /** NativeFlowInfo paramsJson */ + paramsJson?: (string|null); + } + + /** Represents a NativeFlowInfo. */ + class NativeFlowInfo implements INativeFlowInfo { + + /** + * Constructs a new NativeFlowInfo. + * @param [properties] Properties to set + */ + constructor(properties?: proto.INativeFlowInfo); + + /** NativeFlowInfo name. */ + public name: string; + + /** NativeFlowInfo paramsJson. */ + public paramsJson: string; + + /** + * Creates a new NativeFlowInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns NativeFlowInfo instance + */ + public static create(properties?: proto.INativeFlowInfo): proto.NativeFlowInfo; + + /** + * Encodes the specified NativeFlowInfo message. Does not implicitly {@link proto.NativeFlowInfo.verify|verify} messages. + * @param message NativeFlowInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.INativeFlowInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified NativeFlowInfo message, length delimited. Does not implicitly {@link proto.NativeFlowInfo.verify|verify} messages. + * @param message NativeFlowInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.INativeFlowInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a NativeFlowInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns NativeFlowInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.NativeFlowInfo; + + /** + * Decodes a NativeFlowInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns NativeFlowInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.NativeFlowInfo; + + /** + * Verifies a NativeFlowInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a NativeFlowInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns NativeFlowInfo + */ + public static fromObject(object: { [k: string]: any }): proto.NativeFlowInfo; + + /** + * Creates a plain object from a NativeFlowInfo message. Also converts values to other types if specified. + * @param message NativeFlowInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.NativeFlowInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this NativeFlowInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Button. */ + interface IButton { + + /** Button buttonId */ + buttonId?: (string|null); + + /** Button buttonText */ + buttonText?: (proto.IButtonText|null); + + /** Button type */ + type?: (proto.Button.ButtonType|null); + + /** Button nativeFlowInfo */ + nativeFlowInfo?: (proto.INativeFlowInfo|null); + } + + /** Represents a Button. */ + class Button implements IButton { + + /** + * Constructs a new Button. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IButton); + + /** Button buttonId. */ + public buttonId: string; + + /** Button buttonText. */ + public buttonText?: (proto.IButtonText|null); + + /** Button type. */ + public type: proto.Button.ButtonType; + + /** Button nativeFlowInfo. */ + public nativeFlowInfo?: (proto.INativeFlowInfo|null); + + /** + * Creates a new Button instance using the specified properties. + * @param [properties] Properties to set + * @returns Button instance + */ + public static create(properties?: proto.IButton): proto.Button; + + /** + * Encodes the specified Button message. Does not implicitly {@link proto.Button.verify|verify} messages. + * @param message Button message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Button message, length delimited. Does not implicitly {@link proto.Button.verify|verify} messages. + * @param message Button message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Button message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Button + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Button; + + /** + * Decodes a Button message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Button + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Button; + + /** + * Verifies a Button message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Button message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Button + */ + public static fromObject(object: { [k: string]: any }): proto.Button; + + /** + * Creates a plain object from a Button message. Also converts values to other types if specified. + * @param message Button + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Button, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Button to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace Button { + + /** ButtonType enum. */ + enum ButtonType { + UNKNOWN = 0, + RESPONSE = 1, + NATIVE_FLOW = 2 + } + } + + /** Properties of a ButtonsMessage. */ + interface IButtonsMessage { + + /** ButtonsMessage contentText */ + contentText?: (string|null); + + /** ButtonsMessage footerText */ + footerText?: (string|null); + + /** ButtonsMessage contextInfo */ + contextInfo?: (proto.IContextInfo|null); + + /** ButtonsMessage buttons */ + buttons?: (proto.IButton[]|null); + + /** ButtonsMessage headerType */ + headerType?: (proto.ButtonsMessage.ButtonsMessageHeaderType|null); + + /** ButtonsMessage text */ + text?: (string|null); + + /** ButtonsMessage documentMessage */ + documentMessage?: (proto.IDocumentMessage|null); + + /** ButtonsMessage imageMessage */ + imageMessage?: (proto.IImageMessage|null); + + /** ButtonsMessage videoMessage */ + videoMessage?: (proto.IVideoMessage|null); + + /** ButtonsMessage locationMessage */ + locationMessage?: (proto.ILocationMessage|null); + } + + /** Represents a ButtonsMessage. */ + class ButtonsMessage implements IButtonsMessage { + + /** + * Constructs a new ButtonsMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IButtonsMessage); + + /** ButtonsMessage contentText. */ + public contentText: string; + + /** ButtonsMessage footerText. */ + public footerText: string; + + /** ButtonsMessage contextInfo. */ + public contextInfo?: (proto.IContextInfo|null); + + /** ButtonsMessage buttons. */ + public buttons: proto.IButton[]; + + /** ButtonsMessage headerType. */ + public headerType: proto.ButtonsMessage.ButtonsMessageHeaderType; + + /** ButtonsMessage text. */ + public text?: (string|null); + + /** ButtonsMessage documentMessage. */ + public documentMessage?: (proto.IDocumentMessage|null); + + /** ButtonsMessage imageMessage. */ + public imageMessage?: (proto.IImageMessage|null); + + /** ButtonsMessage videoMessage. */ + public videoMessage?: (proto.IVideoMessage|null); + + /** ButtonsMessage locationMessage. */ + public locationMessage?: (proto.ILocationMessage|null); + + /** ButtonsMessage header. */ + public header?: ("text"|"documentMessage"|"imageMessage"|"videoMessage"|"locationMessage"); + + /** + * Creates a new ButtonsMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns ButtonsMessage instance + */ + public static create(properties?: proto.IButtonsMessage): proto.ButtonsMessage; + + /** + * Encodes the specified ButtonsMessage message. Does not implicitly {@link proto.ButtonsMessage.verify|verify} messages. + * @param message ButtonsMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IButtonsMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ButtonsMessage message, length delimited. Does not implicitly {@link proto.ButtonsMessage.verify|verify} messages. + * @param message ButtonsMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IButtonsMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ButtonsMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ButtonsMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ButtonsMessage; + + /** + * Decodes a ButtonsMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ButtonsMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ButtonsMessage; + + /** + * Verifies a ButtonsMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ButtonsMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ButtonsMessage + */ + public static fromObject(object: { [k: string]: any }): proto.ButtonsMessage; + + /** + * Creates a plain object from a ButtonsMessage message. Also converts values to other types if specified. + * @param message ButtonsMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ButtonsMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ButtonsMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace ButtonsMessage { + + /** ButtonsMessageHeaderType enum. */ + enum ButtonsMessageHeaderType { + UNKNOWN = 0, + EMPTY = 1, + TEXT = 2, + DOCUMENT = 3, + IMAGE = 4, + VIDEO = 5, + LOCATION = 6 + } + } + + /** Properties of a ButtonsResponseMessage. */ + interface IButtonsResponseMessage { + + /** ButtonsResponseMessage selectedButtonId */ + selectedButtonId?: (string|null); + + /** ButtonsResponseMessage contextInfo */ + contextInfo?: (proto.IContextInfo|null); + + /** ButtonsResponseMessage type */ + type?: (proto.ButtonsResponseMessage.ButtonsResponseMessageType|null); + + /** ButtonsResponseMessage selectedDisplayText */ + selectedDisplayText?: (string|null); + } + + /** Represents a ButtonsResponseMessage. */ + class ButtonsResponseMessage implements IButtonsResponseMessage { + + /** + * Constructs a new ButtonsResponseMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IButtonsResponseMessage); + + /** ButtonsResponseMessage selectedButtonId. */ + public selectedButtonId: string; + + /** ButtonsResponseMessage contextInfo. */ + public contextInfo?: (proto.IContextInfo|null); + + /** ButtonsResponseMessage type. */ + public type: proto.ButtonsResponseMessage.ButtonsResponseMessageType; + + /** ButtonsResponseMessage selectedDisplayText. */ + public selectedDisplayText?: (string|null); + + /** ButtonsResponseMessage response. */ + public response?: "selectedDisplayText"; + + /** + * Creates a new ButtonsResponseMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns ButtonsResponseMessage instance + */ + public static create(properties?: proto.IButtonsResponseMessage): proto.ButtonsResponseMessage; + + /** + * Encodes the specified ButtonsResponseMessage message. Does not implicitly {@link proto.ButtonsResponseMessage.verify|verify} messages. + * @param message ButtonsResponseMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IButtonsResponseMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ButtonsResponseMessage message, length delimited. Does not implicitly {@link proto.ButtonsResponseMessage.verify|verify} messages. + * @param message ButtonsResponseMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IButtonsResponseMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ButtonsResponseMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ButtonsResponseMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ButtonsResponseMessage; + + /** + * Decodes a ButtonsResponseMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ButtonsResponseMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ButtonsResponseMessage; + + /** + * Verifies a ButtonsResponseMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ButtonsResponseMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ButtonsResponseMessage + */ + public static fromObject(object: { [k: string]: any }): proto.ButtonsResponseMessage; + + /** + * Creates a plain object from a ButtonsResponseMessage message. Also converts values to other types if specified. + * @param message ButtonsResponseMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ButtonsResponseMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ButtonsResponseMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace ButtonsResponseMessage { + + /** ButtonsResponseMessageType enum. */ + enum ButtonsResponseMessageType { + UNKNOWN = 0, + DISPLAY_TEXT = 1 + } + } + /** Properties of a Message. */ interface IMessage { @@ -8641,6 +16316,9 @@ export namespace proto { /** Message deviceSentMessage */ deviceSentMessage?: (proto.IDeviceSentMessage|null); + /** Message messageContextInfo */ + messageContextInfo?: (proto.IMessageContextInfo|null); + /** Message listMessage */ listMessage?: (proto.IListMessage|null); @@ -8655,6 +16333,18 @@ export namespace proto { /** Message ephemeralMessage */ ephemeralMessage?: (proto.IFutureProofMessage|null); + + /** Message invoiceMessage */ + invoiceMessage?: (proto.IInvoiceMessage|null); + + /** Message buttonsMessage */ + buttonsMessage?: (proto.IButtonsMessage|null); + + /** Message buttonsResponseMessage */ + buttonsResponseMessage?: (proto.IButtonsResponseMessage|null); + + /** Message paymentInviteMessage */ + paymentInviteMessage?: (proto.IPaymentInviteMessage|null); } /** Represents a Message. */ @@ -8744,6 +16434,9 @@ export namespace proto { /** Message deviceSentMessage. */ public deviceSentMessage?: (proto.IDeviceSentMessage|null); + /** Message messageContextInfo. */ + public messageContextInfo?: (proto.IMessageContextInfo|null); + /** Message listMessage. */ public listMessage?: (proto.IListMessage|null); @@ -8759,6 +16452,18 @@ export namespace proto { /** Message ephemeralMessage. */ public ephemeralMessage?: (proto.IFutureProofMessage|null); + /** Message invoiceMessage. */ + public invoiceMessage?: (proto.IInvoiceMessage|null); + + /** Message buttonsMessage. */ + public buttonsMessage?: (proto.IButtonsMessage|null); + + /** Message buttonsResponseMessage. */ + public buttonsResponseMessage?: (proto.IButtonsResponseMessage|null); + + /** Message paymentInviteMessage. */ + public paymentInviteMessage?: (proto.IPaymentInviteMessage|null); + /** * Creates a new Message instance using the specified properties. * @param [properties] Properties to set @@ -8830,6 +16535,644 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + /** Properties of a CompanionProps. */ + interface ICompanionProps { + + /** CompanionProps os */ + os?: (string|null); + + /** CompanionProps version */ + version?: (proto.IAppVersion|null); + + /** CompanionProps platformType */ + platformType?: (proto.CompanionProps.CompanionPropsPlatformType|null); + + /** CompanionProps requireFullSync */ + requireFullSync?: (boolean|null); + } + + /** Represents a CompanionProps. */ + class CompanionProps implements ICompanionProps { + + /** + * Constructs a new CompanionProps. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ICompanionProps); + + /** CompanionProps os. */ + public os: string; + + /** CompanionProps version. */ + public version?: (proto.IAppVersion|null); + + /** CompanionProps platformType. */ + public platformType: proto.CompanionProps.CompanionPropsPlatformType; + + /** CompanionProps requireFullSync. */ + public requireFullSync: boolean; + + /** + * Creates a new CompanionProps instance using the specified properties. + * @param [properties] Properties to set + * @returns CompanionProps instance + */ + public static create(properties?: proto.ICompanionProps): proto.CompanionProps; + + /** + * Encodes the specified CompanionProps message. Does not implicitly {@link proto.CompanionProps.verify|verify} messages. + * @param message CompanionProps message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ICompanionProps, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified CompanionProps message, length delimited. Does not implicitly {@link proto.CompanionProps.verify|verify} messages. + * @param message CompanionProps message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ICompanionProps, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a CompanionProps message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns CompanionProps + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.CompanionProps; + + /** + * Decodes a CompanionProps message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns CompanionProps + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.CompanionProps; + + /** + * Verifies a CompanionProps message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a CompanionProps message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns CompanionProps + */ + public static fromObject(object: { [k: string]: any }): proto.CompanionProps; + + /** + * Creates a plain object from a CompanionProps message. Also converts values to other types if specified. + * @param message CompanionProps + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.CompanionProps, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this CompanionProps to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace CompanionProps { + + /** CompanionPropsPlatformType enum. */ + enum CompanionPropsPlatformType { + UNKNOWN = 0, + CHROME = 1, + FIREFOX = 2, + IE = 3, + OPERA = 4, + SAFARI = 5, + EDGE = 6, + DESKTOP = 7, + IPAD = 8, + ANDROID_TABLET = 9, + OHANA = 10, + ALOHA = 11, + CATALINA = 12 + } + } + + /** Properties of a ADVSignedDeviceIdentityHMAC. */ + interface IADVSignedDeviceIdentityHMAC { + + /** ADVSignedDeviceIdentityHMAC details */ + details?: (Uint8Array|null); + + /** ADVSignedDeviceIdentityHMAC hmac */ + hmac?: (Uint8Array|null); + } + + /** Represents a ADVSignedDeviceIdentityHMAC. */ + class ADVSignedDeviceIdentityHMAC implements IADVSignedDeviceIdentityHMAC { + + /** + * Constructs a new ADVSignedDeviceIdentityHMAC. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IADVSignedDeviceIdentityHMAC); + + /** ADVSignedDeviceIdentityHMAC details. */ + public details: Uint8Array; + + /** ADVSignedDeviceIdentityHMAC hmac. */ + public hmac: Uint8Array; + + /** + * Creates a new ADVSignedDeviceIdentityHMAC instance using the specified properties. + * @param [properties] Properties to set + * @returns ADVSignedDeviceIdentityHMAC instance + */ + public static create(properties?: proto.IADVSignedDeviceIdentityHMAC): proto.ADVSignedDeviceIdentityHMAC; + + /** + * Encodes the specified ADVSignedDeviceIdentityHMAC message. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages. + * @param message ADVSignedDeviceIdentityHMAC message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IADVSignedDeviceIdentityHMAC, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ADVSignedDeviceIdentityHMAC message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages. + * @param message ADVSignedDeviceIdentityHMAC message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IADVSignedDeviceIdentityHMAC, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ADVSignedDeviceIdentityHMAC + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVSignedDeviceIdentityHMAC; + + /** + * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ADVSignedDeviceIdentityHMAC + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVSignedDeviceIdentityHMAC; + + /** + * Verifies a ADVSignedDeviceIdentityHMAC message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ADVSignedDeviceIdentityHMAC message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ADVSignedDeviceIdentityHMAC + */ + public static fromObject(object: { [k: string]: any }): proto.ADVSignedDeviceIdentityHMAC; + + /** + * Creates a plain object from a ADVSignedDeviceIdentityHMAC message. Also converts values to other types if specified. + * @param message ADVSignedDeviceIdentityHMAC + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ADVSignedDeviceIdentityHMAC, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ADVSignedDeviceIdentityHMAC to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ADVSignedDeviceIdentity. */ + interface IADVSignedDeviceIdentity { + + /** ADVSignedDeviceIdentity details */ + details?: (Uint8Array|null); + + /** ADVSignedDeviceIdentity accountSignatureKey */ + accountSignatureKey?: (Uint8Array|null); + + /** ADVSignedDeviceIdentity accountSignature */ + accountSignature?: (Uint8Array|null); + + /** ADVSignedDeviceIdentity deviceSignature */ + deviceSignature?: (Uint8Array|null); + } + + /** Represents a ADVSignedDeviceIdentity. */ + class ADVSignedDeviceIdentity implements IADVSignedDeviceIdentity { + + /** + * Constructs a new ADVSignedDeviceIdentity. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IADVSignedDeviceIdentity); + + /** ADVSignedDeviceIdentity details. */ + public details: Uint8Array; + + /** ADVSignedDeviceIdentity accountSignatureKey. */ + public accountSignatureKey: Uint8Array; + + /** ADVSignedDeviceIdentity accountSignature. */ + public accountSignature: Uint8Array; + + /** ADVSignedDeviceIdentity deviceSignature. */ + public deviceSignature: Uint8Array; + + /** + * Creates a new ADVSignedDeviceIdentity instance using the specified properties. + * @param [properties] Properties to set + * @returns ADVSignedDeviceIdentity instance + */ + public static create(properties?: proto.IADVSignedDeviceIdentity): proto.ADVSignedDeviceIdentity; + + /** + * Encodes the specified ADVSignedDeviceIdentity message. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages. + * @param message ADVSignedDeviceIdentity message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IADVSignedDeviceIdentity, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ADVSignedDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages. + * @param message ADVSignedDeviceIdentity message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IADVSignedDeviceIdentity, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ADVSignedDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVSignedDeviceIdentity; + + /** + * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ADVSignedDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVSignedDeviceIdentity; + + /** + * Verifies a ADVSignedDeviceIdentity message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ADVSignedDeviceIdentity message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ADVSignedDeviceIdentity + */ + public static fromObject(object: { [k: string]: any }): proto.ADVSignedDeviceIdentity; + + /** + * Creates a plain object from a ADVSignedDeviceIdentity message. Also converts values to other types if specified. + * @param message ADVSignedDeviceIdentity + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ADVSignedDeviceIdentity, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ADVSignedDeviceIdentity to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ADVDeviceIdentity. */ + interface IADVDeviceIdentity { + + /** ADVDeviceIdentity rawId */ + rawId?: (number|null); + + /** ADVDeviceIdentity timestamp */ + timestamp?: (number|Long|null); + + /** ADVDeviceIdentity keyIndex */ + keyIndex?: (number|null); + } + + /** Represents a ADVDeviceIdentity. */ + class ADVDeviceIdentity implements IADVDeviceIdentity { + + /** + * Constructs a new ADVDeviceIdentity. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IADVDeviceIdentity); + + /** ADVDeviceIdentity rawId. */ + public rawId: number; + + /** ADVDeviceIdentity timestamp. */ + public timestamp: (number|Long); + + /** ADVDeviceIdentity keyIndex. */ + public keyIndex: number; + + /** + * Creates a new ADVDeviceIdentity instance using the specified properties. + * @param [properties] Properties to set + * @returns ADVDeviceIdentity instance + */ + public static create(properties?: proto.IADVDeviceIdentity): proto.ADVDeviceIdentity; + + /** + * Encodes the specified ADVDeviceIdentity message. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages. + * @param message ADVDeviceIdentity message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IADVDeviceIdentity, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ADVDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages. + * @param message ADVDeviceIdentity message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IADVDeviceIdentity, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ADVDeviceIdentity message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ADVDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVDeviceIdentity; + + /** + * Decodes a ADVDeviceIdentity message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ADVDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVDeviceIdentity; + + /** + * Verifies a ADVDeviceIdentity message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ADVDeviceIdentity message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ADVDeviceIdentity + */ + public static fromObject(object: { [k: string]: any }): proto.ADVDeviceIdentity; + + /** + * Creates a plain object from a ADVDeviceIdentity message. Also converts values to other types if specified. + * @param message ADVDeviceIdentity + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ADVDeviceIdentity, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ADVDeviceIdentity to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ADVSignedKeyIndexList. */ + interface IADVSignedKeyIndexList { + + /** ADVSignedKeyIndexList details */ + details?: (Uint8Array|null); + + /** ADVSignedKeyIndexList accountSignature */ + accountSignature?: (Uint8Array|null); + } + + /** Represents a ADVSignedKeyIndexList. */ + class ADVSignedKeyIndexList implements IADVSignedKeyIndexList { + + /** + * Constructs a new ADVSignedKeyIndexList. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IADVSignedKeyIndexList); + + /** ADVSignedKeyIndexList details. */ + public details: Uint8Array; + + /** ADVSignedKeyIndexList accountSignature. */ + public accountSignature: Uint8Array; + + /** + * Creates a new ADVSignedKeyIndexList instance using the specified properties. + * @param [properties] Properties to set + * @returns ADVSignedKeyIndexList instance + */ + public static create(properties?: proto.IADVSignedKeyIndexList): proto.ADVSignedKeyIndexList; + + /** + * Encodes the specified ADVSignedKeyIndexList message. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages. + * @param message ADVSignedKeyIndexList message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IADVSignedKeyIndexList, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ADVSignedKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages. + * @param message ADVSignedKeyIndexList message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IADVSignedKeyIndexList, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ADVSignedKeyIndexList + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVSignedKeyIndexList; + + /** + * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ADVSignedKeyIndexList + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVSignedKeyIndexList; + + /** + * Verifies a ADVSignedKeyIndexList message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ADVSignedKeyIndexList message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ADVSignedKeyIndexList + */ + public static fromObject(object: { [k: string]: any }): proto.ADVSignedKeyIndexList; + + /** + * Creates a plain object from a ADVSignedKeyIndexList message. Also converts values to other types if specified. + * @param message ADVSignedKeyIndexList + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ADVSignedKeyIndexList, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ADVSignedKeyIndexList to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ADVKeyIndexList. */ + interface IADVKeyIndexList { + + /** ADVKeyIndexList rawId */ + rawId?: (number|null); + + /** ADVKeyIndexList timestamp */ + timestamp?: (number|Long|null); + + /** ADVKeyIndexList currentIndex */ + currentIndex?: (number|null); + + /** ADVKeyIndexList validIndexes */ + validIndexes?: (number[]|null); + } + + /** Represents a ADVKeyIndexList. */ + class ADVKeyIndexList implements IADVKeyIndexList { + + /** + * Constructs a new ADVKeyIndexList. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IADVKeyIndexList); + + /** ADVKeyIndexList rawId. */ + public rawId: number; + + /** ADVKeyIndexList timestamp. */ + public timestamp: (number|Long); + + /** ADVKeyIndexList currentIndex. */ + public currentIndex: number; + + /** ADVKeyIndexList validIndexes. */ + public validIndexes: number[]; + + /** + * Creates a new ADVKeyIndexList instance using the specified properties. + * @param [properties] Properties to set + * @returns ADVKeyIndexList instance + */ + public static create(properties?: proto.IADVKeyIndexList): proto.ADVKeyIndexList; + + /** + * Encodes the specified ADVKeyIndexList message. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages. + * @param message ADVKeyIndexList message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IADVKeyIndexList, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ADVKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages. + * @param message ADVKeyIndexList message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IADVKeyIndexList, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ADVKeyIndexList message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ADVKeyIndexList + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVKeyIndexList; + + /** + * Decodes a ADVKeyIndexList message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ADVKeyIndexList + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVKeyIndexList; + + /** + * Verifies a ADVKeyIndexList message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ADVKeyIndexList message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ADVKeyIndexList + */ + public static fromObject(object: { [k: string]: any }): proto.ADVKeyIndexList; + + /** + * Creates a plain object from a ADVKeyIndexList message. Also converts values to other types if specified. + * @param message ADVKeyIndexList + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ADVKeyIndexList, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ADVKeyIndexList to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of a MessageKey. */ interface IMessageKey { @@ -8937,4 +17280,1398 @@ export namespace proto { */ public toJSON(): { [k: string]: any }; } + + /** Properties of a PhotoChange. */ + interface IPhotoChange { + + /** PhotoChange oldPhoto */ + oldPhoto?: (Uint8Array|null); + + /** PhotoChange newPhoto */ + newPhoto?: (Uint8Array|null); + + /** PhotoChange newPhotoId */ + newPhotoId?: (number|null); + } + + /** Represents a PhotoChange. */ + class PhotoChange implements IPhotoChange { + + /** + * Constructs a new PhotoChange. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPhotoChange); + + /** PhotoChange oldPhoto. */ + public oldPhoto: Uint8Array; + + /** PhotoChange newPhoto. */ + public newPhoto: Uint8Array; + + /** PhotoChange newPhotoId. */ + public newPhotoId: number; + + /** + * Creates a new PhotoChange instance using the specified properties. + * @param [properties] Properties to set + * @returns PhotoChange instance + */ + public static create(properties?: proto.IPhotoChange): proto.PhotoChange; + + /** + * Encodes the specified PhotoChange message. Does not implicitly {@link proto.PhotoChange.verify|verify} messages. + * @param message PhotoChange message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPhotoChange, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified PhotoChange message, length delimited. Does not implicitly {@link proto.PhotoChange.verify|verify} messages. + * @param message PhotoChange message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPhotoChange, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a PhotoChange message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns PhotoChange + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PhotoChange; + + /** + * Decodes a PhotoChange message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns PhotoChange + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PhotoChange; + + /** + * Verifies a PhotoChange message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a PhotoChange message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns PhotoChange + */ + public static fromObject(object: { [k: string]: any }): proto.PhotoChange; + + /** + * Creates a plain object from a PhotoChange message. Also converts values to other types if specified. + * @param message PhotoChange + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.PhotoChange, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this PhotoChange to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a MediaData. */ + interface IMediaData { + + /** MediaData localPath */ + localPath?: (string|null); + } + + /** Represents a MediaData. */ + class MediaData implements IMediaData { + + /** + * Constructs a new MediaData. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMediaData); + + /** MediaData localPath. */ + public localPath: string; + + /** + * Creates a new MediaData instance using the specified properties. + * @param [properties] Properties to set + * @returns MediaData instance + */ + public static create(properties?: proto.IMediaData): proto.MediaData; + + /** + * Encodes the specified MediaData message. Does not implicitly {@link proto.MediaData.verify|verify} messages. + * @param message MediaData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMediaData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MediaData message, length delimited. Does not implicitly {@link proto.MediaData.verify|verify} messages. + * @param message MediaData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMediaData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MediaData message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MediaData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MediaData; + + /** + * Decodes a MediaData message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MediaData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MediaData; + + /** + * Verifies a MediaData message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MediaData message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MediaData + */ + public static fromObject(object: { [k: string]: any }): proto.MediaData; + + /** + * Creates a plain object from a MediaData message. Also converts values to other types if specified. + * @param message MediaData + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MediaData, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MediaData to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a WebFeatures. */ + interface IWebFeatures { + + /** WebFeatures labelsDisplay */ + labelsDisplay?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures voipIndividualOutgoing */ + voipIndividualOutgoing?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures groupsV3 */ + groupsV3?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures groupsV3Create */ + groupsV3Create?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures changeNumberV2 */ + changeNumberV2?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures queryStatusV3Thumbnail */ + queryStatusV3Thumbnail?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures liveLocations */ + liveLocations?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures queryVname */ + queryVname?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures voipIndividualIncoming */ + voipIndividualIncoming?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures quickRepliesQuery */ + quickRepliesQuery?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures payments */ + payments?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures stickerPackQuery */ + stickerPackQuery?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures liveLocationsFinal */ + liveLocationsFinal?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures labelsEdit */ + labelsEdit?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures mediaUpload */ + mediaUpload?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures mediaUploadRichQuickReplies */ + mediaUploadRichQuickReplies?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures vnameV2 */ + vnameV2?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures videoPlaybackUrl */ + videoPlaybackUrl?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures statusRanking */ + statusRanking?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures voipIndividualVideo */ + voipIndividualVideo?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures thirdPartyStickers */ + thirdPartyStickers?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures frequentlyForwardedSetting */ + frequentlyForwardedSetting?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures groupsV4JoinPermission */ + groupsV4JoinPermission?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures recentStickers */ + recentStickers?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures catalog */ + catalog?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures starredStickers */ + starredStickers?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures voipGroupCall */ + voipGroupCall?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures templateMessage */ + templateMessage?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures templateMessageInteractivity */ + templateMessageInteractivity?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures ephemeralMessages */ + ephemeralMessages?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures e2ENotificationSync */ + e2ENotificationSync?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures recentStickersV2 */ + recentStickersV2?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures recentStickersV3 */ + recentStickersV3?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures userNotice */ + userNotice?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures support */ + support?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures groupUiiCleanup */ + groupUiiCleanup?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures groupDogfoodingInternalOnly */ + groupDogfoodingInternalOnly?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures settingsSync */ + settingsSync?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures archiveV2 */ + archiveV2?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures ephemeralAllowGroupMembers */ + ephemeralAllowGroupMembers?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures ephemeral24HDuration */ + ephemeral24HDuration?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures mdForceUpgrade */ + mdForceUpgrade?: (proto.WebFeatures.WebFeaturesFlag|null); + } + + /** Represents a WebFeatures. */ + class WebFeatures implements IWebFeatures { + + /** + * Constructs a new WebFeatures. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IWebFeatures); + + /** WebFeatures labelsDisplay. */ + public labelsDisplay: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures voipIndividualOutgoing. */ + public voipIndividualOutgoing: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures groupsV3. */ + public groupsV3: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures groupsV3Create. */ + public groupsV3Create: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures changeNumberV2. */ + public changeNumberV2: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures queryStatusV3Thumbnail. */ + public queryStatusV3Thumbnail: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures liveLocations. */ + public liveLocations: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures queryVname. */ + public queryVname: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures voipIndividualIncoming. */ + public voipIndividualIncoming: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures quickRepliesQuery. */ + public quickRepliesQuery: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures payments. */ + public payments: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures stickerPackQuery. */ + public stickerPackQuery: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures liveLocationsFinal. */ + public liveLocationsFinal: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures labelsEdit. */ + public labelsEdit: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures mediaUpload. */ + public mediaUpload: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures mediaUploadRichQuickReplies. */ + public mediaUploadRichQuickReplies: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures vnameV2. */ + public vnameV2: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures videoPlaybackUrl. */ + public videoPlaybackUrl: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures statusRanking. */ + public statusRanking: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures voipIndividualVideo. */ + public voipIndividualVideo: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures thirdPartyStickers. */ + public thirdPartyStickers: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures frequentlyForwardedSetting. */ + public frequentlyForwardedSetting: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures groupsV4JoinPermission. */ + public groupsV4JoinPermission: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures recentStickers. */ + public recentStickers: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures catalog. */ + public catalog: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures starredStickers. */ + public starredStickers: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures voipGroupCall. */ + public voipGroupCall: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures templateMessage. */ + public templateMessage: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures templateMessageInteractivity. */ + public templateMessageInteractivity: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures ephemeralMessages. */ + public ephemeralMessages: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures e2ENotificationSync. */ + public e2ENotificationSync: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures recentStickersV2. */ + public recentStickersV2: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures recentStickersV3. */ + public recentStickersV3: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures userNotice. */ + public userNotice: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures support. */ + public support: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures groupUiiCleanup. */ + public groupUiiCleanup: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures groupDogfoodingInternalOnly. */ + public groupDogfoodingInternalOnly: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures settingsSync. */ + public settingsSync: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures archiveV2. */ + public archiveV2: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures ephemeralAllowGroupMembers. */ + public ephemeralAllowGroupMembers: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures ephemeral24HDuration. */ + public ephemeral24HDuration: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures mdForceUpgrade. */ + public mdForceUpgrade: proto.WebFeatures.WebFeaturesFlag; + + /** + * Creates a new WebFeatures instance using the specified properties. + * @param [properties] Properties to set + * @returns WebFeatures instance + */ + public static create(properties?: proto.IWebFeatures): proto.WebFeatures; + + /** + * Encodes the specified WebFeatures message. Does not implicitly {@link proto.WebFeatures.verify|verify} messages. + * @param message WebFeatures message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IWebFeatures, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified WebFeatures message, length delimited. Does not implicitly {@link proto.WebFeatures.verify|verify} messages. + * @param message WebFeatures message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IWebFeatures, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a WebFeatures message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns WebFeatures + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WebFeatures; + + /** + * Decodes a WebFeatures message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns WebFeatures + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WebFeatures; + + /** + * Verifies a WebFeatures message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a WebFeatures message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns WebFeatures + */ + public static fromObject(object: { [k: string]: any }): proto.WebFeatures; + + /** + * Creates a plain object from a WebFeatures message. Also converts values to other types if specified. + * @param message WebFeatures + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.WebFeatures, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this WebFeatures to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace WebFeatures { + + /** WebFeaturesFlag enum. */ + enum WebFeaturesFlag { + NOT_STARTED = 0, + FORCE_UPGRADE = 1, + DEVELOPMENT = 2, + PRODUCTION = 3 + } + } + + /** Properties of a NotificationMessageInfo. */ + interface INotificationMessageInfo { + + /** NotificationMessageInfo key */ + key?: (proto.IMessageKey|null); + + /** NotificationMessageInfo message */ + message?: (proto.IMessage|null); + + /** NotificationMessageInfo messageTimestamp */ + messageTimestamp?: (number|Long|null); + + /** NotificationMessageInfo participant */ + participant?: (string|null); + } + + /** Represents a NotificationMessageInfo. */ + class NotificationMessageInfo implements INotificationMessageInfo { + + /** + * Constructs a new NotificationMessageInfo. + * @param [properties] Properties to set + */ + constructor(properties?: proto.INotificationMessageInfo); + + /** NotificationMessageInfo key. */ + public key?: (proto.IMessageKey|null); + + /** NotificationMessageInfo message. */ + public message?: (proto.IMessage|null); + + /** NotificationMessageInfo messageTimestamp. */ + public messageTimestamp: (number|Long); + + /** NotificationMessageInfo participant. */ + public participant: string; + + /** + * Creates a new NotificationMessageInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns NotificationMessageInfo instance + */ + public static create(properties?: proto.INotificationMessageInfo): proto.NotificationMessageInfo; + + /** + * Encodes the specified NotificationMessageInfo message. Does not implicitly {@link proto.NotificationMessageInfo.verify|verify} messages. + * @param message NotificationMessageInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.INotificationMessageInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified NotificationMessageInfo message, length delimited. Does not implicitly {@link proto.NotificationMessageInfo.verify|verify} messages. + * @param message NotificationMessageInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.INotificationMessageInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a NotificationMessageInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns NotificationMessageInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.NotificationMessageInfo; + + /** + * Decodes a NotificationMessageInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns NotificationMessageInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.NotificationMessageInfo; + + /** + * Verifies a NotificationMessageInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a NotificationMessageInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns NotificationMessageInfo + */ + public static fromObject(object: { [k: string]: any }): proto.NotificationMessageInfo; + + /** + * Creates a plain object from a NotificationMessageInfo message. Also converts values to other types if specified. + * @param message NotificationMessageInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.NotificationMessageInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this NotificationMessageInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a WebNotificationsInfo. */ + interface IWebNotificationsInfo { + + /** WebNotificationsInfo timestamp */ + timestamp?: (number|Long|null); + + /** WebNotificationsInfo unreadChats */ + unreadChats?: (number|null); + + /** WebNotificationsInfo notifyMessageCount */ + notifyMessageCount?: (number|null); + + /** WebNotificationsInfo notifyMessages */ + notifyMessages?: (proto.IWebMessageInfo[]|null); + } + + /** Represents a WebNotificationsInfo. */ + class WebNotificationsInfo implements IWebNotificationsInfo { + + /** + * Constructs a new WebNotificationsInfo. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IWebNotificationsInfo); + + /** WebNotificationsInfo timestamp. */ + public timestamp: (number|Long); + + /** WebNotificationsInfo unreadChats. */ + public unreadChats: number; + + /** WebNotificationsInfo notifyMessageCount. */ + public notifyMessageCount: number; + + /** WebNotificationsInfo notifyMessages. */ + public notifyMessages: proto.IWebMessageInfo[]; + + /** + * Creates a new WebNotificationsInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns WebNotificationsInfo instance + */ + public static create(properties?: proto.IWebNotificationsInfo): proto.WebNotificationsInfo; + + /** + * Encodes the specified WebNotificationsInfo message. Does not implicitly {@link proto.WebNotificationsInfo.verify|verify} messages. + * @param message WebNotificationsInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IWebNotificationsInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified WebNotificationsInfo message, length delimited. Does not implicitly {@link proto.WebNotificationsInfo.verify|verify} messages. + * @param message WebNotificationsInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IWebNotificationsInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a WebNotificationsInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns WebNotificationsInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WebNotificationsInfo; + + /** + * Decodes a WebNotificationsInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns WebNotificationsInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WebNotificationsInfo; + + /** + * Verifies a WebNotificationsInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a WebNotificationsInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns WebNotificationsInfo + */ + public static fromObject(object: { [k: string]: any }): proto.WebNotificationsInfo; + + /** + * Creates a plain object from a WebNotificationsInfo message. Also converts values to other types if specified. + * @param message WebNotificationsInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.WebNotificationsInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this WebNotificationsInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a PaymentInfo. */ + interface IPaymentInfo { + + /** PaymentInfo currencyDeprecated */ + currencyDeprecated?: (proto.PaymentInfo.PaymentInfoCurrency|null); + + /** PaymentInfo amount1000 */ + amount1000?: (number|Long|null); + + /** PaymentInfo receiverJid */ + receiverJid?: (string|null); + + /** PaymentInfo status */ + status?: (proto.PaymentInfo.PaymentInfoStatus|null); + + /** PaymentInfo transactionTimestamp */ + transactionTimestamp?: (number|Long|null); + + /** PaymentInfo requestMessageKey */ + requestMessageKey?: (proto.IMessageKey|null); + + /** PaymentInfo expiryTimestamp */ + expiryTimestamp?: (number|Long|null); + + /** PaymentInfo futureproofed */ + futureproofed?: (boolean|null); + + /** PaymentInfo currency */ + currency?: (string|null); + + /** PaymentInfo txnStatus */ + txnStatus?: (proto.PaymentInfo.PaymentInfoTxnStatus|null); + + /** PaymentInfo useNoviFiatFormat */ + useNoviFiatFormat?: (boolean|null); + + /** PaymentInfo primaryAmount */ + primaryAmount?: (proto.IMoney|null); + + /** PaymentInfo exchangeAmount */ + exchangeAmount?: (proto.IMoney|null); + } + + /** Represents a PaymentInfo. */ + class PaymentInfo implements IPaymentInfo { + + /** + * Constructs a new PaymentInfo. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPaymentInfo); + + /** PaymentInfo currencyDeprecated. */ + public currencyDeprecated: proto.PaymentInfo.PaymentInfoCurrency; + + /** PaymentInfo amount1000. */ + public amount1000: (number|Long); + + /** PaymentInfo receiverJid. */ + public receiverJid: string; + + /** PaymentInfo status. */ + public status: proto.PaymentInfo.PaymentInfoStatus; + + /** PaymentInfo transactionTimestamp. */ + public transactionTimestamp: (number|Long); + + /** PaymentInfo requestMessageKey. */ + public requestMessageKey?: (proto.IMessageKey|null); + + /** PaymentInfo expiryTimestamp. */ + public expiryTimestamp: (number|Long); + + /** PaymentInfo futureproofed. */ + public futureproofed: boolean; + + /** PaymentInfo currency. */ + public currency: string; + + /** PaymentInfo txnStatus. */ + public txnStatus: proto.PaymentInfo.PaymentInfoTxnStatus; + + /** PaymentInfo useNoviFiatFormat. */ + public useNoviFiatFormat: boolean; + + /** PaymentInfo primaryAmount. */ + public primaryAmount?: (proto.IMoney|null); + + /** PaymentInfo exchangeAmount. */ + public exchangeAmount?: (proto.IMoney|null); + + /** + * Creates a new PaymentInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns PaymentInfo instance + */ + public static create(properties?: proto.IPaymentInfo): proto.PaymentInfo; + + /** + * Encodes the specified PaymentInfo message. Does not implicitly {@link proto.PaymentInfo.verify|verify} messages. + * @param message PaymentInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPaymentInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified PaymentInfo message, length delimited. Does not implicitly {@link proto.PaymentInfo.verify|verify} messages. + * @param message PaymentInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPaymentInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a PaymentInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns PaymentInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PaymentInfo; + + /** + * Decodes a PaymentInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns PaymentInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PaymentInfo; + + /** + * Verifies a PaymentInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a PaymentInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns PaymentInfo + */ + public static fromObject(object: { [k: string]: any }): proto.PaymentInfo; + + /** + * Creates a plain object from a PaymentInfo message. Also converts values to other types if specified. + * @param message PaymentInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.PaymentInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this PaymentInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace PaymentInfo { + + /** PaymentInfoCurrency enum. */ + enum PaymentInfoCurrency { + UNKNOWN_CURRENCY = 0, + INR = 1 + } + + /** PaymentInfoStatus enum. */ + enum PaymentInfoStatus { + UNKNOWN_STATUS = 0, + PROCESSING = 1, + SENT = 2, + NEED_TO_ACCEPT = 3, + COMPLETE = 4, + COULD_NOT_COMPLETE = 5, + REFUNDED = 6, + EXPIRED = 7, + REJECTED = 8, + CANCELLED = 9, + WAITING_FOR_PAYER = 10, + WAITING = 11 + } + + /** PaymentInfoTxnStatus enum. */ + enum PaymentInfoTxnStatus { + UNKNOWN = 0, + PENDING_SETUP = 1, + PENDING_RECEIVER_SETUP = 2, + INIT = 3, + SUCCESS = 4, + COMPLETED = 5, + FAILED = 6, + FAILED_RISK = 7, + FAILED_PROCESSING = 8, + FAILED_RECEIVER_PROCESSING = 9, + FAILED_DA = 10, + FAILED_DA_FINAL = 11, + REFUNDED_TXN = 12, + REFUND_FAILED = 13, + REFUND_FAILED_PROCESSING = 14, + REFUND_FAILED_DA = 15, + EXPIRED_TXN = 16, + AUTH_CANCELED = 17, + AUTH_CANCEL_FAILED_PROCESSING = 18, + AUTH_CANCEL_FAILED = 19, + COLLECT_INIT = 20, + COLLECT_SUCCESS = 21, + COLLECT_FAILED = 22, + COLLECT_FAILED_RISK = 23, + COLLECT_REJECTED = 24, + COLLECT_EXPIRED = 25, + COLLECT_CANCELED = 26, + COLLECT_CANCELLING = 27, + IN_REVIEW = 28 + } + } + + /** Properties of a WebMessageInfo. */ + interface IWebMessageInfo { + + /** WebMessageInfo key */ + key: proto.IMessageKey; + + /** WebMessageInfo message */ + message?: (proto.IMessage|null); + + /** WebMessageInfo messageTimestamp */ + messageTimestamp?: (number|Long|null); + + /** WebMessageInfo status */ + status?: (proto.WebMessageInfo.WebMessageInfoStatus|null); + + /** WebMessageInfo participant */ + participant?: (string|null); + + /** WebMessageInfo messageC2STimestamp */ + messageC2STimestamp?: (number|Long|null); + + /** WebMessageInfo ignore */ + ignore?: (boolean|null); + + /** WebMessageInfo starred */ + starred?: (boolean|null); + + /** WebMessageInfo broadcast */ + broadcast?: (boolean|null); + + /** WebMessageInfo pushName */ + pushName?: (string|null); + + /** WebMessageInfo mediaCiphertextSha256 */ + mediaCiphertextSha256?: (Uint8Array|null); + + /** WebMessageInfo multicast */ + multicast?: (boolean|null); + + /** WebMessageInfo urlText */ + urlText?: (boolean|null); + + /** WebMessageInfo urlNumber */ + urlNumber?: (boolean|null); + + /** WebMessageInfo messageStubType */ + messageStubType?: (proto.WebMessageInfo.WebMessageInfoStubType|null); + + /** WebMessageInfo clearMedia */ + clearMedia?: (boolean|null); + + /** WebMessageInfo messageStubParameters */ + messageStubParameters?: (string[]|null); + + /** WebMessageInfo duration */ + duration?: (number|null); + + /** WebMessageInfo labels */ + labels?: (string[]|null); + + /** WebMessageInfo paymentInfo */ + paymentInfo?: (proto.IPaymentInfo|null); + + /** WebMessageInfo finalLiveLocation */ + finalLiveLocation?: (proto.ILiveLocationMessage|null); + + /** WebMessageInfo quotedPaymentInfo */ + quotedPaymentInfo?: (proto.IPaymentInfo|null); + + /** WebMessageInfo ephemeralStartTimestamp */ + ephemeralStartTimestamp?: (number|Long|null); + + /** WebMessageInfo ephemeralDuration */ + ephemeralDuration?: (number|null); + + /** WebMessageInfo ephemeralOffToOn */ + ephemeralOffToOn?: (boolean|null); + + /** WebMessageInfo ephemeralOutOfSync */ + ephemeralOutOfSync?: (boolean|null); + + /** WebMessageInfo bizPrivacyStatus */ + bizPrivacyStatus?: (proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus|null); + + /** WebMessageInfo verifiedBizName */ + verifiedBizName?: (string|null); + + /** WebMessageInfo mediaData */ + mediaData?: (proto.IMediaData|null); + + /** WebMessageInfo photoChange */ + photoChange?: (proto.IPhotoChange|null); + } + + /** Represents a WebMessageInfo. */ + class WebMessageInfo implements IWebMessageInfo { + + /** + * Constructs a new WebMessageInfo. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IWebMessageInfo); + + /** WebMessageInfo key. */ + public key: proto.IMessageKey; + + /** WebMessageInfo message. */ + public message?: (proto.IMessage|null); + + /** WebMessageInfo messageTimestamp. */ + public messageTimestamp: (number|Long); + + /** WebMessageInfo status. */ + public status: proto.WebMessageInfo.WebMessageInfoStatus; + + /** WebMessageInfo participant. */ + public participant: string; + + /** WebMessageInfo messageC2STimestamp. */ + public messageC2STimestamp: (number|Long); + + /** WebMessageInfo ignore. */ + public ignore: boolean; + + /** WebMessageInfo starred. */ + public starred: boolean; + + /** WebMessageInfo broadcast. */ + public broadcast: boolean; + + /** WebMessageInfo pushName. */ + public pushName: string; + + /** WebMessageInfo mediaCiphertextSha256. */ + public mediaCiphertextSha256: Uint8Array; + + /** WebMessageInfo multicast. */ + public multicast: boolean; + + /** WebMessageInfo urlText. */ + public urlText: boolean; + + /** WebMessageInfo urlNumber. */ + public urlNumber: boolean; + + /** WebMessageInfo messageStubType. */ + public messageStubType: proto.WebMessageInfo.WebMessageInfoStubType; + + /** WebMessageInfo clearMedia. */ + public clearMedia: boolean; + + /** WebMessageInfo messageStubParameters. */ + public messageStubParameters: string[]; + + /** WebMessageInfo duration. */ + public duration: number; + + /** WebMessageInfo labels. */ + public labels: string[]; + + /** WebMessageInfo paymentInfo. */ + public paymentInfo?: (proto.IPaymentInfo|null); + + /** WebMessageInfo finalLiveLocation. */ + public finalLiveLocation?: (proto.ILiveLocationMessage|null); + + /** WebMessageInfo quotedPaymentInfo. */ + public quotedPaymentInfo?: (proto.IPaymentInfo|null); + + /** WebMessageInfo ephemeralStartTimestamp. */ + public ephemeralStartTimestamp: (number|Long); + + /** WebMessageInfo ephemeralDuration. */ + public ephemeralDuration: number; + + /** WebMessageInfo ephemeralOffToOn. */ + public ephemeralOffToOn: boolean; + + /** WebMessageInfo ephemeralOutOfSync. */ + public ephemeralOutOfSync: boolean; + + /** WebMessageInfo bizPrivacyStatus. */ + public bizPrivacyStatus: proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus; + + /** WebMessageInfo verifiedBizName. */ + public verifiedBizName: string; + + /** WebMessageInfo mediaData. */ + public mediaData?: (proto.IMediaData|null); + + /** WebMessageInfo photoChange. */ + public photoChange?: (proto.IPhotoChange|null); + + /** + * Creates a new WebMessageInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns WebMessageInfo instance + */ + public static create(properties?: proto.IWebMessageInfo): proto.WebMessageInfo; + + /** + * Encodes the specified WebMessageInfo message. Does not implicitly {@link proto.WebMessageInfo.verify|verify} messages. + * @param message WebMessageInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IWebMessageInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified WebMessageInfo message, length delimited. Does not implicitly {@link proto.WebMessageInfo.verify|verify} messages. + * @param message WebMessageInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IWebMessageInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a WebMessageInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns WebMessageInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WebMessageInfo; + + /** + * Decodes a WebMessageInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns WebMessageInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WebMessageInfo; + + /** + * Verifies a WebMessageInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a WebMessageInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns WebMessageInfo + */ + public static fromObject(object: { [k: string]: any }): proto.WebMessageInfo; + + /** + * Creates a plain object from a WebMessageInfo message. Also converts values to other types if specified. + * @param message WebMessageInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.WebMessageInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this WebMessageInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace WebMessageInfo { + + /** WebMessageInfoStatus enum. */ + enum WebMessageInfoStatus { + ERROR = 0, + PENDING = 1, + SERVER_ACK = 2, + DELIVERY_ACK = 3, + READ = 4, + PLAYED = 5 + } + + /** WebMessageInfoStubType enum. */ + enum WebMessageInfoStubType { + UNKNOWN = 0, + REVOKE = 1, + CIPHERTEXT = 2, + FUTUREPROOF = 3, + NON_VERIFIED_TRANSITION = 4, + UNVERIFIED_TRANSITION = 5, + VERIFIED_TRANSITION = 6, + VERIFIED_LOW_UNKNOWN = 7, + VERIFIED_HIGH = 8, + VERIFIED_INITIAL_UNKNOWN = 9, + VERIFIED_INITIAL_LOW = 10, + VERIFIED_INITIAL_HIGH = 11, + VERIFIED_TRANSITION_ANY_TO_NONE = 12, + VERIFIED_TRANSITION_ANY_TO_HIGH = 13, + VERIFIED_TRANSITION_HIGH_TO_LOW = 14, + VERIFIED_TRANSITION_HIGH_TO_UNKNOWN = 15, + VERIFIED_TRANSITION_UNKNOWN_TO_LOW = 16, + VERIFIED_TRANSITION_LOW_TO_UNKNOWN = 17, + VERIFIED_TRANSITION_NONE_TO_LOW = 18, + VERIFIED_TRANSITION_NONE_TO_UNKNOWN = 19, + GROUP_CREATE = 20, + GROUP_CHANGE_SUBJECT = 21, + GROUP_CHANGE_ICON = 22, + GROUP_CHANGE_INVITE_LINK = 23, + GROUP_CHANGE_DESCRIPTION = 24, + GROUP_CHANGE_RESTRICT = 25, + GROUP_CHANGE_ANNOUNCE = 26, + GROUP_PARTICIPANT_ADD = 27, + GROUP_PARTICIPANT_REMOVE = 28, + GROUP_PARTICIPANT_PROMOTE = 29, + GROUP_PARTICIPANT_DEMOTE = 30, + GROUP_PARTICIPANT_INVITE = 31, + GROUP_PARTICIPANT_LEAVE = 32, + GROUP_PARTICIPANT_CHANGE_NUMBER = 33, + BROADCAST_CREATE = 34, + BROADCAST_ADD = 35, + BROADCAST_REMOVE = 36, + GENERIC_NOTIFICATION = 37, + E2E_IDENTITY_CHANGED = 38, + E2E_ENCRYPTED = 39, + CALL_MISSED_VOICE = 40, + CALL_MISSED_VIDEO = 41, + INDIVIDUAL_CHANGE_NUMBER = 42, + GROUP_DELETE = 43, + GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE = 44, + CALL_MISSED_GROUP_VOICE = 45, + CALL_MISSED_GROUP_VIDEO = 46, + PAYMENT_CIPHERTEXT = 47, + PAYMENT_FUTUREPROOF = 48, + PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED = 49, + PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED = 50, + PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED = 51, + PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP = 52, + PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP = 53, + PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER = 54, + PAYMENT_ACTION_SEND_PAYMENT_REMINDER = 55, + PAYMENT_ACTION_SEND_PAYMENT_INVITATION = 56, + PAYMENT_ACTION_REQUEST_DECLINED = 57, + PAYMENT_ACTION_REQUEST_EXPIRED = 58, + PAYMENT_ACTION_REQUEST_CANCELLED = 59, + BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM = 60, + BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP = 61, + BIZ_INTRO_TOP = 62, + BIZ_INTRO_BOTTOM = 63, + BIZ_NAME_CHANGE = 64, + BIZ_MOVE_TO_CONSUMER_APP = 65, + BIZ_TWO_TIER_MIGRATION_TOP = 66, + BIZ_TWO_TIER_MIGRATION_BOTTOM = 67, + OVERSIZED = 68, + GROUP_CHANGE_NO_FREQUENTLY_FORWARDED = 69, + GROUP_V4_ADD_INVITE_SENT = 70, + GROUP_PARTICIPANT_ADD_REQUEST_JOIN = 71, + CHANGE_EPHEMERAL_SETTING = 72, + E2E_DEVICE_CHANGED = 73, + VIEWED_ONCE = 74, + E2E_ENCRYPTED_NOW = 75, + BLUE_MSG_BSP_FB_TO_BSP_PREMISE = 76, + BLUE_MSG_BSP_FB_TO_SELF_FB = 77, + BLUE_MSG_BSP_FB_TO_SELF_PREMISE = 78, + BLUE_MSG_BSP_FB_UNVERIFIED = 79, + BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED = 80, + BLUE_MSG_BSP_FB_VERIFIED = 81, + BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED = 82, + BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE = 83, + BLUE_MSG_BSP_PREMISE_UNVERIFIED = 84, + BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED = 85, + BLUE_MSG_BSP_PREMISE_VERIFIED = 86, + BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED = 87, + BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED = 88, + BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED = 89, + BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED = 90, + BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED = 91, + BLUE_MSG_SELF_FB_TO_BSP_PREMISE = 92, + BLUE_MSG_SELF_FB_TO_SELF_PREMISE = 93, + BLUE_MSG_SELF_FB_UNVERIFIED = 94, + BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED = 95, + BLUE_MSG_SELF_FB_VERIFIED = 96, + BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED = 97, + BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE = 98, + BLUE_MSG_SELF_PREMISE_UNVERIFIED = 99, + BLUE_MSG_SELF_PREMISE_VERIFIED = 100, + BLUE_MSG_TO_BSP_FB = 101, + BLUE_MSG_TO_CONSUMER = 102, + BLUE_MSG_TO_SELF_FB = 103, + BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED = 104, + BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED = 105, + BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED = 106, + BLUE_MSG_UNVERIFIED_TO_VERIFIED = 107, + BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED = 108, + BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED = 109, + BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED = 110, + BLUE_MSG_VERIFIED_TO_UNVERIFIED = 111, + BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED = 112, + BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED = 113, + BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED = 114, + BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED = 115, + BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED = 116, + BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED = 117, + E2E_IDENTITY_UNAVAILABLE = 118, + GROUP_CREATING = 119, + GROUP_CREATE_FAILED = 120, + GROUP_BOUNCED = 121, + BLOCK_CONTACT = 122, + EPHEMERAL_SETTING_NOT_APPLIED = 123, + SYNC_FAILED = 124, + SYNCING = 125, + BIZ_PRIVACY_MODE_INIT_FB = 126, + BIZ_PRIVACY_MODE_INIT_BSP = 127, + BIZ_PRIVACY_MODE_TO_FB = 128, + BIZ_PRIVACY_MODE_TO_BSP = 129 + } + + /** WebMessageInfoBizPrivacyStatus enum. */ + enum WebMessageInfoBizPrivacyStatus { + E2EE = 0, + FB = 2, + BSP = 1, + BSP_AND_FB = 3 + } + } } diff --git a/WAMessage/WAMessage.js b/WAMessage/WAMessage.js index 6436c3c..140aede 100644 --- a/WAMessage/WAMessage.js +++ b/WAMessage/WAMessage.js @@ -18,60 +18,28 @@ $root.proto = (function() { */ var proto = {}; - proto.WebFeatures = (function() { + proto.AppVersion = (function() { /** - * Properties of a WebFeatures. + * Properties of an AppVersion. * @memberof proto - * @interface IWebFeatures - * @property {proto.WebFeatures.WebFeaturesFlag|null} [labelsDisplay] WebFeatures labelsDisplay - * @property {proto.WebFeatures.WebFeaturesFlag|null} [voipIndividualOutgoing] WebFeatures voipIndividualOutgoing - * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupsV3] WebFeatures groupsV3 - * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupsV3Create] WebFeatures groupsV3Create - * @property {proto.WebFeatures.WebFeaturesFlag|null} [changeNumberV2] WebFeatures changeNumberV2 - * @property {proto.WebFeatures.WebFeaturesFlag|null} [queryStatusV3Thumbnail] WebFeatures queryStatusV3Thumbnail - * @property {proto.WebFeatures.WebFeaturesFlag|null} [liveLocations] WebFeatures liveLocations - * @property {proto.WebFeatures.WebFeaturesFlag|null} [queryVname] WebFeatures queryVname - * @property {proto.WebFeatures.WebFeaturesFlag|null} [voipIndividualIncoming] WebFeatures voipIndividualIncoming - * @property {proto.WebFeatures.WebFeaturesFlag|null} [quickRepliesQuery] WebFeatures quickRepliesQuery - * @property {proto.WebFeatures.WebFeaturesFlag|null} [payments] WebFeatures payments - * @property {proto.WebFeatures.WebFeaturesFlag|null} [stickerPackQuery] WebFeatures stickerPackQuery - * @property {proto.WebFeatures.WebFeaturesFlag|null} [liveLocationsFinal] WebFeatures liveLocationsFinal - * @property {proto.WebFeatures.WebFeaturesFlag|null} [labelsEdit] WebFeatures labelsEdit - * @property {proto.WebFeatures.WebFeaturesFlag|null} [mediaUpload] WebFeatures mediaUpload - * @property {proto.WebFeatures.WebFeaturesFlag|null} [mediaUploadRichQuickReplies] WebFeatures mediaUploadRichQuickReplies - * @property {proto.WebFeatures.WebFeaturesFlag|null} [vnameV2] WebFeatures vnameV2 - * @property {proto.WebFeatures.WebFeaturesFlag|null} [videoPlaybackUrl] WebFeatures videoPlaybackUrl - * @property {proto.WebFeatures.WebFeaturesFlag|null} [statusRanking] WebFeatures statusRanking - * @property {proto.WebFeatures.WebFeaturesFlag|null} [voipIndividualVideo] WebFeatures voipIndividualVideo - * @property {proto.WebFeatures.WebFeaturesFlag|null} [thirdPartyStickers] WebFeatures thirdPartyStickers - * @property {proto.WebFeatures.WebFeaturesFlag|null} [frequentlyForwardedSetting] WebFeatures frequentlyForwardedSetting - * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupsV4JoinPermission] WebFeatures groupsV4JoinPermission - * @property {proto.WebFeatures.WebFeaturesFlag|null} [recentStickers] WebFeatures recentStickers - * @property {proto.WebFeatures.WebFeaturesFlag|null} [catalog] WebFeatures catalog - * @property {proto.WebFeatures.WebFeaturesFlag|null} [starredStickers] WebFeatures starredStickers - * @property {proto.WebFeatures.WebFeaturesFlag|null} [voipGroupCall] WebFeatures voipGroupCall - * @property {proto.WebFeatures.WebFeaturesFlag|null} [templateMessage] WebFeatures templateMessage - * @property {proto.WebFeatures.WebFeaturesFlag|null} [templateMessageInteractivity] WebFeatures templateMessageInteractivity - * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeralMessages] WebFeatures ephemeralMessages - * @property {proto.WebFeatures.WebFeaturesFlag|null} [e2ENotificationSync] WebFeatures e2ENotificationSync - * @property {proto.WebFeatures.WebFeaturesFlag|null} [recentStickersV2] WebFeatures recentStickersV2 - * @property {proto.WebFeatures.WebFeaturesFlag|null} [syncdRelease1] WebFeatures syncdRelease1 - * @property {proto.WebFeatures.WebFeaturesFlag|null} [recentStickersV3] WebFeatures recentStickersV3 - * @property {proto.WebFeatures.WebFeaturesFlag|null} [userNotice] WebFeatures userNotice - * @property {proto.WebFeatures.WebFeaturesFlag|null} [syncdRelease11] WebFeatures syncdRelease11 - * @property {proto.WebFeatures.WebFeaturesFlag|null} [support] WebFeatures support + * @interface IAppVersion + * @property {number|null} [primary] AppVersion primary + * @property {number|null} [secondary] AppVersion secondary + * @property {number|null} [tertiary] AppVersion tertiary + * @property {number|null} [quaternary] AppVersion quaternary + * @property {number|null} [quinary] AppVersion quinary */ /** - * Constructs a new WebFeatures. + * Constructs a new AppVersion. * @memberof proto - * @classdesc Represents a WebFeatures. - * @implements IWebFeatures + * @classdesc Represents an AppVersion. + * @implements IAppVersion * @constructor - * @param {proto.IWebFeatures=} [properties] Properties to set + * @param {proto.IAppVersion=} [properties] Properties to set */ - function WebFeatures(properties) { + function AppVersion(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -79,543 +47,515 @@ $root.proto = (function() { } /** - * WebFeatures labelsDisplay. - * @member {proto.WebFeatures.WebFeaturesFlag} labelsDisplay - * @memberof proto.WebFeatures + * AppVersion primary. + * @member {number} primary + * @memberof proto.AppVersion * @instance */ - WebFeatures.prototype.labelsDisplay = 0; + AppVersion.prototype.primary = 0; /** - * WebFeatures voipIndividualOutgoing. - * @member {proto.WebFeatures.WebFeaturesFlag} voipIndividualOutgoing - * @memberof proto.WebFeatures + * AppVersion secondary. + * @member {number} secondary + * @memberof proto.AppVersion * @instance */ - WebFeatures.prototype.voipIndividualOutgoing = 0; + AppVersion.prototype.secondary = 0; /** - * WebFeatures groupsV3. - * @member {proto.WebFeatures.WebFeaturesFlag} groupsV3 - * @memberof proto.WebFeatures + * AppVersion tertiary. + * @member {number} tertiary + * @memberof proto.AppVersion * @instance */ - WebFeatures.prototype.groupsV3 = 0; + AppVersion.prototype.tertiary = 0; /** - * WebFeatures groupsV3Create. - * @member {proto.WebFeatures.WebFeaturesFlag} groupsV3Create - * @memberof proto.WebFeatures + * AppVersion quaternary. + * @member {number} quaternary + * @memberof proto.AppVersion * @instance */ - WebFeatures.prototype.groupsV3Create = 0; + AppVersion.prototype.quaternary = 0; /** - * WebFeatures changeNumberV2. - * @member {proto.WebFeatures.WebFeaturesFlag} changeNumberV2 - * @memberof proto.WebFeatures + * AppVersion quinary. + * @member {number} quinary + * @memberof proto.AppVersion * @instance */ - WebFeatures.prototype.changeNumberV2 = 0; + AppVersion.prototype.quinary = 0; /** - * WebFeatures queryStatusV3Thumbnail. - * @member {proto.WebFeatures.WebFeaturesFlag} queryStatusV3Thumbnail - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.queryStatusV3Thumbnail = 0; - - /** - * WebFeatures liveLocations. - * @member {proto.WebFeatures.WebFeaturesFlag} liveLocations - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.liveLocations = 0; - - /** - * WebFeatures queryVname. - * @member {proto.WebFeatures.WebFeaturesFlag} queryVname - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.queryVname = 0; - - /** - * WebFeatures voipIndividualIncoming. - * @member {proto.WebFeatures.WebFeaturesFlag} voipIndividualIncoming - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.voipIndividualIncoming = 0; - - /** - * WebFeatures quickRepliesQuery. - * @member {proto.WebFeatures.WebFeaturesFlag} quickRepliesQuery - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.quickRepliesQuery = 0; - - /** - * WebFeatures payments. - * @member {proto.WebFeatures.WebFeaturesFlag} payments - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.payments = 0; - - /** - * WebFeatures stickerPackQuery. - * @member {proto.WebFeatures.WebFeaturesFlag} stickerPackQuery - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.stickerPackQuery = 0; - - /** - * WebFeatures liveLocationsFinal. - * @member {proto.WebFeatures.WebFeaturesFlag} liveLocationsFinal - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.liveLocationsFinal = 0; - - /** - * WebFeatures labelsEdit. - * @member {proto.WebFeatures.WebFeaturesFlag} labelsEdit - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.labelsEdit = 0; - - /** - * WebFeatures mediaUpload. - * @member {proto.WebFeatures.WebFeaturesFlag} mediaUpload - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.mediaUpload = 0; - - /** - * WebFeatures mediaUploadRichQuickReplies. - * @member {proto.WebFeatures.WebFeaturesFlag} mediaUploadRichQuickReplies - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.mediaUploadRichQuickReplies = 0; - - /** - * WebFeatures vnameV2. - * @member {proto.WebFeatures.WebFeaturesFlag} vnameV2 - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.vnameV2 = 0; - - /** - * WebFeatures videoPlaybackUrl. - * @member {proto.WebFeatures.WebFeaturesFlag} videoPlaybackUrl - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.videoPlaybackUrl = 0; - - /** - * WebFeatures statusRanking. - * @member {proto.WebFeatures.WebFeaturesFlag} statusRanking - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.statusRanking = 0; - - /** - * WebFeatures voipIndividualVideo. - * @member {proto.WebFeatures.WebFeaturesFlag} voipIndividualVideo - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.voipIndividualVideo = 0; - - /** - * WebFeatures thirdPartyStickers. - * @member {proto.WebFeatures.WebFeaturesFlag} thirdPartyStickers - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.thirdPartyStickers = 0; - - /** - * WebFeatures frequentlyForwardedSetting. - * @member {proto.WebFeatures.WebFeaturesFlag} frequentlyForwardedSetting - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.frequentlyForwardedSetting = 0; - - /** - * WebFeatures groupsV4JoinPermission. - * @member {proto.WebFeatures.WebFeaturesFlag} groupsV4JoinPermission - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.groupsV4JoinPermission = 0; - - /** - * WebFeatures recentStickers. - * @member {proto.WebFeatures.WebFeaturesFlag} recentStickers - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.recentStickers = 0; - - /** - * WebFeatures catalog. - * @member {proto.WebFeatures.WebFeaturesFlag} catalog - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.catalog = 0; - - /** - * WebFeatures starredStickers. - * @member {proto.WebFeatures.WebFeaturesFlag} starredStickers - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.starredStickers = 0; - - /** - * WebFeatures voipGroupCall. - * @member {proto.WebFeatures.WebFeaturesFlag} voipGroupCall - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.voipGroupCall = 0; - - /** - * WebFeatures templateMessage. - * @member {proto.WebFeatures.WebFeaturesFlag} templateMessage - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.templateMessage = 0; - - /** - * WebFeatures templateMessageInteractivity. - * @member {proto.WebFeatures.WebFeaturesFlag} templateMessageInteractivity - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.templateMessageInteractivity = 0; - - /** - * WebFeatures ephemeralMessages. - * @member {proto.WebFeatures.WebFeaturesFlag} ephemeralMessages - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.ephemeralMessages = 0; - - /** - * WebFeatures e2ENotificationSync. - * @member {proto.WebFeatures.WebFeaturesFlag} e2ENotificationSync - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.e2ENotificationSync = 0; - - /** - * WebFeatures recentStickersV2. - * @member {proto.WebFeatures.WebFeaturesFlag} recentStickersV2 - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.recentStickersV2 = 0; - - /** - * WebFeatures syncdRelease1. - * @member {proto.WebFeatures.WebFeaturesFlag} syncdRelease1 - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.syncdRelease1 = 0; - - /** - * WebFeatures recentStickersV3. - * @member {proto.WebFeatures.WebFeaturesFlag} recentStickersV3 - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.recentStickersV3 = 0; - - /** - * WebFeatures userNotice. - * @member {proto.WebFeatures.WebFeaturesFlag} userNotice - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.userNotice = 0; - - /** - * WebFeatures syncdRelease11. - * @member {proto.WebFeatures.WebFeaturesFlag} syncdRelease11 - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.syncdRelease11 = 0; - - /** - * WebFeatures support. - * @member {proto.WebFeatures.WebFeaturesFlag} support - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.support = 0; - - /** - * Creates a new WebFeatures instance using the specified properties. + * Creates a new AppVersion instance using the specified properties. * @function create - * @memberof proto.WebFeatures + * @memberof proto.AppVersion * @static - * @param {proto.IWebFeatures=} [properties] Properties to set - * @returns {proto.WebFeatures} WebFeatures instance + * @param {proto.IAppVersion=} [properties] Properties to set + * @returns {proto.AppVersion} AppVersion instance */ - WebFeatures.create = function create(properties) { - return new WebFeatures(properties); + AppVersion.create = function create(properties) { + return new AppVersion(properties); }; /** - * Encodes the specified WebFeatures message. Does not implicitly {@link proto.WebFeatures.verify|verify} messages. + * Encodes the specified AppVersion message. Does not implicitly {@link proto.AppVersion.verify|verify} messages. * @function encode - * @memberof proto.WebFeatures + * @memberof proto.AppVersion * @static - * @param {proto.IWebFeatures} message WebFeatures message or plain object to encode + * @param {proto.IAppVersion} message AppVersion message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - WebFeatures.encode = function encode(message, writer) { + AppVersion.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.labelsDisplay != null && Object.hasOwnProperty.call(message, "labelsDisplay")) - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.labelsDisplay); - if (message.voipIndividualOutgoing != null && Object.hasOwnProperty.call(message, "voipIndividualOutgoing")) - writer.uint32(/* id 2, wireType 0 =*/16).int32(message.voipIndividualOutgoing); - if (message.groupsV3 != null && Object.hasOwnProperty.call(message, "groupsV3")) - writer.uint32(/* id 3, wireType 0 =*/24).int32(message.groupsV3); - if (message.groupsV3Create != null && Object.hasOwnProperty.call(message, "groupsV3Create")) - writer.uint32(/* id 4, wireType 0 =*/32).int32(message.groupsV3Create); - if (message.changeNumberV2 != null && Object.hasOwnProperty.call(message, "changeNumberV2")) - writer.uint32(/* id 5, wireType 0 =*/40).int32(message.changeNumberV2); - if (message.queryStatusV3Thumbnail != null && Object.hasOwnProperty.call(message, "queryStatusV3Thumbnail")) - writer.uint32(/* id 6, wireType 0 =*/48).int32(message.queryStatusV3Thumbnail); - if (message.liveLocations != null && Object.hasOwnProperty.call(message, "liveLocations")) - writer.uint32(/* id 7, wireType 0 =*/56).int32(message.liveLocations); - if (message.queryVname != null && Object.hasOwnProperty.call(message, "queryVname")) - writer.uint32(/* id 8, wireType 0 =*/64).int32(message.queryVname); - if (message.voipIndividualIncoming != null && Object.hasOwnProperty.call(message, "voipIndividualIncoming")) - writer.uint32(/* id 9, wireType 0 =*/72).int32(message.voipIndividualIncoming); - if (message.quickRepliesQuery != null && Object.hasOwnProperty.call(message, "quickRepliesQuery")) - writer.uint32(/* id 10, wireType 0 =*/80).int32(message.quickRepliesQuery); - if (message.payments != null && Object.hasOwnProperty.call(message, "payments")) - writer.uint32(/* id 11, wireType 0 =*/88).int32(message.payments); - if (message.stickerPackQuery != null && Object.hasOwnProperty.call(message, "stickerPackQuery")) - writer.uint32(/* id 12, wireType 0 =*/96).int32(message.stickerPackQuery); - if (message.liveLocationsFinal != null && Object.hasOwnProperty.call(message, "liveLocationsFinal")) - writer.uint32(/* id 13, wireType 0 =*/104).int32(message.liveLocationsFinal); - if (message.labelsEdit != null && Object.hasOwnProperty.call(message, "labelsEdit")) - writer.uint32(/* id 14, wireType 0 =*/112).int32(message.labelsEdit); - if (message.mediaUpload != null && Object.hasOwnProperty.call(message, "mediaUpload")) - writer.uint32(/* id 15, wireType 0 =*/120).int32(message.mediaUpload); - if (message.mediaUploadRichQuickReplies != null && Object.hasOwnProperty.call(message, "mediaUploadRichQuickReplies")) - writer.uint32(/* id 18, wireType 0 =*/144).int32(message.mediaUploadRichQuickReplies); - if (message.vnameV2 != null && Object.hasOwnProperty.call(message, "vnameV2")) - writer.uint32(/* id 19, wireType 0 =*/152).int32(message.vnameV2); - if (message.videoPlaybackUrl != null && Object.hasOwnProperty.call(message, "videoPlaybackUrl")) - writer.uint32(/* id 20, wireType 0 =*/160).int32(message.videoPlaybackUrl); - if (message.statusRanking != null && Object.hasOwnProperty.call(message, "statusRanking")) - writer.uint32(/* id 21, wireType 0 =*/168).int32(message.statusRanking); - if (message.voipIndividualVideo != null && Object.hasOwnProperty.call(message, "voipIndividualVideo")) - writer.uint32(/* id 22, wireType 0 =*/176).int32(message.voipIndividualVideo); - if (message.thirdPartyStickers != null && Object.hasOwnProperty.call(message, "thirdPartyStickers")) - writer.uint32(/* id 23, wireType 0 =*/184).int32(message.thirdPartyStickers); - if (message.frequentlyForwardedSetting != null && Object.hasOwnProperty.call(message, "frequentlyForwardedSetting")) - writer.uint32(/* id 24, wireType 0 =*/192).int32(message.frequentlyForwardedSetting); - if (message.groupsV4JoinPermission != null && Object.hasOwnProperty.call(message, "groupsV4JoinPermission")) - writer.uint32(/* id 25, wireType 0 =*/200).int32(message.groupsV4JoinPermission); - if (message.recentStickers != null && Object.hasOwnProperty.call(message, "recentStickers")) - writer.uint32(/* id 26, wireType 0 =*/208).int32(message.recentStickers); - if (message.catalog != null && Object.hasOwnProperty.call(message, "catalog")) - writer.uint32(/* id 27, wireType 0 =*/216).int32(message.catalog); - if (message.starredStickers != null && Object.hasOwnProperty.call(message, "starredStickers")) - writer.uint32(/* id 28, wireType 0 =*/224).int32(message.starredStickers); - if (message.voipGroupCall != null && Object.hasOwnProperty.call(message, "voipGroupCall")) - writer.uint32(/* id 29, wireType 0 =*/232).int32(message.voipGroupCall); - if (message.templateMessage != null && Object.hasOwnProperty.call(message, "templateMessage")) - writer.uint32(/* id 30, wireType 0 =*/240).int32(message.templateMessage); - if (message.templateMessageInteractivity != null && Object.hasOwnProperty.call(message, "templateMessageInteractivity")) - writer.uint32(/* id 31, wireType 0 =*/248).int32(message.templateMessageInteractivity); - if (message.ephemeralMessages != null && Object.hasOwnProperty.call(message, "ephemeralMessages")) - writer.uint32(/* id 32, wireType 0 =*/256).int32(message.ephemeralMessages); - if (message.e2ENotificationSync != null && Object.hasOwnProperty.call(message, "e2ENotificationSync")) - writer.uint32(/* id 33, wireType 0 =*/264).int32(message.e2ENotificationSync); - if (message.recentStickersV2 != null && Object.hasOwnProperty.call(message, "recentStickersV2")) - writer.uint32(/* id 34, wireType 0 =*/272).int32(message.recentStickersV2); - if (message.syncdRelease1 != null && Object.hasOwnProperty.call(message, "syncdRelease1")) - writer.uint32(/* id 35, wireType 0 =*/280).int32(message.syncdRelease1); - if (message.recentStickersV3 != null && Object.hasOwnProperty.call(message, "recentStickersV3")) - writer.uint32(/* id 36, wireType 0 =*/288).int32(message.recentStickersV3); - if (message.userNotice != null && Object.hasOwnProperty.call(message, "userNotice")) - writer.uint32(/* id 37, wireType 0 =*/296).int32(message.userNotice); - if (message.syncdRelease11 != null && Object.hasOwnProperty.call(message, "syncdRelease11")) - writer.uint32(/* id 38, wireType 0 =*/304).int32(message.syncdRelease11); - if (message.support != null && Object.hasOwnProperty.call(message, "support")) - writer.uint32(/* id 39, wireType 0 =*/312).int32(message.support); + if (message.primary != null && Object.hasOwnProperty.call(message, "primary")) + writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.primary); + if (message.secondary != null && Object.hasOwnProperty.call(message, "secondary")) + writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.secondary); + if (message.tertiary != null && Object.hasOwnProperty.call(message, "tertiary")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.tertiary); + if (message.quaternary != null && Object.hasOwnProperty.call(message, "quaternary")) + writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.quaternary); + if (message.quinary != null && Object.hasOwnProperty.call(message, "quinary")) + writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.quinary); return writer; }; /** - * Encodes the specified WebFeatures message, length delimited. Does not implicitly {@link proto.WebFeatures.verify|verify} messages. + * Encodes the specified AppVersion message, length delimited. Does not implicitly {@link proto.AppVersion.verify|verify} messages. * @function encodeDelimited - * @memberof proto.WebFeatures + * @memberof proto.AppVersion * @static - * @param {proto.IWebFeatures} message WebFeatures message or plain object to encode + * @param {proto.IAppVersion} message AppVersion message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - WebFeatures.encodeDelimited = function encodeDelimited(message, writer) { + AppVersion.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; /** - * Decodes a WebFeatures message from the specified reader or buffer. + * Decodes an AppVersion message from the specified reader or buffer. * @function decode - * @memberof proto.WebFeatures + * @memberof proto.AppVersion * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from * @param {number} [length] Message length if known beforehand - * @returns {proto.WebFeatures} WebFeatures + * @returns {proto.AppVersion} AppVersion * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - WebFeatures.decode = function decode(reader, length) { + AppVersion.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebFeatures(); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AppVersion(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.labelsDisplay = reader.int32(); + message.primary = reader.uint32(); break; case 2: - message.voipIndividualOutgoing = reader.int32(); + message.secondary = reader.uint32(); break; case 3: - message.groupsV3 = reader.int32(); + message.tertiary = reader.uint32(); break; case 4: - message.groupsV3Create = reader.int32(); + message.quaternary = reader.uint32(); break; case 5: - message.changeNumberV2 = reader.int32(); + message.quinary = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an AppVersion message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.AppVersion + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.AppVersion} AppVersion + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + AppVersion.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an AppVersion message. + * @function verify + * @memberof proto.AppVersion + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + AppVersion.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.primary != null && message.hasOwnProperty("primary")) + if (!$util.isInteger(message.primary)) + return "primary: integer expected"; + if (message.secondary != null && message.hasOwnProperty("secondary")) + if (!$util.isInteger(message.secondary)) + return "secondary: integer expected"; + if (message.tertiary != null && message.hasOwnProperty("tertiary")) + if (!$util.isInteger(message.tertiary)) + return "tertiary: integer expected"; + if (message.quaternary != null && message.hasOwnProperty("quaternary")) + if (!$util.isInteger(message.quaternary)) + return "quaternary: integer expected"; + if (message.quinary != null && message.hasOwnProperty("quinary")) + if (!$util.isInteger(message.quinary)) + return "quinary: integer expected"; + return null; + }; + + /** + * Creates an AppVersion message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.AppVersion + * @static + * @param {Object.} object Plain object + * @returns {proto.AppVersion} AppVersion + */ + AppVersion.fromObject = function fromObject(object) { + if (object instanceof $root.proto.AppVersion) + return object; + var message = new $root.proto.AppVersion(); + if (object.primary != null) + message.primary = object.primary >>> 0; + if (object.secondary != null) + message.secondary = object.secondary >>> 0; + if (object.tertiary != null) + message.tertiary = object.tertiary >>> 0; + if (object.quaternary != null) + message.quaternary = object.quaternary >>> 0; + if (object.quinary != null) + message.quinary = object.quinary >>> 0; + return message; + }; + + /** + * Creates a plain object from an AppVersion message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.AppVersion + * @static + * @param {proto.AppVersion} message AppVersion + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + AppVersion.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.primary = 0; + object.secondary = 0; + object.tertiary = 0; + object.quaternary = 0; + object.quinary = 0; + } + if (message.primary != null && message.hasOwnProperty("primary")) + object.primary = message.primary; + if (message.secondary != null && message.hasOwnProperty("secondary")) + object.secondary = message.secondary; + if (message.tertiary != null && message.hasOwnProperty("tertiary")) + object.tertiary = message.tertiary; + if (message.quaternary != null && message.hasOwnProperty("quaternary")) + object.quaternary = message.quaternary; + if (message.quinary != null && message.hasOwnProperty("quinary")) + object.quinary = message.quinary; + return object; + }; + + /** + * Converts this AppVersion to JSON. + * @function toJSON + * @memberof proto.AppVersion + * @instance + * @returns {Object.} JSON object + */ + AppVersion.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return AppVersion; + })(); + + proto.UserAgent = (function() { + + /** + * Properties of a UserAgent. + * @memberof proto + * @interface IUserAgent + * @property {proto.UserAgent.UserAgentPlatform|null} [platform] UserAgent platform + * @property {proto.IAppVersion|null} [appVersion] UserAgent appVersion + * @property {string|null} [mcc] UserAgent mcc + * @property {string|null} [mnc] UserAgent mnc + * @property {string|null} [osVersion] UserAgent osVersion + * @property {string|null} [manufacturer] UserAgent manufacturer + * @property {string|null} [device] UserAgent device + * @property {string|null} [osBuildNumber] UserAgent osBuildNumber + * @property {string|null} [phoneId] UserAgent phoneId + * @property {proto.UserAgent.UserAgentReleaseChannel|null} [releaseChannel] UserAgent releaseChannel + * @property {string|null} [localeLanguageIso6391] UserAgent localeLanguageIso6391 + * @property {string|null} [localeCountryIso31661Alpha2] UserAgent localeCountryIso31661Alpha2 + * @property {string|null} [deviceBoard] UserAgent deviceBoard + */ + + /** + * Constructs a new UserAgent. + * @memberof proto + * @classdesc Represents a UserAgent. + * @implements IUserAgent + * @constructor + * @param {proto.IUserAgent=} [properties] Properties to set + */ + function UserAgent(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * UserAgent platform. + * @member {proto.UserAgent.UserAgentPlatform} platform + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.platform = 0; + + /** + * UserAgent appVersion. + * @member {proto.IAppVersion|null|undefined} appVersion + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.appVersion = null; + + /** + * UserAgent mcc. + * @member {string} mcc + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.mcc = ""; + + /** + * UserAgent mnc. + * @member {string} mnc + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.mnc = ""; + + /** + * UserAgent osVersion. + * @member {string} osVersion + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.osVersion = ""; + + /** + * UserAgent manufacturer. + * @member {string} manufacturer + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.manufacturer = ""; + + /** + * UserAgent device. + * @member {string} device + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.device = ""; + + /** + * UserAgent osBuildNumber. + * @member {string} osBuildNumber + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.osBuildNumber = ""; + + /** + * UserAgent phoneId. + * @member {string} phoneId + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.phoneId = ""; + + /** + * UserAgent releaseChannel. + * @member {proto.UserAgent.UserAgentReleaseChannel} releaseChannel + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.releaseChannel = 0; + + /** + * UserAgent localeLanguageIso6391. + * @member {string} localeLanguageIso6391 + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.localeLanguageIso6391 = ""; + + /** + * UserAgent localeCountryIso31661Alpha2. + * @member {string} localeCountryIso31661Alpha2 + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.localeCountryIso31661Alpha2 = ""; + + /** + * UserAgent deviceBoard. + * @member {string} deviceBoard + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.deviceBoard = ""; + + /** + * Creates a new UserAgent instance using the specified properties. + * @function create + * @memberof proto.UserAgent + * @static + * @param {proto.IUserAgent=} [properties] Properties to set + * @returns {proto.UserAgent} UserAgent instance + */ + UserAgent.create = function create(properties) { + return new UserAgent(properties); + }; + + /** + * Encodes the specified UserAgent message. Does not implicitly {@link proto.UserAgent.verify|verify} messages. + * @function encode + * @memberof proto.UserAgent + * @static + * @param {proto.IUserAgent} message UserAgent message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UserAgent.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.platform != null && Object.hasOwnProperty.call(message, "platform")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.platform); + if (message.appVersion != null && Object.hasOwnProperty.call(message, "appVersion")) + $root.proto.AppVersion.encode(message.appVersion, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.mcc != null && Object.hasOwnProperty.call(message, "mcc")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.mcc); + if (message.mnc != null && Object.hasOwnProperty.call(message, "mnc")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.mnc); + if (message.osVersion != null && Object.hasOwnProperty.call(message, "osVersion")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.osVersion); + if (message.manufacturer != null && Object.hasOwnProperty.call(message, "manufacturer")) + writer.uint32(/* id 6, wireType 2 =*/50).string(message.manufacturer); + if (message.device != null && Object.hasOwnProperty.call(message, "device")) + writer.uint32(/* id 7, wireType 2 =*/58).string(message.device); + if (message.osBuildNumber != null && Object.hasOwnProperty.call(message, "osBuildNumber")) + writer.uint32(/* id 8, wireType 2 =*/66).string(message.osBuildNumber); + if (message.phoneId != null && Object.hasOwnProperty.call(message, "phoneId")) + writer.uint32(/* id 9, wireType 2 =*/74).string(message.phoneId); + if (message.releaseChannel != null && Object.hasOwnProperty.call(message, "releaseChannel")) + writer.uint32(/* id 10, wireType 0 =*/80).int32(message.releaseChannel); + if (message.localeLanguageIso6391 != null && Object.hasOwnProperty.call(message, "localeLanguageIso6391")) + writer.uint32(/* id 11, wireType 2 =*/90).string(message.localeLanguageIso6391); + if (message.localeCountryIso31661Alpha2 != null && Object.hasOwnProperty.call(message, "localeCountryIso31661Alpha2")) + writer.uint32(/* id 12, wireType 2 =*/98).string(message.localeCountryIso31661Alpha2); + if (message.deviceBoard != null && Object.hasOwnProperty.call(message, "deviceBoard")) + writer.uint32(/* id 13, wireType 2 =*/106).string(message.deviceBoard); + return writer; + }; + + /** + * Encodes the specified UserAgent message, length delimited. Does not implicitly {@link proto.UserAgent.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.UserAgent + * @static + * @param {proto.IUserAgent} message UserAgent message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UserAgent.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a UserAgent message from the specified reader or buffer. + * @function decode + * @memberof proto.UserAgent + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.UserAgent} UserAgent + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UserAgent.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.UserAgent(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.platform = reader.int32(); + break; + case 2: + message.appVersion = $root.proto.AppVersion.decode(reader, reader.uint32()); + break; + case 3: + message.mcc = reader.string(); + break; + case 4: + message.mnc = reader.string(); + break; + case 5: + message.osVersion = reader.string(); break; case 6: - message.queryStatusV3Thumbnail = reader.int32(); + message.manufacturer = reader.string(); break; case 7: - message.liveLocations = reader.int32(); + message.device = reader.string(); break; case 8: - message.queryVname = reader.int32(); + message.osBuildNumber = reader.string(); break; case 9: - message.voipIndividualIncoming = reader.int32(); + message.phoneId = reader.string(); break; case 10: - message.quickRepliesQuery = reader.int32(); + message.releaseChannel = reader.int32(); break; case 11: - message.payments = reader.int32(); + message.localeLanguageIso6391 = reader.string(); break; case 12: - message.stickerPackQuery = reader.int32(); + message.localeCountryIso31661Alpha2 = reader.string(); break; case 13: - message.liveLocationsFinal = reader.int32(); - break; - case 14: - message.labelsEdit = reader.int32(); - break; - case 15: - message.mediaUpload = reader.int32(); - break; - case 18: - message.mediaUploadRichQuickReplies = reader.int32(); - break; - case 19: - message.vnameV2 = reader.int32(); - break; - case 20: - message.videoPlaybackUrl = reader.int32(); - break; - case 21: - message.statusRanking = reader.int32(); - break; - case 22: - message.voipIndividualVideo = reader.int32(); - break; - case 23: - message.thirdPartyStickers = reader.int32(); - break; - case 24: - message.frequentlyForwardedSetting = reader.int32(); - break; - case 25: - message.groupsV4JoinPermission = reader.int32(); - break; - case 26: - message.recentStickers = reader.int32(); - break; - case 27: - message.catalog = reader.int32(); - break; - case 28: - message.starredStickers = reader.int32(); - break; - case 29: - message.voipGroupCall = reader.int32(); - break; - case 30: - message.templateMessage = reader.int32(); - break; - case 31: - message.templateMessageInteractivity = reader.int32(); - break; - case 32: - message.ephemeralMessages = reader.int32(); - break; - case 33: - message.e2ENotificationSync = reader.int32(); - break; - case 34: - message.recentStickersV2 = reader.int32(); - break; - case 35: - message.syncdRelease1 = reader.int32(); - break; - case 36: - message.recentStickersV3 = reader.int32(); - break; - case 37: - message.userNotice = reader.int32(); - break; - case 38: - message.syncdRelease11 = reader.int32(); - break; - case 39: - message.support = reader.int32(); + message.deviceBoard = reader.string(); break; default: reader.skipType(tag & 7); @@ -626,2124 +566,36 @@ $root.proto = (function() { }; /** - * Decodes a WebFeatures message from the specified reader or buffer, length delimited. + * Decodes a UserAgent message from the specified reader or buffer, length delimited. * @function decodeDelimited - * @memberof proto.WebFeatures + * @memberof proto.UserAgent * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.WebFeatures} WebFeatures + * @returns {proto.UserAgent} UserAgent * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - WebFeatures.decodeDelimited = function decodeDelimited(reader) { + UserAgent.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; /** - * Verifies a WebFeatures message. + * Verifies a UserAgent message. * @function verify - * @memberof proto.WebFeatures + * @memberof proto.UserAgent * @static * @param {Object.} message Plain object to verify * @returns {string|null} `null` if valid, otherwise the reason why it is not */ - WebFeatures.verify = function verify(message) { + UserAgent.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.labelsDisplay != null && message.hasOwnProperty("labelsDisplay")) - switch (message.labelsDisplay) { + if (message.platform != null && message.hasOwnProperty("platform")) + switch (message.platform) { default: - return "labelsDisplay: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.voipIndividualOutgoing != null && message.hasOwnProperty("voipIndividualOutgoing")) - switch (message.voipIndividualOutgoing) { - default: - return "voipIndividualOutgoing: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.groupsV3 != null && message.hasOwnProperty("groupsV3")) - switch (message.groupsV3) { - default: - return "groupsV3: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.groupsV3Create != null && message.hasOwnProperty("groupsV3Create")) - switch (message.groupsV3Create) { - default: - return "groupsV3Create: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.changeNumberV2 != null && message.hasOwnProperty("changeNumberV2")) - switch (message.changeNumberV2) { - default: - return "changeNumberV2: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.queryStatusV3Thumbnail != null && message.hasOwnProperty("queryStatusV3Thumbnail")) - switch (message.queryStatusV3Thumbnail) { - default: - return "queryStatusV3Thumbnail: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.liveLocations != null && message.hasOwnProperty("liveLocations")) - switch (message.liveLocations) { - default: - return "liveLocations: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.queryVname != null && message.hasOwnProperty("queryVname")) - switch (message.queryVname) { - default: - return "queryVname: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.voipIndividualIncoming != null && message.hasOwnProperty("voipIndividualIncoming")) - switch (message.voipIndividualIncoming) { - default: - return "voipIndividualIncoming: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.quickRepliesQuery != null && message.hasOwnProperty("quickRepliesQuery")) - switch (message.quickRepliesQuery) { - default: - return "quickRepliesQuery: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.payments != null && message.hasOwnProperty("payments")) - switch (message.payments) { - default: - return "payments: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.stickerPackQuery != null && message.hasOwnProperty("stickerPackQuery")) - switch (message.stickerPackQuery) { - default: - return "stickerPackQuery: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.liveLocationsFinal != null && message.hasOwnProperty("liveLocationsFinal")) - switch (message.liveLocationsFinal) { - default: - return "liveLocationsFinal: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.labelsEdit != null && message.hasOwnProperty("labelsEdit")) - switch (message.labelsEdit) { - default: - return "labelsEdit: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.mediaUpload != null && message.hasOwnProperty("mediaUpload")) - switch (message.mediaUpload) { - default: - return "mediaUpload: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.mediaUploadRichQuickReplies != null && message.hasOwnProperty("mediaUploadRichQuickReplies")) - switch (message.mediaUploadRichQuickReplies) { - default: - return "mediaUploadRichQuickReplies: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.vnameV2 != null && message.hasOwnProperty("vnameV2")) - switch (message.vnameV2) { - default: - return "vnameV2: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.videoPlaybackUrl != null && message.hasOwnProperty("videoPlaybackUrl")) - switch (message.videoPlaybackUrl) { - default: - return "videoPlaybackUrl: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.statusRanking != null && message.hasOwnProperty("statusRanking")) - switch (message.statusRanking) { - default: - return "statusRanking: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.voipIndividualVideo != null && message.hasOwnProperty("voipIndividualVideo")) - switch (message.voipIndividualVideo) { - default: - return "voipIndividualVideo: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.thirdPartyStickers != null && message.hasOwnProperty("thirdPartyStickers")) - switch (message.thirdPartyStickers) { - default: - return "thirdPartyStickers: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.frequentlyForwardedSetting != null && message.hasOwnProperty("frequentlyForwardedSetting")) - switch (message.frequentlyForwardedSetting) { - default: - return "frequentlyForwardedSetting: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.groupsV4JoinPermission != null && message.hasOwnProperty("groupsV4JoinPermission")) - switch (message.groupsV4JoinPermission) { - default: - return "groupsV4JoinPermission: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.recentStickers != null && message.hasOwnProperty("recentStickers")) - switch (message.recentStickers) { - default: - return "recentStickers: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.catalog != null && message.hasOwnProperty("catalog")) - switch (message.catalog) { - default: - return "catalog: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.starredStickers != null && message.hasOwnProperty("starredStickers")) - switch (message.starredStickers) { - default: - return "starredStickers: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.voipGroupCall != null && message.hasOwnProperty("voipGroupCall")) - switch (message.voipGroupCall) { - default: - return "voipGroupCall: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.templateMessage != null && message.hasOwnProperty("templateMessage")) - switch (message.templateMessage) { - default: - return "templateMessage: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.templateMessageInteractivity != null && message.hasOwnProperty("templateMessageInteractivity")) - switch (message.templateMessageInteractivity) { - default: - return "templateMessageInteractivity: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.ephemeralMessages != null && message.hasOwnProperty("ephemeralMessages")) - switch (message.ephemeralMessages) { - default: - return "ephemeralMessages: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.e2ENotificationSync != null && message.hasOwnProperty("e2ENotificationSync")) - switch (message.e2ENotificationSync) { - default: - return "e2ENotificationSync: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.recentStickersV2 != null && message.hasOwnProperty("recentStickersV2")) - switch (message.recentStickersV2) { - default: - return "recentStickersV2: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.syncdRelease1 != null && message.hasOwnProperty("syncdRelease1")) - switch (message.syncdRelease1) { - default: - return "syncdRelease1: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.recentStickersV3 != null && message.hasOwnProperty("recentStickersV3")) - switch (message.recentStickersV3) { - default: - return "recentStickersV3: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.userNotice != null && message.hasOwnProperty("userNotice")) - switch (message.userNotice) { - default: - return "userNotice: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.syncdRelease11 != null && message.hasOwnProperty("syncdRelease11")) - switch (message.syncdRelease11) { - default: - return "syncdRelease11: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.support != null && message.hasOwnProperty("support")) - switch (message.support) { - default: - return "support: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - return null; - }; - - /** - * Creates a WebFeatures message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.WebFeatures - * @static - * @param {Object.} object Plain object - * @returns {proto.WebFeatures} WebFeatures - */ - WebFeatures.fromObject = function fromObject(object) { - if (object instanceof $root.proto.WebFeatures) - return object; - var message = new $root.proto.WebFeatures(); - switch (object.labelsDisplay) { - case "NOT_STARTED": - case 0: - message.labelsDisplay = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.labelsDisplay = 1; - break; - case "DEVELOPMENT": - case 2: - message.labelsDisplay = 2; - break; - case "PRODUCTION": - case 3: - message.labelsDisplay = 3; - break; - } - switch (object.voipIndividualOutgoing) { - case "NOT_STARTED": - case 0: - message.voipIndividualOutgoing = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.voipIndividualOutgoing = 1; - break; - case "DEVELOPMENT": - case 2: - message.voipIndividualOutgoing = 2; - break; - case "PRODUCTION": - case 3: - message.voipIndividualOutgoing = 3; - break; - } - switch (object.groupsV3) { - case "NOT_STARTED": - case 0: - message.groupsV3 = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.groupsV3 = 1; - break; - case "DEVELOPMENT": - case 2: - message.groupsV3 = 2; - break; - case "PRODUCTION": - case 3: - message.groupsV3 = 3; - break; - } - switch (object.groupsV3Create) { - case "NOT_STARTED": - case 0: - message.groupsV3Create = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.groupsV3Create = 1; - break; - case "DEVELOPMENT": - case 2: - message.groupsV3Create = 2; - break; - case "PRODUCTION": - case 3: - message.groupsV3Create = 3; - break; - } - switch (object.changeNumberV2) { - case "NOT_STARTED": - case 0: - message.changeNumberV2 = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.changeNumberV2 = 1; - break; - case "DEVELOPMENT": - case 2: - message.changeNumberV2 = 2; - break; - case "PRODUCTION": - case 3: - message.changeNumberV2 = 3; - break; - } - switch (object.queryStatusV3Thumbnail) { - case "NOT_STARTED": - case 0: - message.queryStatusV3Thumbnail = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.queryStatusV3Thumbnail = 1; - break; - case "DEVELOPMENT": - case 2: - message.queryStatusV3Thumbnail = 2; - break; - case "PRODUCTION": - case 3: - message.queryStatusV3Thumbnail = 3; - break; - } - switch (object.liveLocations) { - case "NOT_STARTED": - case 0: - message.liveLocations = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.liveLocations = 1; - break; - case "DEVELOPMENT": - case 2: - message.liveLocations = 2; - break; - case "PRODUCTION": - case 3: - message.liveLocations = 3; - break; - } - switch (object.queryVname) { - case "NOT_STARTED": - case 0: - message.queryVname = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.queryVname = 1; - break; - case "DEVELOPMENT": - case 2: - message.queryVname = 2; - break; - case "PRODUCTION": - case 3: - message.queryVname = 3; - break; - } - switch (object.voipIndividualIncoming) { - case "NOT_STARTED": - case 0: - message.voipIndividualIncoming = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.voipIndividualIncoming = 1; - break; - case "DEVELOPMENT": - case 2: - message.voipIndividualIncoming = 2; - break; - case "PRODUCTION": - case 3: - message.voipIndividualIncoming = 3; - break; - } - switch (object.quickRepliesQuery) { - case "NOT_STARTED": - case 0: - message.quickRepliesQuery = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.quickRepliesQuery = 1; - break; - case "DEVELOPMENT": - case 2: - message.quickRepliesQuery = 2; - break; - case "PRODUCTION": - case 3: - message.quickRepliesQuery = 3; - break; - } - switch (object.payments) { - case "NOT_STARTED": - case 0: - message.payments = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.payments = 1; - break; - case "DEVELOPMENT": - case 2: - message.payments = 2; - break; - case "PRODUCTION": - case 3: - message.payments = 3; - break; - } - switch (object.stickerPackQuery) { - case "NOT_STARTED": - case 0: - message.stickerPackQuery = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.stickerPackQuery = 1; - break; - case "DEVELOPMENT": - case 2: - message.stickerPackQuery = 2; - break; - case "PRODUCTION": - case 3: - message.stickerPackQuery = 3; - break; - } - switch (object.liveLocationsFinal) { - case "NOT_STARTED": - case 0: - message.liveLocationsFinal = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.liveLocationsFinal = 1; - break; - case "DEVELOPMENT": - case 2: - message.liveLocationsFinal = 2; - break; - case "PRODUCTION": - case 3: - message.liveLocationsFinal = 3; - break; - } - switch (object.labelsEdit) { - case "NOT_STARTED": - case 0: - message.labelsEdit = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.labelsEdit = 1; - break; - case "DEVELOPMENT": - case 2: - message.labelsEdit = 2; - break; - case "PRODUCTION": - case 3: - message.labelsEdit = 3; - break; - } - switch (object.mediaUpload) { - case "NOT_STARTED": - case 0: - message.mediaUpload = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.mediaUpload = 1; - break; - case "DEVELOPMENT": - case 2: - message.mediaUpload = 2; - break; - case "PRODUCTION": - case 3: - message.mediaUpload = 3; - break; - } - switch (object.mediaUploadRichQuickReplies) { - case "NOT_STARTED": - case 0: - message.mediaUploadRichQuickReplies = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.mediaUploadRichQuickReplies = 1; - break; - case "DEVELOPMENT": - case 2: - message.mediaUploadRichQuickReplies = 2; - break; - case "PRODUCTION": - case 3: - message.mediaUploadRichQuickReplies = 3; - break; - } - switch (object.vnameV2) { - case "NOT_STARTED": - case 0: - message.vnameV2 = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.vnameV2 = 1; - break; - case "DEVELOPMENT": - case 2: - message.vnameV2 = 2; - break; - case "PRODUCTION": - case 3: - message.vnameV2 = 3; - break; - } - switch (object.videoPlaybackUrl) { - case "NOT_STARTED": - case 0: - message.videoPlaybackUrl = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.videoPlaybackUrl = 1; - break; - case "DEVELOPMENT": - case 2: - message.videoPlaybackUrl = 2; - break; - case "PRODUCTION": - case 3: - message.videoPlaybackUrl = 3; - break; - } - switch (object.statusRanking) { - case "NOT_STARTED": - case 0: - message.statusRanking = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.statusRanking = 1; - break; - case "DEVELOPMENT": - case 2: - message.statusRanking = 2; - break; - case "PRODUCTION": - case 3: - message.statusRanking = 3; - break; - } - switch (object.voipIndividualVideo) { - case "NOT_STARTED": - case 0: - message.voipIndividualVideo = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.voipIndividualVideo = 1; - break; - case "DEVELOPMENT": - case 2: - message.voipIndividualVideo = 2; - break; - case "PRODUCTION": - case 3: - message.voipIndividualVideo = 3; - break; - } - switch (object.thirdPartyStickers) { - case "NOT_STARTED": - case 0: - message.thirdPartyStickers = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.thirdPartyStickers = 1; - break; - case "DEVELOPMENT": - case 2: - message.thirdPartyStickers = 2; - break; - case "PRODUCTION": - case 3: - message.thirdPartyStickers = 3; - break; - } - switch (object.frequentlyForwardedSetting) { - case "NOT_STARTED": - case 0: - message.frequentlyForwardedSetting = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.frequentlyForwardedSetting = 1; - break; - case "DEVELOPMENT": - case 2: - message.frequentlyForwardedSetting = 2; - break; - case "PRODUCTION": - case 3: - message.frequentlyForwardedSetting = 3; - break; - } - switch (object.groupsV4JoinPermission) { - case "NOT_STARTED": - case 0: - message.groupsV4JoinPermission = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.groupsV4JoinPermission = 1; - break; - case "DEVELOPMENT": - case 2: - message.groupsV4JoinPermission = 2; - break; - case "PRODUCTION": - case 3: - message.groupsV4JoinPermission = 3; - break; - } - switch (object.recentStickers) { - case "NOT_STARTED": - case 0: - message.recentStickers = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.recentStickers = 1; - break; - case "DEVELOPMENT": - case 2: - message.recentStickers = 2; - break; - case "PRODUCTION": - case 3: - message.recentStickers = 3; - break; - } - switch (object.catalog) { - case "NOT_STARTED": - case 0: - message.catalog = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.catalog = 1; - break; - case "DEVELOPMENT": - case 2: - message.catalog = 2; - break; - case "PRODUCTION": - case 3: - message.catalog = 3; - break; - } - switch (object.starredStickers) { - case "NOT_STARTED": - case 0: - message.starredStickers = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.starredStickers = 1; - break; - case "DEVELOPMENT": - case 2: - message.starredStickers = 2; - break; - case "PRODUCTION": - case 3: - message.starredStickers = 3; - break; - } - switch (object.voipGroupCall) { - case "NOT_STARTED": - case 0: - message.voipGroupCall = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.voipGroupCall = 1; - break; - case "DEVELOPMENT": - case 2: - message.voipGroupCall = 2; - break; - case "PRODUCTION": - case 3: - message.voipGroupCall = 3; - break; - } - switch (object.templateMessage) { - case "NOT_STARTED": - case 0: - message.templateMessage = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.templateMessage = 1; - break; - case "DEVELOPMENT": - case 2: - message.templateMessage = 2; - break; - case "PRODUCTION": - case 3: - message.templateMessage = 3; - break; - } - switch (object.templateMessageInteractivity) { - case "NOT_STARTED": - case 0: - message.templateMessageInteractivity = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.templateMessageInteractivity = 1; - break; - case "DEVELOPMENT": - case 2: - message.templateMessageInteractivity = 2; - break; - case "PRODUCTION": - case 3: - message.templateMessageInteractivity = 3; - break; - } - switch (object.ephemeralMessages) { - case "NOT_STARTED": - case 0: - message.ephemeralMessages = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.ephemeralMessages = 1; - break; - case "DEVELOPMENT": - case 2: - message.ephemeralMessages = 2; - break; - case "PRODUCTION": - case 3: - message.ephemeralMessages = 3; - break; - } - switch (object.e2ENotificationSync) { - case "NOT_STARTED": - case 0: - message.e2ENotificationSync = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.e2ENotificationSync = 1; - break; - case "DEVELOPMENT": - case 2: - message.e2ENotificationSync = 2; - break; - case "PRODUCTION": - case 3: - message.e2ENotificationSync = 3; - break; - } - switch (object.recentStickersV2) { - case "NOT_STARTED": - case 0: - message.recentStickersV2 = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.recentStickersV2 = 1; - break; - case "DEVELOPMENT": - case 2: - message.recentStickersV2 = 2; - break; - case "PRODUCTION": - case 3: - message.recentStickersV2 = 3; - break; - } - switch (object.syncdRelease1) { - case "NOT_STARTED": - case 0: - message.syncdRelease1 = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.syncdRelease1 = 1; - break; - case "DEVELOPMENT": - case 2: - message.syncdRelease1 = 2; - break; - case "PRODUCTION": - case 3: - message.syncdRelease1 = 3; - break; - } - switch (object.recentStickersV3) { - case "NOT_STARTED": - case 0: - message.recentStickersV3 = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.recentStickersV3 = 1; - break; - case "DEVELOPMENT": - case 2: - message.recentStickersV3 = 2; - break; - case "PRODUCTION": - case 3: - message.recentStickersV3 = 3; - break; - } - switch (object.userNotice) { - case "NOT_STARTED": - case 0: - message.userNotice = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.userNotice = 1; - break; - case "DEVELOPMENT": - case 2: - message.userNotice = 2; - break; - case "PRODUCTION": - case 3: - message.userNotice = 3; - break; - } - switch (object.syncdRelease11) { - case "NOT_STARTED": - case 0: - message.syncdRelease11 = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.syncdRelease11 = 1; - break; - case "DEVELOPMENT": - case 2: - message.syncdRelease11 = 2; - break; - case "PRODUCTION": - case 3: - message.syncdRelease11 = 3; - break; - } - switch (object.support) { - case "NOT_STARTED": - case 0: - message.support = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.support = 1; - break; - case "DEVELOPMENT": - case 2: - message.support = 2; - break; - case "PRODUCTION": - case 3: - message.support = 3; - break; - } - return message; - }; - - /** - * Creates a plain object from a WebFeatures message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.WebFeatures - * @static - * @param {proto.WebFeatures} message WebFeatures - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - WebFeatures.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.labelsDisplay = options.enums === String ? "NOT_STARTED" : 0; - object.voipIndividualOutgoing = options.enums === String ? "NOT_STARTED" : 0; - object.groupsV3 = options.enums === String ? "NOT_STARTED" : 0; - object.groupsV3Create = options.enums === String ? "NOT_STARTED" : 0; - object.changeNumberV2 = options.enums === String ? "NOT_STARTED" : 0; - object.queryStatusV3Thumbnail = options.enums === String ? "NOT_STARTED" : 0; - object.liveLocations = options.enums === String ? "NOT_STARTED" : 0; - object.queryVname = options.enums === String ? "NOT_STARTED" : 0; - object.voipIndividualIncoming = options.enums === String ? "NOT_STARTED" : 0; - object.quickRepliesQuery = options.enums === String ? "NOT_STARTED" : 0; - object.payments = options.enums === String ? "NOT_STARTED" : 0; - object.stickerPackQuery = options.enums === String ? "NOT_STARTED" : 0; - object.liveLocationsFinal = options.enums === String ? "NOT_STARTED" : 0; - object.labelsEdit = options.enums === String ? "NOT_STARTED" : 0; - object.mediaUpload = options.enums === String ? "NOT_STARTED" : 0; - object.mediaUploadRichQuickReplies = options.enums === String ? "NOT_STARTED" : 0; - object.vnameV2 = options.enums === String ? "NOT_STARTED" : 0; - object.videoPlaybackUrl = options.enums === String ? "NOT_STARTED" : 0; - object.statusRanking = options.enums === String ? "NOT_STARTED" : 0; - object.voipIndividualVideo = options.enums === String ? "NOT_STARTED" : 0; - object.thirdPartyStickers = options.enums === String ? "NOT_STARTED" : 0; - object.frequentlyForwardedSetting = options.enums === String ? "NOT_STARTED" : 0; - object.groupsV4JoinPermission = options.enums === String ? "NOT_STARTED" : 0; - object.recentStickers = options.enums === String ? "NOT_STARTED" : 0; - object.catalog = options.enums === String ? "NOT_STARTED" : 0; - object.starredStickers = options.enums === String ? "NOT_STARTED" : 0; - object.voipGroupCall = options.enums === String ? "NOT_STARTED" : 0; - object.templateMessage = options.enums === String ? "NOT_STARTED" : 0; - object.templateMessageInteractivity = options.enums === String ? "NOT_STARTED" : 0; - object.ephemeralMessages = options.enums === String ? "NOT_STARTED" : 0; - object.e2ENotificationSync = options.enums === String ? "NOT_STARTED" : 0; - object.recentStickersV2 = options.enums === String ? "NOT_STARTED" : 0; - object.syncdRelease1 = options.enums === String ? "NOT_STARTED" : 0; - object.recentStickersV3 = options.enums === String ? "NOT_STARTED" : 0; - object.userNotice = options.enums === String ? "NOT_STARTED" : 0; - object.syncdRelease11 = options.enums === String ? "NOT_STARTED" : 0; - object.support = options.enums === String ? "NOT_STARTED" : 0; - } - if (message.labelsDisplay != null && message.hasOwnProperty("labelsDisplay")) - object.labelsDisplay = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.labelsDisplay] : message.labelsDisplay; - if (message.voipIndividualOutgoing != null && message.hasOwnProperty("voipIndividualOutgoing")) - object.voipIndividualOutgoing = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.voipIndividualOutgoing] : message.voipIndividualOutgoing; - if (message.groupsV3 != null && message.hasOwnProperty("groupsV3")) - object.groupsV3 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupsV3] : message.groupsV3; - if (message.groupsV3Create != null && message.hasOwnProperty("groupsV3Create")) - object.groupsV3Create = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupsV3Create] : message.groupsV3Create; - if (message.changeNumberV2 != null && message.hasOwnProperty("changeNumberV2")) - object.changeNumberV2 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.changeNumberV2] : message.changeNumberV2; - if (message.queryStatusV3Thumbnail != null && message.hasOwnProperty("queryStatusV3Thumbnail")) - object.queryStatusV3Thumbnail = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.queryStatusV3Thumbnail] : message.queryStatusV3Thumbnail; - if (message.liveLocations != null && message.hasOwnProperty("liveLocations")) - object.liveLocations = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.liveLocations] : message.liveLocations; - if (message.queryVname != null && message.hasOwnProperty("queryVname")) - object.queryVname = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.queryVname] : message.queryVname; - if (message.voipIndividualIncoming != null && message.hasOwnProperty("voipIndividualIncoming")) - object.voipIndividualIncoming = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.voipIndividualIncoming] : message.voipIndividualIncoming; - if (message.quickRepliesQuery != null && message.hasOwnProperty("quickRepliesQuery")) - object.quickRepliesQuery = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.quickRepliesQuery] : message.quickRepliesQuery; - if (message.payments != null && message.hasOwnProperty("payments")) - object.payments = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.payments] : message.payments; - if (message.stickerPackQuery != null && message.hasOwnProperty("stickerPackQuery")) - object.stickerPackQuery = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.stickerPackQuery] : message.stickerPackQuery; - if (message.liveLocationsFinal != null && message.hasOwnProperty("liveLocationsFinal")) - object.liveLocationsFinal = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.liveLocationsFinal] : message.liveLocationsFinal; - if (message.labelsEdit != null && message.hasOwnProperty("labelsEdit")) - object.labelsEdit = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.labelsEdit] : message.labelsEdit; - if (message.mediaUpload != null && message.hasOwnProperty("mediaUpload")) - object.mediaUpload = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.mediaUpload] : message.mediaUpload; - if (message.mediaUploadRichQuickReplies != null && message.hasOwnProperty("mediaUploadRichQuickReplies")) - object.mediaUploadRichQuickReplies = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.mediaUploadRichQuickReplies] : message.mediaUploadRichQuickReplies; - if (message.vnameV2 != null && message.hasOwnProperty("vnameV2")) - object.vnameV2 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.vnameV2] : message.vnameV2; - if (message.videoPlaybackUrl != null && message.hasOwnProperty("videoPlaybackUrl")) - object.videoPlaybackUrl = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.videoPlaybackUrl] : message.videoPlaybackUrl; - if (message.statusRanking != null && message.hasOwnProperty("statusRanking")) - object.statusRanking = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.statusRanking] : message.statusRanking; - if (message.voipIndividualVideo != null && message.hasOwnProperty("voipIndividualVideo")) - object.voipIndividualVideo = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.voipIndividualVideo] : message.voipIndividualVideo; - if (message.thirdPartyStickers != null && message.hasOwnProperty("thirdPartyStickers")) - object.thirdPartyStickers = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.thirdPartyStickers] : message.thirdPartyStickers; - if (message.frequentlyForwardedSetting != null && message.hasOwnProperty("frequentlyForwardedSetting")) - object.frequentlyForwardedSetting = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.frequentlyForwardedSetting] : message.frequentlyForwardedSetting; - if (message.groupsV4JoinPermission != null && message.hasOwnProperty("groupsV4JoinPermission")) - object.groupsV4JoinPermission = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupsV4JoinPermission] : message.groupsV4JoinPermission; - if (message.recentStickers != null && message.hasOwnProperty("recentStickers")) - object.recentStickers = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.recentStickers] : message.recentStickers; - if (message.catalog != null && message.hasOwnProperty("catalog")) - object.catalog = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.catalog] : message.catalog; - if (message.starredStickers != null && message.hasOwnProperty("starredStickers")) - object.starredStickers = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.starredStickers] : message.starredStickers; - if (message.voipGroupCall != null && message.hasOwnProperty("voipGroupCall")) - object.voipGroupCall = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.voipGroupCall] : message.voipGroupCall; - if (message.templateMessage != null && message.hasOwnProperty("templateMessage")) - object.templateMessage = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.templateMessage] : message.templateMessage; - if (message.templateMessageInteractivity != null && message.hasOwnProperty("templateMessageInteractivity")) - object.templateMessageInteractivity = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.templateMessageInteractivity] : message.templateMessageInteractivity; - if (message.ephemeralMessages != null && message.hasOwnProperty("ephemeralMessages")) - object.ephemeralMessages = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.ephemeralMessages] : message.ephemeralMessages; - if (message.e2ENotificationSync != null && message.hasOwnProperty("e2ENotificationSync")) - object.e2ENotificationSync = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.e2ENotificationSync] : message.e2ENotificationSync; - if (message.recentStickersV2 != null && message.hasOwnProperty("recentStickersV2")) - object.recentStickersV2 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.recentStickersV2] : message.recentStickersV2; - if (message.syncdRelease1 != null && message.hasOwnProperty("syncdRelease1")) - object.syncdRelease1 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.syncdRelease1] : message.syncdRelease1; - if (message.recentStickersV3 != null && message.hasOwnProperty("recentStickersV3")) - object.recentStickersV3 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.recentStickersV3] : message.recentStickersV3; - if (message.userNotice != null && message.hasOwnProperty("userNotice")) - object.userNotice = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.userNotice] : message.userNotice; - if (message.syncdRelease11 != null && message.hasOwnProperty("syncdRelease11")) - object.syncdRelease11 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.syncdRelease11] : message.syncdRelease11; - if (message.support != null && message.hasOwnProperty("support")) - object.support = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.support] : message.support; - return object; - }; - - /** - * Converts this WebFeatures to JSON. - * @function toJSON - * @memberof proto.WebFeatures - * @instance - * @returns {Object.} JSON object - */ - WebFeatures.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * WebFeaturesFlag enum. - * @name proto.WebFeatures.WebFeaturesFlag - * @enum {number} - * @property {number} NOT_STARTED=0 NOT_STARTED value - * @property {number} FORCE_UPGRADE=1 FORCE_UPGRADE value - * @property {number} DEVELOPMENT=2 DEVELOPMENT value - * @property {number} PRODUCTION=3 PRODUCTION value - */ - WebFeatures.WebFeaturesFlag = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "NOT_STARTED"] = 0; - values[valuesById[1] = "FORCE_UPGRADE"] = 1; - values[valuesById[2] = "DEVELOPMENT"] = 2; - values[valuesById[3] = "PRODUCTION"] = 3; - return values; - })(); - - return WebFeatures; - })(); - - proto.NotificationMessageInfo = (function() { - - /** - * Properties of a NotificationMessageInfo. - * @memberof proto - * @interface INotificationMessageInfo - * @property {proto.IMessageKey|null} [key] NotificationMessageInfo key - * @property {proto.IMessage|null} [message] NotificationMessageInfo message - * @property {number|Long|null} [messageTimestamp] NotificationMessageInfo messageTimestamp - * @property {string|null} [participant] NotificationMessageInfo participant - */ - - /** - * Constructs a new NotificationMessageInfo. - * @memberof proto - * @classdesc Represents a NotificationMessageInfo. - * @implements INotificationMessageInfo - * @constructor - * @param {proto.INotificationMessageInfo=} [properties] Properties to set - */ - function NotificationMessageInfo(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * NotificationMessageInfo key. - * @member {proto.IMessageKey|null|undefined} key - * @memberof proto.NotificationMessageInfo - * @instance - */ - NotificationMessageInfo.prototype.key = null; - - /** - * NotificationMessageInfo message. - * @member {proto.IMessage|null|undefined} message - * @memberof proto.NotificationMessageInfo - * @instance - */ - NotificationMessageInfo.prototype.message = null; - - /** - * NotificationMessageInfo messageTimestamp. - * @member {number|Long} messageTimestamp - * @memberof proto.NotificationMessageInfo - * @instance - */ - NotificationMessageInfo.prototype.messageTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * NotificationMessageInfo participant. - * @member {string} participant - * @memberof proto.NotificationMessageInfo - * @instance - */ - NotificationMessageInfo.prototype.participant = ""; - - /** - * Creates a new NotificationMessageInfo instance using the specified properties. - * @function create - * @memberof proto.NotificationMessageInfo - * @static - * @param {proto.INotificationMessageInfo=} [properties] Properties to set - * @returns {proto.NotificationMessageInfo} NotificationMessageInfo instance - */ - NotificationMessageInfo.create = function create(properties) { - return new NotificationMessageInfo(properties); - }; - - /** - * Encodes the specified NotificationMessageInfo message. Does not implicitly {@link proto.NotificationMessageInfo.verify|verify} messages. - * @function encode - * @memberof proto.NotificationMessageInfo - * @static - * @param {proto.INotificationMessageInfo} message NotificationMessageInfo message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - NotificationMessageInfo.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.key != null && Object.hasOwnProperty.call(message, "key")) - $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.message != null && Object.hasOwnProperty.call(message, "message")) - $root.proto.Message.encode(message.message, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.messageTimestamp != null && Object.hasOwnProperty.call(message, "messageTimestamp")) - writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.messageTimestamp); - if (message.participant != null && Object.hasOwnProperty.call(message, "participant")) - writer.uint32(/* id 4, wireType 2 =*/34).string(message.participant); - return writer; - }; - - /** - * Encodes the specified NotificationMessageInfo message, length delimited. Does not implicitly {@link proto.NotificationMessageInfo.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.NotificationMessageInfo - * @static - * @param {proto.INotificationMessageInfo} message NotificationMessageInfo message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - NotificationMessageInfo.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a NotificationMessageInfo message from the specified reader or buffer. - * @function decode - * @memberof proto.NotificationMessageInfo - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.NotificationMessageInfo} NotificationMessageInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - NotificationMessageInfo.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NotificationMessageInfo(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.key = $root.proto.MessageKey.decode(reader, reader.uint32()); - break; - case 2: - message.message = $root.proto.Message.decode(reader, reader.uint32()); - break; - case 3: - message.messageTimestamp = reader.uint64(); - break; - case 4: - message.participant = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a NotificationMessageInfo message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.NotificationMessageInfo - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.NotificationMessageInfo} NotificationMessageInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - NotificationMessageInfo.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a NotificationMessageInfo message. - * @function verify - * @memberof proto.NotificationMessageInfo - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - NotificationMessageInfo.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.key != null && message.hasOwnProperty("key")) { - var error = $root.proto.MessageKey.verify(message.key); - if (error) - return "key." + error; - } - if (message.message != null && message.hasOwnProperty("message")) { - var error = $root.proto.Message.verify(message.message); - if (error) - return "message." + error; - } - if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) - if (!$util.isInteger(message.messageTimestamp) && !(message.messageTimestamp && $util.isInteger(message.messageTimestamp.low) && $util.isInteger(message.messageTimestamp.high))) - return "messageTimestamp: integer|Long expected"; - if (message.participant != null && message.hasOwnProperty("participant")) - if (!$util.isString(message.participant)) - return "participant: string expected"; - return null; - }; - - /** - * Creates a NotificationMessageInfo message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.NotificationMessageInfo - * @static - * @param {Object.} object Plain object - * @returns {proto.NotificationMessageInfo} NotificationMessageInfo - */ - NotificationMessageInfo.fromObject = function fromObject(object) { - if (object instanceof $root.proto.NotificationMessageInfo) - return object; - var message = new $root.proto.NotificationMessageInfo(); - if (object.key != null) { - if (typeof object.key !== "object") - throw TypeError(".proto.NotificationMessageInfo.key: object expected"); - message.key = $root.proto.MessageKey.fromObject(object.key); - } - if (object.message != null) { - if (typeof object.message !== "object") - throw TypeError(".proto.NotificationMessageInfo.message: object expected"); - message.message = $root.proto.Message.fromObject(object.message); - } - if (object.messageTimestamp != null) - if ($util.Long) - (message.messageTimestamp = $util.Long.fromValue(object.messageTimestamp)).unsigned = true; - else if (typeof object.messageTimestamp === "string") - message.messageTimestamp = parseInt(object.messageTimestamp, 10); - else if (typeof object.messageTimestamp === "number") - message.messageTimestamp = object.messageTimestamp; - else if (typeof object.messageTimestamp === "object") - message.messageTimestamp = new $util.LongBits(object.messageTimestamp.low >>> 0, object.messageTimestamp.high >>> 0).toNumber(true); - if (object.participant != null) - message.participant = String(object.participant); - return message; - }; - - /** - * Creates a plain object from a NotificationMessageInfo message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.NotificationMessageInfo - * @static - * @param {proto.NotificationMessageInfo} message NotificationMessageInfo - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - NotificationMessageInfo.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.key = null; - object.message = null; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.messageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.messageTimestamp = options.longs === String ? "0" : 0; - object.participant = ""; - } - if (message.key != null && message.hasOwnProperty("key")) - object.key = $root.proto.MessageKey.toObject(message.key, options); - if (message.message != null && message.hasOwnProperty("message")) - object.message = $root.proto.Message.toObject(message.message, options); - if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) - if (typeof message.messageTimestamp === "number") - object.messageTimestamp = options.longs === String ? String(message.messageTimestamp) : message.messageTimestamp; - else - object.messageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.messageTimestamp) : options.longs === Number ? new $util.LongBits(message.messageTimestamp.low >>> 0, message.messageTimestamp.high >>> 0).toNumber(true) : message.messageTimestamp; - if (message.participant != null && message.hasOwnProperty("participant")) - object.participant = message.participant; - return object; - }; - - /** - * Converts this NotificationMessageInfo to JSON. - * @function toJSON - * @memberof proto.NotificationMessageInfo - * @instance - * @returns {Object.} JSON object - */ - NotificationMessageInfo.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return NotificationMessageInfo; - })(); - - proto.WebNotificationsInfo = (function() { - - /** - * Properties of a WebNotificationsInfo. - * @memberof proto - * @interface IWebNotificationsInfo - * @property {number|Long|null} [timestamp] WebNotificationsInfo timestamp - * @property {number|null} [unreadChats] WebNotificationsInfo unreadChats - * @property {number|null} [notifyMessageCount] WebNotificationsInfo notifyMessageCount - * @property {Array.|null} [notifyMessages] WebNotificationsInfo notifyMessages - */ - - /** - * Constructs a new WebNotificationsInfo. - * @memberof proto - * @classdesc Represents a WebNotificationsInfo. - * @implements IWebNotificationsInfo - * @constructor - * @param {proto.IWebNotificationsInfo=} [properties] Properties to set - */ - function WebNotificationsInfo(properties) { - this.notifyMessages = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * WebNotificationsInfo timestamp. - * @member {number|Long} timestamp - * @memberof proto.WebNotificationsInfo - * @instance - */ - WebNotificationsInfo.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * WebNotificationsInfo unreadChats. - * @member {number} unreadChats - * @memberof proto.WebNotificationsInfo - * @instance - */ - WebNotificationsInfo.prototype.unreadChats = 0; - - /** - * WebNotificationsInfo notifyMessageCount. - * @member {number} notifyMessageCount - * @memberof proto.WebNotificationsInfo - * @instance - */ - WebNotificationsInfo.prototype.notifyMessageCount = 0; - - /** - * WebNotificationsInfo notifyMessages. - * @member {Array.} notifyMessages - * @memberof proto.WebNotificationsInfo - * @instance - */ - WebNotificationsInfo.prototype.notifyMessages = $util.emptyArray; - - /** - * Creates a new WebNotificationsInfo instance using the specified properties. - * @function create - * @memberof proto.WebNotificationsInfo - * @static - * @param {proto.IWebNotificationsInfo=} [properties] Properties to set - * @returns {proto.WebNotificationsInfo} WebNotificationsInfo instance - */ - WebNotificationsInfo.create = function create(properties) { - return new WebNotificationsInfo(properties); - }; - - /** - * Encodes the specified WebNotificationsInfo message. Does not implicitly {@link proto.WebNotificationsInfo.verify|verify} messages. - * @function encode - * @memberof proto.WebNotificationsInfo - * @static - * @param {proto.IWebNotificationsInfo} message WebNotificationsInfo message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - WebNotificationsInfo.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) - writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.timestamp); - if (message.unreadChats != null && Object.hasOwnProperty.call(message, "unreadChats")) - writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.unreadChats); - if (message.notifyMessageCount != null && Object.hasOwnProperty.call(message, "notifyMessageCount")) - writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.notifyMessageCount); - if (message.notifyMessages != null && message.notifyMessages.length) - for (var i = 0; i < message.notifyMessages.length; ++i) - $root.proto.WebMessageInfo.encode(message.notifyMessages[i], writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified WebNotificationsInfo message, length delimited. Does not implicitly {@link proto.WebNotificationsInfo.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.WebNotificationsInfo - * @static - * @param {proto.IWebNotificationsInfo} message WebNotificationsInfo message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - WebNotificationsInfo.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a WebNotificationsInfo message from the specified reader or buffer. - * @function decode - * @memberof proto.WebNotificationsInfo - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.WebNotificationsInfo} WebNotificationsInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - WebNotificationsInfo.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebNotificationsInfo(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 2: - message.timestamp = reader.uint64(); - break; - case 3: - message.unreadChats = reader.uint32(); - break; - case 4: - message.notifyMessageCount = reader.uint32(); - break; - case 5: - if (!(message.notifyMessages && message.notifyMessages.length)) - message.notifyMessages = []; - message.notifyMessages.push($root.proto.WebMessageInfo.decode(reader, reader.uint32())); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a WebNotificationsInfo message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.WebNotificationsInfo - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.WebNotificationsInfo} WebNotificationsInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - WebNotificationsInfo.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a WebNotificationsInfo message. - * @function verify - * @memberof proto.WebNotificationsInfo - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - WebNotificationsInfo.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.timestamp != null && message.hasOwnProperty("timestamp")) - if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) - return "timestamp: integer|Long expected"; - if (message.unreadChats != null && message.hasOwnProperty("unreadChats")) - if (!$util.isInteger(message.unreadChats)) - return "unreadChats: integer expected"; - if (message.notifyMessageCount != null && message.hasOwnProperty("notifyMessageCount")) - if (!$util.isInteger(message.notifyMessageCount)) - return "notifyMessageCount: integer expected"; - if (message.notifyMessages != null && message.hasOwnProperty("notifyMessages")) { - if (!Array.isArray(message.notifyMessages)) - return "notifyMessages: array expected"; - for (var i = 0; i < message.notifyMessages.length; ++i) { - var error = $root.proto.WebMessageInfo.verify(message.notifyMessages[i]); - if (error) - return "notifyMessages." + error; - } - } - return null; - }; - - /** - * Creates a WebNotificationsInfo message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.WebNotificationsInfo - * @static - * @param {Object.} object Plain object - * @returns {proto.WebNotificationsInfo} WebNotificationsInfo - */ - WebNotificationsInfo.fromObject = function fromObject(object) { - if (object instanceof $root.proto.WebNotificationsInfo) - return object; - var message = new $root.proto.WebNotificationsInfo(); - if (object.timestamp != null) - if ($util.Long) - (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = true; - else if (typeof object.timestamp === "string") - message.timestamp = parseInt(object.timestamp, 10); - else if (typeof object.timestamp === "number") - message.timestamp = object.timestamp; - else if (typeof object.timestamp === "object") - message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(true); - if (object.unreadChats != null) - message.unreadChats = object.unreadChats >>> 0; - if (object.notifyMessageCount != null) - message.notifyMessageCount = object.notifyMessageCount >>> 0; - if (object.notifyMessages) { - if (!Array.isArray(object.notifyMessages)) - throw TypeError(".proto.WebNotificationsInfo.notifyMessages: array expected"); - message.notifyMessages = []; - for (var i = 0; i < object.notifyMessages.length; ++i) { - if (typeof object.notifyMessages[i] !== "object") - throw TypeError(".proto.WebNotificationsInfo.notifyMessages: object expected"); - message.notifyMessages[i] = $root.proto.WebMessageInfo.fromObject(object.notifyMessages[i]); - } - } - return message; - }; - - /** - * Creates a plain object from a WebNotificationsInfo message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.WebNotificationsInfo - * @static - * @param {proto.WebNotificationsInfo} message WebNotificationsInfo - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - WebNotificationsInfo.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.notifyMessages = []; - if (options.defaults) { - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.timestamp = options.longs === String ? "0" : 0; - object.unreadChats = 0; - object.notifyMessageCount = 0; - } - if (message.timestamp != null && message.hasOwnProperty("timestamp")) - if (typeof message.timestamp === "number") - object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; - else - object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber(true) : message.timestamp; - if (message.unreadChats != null && message.hasOwnProperty("unreadChats")) - object.unreadChats = message.unreadChats; - if (message.notifyMessageCount != null && message.hasOwnProperty("notifyMessageCount")) - object.notifyMessageCount = message.notifyMessageCount; - if (message.notifyMessages && message.notifyMessages.length) { - object.notifyMessages = []; - for (var j = 0; j < message.notifyMessages.length; ++j) - object.notifyMessages[j] = $root.proto.WebMessageInfo.toObject(message.notifyMessages[j], options); - } - return object; - }; - - /** - * Converts this WebNotificationsInfo to JSON. - * @function toJSON - * @memberof proto.WebNotificationsInfo - * @instance - * @returns {Object.} JSON object - */ - WebNotificationsInfo.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return WebNotificationsInfo; - })(); - - proto.PaymentInfo = (function() { - - /** - * Properties of a PaymentInfo. - * @memberof proto - * @interface IPaymentInfo - * @property {proto.PaymentInfo.PaymentInfoCurrency|null} [currencyDeprecated] PaymentInfo currencyDeprecated - * @property {number|Long|null} [amount1000] PaymentInfo amount1000 - * @property {string|null} [receiverJid] PaymentInfo receiverJid - * @property {proto.PaymentInfo.PaymentInfoStatus|null} [status] PaymentInfo status - * @property {number|Long|null} [transactionTimestamp] PaymentInfo transactionTimestamp - * @property {proto.IMessageKey|null} [requestMessageKey] PaymentInfo requestMessageKey - * @property {number|Long|null} [expiryTimestamp] PaymentInfo expiryTimestamp - * @property {boolean|null} [futureproofed] PaymentInfo futureproofed - * @property {string|null} [currency] PaymentInfo currency - * @property {proto.PaymentInfo.PaymentInfoTxnStatus|null} [txnStatus] PaymentInfo txnStatus - */ - - /** - * Constructs a new PaymentInfo. - * @memberof proto - * @classdesc Represents a PaymentInfo. - * @implements IPaymentInfo - * @constructor - * @param {proto.IPaymentInfo=} [properties] Properties to set - */ - function PaymentInfo(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * PaymentInfo currencyDeprecated. - * @member {proto.PaymentInfo.PaymentInfoCurrency} currencyDeprecated - * @memberof proto.PaymentInfo - * @instance - */ - PaymentInfo.prototype.currencyDeprecated = 0; - - /** - * PaymentInfo amount1000. - * @member {number|Long} amount1000 - * @memberof proto.PaymentInfo - * @instance - */ - PaymentInfo.prototype.amount1000 = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * PaymentInfo receiverJid. - * @member {string} receiverJid - * @memberof proto.PaymentInfo - * @instance - */ - PaymentInfo.prototype.receiverJid = ""; - - /** - * PaymentInfo status. - * @member {proto.PaymentInfo.PaymentInfoStatus} status - * @memberof proto.PaymentInfo - * @instance - */ - PaymentInfo.prototype.status = 0; - - /** - * PaymentInfo transactionTimestamp. - * @member {number|Long} transactionTimestamp - * @memberof proto.PaymentInfo - * @instance - */ - PaymentInfo.prototype.transactionTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * PaymentInfo requestMessageKey. - * @member {proto.IMessageKey|null|undefined} requestMessageKey - * @memberof proto.PaymentInfo - * @instance - */ - PaymentInfo.prototype.requestMessageKey = null; - - /** - * PaymentInfo expiryTimestamp. - * @member {number|Long} expiryTimestamp - * @memberof proto.PaymentInfo - * @instance - */ - PaymentInfo.prototype.expiryTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * PaymentInfo futureproofed. - * @member {boolean} futureproofed - * @memberof proto.PaymentInfo - * @instance - */ - PaymentInfo.prototype.futureproofed = false; - - /** - * PaymentInfo currency. - * @member {string} currency - * @memberof proto.PaymentInfo - * @instance - */ - PaymentInfo.prototype.currency = ""; - - /** - * PaymentInfo txnStatus. - * @member {proto.PaymentInfo.PaymentInfoTxnStatus} txnStatus - * @memberof proto.PaymentInfo - * @instance - */ - PaymentInfo.prototype.txnStatus = 0; - - /** - * Creates a new PaymentInfo instance using the specified properties. - * @function create - * @memberof proto.PaymentInfo - * @static - * @param {proto.IPaymentInfo=} [properties] Properties to set - * @returns {proto.PaymentInfo} PaymentInfo instance - */ - PaymentInfo.create = function create(properties) { - return new PaymentInfo(properties); - }; - - /** - * Encodes the specified PaymentInfo message. Does not implicitly {@link proto.PaymentInfo.verify|verify} messages. - * @function encode - * @memberof proto.PaymentInfo - * @static - * @param {proto.IPaymentInfo} message PaymentInfo message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - PaymentInfo.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.currencyDeprecated != null && Object.hasOwnProperty.call(message, "currencyDeprecated")) - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.currencyDeprecated); - if (message.amount1000 != null && Object.hasOwnProperty.call(message, "amount1000")) - writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.amount1000); - if (message.receiverJid != null && Object.hasOwnProperty.call(message, "receiverJid")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.receiverJid); - if (message.status != null && Object.hasOwnProperty.call(message, "status")) - writer.uint32(/* id 4, wireType 0 =*/32).int32(message.status); - if (message.transactionTimestamp != null && Object.hasOwnProperty.call(message, "transactionTimestamp")) - writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.transactionTimestamp); - if (message.requestMessageKey != null && Object.hasOwnProperty.call(message, "requestMessageKey")) - $root.proto.MessageKey.encode(message.requestMessageKey, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); - if (message.expiryTimestamp != null && Object.hasOwnProperty.call(message, "expiryTimestamp")) - writer.uint32(/* id 7, wireType 0 =*/56).uint64(message.expiryTimestamp); - if (message.futureproofed != null && Object.hasOwnProperty.call(message, "futureproofed")) - writer.uint32(/* id 8, wireType 0 =*/64).bool(message.futureproofed); - if (message.currency != null && Object.hasOwnProperty.call(message, "currency")) - writer.uint32(/* id 9, wireType 2 =*/74).string(message.currency); - if (message.txnStatus != null && Object.hasOwnProperty.call(message, "txnStatus")) - writer.uint32(/* id 10, wireType 0 =*/80).int32(message.txnStatus); - return writer; - }; - - /** - * Encodes the specified PaymentInfo message, length delimited. Does not implicitly {@link proto.PaymentInfo.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.PaymentInfo - * @static - * @param {proto.IPaymentInfo} message PaymentInfo message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - PaymentInfo.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a PaymentInfo message from the specified reader or buffer. - * @function decode - * @memberof proto.PaymentInfo - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.PaymentInfo} PaymentInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - PaymentInfo.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentInfo(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.currencyDeprecated = reader.int32(); - break; - case 2: - message.amount1000 = reader.uint64(); - break; - case 3: - message.receiverJid = reader.string(); - break; - case 4: - message.status = reader.int32(); - break; - case 5: - message.transactionTimestamp = reader.uint64(); - break; - case 6: - message.requestMessageKey = $root.proto.MessageKey.decode(reader, reader.uint32()); - break; - case 7: - message.expiryTimestamp = reader.uint64(); - break; - case 8: - message.futureproofed = reader.bool(); - break; - case 9: - message.currency = reader.string(); - break; - case 10: - message.txnStatus = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a PaymentInfo message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.PaymentInfo - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.PaymentInfo} PaymentInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - PaymentInfo.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a PaymentInfo message. - * @function verify - * @memberof proto.PaymentInfo - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - PaymentInfo.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.currencyDeprecated != null && message.hasOwnProperty("currencyDeprecated")) - switch (message.currencyDeprecated) { - default: - return "currencyDeprecated: enum value expected"; - case 0: - case 1: - break; - } - if (message.amount1000 != null && message.hasOwnProperty("amount1000")) - if (!$util.isInteger(message.amount1000) && !(message.amount1000 && $util.isInteger(message.amount1000.low) && $util.isInteger(message.amount1000.high))) - return "amount1000: integer|Long expected"; - if (message.receiverJid != null && message.hasOwnProperty("receiverJid")) - if (!$util.isString(message.receiverJid)) - return "receiverJid: string expected"; - if (message.status != null && message.hasOwnProperty("status")) - switch (message.status) { - default: - return "status: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - break; - } - if (message.transactionTimestamp != null && message.hasOwnProperty("transactionTimestamp")) - if (!$util.isInteger(message.transactionTimestamp) && !(message.transactionTimestamp && $util.isInteger(message.transactionTimestamp.low) && $util.isInteger(message.transactionTimestamp.high))) - return "transactionTimestamp: integer|Long expected"; - if (message.requestMessageKey != null && message.hasOwnProperty("requestMessageKey")) { - var error = $root.proto.MessageKey.verify(message.requestMessageKey); - if (error) - return "requestMessageKey." + error; - } - if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp")) - if (!$util.isInteger(message.expiryTimestamp) && !(message.expiryTimestamp && $util.isInteger(message.expiryTimestamp.low) && $util.isInteger(message.expiryTimestamp.high))) - return "expiryTimestamp: integer|Long expected"; - if (message.futureproofed != null && message.hasOwnProperty("futureproofed")) - if (typeof message.futureproofed !== "boolean") - return "futureproofed: boolean expected"; - if (message.currency != null && message.hasOwnProperty("currency")) - if (!$util.isString(message.currency)) - return "currency: string expected"; - if (message.txnStatus != null && message.hasOwnProperty("txnStatus")) - switch (message.txnStatus) { - default: - return "txnStatus: enum value expected"; + return "platform: enum value expected"; case 0: case 1: case 2: @@ -2770,483 +622,399 @@ $root.proto = (function() { case 23: case 24: case 25: - case 26: - case 27: break; } + if (message.appVersion != null && message.hasOwnProperty("appVersion")) { + var error = $root.proto.AppVersion.verify(message.appVersion); + if (error) + return "appVersion." + error; + } + if (message.mcc != null && message.hasOwnProperty("mcc")) + if (!$util.isString(message.mcc)) + return "mcc: string expected"; + if (message.mnc != null && message.hasOwnProperty("mnc")) + if (!$util.isString(message.mnc)) + return "mnc: string expected"; + if (message.osVersion != null && message.hasOwnProperty("osVersion")) + if (!$util.isString(message.osVersion)) + return "osVersion: string expected"; + if (message.manufacturer != null && message.hasOwnProperty("manufacturer")) + if (!$util.isString(message.manufacturer)) + return "manufacturer: string expected"; + if (message.device != null && message.hasOwnProperty("device")) + if (!$util.isString(message.device)) + return "device: string expected"; + if (message.osBuildNumber != null && message.hasOwnProperty("osBuildNumber")) + if (!$util.isString(message.osBuildNumber)) + return "osBuildNumber: string expected"; + if (message.phoneId != null && message.hasOwnProperty("phoneId")) + if (!$util.isString(message.phoneId)) + return "phoneId: string expected"; + if (message.releaseChannel != null && message.hasOwnProperty("releaseChannel")) + switch (message.releaseChannel) { + default: + return "releaseChannel: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.localeLanguageIso6391 != null && message.hasOwnProperty("localeLanguageIso6391")) + if (!$util.isString(message.localeLanguageIso6391)) + return "localeLanguageIso6391: string expected"; + if (message.localeCountryIso31661Alpha2 != null && message.hasOwnProperty("localeCountryIso31661Alpha2")) + if (!$util.isString(message.localeCountryIso31661Alpha2)) + return "localeCountryIso31661Alpha2: string expected"; + if (message.deviceBoard != null && message.hasOwnProperty("deviceBoard")) + if (!$util.isString(message.deviceBoard)) + return "deviceBoard: string expected"; return null; }; /** - * Creates a PaymentInfo message from a plain object. Also converts values to their respective internal types. + * Creates a UserAgent message from a plain object. Also converts values to their respective internal types. * @function fromObject - * @memberof proto.PaymentInfo + * @memberof proto.UserAgent * @static * @param {Object.} object Plain object - * @returns {proto.PaymentInfo} PaymentInfo + * @returns {proto.UserAgent} UserAgent */ - PaymentInfo.fromObject = function fromObject(object) { - if (object instanceof $root.proto.PaymentInfo) + UserAgent.fromObject = function fromObject(object) { + if (object instanceof $root.proto.UserAgent) return object; - var message = new $root.proto.PaymentInfo(); - switch (object.currencyDeprecated) { - case "UNKNOWN_CURRENCY": + var message = new $root.proto.UserAgent(); + switch (object.platform) { + case "ANDROID": case 0: - message.currencyDeprecated = 0; + message.platform = 0; break; - case "INR": + case "IOS": case 1: - message.currencyDeprecated = 1; + message.platform = 1; break; - } - if (object.amount1000 != null) - if ($util.Long) - (message.amount1000 = $util.Long.fromValue(object.amount1000)).unsigned = true; - else if (typeof object.amount1000 === "string") - message.amount1000 = parseInt(object.amount1000, 10); - else if (typeof object.amount1000 === "number") - message.amount1000 = object.amount1000; - else if (typeof object.amount1000 === "object") - message.amount1000 = new $util.LongBits(object.amount1000.low >>> 0, object.amount1000.high >>> 0).toNumber(true); - if (object.receiverJid != null) - message.receiverJid = String(object.receiverJid); - switch (object.status) { - case "UNKNOWN_STATUS": - case 0: - message.status = 0; - break; - case "PROCESSING": - case 1: - message.status = 1; - break; - case "SENT": + case "WINDOWS_PHONE": case 2: - message.status = 2; + message.platform = 2; break; - case "NEED_TO_ACCEPT": + case "BLACKBERRY": case 3: - message.status = 3; + message.platform = 3; break; - case "COMPLETE": + case "BLACKBERRYX": case 4: - message.status = 4; + message.platform = 4; break; - case "COULD_NOT_COMPLETE": + case "S40": case 5: - message.status = 5; + message.platform = 5; break; - case "REFUNDED": + case "S60": case 6: - message.status = 6; + message.platform = 6; break; - case "EXPIRED": + case "PYTHON_CLIENT": case 7: - message.status = 7; + message.platform = 7; break; - case "REJECTED": + case "TIZEN": case 8: - message.status = 8; + message.platform = 8; break; - case "CANCELLED": + case "ENTERPRISE": case 9: - message.status = 9; + message.platform = 9; break; - case "WAITING_FOR_PAYER": + case "SMB_ANDROID": case 10: - message.status = 10; + message.platform = 10; break; - case "WAITING": + case "KAIOS": case 11: - message.status = 11; + message.platform = 11; break; - } - if (object.transactionTimestamp != null) - if ($util.Long) - (message.transactionTimestamp = $util.Long.fromValue(object.transactionTimestamp)).unsigned = true; - else if (typeof object.transactionTimestamp === "string") - message.transactionTimestamp = parseInt(object.transactionTimestamp, 10); - else if (typeof object.transactionTimestamp === "number") - message.transactionTimestamp = object.transactionTimestamp; - else if (typeof object.transactionTimestamp === "object") - message.transactionTimestamp = new $util.LongBits(object.transactionTimestamp.low >>> 0, object.transactionTimestamp.high >>> 0).toNumber(true); - if (object.requestMessageKey != null) { - if (typeof object.requestMessageKey !== "object") - throw TypeError(".proto.PaymentInfo.requestMessageKey: object expected"); - message.requestMessageKey = $root.proto.MessageKey.fromObject(object.requestMessageKey); - } - if (object.expiryTimestamp != null) - if ($util.Long) - (message.expiryTimestamp = $util.Long.fromValue(object.expiryTimestamp)).unsigned = true; - else if (typeof object.expiryTimestamp === "string") - message.expiryTimestamp = parseInt(object.expiryTimestamp, 10); - else if (typeof object.expiryTimestamp === "number") - message.expiryTimestamp = object.expiryTimestamp; - else if (typeof object.expiryTimestamp === "object") - message.expiryTimestamp = new $util.LongBits(object.expiryTimestamp.low >>> 0, object.expiryTimestamp.high >>> 0).toNumber(true); - if (object.futureproofed != null) - message.futureproofed = Boolean(object.futureproofed); - if (object.currency != null) - message.currency = String(object.currency); - switch (object.txnStatus) { - case "UNKNOWN": - case 0: - message.txnStatus = 0; - break; - case "PENDING_SETUP": - case 1: - message.txnStatus = 1; - break; - case "PENDING_RECEIVER_SETUP": - case 2: - message.txnStatus = 2; - break; - case "INIT": - case 3: - message.txnStatus = 3; - break; - case "SUCCESS": - case 4: - message.txnStatus = 4; - break; - case "COMPLETED": - case 5: - message.txnStatus = 5; - break; - case "FAILED": - case 6: - message.txnStatus = 6; - break; - case "FAILED_RISK": - case 7: - message.txnStatus = 7; - break; - case "FAILED_PROCESSING": - case 8: - message.txnStatus = 8; - break; - case "FAILED_RECEIVER_PROCESSING": - case 9: - message.txnStatus = 9; - break; - case "FAILED_DA": - case 10: - message.txnStatus = 10; - break; - case "FAILED_DA_FINAL": - case 11: - message.txnStatus = 11; - break; - case "REFUNDED_TXN": + case "SMB_IOS": case 12: - message.txnStatus = 12; + message.platform = 12; break; - case "REFUND_FAILED": + case "WINDOWS": case 13: - message.txnStatus = 13; + message.platform = 13; break; - case "REFUND_FAILED_PROCESSING": + case "WEB": case 14: - message.txnStatus = 14; + message.platform = 14; break; - case "REFUND_FAILED_DA": + case "PORTAL": case 15: - message.txnStatus = 15; + message.platform = 15; break; - case "EXPIRED_TXN": + case "GREEN_ANDROID": case 16: - message.txnStatus = 16; + message.platform = 16; break; - case "AUTH_CANCELED": + case "GREEN_IPHONE": case 17: - message.txnStatus = 17; + message.platform = 17; break; - case "AUTH_CANCEL_FAILED_PROCESSING": + case "BLUE_ANDROID": case 18: - message.txnStatus = 18; + message.platform = 18; break; - case "AUTH_CANCEL_FAILED": + case "BLUE_IPHONE": case 19: - message.txnStatus = 19; + message.platform = 19; break; - case "COLLECT_INIT": + case "FBLITE_ANDROID": case 20: - message.txnStatus = 20; + message.platform = 20; break; - case "COLLECT_SUCCESS": + case "MLITE_ANDROID": case 21: - message.txnStatus = 21; + message.platform = 21; break; - case "COLLECT_FAILED": + case "IGLITE_ANDROID": case 22: - message.txnStatus = 22; + message.platform = 22; break; - case "COLLECT_FAILED_RISK": + case "PAGE": case 23: - message.txnStatus = 23; + message.platform = 23; break; - case "COLLECT_REJECTED": + case "MACOS": case 24: - message.txnStatus = 24; + message.platform = 24; break; - case "COLLECT_EXPIRED": + case "VR": case 25: - message.txnStatus = 25; - break; - case "COLLECT_CANCELED": - case 26: - message.txnStatus = 26; - break; - case "COLLECT_CANCELLING": - case 27: - message.txnStatus = 27; + message.platform = 25; break; } + if (object.appVersion != null) { + if (typeof object.appVersion !== "object") + throw TypeError(".proto.UserAgent.appVersion: object expected"); + message.appVersion = $root.proto.AppVersion.fromObject(object.appVersion); + } + if (object.mcc != null) + message.mcc = String(object.mcc); + if (object.mnc != null) + message.mnc = String(object.mnc); + if (object.osVersion != null) + message.osVersion = String(object.osVersion); + if (object.manufacturer != null) + message.manufacturer = String(object.manufacturer); + if (object.device != null) + message.device = String(object.device); + if (object.osBuildNumber != null) + message.osBuildNumber = String(object.osBuildNumber); + if (object.phoneId != null) + message.phoneId = String(object.phoneId); + switch (object.releaseChannel) { + case "RELEASE": + case 0: + message.releaseChannel = 0; + break; + case "BETA": + case 1: + message.releaseChannel = 1; + break; + case "ALPHA": + case 2: + message.releaseChannel = 2; + break; + case "DEBUG": + case 3: + message.releaseChannel = 3; + break; + } + if (object.localeLanguageIso6391 != null) + message.localeLanguageIso6391 = String(object.localeLanguageIso6391); + if (object.localeCountryIso31661Alpha2 != null) + message.localeCountryIso31661Alpha2 = String(object.localeCountryIso31661Alpha2); + if (object.deviceBoard != null) + message.deviceBoard = String(object.deviceBoard); return message; }; /** - * Creates a plain object from a PaymentInfo message. Also converts values to other types if specified. + * Creates a plain object from a UserAgent message. Also converts values to other types if specified. * @function toObject - * @memberof proto.PaymentInfo + * @memberof proto.UserAgent * @static - * @param {proto.PaymentInfo} message PaymentInfo + * @param {proto.UserAgent} message UserAgent * @param {$protobuf.IConversionOptions} [options] Conversion options * @returns {Object.} Plain object */ - PaymentInfo.toObject = function toObject(message, options) { + UserAgent.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { - object.currencyDeprecated = options.enums === String ? "UNKNOWN_CURRENCY" : 0; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.amount1000 = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.amount1000 = options.longs === String ? "0" : 0; - object.receiverJid = ""; - object.status = options.enums === String ? "UNKNOWN_STATUS" : 0; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.transactionTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.transactionTimestamp = options.longs === String ? "0" : 0; - object.requestMessageKey = null; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.expiryTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.expiryTimestamp = options.longs === String ? "0" : 0; - object.futureproofed = false; - object.currency = ""; - object.txnStatus = options.enums === String ? "UNKNOWN" : 0; + object.platform = options.enums === String ? "ANDROID" : 0; + object.appVersion = null; + object.mcc = ""; + object.mnc = ""; + object.osVersion = ""; + object.manufacturer = ""; + object.device = ""; + object.osBuildNumber = ""; + object.phoneId = ""; + object.releaseChannel = options.enums === String ? "RELEASE" : 0; + object.localeLanguageIso6391 = ""; + object.localeCountryIso31661Alpha2 = ""; + object.deviceBoard = ""; } - if (message.currencyDeprecated != null && message.hasOwnProperty("currencyDeprecated")) - object.currencyDeprecated = options.enums === String ? $root.proto.PaymentInfo.PaymentInfoCurrency[message.currencyDeprecated] : message.currencyDeprecated; - if (message.amount1000 != null && message.hasOwnProperty("amount1000")) - if (typeof message.amount1000 === "number") - object.amount1000 = options.longs === String ? String(message.amount1000) : message.amount1000; - else - object.amount1000 = options.longs === String ? $util.Long.prototype.toString.call(message.amount1000) : options.longs === Number ? new $util.LongBits(message.amount1000.low >>> 0, message.amount1000.high >>> 0).toNumber(true) : message.amount1000; - if (message.receiverJid != null && message.hasOwnProperty("receiverJid")) - object.receiverJid = message.receiverJid; - if (message.status != null && message.hasOwnProperty("status")) - object.status = options.enums === String ? $root.proto.PaymentInfo.PaymentInfoStatus[message.status] : message.status; - if (message.transactionTimestamp != null && message.hasOwnProperty("transactionTimestamp")) - if (typeof message.transactionTimestamp === "number") - object.transactionTimestamp = options.longs === String ? String(message.transactionTimestamp) : message.transactionTimestamp; - else - object.transactionTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.transactionTimestamp) : options.longs === Number ? new $util.LongBits(message.transactionTimestamp.low >>> 0, message.transactionTimestamp.high >>> 0).toNumber(true) : message.transactionTimestamp; - if (message.requestMessageKey != null && message.hasOwnProperty("requestMessageKey")) - object.requestMessageKey = $root.proto.MessageKey.toObject(message.requestMessageKey, options); - if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp")) - if (typeof message.expiryTimestamp === "number") - object.expiryTimestamp = options.longs === String ? String(message.expiryTimestamp) : message.expiryTimestamp; - else - object.expiryTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.expiryTimestamp) : options.longs === Number ? new $util.LongBits(message.expiryTimestamp.low >>> 0, message.expiryTimestamp.high >>> 0).toNumber(true) : message.expiryTimestamp; - if (message.futureproofed != null && message.hasOwnProperty("futureproofed")) - object.futureproofed = message.futureproofed; - if (message.currency != null && message.hasOwnProperty("currency")) - object.currency = message.currency; - if (message.txnStatus != null && message.hasOwnProperty("txnStatus")) - object.txnStatus = options.enums === String ? $root.proto.PaymentInfo.PaymentInfoTxnStatus[message.txnStatus] : message.txnStatus; + if (message.platform != null && message.hasOwnProperty("platform")) + object.platform = options.enums === String ? $root.proto.UserAgent.UserAgentPlatform[message.platform] : message.platform; + if (message.appVersion != null && message.hasOwnProperty("appVersion")) + object.appVersion = $root.proto.AppVersion.toObject(message.appVersion, options); + if (message.mcc != null && message.hasOwnProperty("mcc")) + object.mcc = message.mcc; + if (message.mnc != null && message.hasOwnProperty("mnc")) + object.mnc = message.mnc; + if (message.osVersion != null && message.hasOwnProperty("osVersion")) + object.osVersion = message.osVersion; + if (message.manufacturer != null && message.hasOwnProperty("manufacturer")) + object.manufacturer = message.manufacturer; + if (message.device != null && message.hasOwnProperty("device")) + object.device = message.device; + if (message.osBuildNumber != null && message.hasOwnProperty("osBuildNumber")) + object.osBuildNumber = message.osBuildNumber; + if (message.phoneId != null && message.hasOwnProperty("phoneId")) + object.phoneId = message.phoneId; + if (message.releaseChannel != null && message.hasOwnProperty("releaseChannel")) + object.releaseChannel = options.enums === String ? $root.proto.UserAgent.UserAgentReleaseChannel[message.releaseChannel] : message.releaseChannel; + if (message.localeLanguageIso6391 != null && message.hasOwnProperty("localeLanguageIso6391")) + object.localeLanguageIso6391 = message.localeLanguageIso6391; + if (message.localeCountryIso31661Alpha2 != null && message.hasOwnProperty("localeCountryIso31661Alpha2")) + object.localeCountryIso31661Alpha2 = message.localeCountryIso31661Alpha2; + if (message.deviceBoard != null && message.hasOwnProperty("deviceBoard")) + object.deviceBoard = message.deviceBoard; return object; }; /** - * Converts this PaymentInfo to JSON. + * Converts this UserAgent to JSON. * @function toJSON - * @memberof proto.PaymentInfo + * @memberof proto.UserAgent * @instance * @returns {Object.} JSON object */ - PaymentInfo.prototype.toJSON = function toJSON() { + UserAgent.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; /** - * PaymentInfoCurrency enum. - * @name proto.PaymentInfo.PaymentInfoCurrency + * UserAgentPlatform enum. + * @name proto.UserAgent.UserAgentPlatform * @enum {number} - * @property {number} UNKNOWN_CURRENCY=0 UNKNOWN_CURRENCY value - * @property {number} INR=1 INR value + * @property {number} ANDROID=0 ANDROID value + * @property {number} IOS=1 IOS value + * @property {number} WINDOWS_PHONE=2 WINDOWS_PHONE value + * @property {number} BLACKBERRY=3 BLACKBERRY value + * @property {number} BLACKBERRYX=4 BLACKBERRYX value + * @property {number} S40=5 S40 value + * @property {number} S60=6 S60 value + * @property {number} PYTHON_CLIENT=7 PYTHON_CLIENT value + * @property {number} TIZEN=8 TIZEN value + * @property {number} ENTERPRISE=9 ENTERPRISE value + * @property {number} SMB_ANDROID=10 SMB_ANDROID value + * @property {number} KAIOS=11 KAIOS value + * @property {number} SMB_IOS=12 SMB_IOS value + * @property {number} WINDOWS=13 WINDOWS value + * @property {number} WEB=14 WEB value + * @property {number} PORTAL=15 PORTAL value + * @property {number} GREEN_ANDROID=16 GREEN_ANDROID value + * @property {number} GREEN_IPHONE=17 GREEN_IPHONE value + * @property {number} BLUE_ANDROID=18 BLUE_ANDROID value + * @property {number} BLUE_IPHONE=19 BLUE_IPHONE value + * @property {number} FBLITE_ANDROID=20 FBLITE_ANDROID value + * @property {number} MLITE_ANDROID=21 MLITE_ANDROID value + * @property {number} IGLITE_ANDROID=22 IGLITE_ANDROID value + * @property {number} PAGE=23 PAGE value + * @property {number} MACOS=24 MACOS value + * @property {number} VR=25 VR value */ - PaymentInfo.PaymentInfoCurrency = (function() { + UserAgent.UserAgentPlatform = (function() { var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "UNKNOWN_CURRENCY"] = 0; - values[valuesById[1] = "INR"] = 1; + values[valuesById[0] = "ANDROID"] = 0; + values[valuesById[1] = "IOS"] = 1; + values[valuesById[2] = "WINDOWS_PHONE"] = 2; + values[valuesById[3] = "BLACKBERRY"] = 3; + values[valuesById[4] = "BLACKBERRYX"] = 4; + values[valuesById[5] = "S40"] = 5; + values[valuesById[6] = "S60"] = 6; + values[valuesById[7] = "PYTHON_CLIENT"] = 7; + values[valuesById[8] = "TIZEN"] = 8; + values[valuesById[9] = "ENTERPRISE"] = 9; + values[valuesById[10] = "SMB_ANDROID"] = 10; + values[valuesById[11] = "KAIOS"] = 11; + values[valuesById[12] = "SMB_IOS"] = 12; + values[valuesById[13] = "WINDOWS"] = 13; + values[valuesById[14] = "WEB"] = 14; + values[valuesById[15] = "PORTAL"] = 15; + values[valuesById[16] = "GREEN_ANDROID"] = 16; + values[valuesById[17] = "GREEN_IPHONE"] = 17; + values[valuesById[18] = "BLUE_ANDROID"] = 18; + values[valuesById[19] = "BLUE_IPHONE"] = 19; + values[valuesById[20] = "FBLITE_ANDROID"] = 20; + values[valuesById[21] = "MLITE_ANDROID"] = 21; + values[valuesById[22] = "IGLITE_ANDROID"] = 22; + values[valuesById[23] = "PAGE"] = 23; + values[valuesById[24] = "MACOS"] = 24; + values[valuesById[25] = "VR"] = 25; return values; })(); /** - * PaymentInfoStatus enum. - * @name proto.PaymentInfo.PaymentInfoStatus + * UserAgentReleaseChannel enum. + * @name proto.UserAgent.UserAgentReleaseChannel * @enum {number} - * @property {number} UNKNOWN_STATUS=0 UNKNOWN_STATUS value - * @property {number} PROCESSING=1 PROCESSING value - * @property {number} SENT=2 SENT value - * @property {number} NEED_TO_ACCEPT=3 NEED_TO_ACCEPT value - * @property {number} COMPLETE=4 COMPLETE value - * @property {number} COULD_NOT_COMPLETE=5 COULD_NOT_COMPLETE value - * @property {number} REFUNDED=6 REFUNDED value - * @property {number} EXPIRED=7 EXPIRED value - * @property {number} REJECTED=8 REJECTED value - * @property {number} CANCELLED=9 CANCELLED value - * @property {number} WAITING_FOR_PAYER=10 WAITING_FOR_PAYER value - * @property {number} WAITING=11 WAITING value + * @property {number} RELEASE=0 RELEASE value + * @property {number} BETA=1 BETA value + * @property {number} ALPHA=2 ALPHA value + * @property {number} DEBUG=3 DEBUG value */ - PaymentInfo.PaymentInfoStatus = (function() { + UserAgent.UserAgentReleaseChannel = (function() { var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "UNKNOWN_STATUS"] = 0; - values[valuesById[1] = "PROCESSING"] = 1; - values[valuesById[2] = "SENT"] = 2; - values[valuesById[3] = "NEED_TO_ACCEPT"] = 3; - values[valuesById[4] = "COMPLETE"] = 4; - values[valuesById[5] = "COULD_NOT_COMPLETE"] = 5; - values[valuesById[6] = "REFUNDED"] = 6; - values[valuesById[7] = "EXPIRED"] = 7; - values[valuesById[8] = "REJECTED"] = 8; - values[valuesById[9] = "CANCELLED"] = 9; - values[valuesById[10] = "WAITING_FOR_PAYER"] = 10; - values[valuesById[11] = "WAITING"] = 11; + values[valuesById[0] = "RELEASE"] = 0; + values[valuesById[1] = "BETA"] = 1; + values[valuesById[2] = "ALPHA"] = 2; + values[valuesById[3] = "DEBUG"] = 3; return values; })(); - /** - * PaymentInfoTxnStatus enum. - * @name proto.PaymentInfo.PaymentInfoTxnStatus - * @enum {number} - * @property {number} UNKNOWN=0 UNKNOWN value - * @property {number} PENDING_SETUP=1 PENDING_SETUP value - * @property {number} PENDING_RECEIVER_SETUP=2 PENDING_RECEIVER_SETUP value - * @property {number} INIT=3 INIT value - * @property {number} SUCCESS=4 SUCCESS value - * @property {number} COMPLETED=5 COMPLETED value - * @property {number} FAILED=6 FAILED value - * @property {number} FAILED_RISK=7 FAILED_RISK value - * @property {number} FAILED_PROCESSING=8 FAILED_PROCESSING value - * @property {number} FAILED_RECEIVER_PROCESSING=9 FAILED_RECEIVER_PROCESSING value - * @property {number} FAILED_DA=10 FAILED_DA value - * @property {number} FAILED_DA_FINAL=11 FAILED_DA_FINAL value - * @property {number} REFUNDED_TXN=12 REFUNDED_TXN value - * @property {number} REFUND_FAILED=13 REFUND_FAILED value - * @property {number} REFUND_FAILED_PROCESSING=14 REFUND_FAILED_PROCESSING value - * @property {number} REFUND_FAILED_DA=15 REFUND_FAILED_DA value - * @property {number} EXPIRED_TXN=16 EXPIRED_TXN value - * @property {number} AUTH_CANCELED=17 AUTH_CANCELED value - * @property {number} AUTH_CANCEL_FAILED_PROCESSING=18 AUTH_CANCEL_FAILED_PROCESSING value - * @property {number} AUTH_CANCEL_FAILED=19 AUTH_CANCEL_FAILED value - * @property {number} COLLECT_INIT=20 COLLECT_INIT value - * @property {number} COLLECT_SUCCESS=21 COLLECT_SUCCESS value - * @property {number} COLLECT_FAILED=22 COLLECT_FAILED value - * @property {number} COLLECT_FAILED_RISK=23 COLLECT_FAILED_RISK value - * @property {number} COLLECT_REJECTED=24 COLLECT_REJECTED value - * @property {number} COLLECT_EXPIRED=25 COLLECT_EXPIRED value - * @property {number} COLLECT_CANCELED=26 COLLECT_CANCELED value - * @property {number} COLLECT_CANCELLING=27 COLLECT_CANCELLING value - */ - PaymentInfo.PaymentInfoTxnStatus = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "UNKNOWN"] = 0; - values[valuesById[1] = "PENDING_SETUP"] = 1; - values[valuesById[2] = "PENDING_RECEIVER_SETUP"] = 2; - values[valuesById[3] = "INIT"] = 3; - values[valuesById[4] = "SUCCESS"] = 4; - values[valuesById[5] = "COMPLETED"] = 5; - values[valuesById[6] = "FAILED"] = 6; - values[valuesById[7] = "FAILED_RISK"] = 7; - values[valuesById[8] = "FAILED_PROCESSING"] = 8; - values[valuesById[9] = "FAILED_RECEIVER_PROCESSING"] = 9; - values[valuesById[10] = "FAILED_DA"] = 10; - values[valuesById[11] = "FAILED_DA_FINAL"] = 11; - values[valuesById[12] = "REFUNDED_TXN"] = 12; - values[valuesById[13] = "REFUND_FAILED"] = 13; - values[valuesById[14] = "REFUND_FAILED_PROCESSING"] = 14; - values[valuesById[15] = "REFUND_FAILED_DA"] = 15; - values[valuesById[16] = "EXPIRED_TXN"] = 16; - values[valuesById[17] = "AUTH_CANCELED"] = 17; - values[valuesById[18] = "AUTH_CANCEL_FAILED_PROCESSING"] = 18; - values[valuesById[19] = "AUTH_CANCEL_FAILED"] = 19; - values[valuesById[20] = "COLLECT_INIT"] = 20; - values[valuesById[21] = "COLLECT_SUCCESS"] = 21; - values[valuesById[22] = "COLLECT_FAILED"] = 22; - values[valuesById[23] = "COLLECT_FAILED_RISK"] = 23; - values[valuesById[24] = "COLLECT_REJECTED"] = 24; - values[valuesById[25] = "COLLECT_EXPIRED"] = 25; - values[valuesById[26] = "COLLECT_CANCELED"] = 26; - values[valuesById[27] = "COLLECT_CANCELLING"] = 27; - return values; - })(); - - return PaymentInfo; + return UserAgent; })(); - proto.WebMessageInfo = (function() { + proto.WebdPayload = (function() { /** - * Properties of a WebMessageInfo. + * Properties of a WebdPayload. * @memberof proto - * @interface IWebMessageInfo - * @property {proto.IMessageKey} key WebMessageInfo key - * @property {proto.IMessage|null} [message] WebMessageInfo message - * @property {number|Long|null} [messageTimestamp] WebMessageInfo messageTimestamp - * @property {proto.WebMessageInfo.WebMessageInfoStatus|null} [status] WebMessageInfo status - * @property {string|null} [participant] WebMessageInfo participant - * @property {boolean|null} [ignore] WebMessageInfo ignore - * @property {boolean|null} [starred] WebMessageInfo starred - * @property {boolean|null} [broadcast] WebMessageInfo broadcast - * @property {string|null} [pushName] WebMessageInfo pushName - * @property {Uint8Array|null} [mediaCiphertextSha256] WebMessageInfo mediaCiphertextSha256 - * @property {boolean|null} [multicast] WebMessageInfo multicast - * @property {boolean|null} [urlText] WebMessageInfo urlText - * @property {boolean|null} [urlNumber] WebMessageInfo urlNumber - * @property {proto.WebMessageInfo.WebMessageInfoStubType|null} [messageStubType] WebMessageInfo messageStubType - * @property {boolean|null} [clearMedia] WebMessageInfo clearMedia - * @property {Array.|null} [messageStubParameters] WebMessageInfo messageStubParameters - * @property {number|null} [duration] WebMessageInfo duration - * @property {Array.|null} [labels] WebMessageInfo labels - * @property {proto.IPaymentInfo|null} [paymentInfo] WebMessageInfo paymentInfo - * @property {proto.ILiveLocationMessage|null} [finalLiveLocation] WebMessageInfo finalLiveLocation - * @property {proto.IPaymentInfo|null} [quotedPaymentInfo] WebMessageInfo quotedPaymentInfo - * @property {number|Long|null} [ephemeralStartTimestamp] WebMessageInfo ephemeralStartTimestamp - * @property {number|null} [ephemeralDuration] WebMessageInfo ephemeralDuration - * @property {boolean|null} [ephemeralOffToOn] WebMessageInfo ephemeralOffToOn - * @property {boolean|null} [ephemeralOutOfSync] WebMessageInfo ephemeralOutOfSync - * @property {proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus|null} [bizPrivacyStatus] WebMessageInfo bizPrivacyStatus - * @property {string|null} [verifiedBizName] WebMessageInfo verifiedBizName + * @interface IWebdPayload + * @property {boolean|null} [usesParticipantInKey] WebdPayload usesParticipantInKey + * @property {boolean|null} [supportsStarredMessages] WebdPayload supportsStarredMessages + * @property {boolean|null} [supportsDocumentMessages] WebdPayload supportsDocumentMessages + * @property {boolean|null} [supportsUrlMessages] WebdPayload supportsUrlMessages + * @property {boolean|null} [supportsMediaRetry] WebdPayload supportsMediaRetry + * @property {boolean|null} [supportsE2EImage] WebdPayload supportsE2EImage + * @property {boolean|null} [supportsE2EVideo] WebdPayload supportsE2EVideo + * @property {boolean|null} [supportsE2EAudio] WebdPayload supportsE2EAudio + * @property {boolean|null} [supportsE2EDocument] WebdPayload supportsE2EDocument + * @property {string|null} [documentTypes] WebdPayload documentTypes + * @property {Uint8Array|null} [features] WebdPayload features */ /** - * Constructs a new WebMessageInfo. + * Constructs a new WebdPayload. * @memberof proto - * @classdesc Represents a WebMessageInfo. - * @implements IWebMessageInfo + * @classdesc Represents a WebdPayload. + * @implements IWebdPayload * @constructor - * @param {proto.IWebMessageInfo=} [properties] Properties to set + * @param {proto.IWebdPayload=} [properties] Properties to set */ - function WebMessageInfo(properties) { - this.messageStubParameters = []; - this.labels = []; + function WebdPayload(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -3254,612 +1022,1846 @@ $root.proto = (function() { } /** - * WebMessageInfo key. - * @member {proto.IMessageKey} key - * @memberof proto.WebMessageInfo + * WebdPayload usesParticipantInKey. + * @member {boolean} usesParticipantInKey + * @memberof proto.WebdPayload * @instance */ - WebMessageInfo.prototype.key = null; + WebdPayload.prototype.usesParticipantInKey = false; /** - * WebMessageInfo message. - * @member {proto.IMessage|null|undefined} message - * @memberof proto.WebMessageInfo + * WebdPayload supportsStarredMessages. + * @member {boolean} supportsStarredMessages + * @memberof proto.WebdPayload * @instance */ - WebMessageInfo.prototype.message = null; + WebdPayload.prototype.supportsStarredMessages = false; /** - * WebMessageInfo messageTimestamp. - * @member {number|Long} messageTimestamp - * @memberof proto.WebMessageInfo + * WebdPayload supportsDocumentMessages. + * @member {boolean} supportsDocumentMessages + * @memberof proto.WebdPayload * @instance */ - WebMessageInfo.prototype.messageTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + WebdPayload.prototype.supportsDocumentMessages = false; /** - * WebMessageInfo status. - * @member {proto.WebMessageInfo.WebMessageInfoStatus} status - * @memberof proto.WebMessageInfo + * WebdPayload supportsUrlMessages. + * @member {boolean} supportsUrlMessages + * @memberof proto.WebdPayload * @instance */ - WebMessageInfo.prototype.status = 0; + WebdPayload.prototype.supportsUrlMessages = false; /** - * WebMessageInfo participant. - * @member {string} participant - * @memberof proto.WebMessageInfo + * WebdPayload supportsMediaRetry. + * @member {boolean} supportsMediaRetry + * @memberof proto.WebdPayload * @instance */ - WebMessageInfo.prototype.participant = ""; + WebdPayload.prototype.supportsMediaRetry = false; /** - * WebMessageInfo ignore. - * @member {boolean} ignore - * @memberof proto.WebMessageInfo + * WebdPayload supportsE2EImage. + * @member {boolean} supportsE2EImage + * @memberof proto.WebdPayload * @instance */ - WebMessageInfo.prototype.ignore = false; + WebdPayload.prototype.supportsE2EImage = false; /** - * WebMessageInfo starred. - * @member {boolean} starred - * @memberof proto.WebMessageInfo + * WebdPayload supportsE2EVideo. + * @member {boolean} supportsE2EVideo + * @memberof proto.WebdPayload * @instance */ - WebMessageInfo.prototype.starred = false; + WebdPayload.prototype.supportsE2EVideo = false; /** - * WebMessageInfo broadcast. - * @member {boolean} broadcast - * @memberof proto.WebMessageInfo + * WebdPayload supportsE2EAudio. + * @member {boolean} supportsE2EAudio + * @memberof proto.WebdPayload * @instance */ - WebMessageInfo.prototype.broadcast = false; + WebdPayload.prototype.supportsE2EAudio = false; /** - * WebMessageInfo pushName. - * @member {string} pushName - * @memberof proto.WebMessageInfo + * WebdPayload supportsE2EDocument. + * @member {boolean} supportsE2EDocument + * @memberof proto.WebdPayload * @instance */ - WebMessageInfo.prototype.pushName = ""; + WebdPayload.prototype.supportsE2EDocument = false; /** - * WebMessageInfo mediaCiphertextSha256. - * @member {Uint8Array} mediaCiphertextSha256 - * @memberof proto.WebMessageInfo + * WebdPayload documentTypes. + * @member {string} documentTypes + * @memberof proto.WebdPayload * @instance */ - WebMessageInfo.prototype.mediaCiphertextSha256 = $util.newBuffer([]); + WebdPayload.prototype.documentTypes = ""; /** - * WebMessageInfo multicast. - * @member {boolean} multicast - * @memberof proto.WebMessageInfo + * WebdPayload features. + * @member {Uint8Array} features + * @memberof proto.WebdPayload * @instance */ - WebMessageInfo.prototype.multicast = false; + WebdPayload.prototype.features = $util.newBuffer([]); /** - * WebMessageInfo urlText. - * @member {boolean} urlText - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.urlText = false; - - /** - * WebMessageInfo urlNumber. - * @member {boolean} urlNumber - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.urlNumber = false; - - /** - * WebMessageInfo messageStubType. - * @member {proto.WebMessageInfo.WebMessageInfoStubType} messageStubType - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.messageStubType = 0; - - /** - * WebMessageInfo clearMedia. - * @member {boolean} clearMedia - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.clearMedia = false; - - /** - * WebMessageInfo messageStubParameters. - * @member {Array.} messageStubParameters - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.messageStubParameters = $util.emptyArray; - - /** - * WebMessageInfo duration. - * @member {number} duration - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.duration = 0; - - /** - * WebMessageInfo labels. - * @member {Array.} labels - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.labels = $util.emptyArray; - - /** - * WebMessageInfo paymentInfo. - * @member {proto.IPaymentInfo|null|undefined} paymentInfo - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.paymentInfo = null; - - /** - * WebMessageInfo finalLiveLocation. - * @member {proto.ILiveLocationMessage|null|undefined} finalLiveLocation - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.finalLiveLocation = null; - - /** - * WebMessageInfo quotedPaymentInfo. - * @member {proto.IPaymentInfo|null|undefined} quotedPaymentInfo - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.quotedPaymentInfo = null; - - /** - * WebMessageInfo ephemeralStartTimestamp. - * @member {number|Long} ephemeralStartTimestamp - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.ephemeralStartTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * WebMessageInfo ephemeralDuration. - * @member {number} ephemeralDuration - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.ephemeralDuration = 0; - - /** - * WebMessageInfo ephemeralOffToOn. - * @member {boolean} ephemeralOffToOn - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.ephemeralOffToOn = false; - - /** - * WebMessageInfo ephemeralOutOfSync. - * @member {boolean} ephemeralOutOfSync - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.ephemeralOutOfSync = false; - - /** - * WebMessageInfo bizPrivacyStatus. - * @member {proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus} bizPrivacyStatus - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.bizPrivacyStatus = 0; - - /** - * WebMessageInfo verifiedBizName. - * @member {string} verifiedBizName - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.verifiedBizName = ""; - - /** - * Creates a new WebMessageInfo instance using the specified properties. + * Creates a new WebdPayload instance using the specified properties. * @function create - * @memberof proto.WebMessageInfo + * @memberof proto.WebdPayload * @static - * @param {proto.IWebMessageInfo=} [properties] Properties to set - * @returns {proto.WebMessageInfo} WebMessageInfo instance + * @param {proto.IWebdPayload=} [properties] Properties to set + * @returns {proto.WebdPayload} WebdPayload instance */ - WebMessageInfo.create = function create(properties) { - return new WebMessageInfo(properties); + WebdPayload.create = function create(properties) { + return new WebdPayload(properties); }; /** - * Encodes the specified WebMessageInfo message. Does not implicitly {@link proto.WebMessageInfo.verify|verify} messages. + * Encodes the specified WebdPayload message. Does not implicitly {@link proto.WebdPayload.verify|verify} messages. * @function encode - * @memberof proto.WebMessageInfo + * @memberof proto.WebdPayload * @static - * @param {proto.IWebMessageInfo} message WebMessageInfo message or plain object to encode + * @param {proto.IWebdPayload} message WebdPayload message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - WebMessageInfo.encode = function encode(message, writer) { + WebdPayload.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.message != null && Object.hasOwnProperty.call(message, "message")) - $root.proto.Message.encode(message.message, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.messageTimestamp != null && Object.hasOwnProperty.call(message, "messageTimestamp")) - writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.messageTimestamp); - if (message.status != null && Object.hasOwnProperty.call(message, "status")) - writer.uint32(/* id 4, wireType 0 =*/32).int32(message.status); - if (message.participant != null && Object.hasOwnProperty.call(message, "participant")) - writer.uint32(/* id 5, wireType 2 =*/42).string(message.participant); - if (message.ignore != null && Object.hasOwnProperty.call(message, "ignore")) - writer.uint32(/* id 16, wireType 0 =*/128).bool(message.ignore); - if (message.starred != null && Object.hasOwnProperty.call(message, "starred")) - writer.uint32(/* id 17, wireType 0 =*/136).bool(message.starred); - if (message.broadcast != null && Object.hasOwnProperty.call(message, "broadcast")) - writer.uint32(/* id 18, wireType 0 =*/144).bool(message.broadcast); - if (message.pushName != null && Object.hasOwnProperty.call(message, "pushName")) - writer.uint32(/* id 19, wireType 2 =*/154).string(message.pushName); - if (message.mediaCiphertextSha256 != null && Object.hasOwnProperty.call(message, "mediaCiphertextSha256")) - writer.uint32(/* id 20, wireType 2 =*/162).bytes(message.mediaCiphertextSha256); - if (message.multicast != null && Object.hasOwnProperty.call(message, "multicast")) - writer.uint32(/* id 21, wireType 0 =*/168).bool(message.multicast); - if (message.urlText != null && Object.hasOwnProperty.call(message, "urlText")) - writer.uint32(/* id 22, wireType 0 =*/176).bool(message.urlText); - if (message.urlNumber != null && Object.hasOwnProperty.call(message, "urlNumber")) - writer.uint32(/* id 23, wireType 0 =*/184).bool(message.urlNumber); - if (message.messageStubType != null && Object.hasOwnProperty.call(message, "messageStubType")) - writer.uint32(/* id 24, wireType 0 =*/192).int32(message.messageStubType); - if (message.clearMedia != null && Object.hasOwnProperty.call(message, "clearMedia")) - writer.uint32(/* id 25, wireType 0 =*/200).bool(message.clearMedia); - if (message.messageStubParameters != null && message.messageStubParameters.length) - for (var i = 0; i < message.messageStubParameters.length; ++i) - writer.uint32(/* id 26, wireType 2 =*/210).string(message.messageStubParameters[i]); - if (message.duration != null && Object.hasOwnProperty.call(message, "duration")) - writer.uint32(/* id 27, wireType 0 =*/216).uint32(message.duration); - if (message.labels != null && message.labels.length) - for (var i = 0; i < message.labels.length; ++i) - writer.uint32(/* id 28, wireType 2 =*/226).string(message.labels[i]); - if (message.paymentInfo != null && Object.hasOwnProperty.call(message, "paymentInfo")) - $root.proto.PaymentInfo.encode(message.paymentInfo, writer.uint32(/* id 29, wireType 2 =*/234).fork()).ldelim(); - if (message.finalLiveLocation != null && Object.hasOwnProperty.call(message, "finalLiveLocation")) - $root.proto.LiveLocationMessage.encode(message.finalLiveLocation, writer.uint32(/* id 30, wireType 2 =*/242).fork()).ldelim(); - if (message.quotedPaymentInfo != null && Object.hasOwnProperty.call(message, "quotedPaymentInfo")) - $root.proto.PaymentInfo.encode(message.quotedPaymentInfo, writer.uint32(/* id 31, wireType 2 =*/250).fork()).ldelim(); - if (message.ephemeralStartTimestamp != null && Object.hasOwnProperty.call(message, "ephemeralStartTimestamp")) - writer.uint32(/* id 32, wireType 0 =*/256).uint64(message.ephemeralStartTimestamp); - if (message.ephemeralDuration != null && Object.hasOwnProperty.call(message, "ephemeralDuration")) - writer.uint32(/* id 33, wireType 0 =*/264).uint32(message.ephemeralDuration); - if (message.ephemeralOffToOn != null && Object.hasOwnProperty.call(message, "ephemeralOffToOn")) - writer.uint32(/* id 34, wireType 0 =*/272).bool(message.ephemeralOffToOn); - if (message.ephemeralOutOfSync != null && Object.hasOwnProperty.call(message, "ephemeralOutOfSync")) - writer.uint32(/* id 35, wireType 0 =*/280).bool(message.ephemeralOutOfSync); - if (message.bizPrivacyStatus != null && Object.hasOwnProperty.call(message, "bizPrivacyStatus")) - writer.uint32(/* id 36, wireType 0 =*/288).int32(message.bizPrivacyStatus); - if (message.verifiedBizName != null && Object.hasOwnProperty.call(message, "verifiedBizName")) - writer.uint32(/* id 37, wireType 2 =*/298).string(message.verifiedBizName); + if (message.usesParticipantInKey != null && Object.hasOwnProperty.call(message, "usesParticipantInKey")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.usesParticipantInKey); + if (message.supportsStarredMessages != null && Object.hasOwnProperty.call(message, "supportsStarredMessages")) + writer.uint32(/* id 2, wireType 0 =*/16).bool(message.supportsStarredMessages); + if (message.supportsDocumentMessages != null && Object.hasOwnProperty.call(message, "supportsDocumentMessages")) + writer.uint32(/* id 3, wireType 0 =*/24).bool(message.supportsDocumentMessages); + if (message.supportsUrlMessages != null && Object.hasOwnProperty.call(message, "supportsUrlMessages")) + writer.uint32(/* id 4, wireType 0 =*/32).bool(message.supportsUrlMessages); + if (message.supportsMediaRetry != null && Object.hasOwnProperty.call(message, "supportsMediaRetry")) + writer.uint32(/* id 5, wireType 0 =*/40).bool(message.supportsMediaRetry); + if (message.supportsE2EImage != null && Object.hasOwnProperty.call(message, "supportsE2EImage")) + writer.uint32(/* id 6, wireType 0 =*/48).bool(message.supportsE2EImage); + if (message.supportsE2EVideo != null && Object.hasOwnProperty.call(message, "supportsE2EVideo")) + writer.uint32(/* id 7, wireType 0 =*/56).bool(message.supportsE2EVideo); + if (message.supportsE2EAudio != null && Object.hasOwnProperty.call(message, "supportsE2EAudio")) + writer.uint32(/* id 8, wireType 0 =*/64).bool(message.supportsE2EAudio); + if (message.supportsE2EDocument != null && Object.hasOwnProperty.call(message, "supportsE2EDocument")) + writer.uint32(/* id 9, wireType 0 =*/72).bool(message.supportsE2EDocument); + if (message.documentTypes != null && Object.hasOwnProperty.call(message, "documentTypes")) + writer.uint32(/* id 10, wireType 2 =*/82).string(message.documentTypes); + if (message.features != null && Object.hasOwnProperty.call(message, "features")) + writer.uint32(/* id 11, wireType 2 =*/90).bytes(message.features); return writer; }; /** - * Encodes the specified WebMessageInfo message, length delimited. Does not implicitly {@link proto.WebMessageInfo.verify|verify} messages. + * Encodes the specified WebdPayload message, length delimited. Does not implicitly {@link proto.WebdPayload.verify|verify} messages. * @function encodeDelimited - * @memberof proto.WebMessageInfo + * @memberof proto.WebdPayload * @static - * @param {proto.IWebMessageInfo} message WebMessageInfo message or plain object to encode + * @param {proto.IWebdPayload} message WebdPayload message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - WebMessageInfo.encodeDelimited = function encodeDelimited(message, writer) { + WebdPayload.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; /** - * Decodes a WebMessageInfo message from the specified reader or buffer. + * Decodes a WebdPayload message from the specified reader or buffer. * @function decode - * @memberof proto.WebMessageInfo + * @memberof proto.WebdPayload * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from * @param {number} [length] Message length if known beforehand - * @returns {proto.WebMessageInfo} WebMessageInfo + * @returns {proto.WebdPayload} WebdPayload * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - WebMessageInfo.decode = function decode(reader, length) { + WebdPayload.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebMessageInfo(); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebdPayload(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.key = $root.proto.MessageKey.decode(reader, reader.uint32()); + message.usesParticipantInKey = reader.bool(); break; case 2: - message.message = $root.proto.Message.decode(reader, reader.uint32()); + message.supportsStarredMessages = reader.bool(); break; case 3: - message.messageTimestamp = reader.uint64(); + message.supportsDocumentMessages = reader.bool(); break; case 4: - message.status = reader.int32(); + message.supportsUrlMessages = reader.bool(); break; case 5: - message.participant = reader.string(); + message.supportsMediaRetry = reader.bool(); + break; + case 6: + message.supportsE2EImage = reader.bool(); + break; + case 7: + message.supportsE2EVideo = reader.bool(); + break; + case 8: + message.supportsE2EAudio = reader.bool(); + break; + case 9: + message.supportsE2EDocument = reader.bool(); + break; + case 10: + message.documentTypes = reader.string(); + break; + case 11: + message.features = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a WebdPayload message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.WebdPayload + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.WebdPayload} WebdPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebdPayload.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a WebdPayload message. + * @function verify + * @memberof proto.WebdPayload + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + WebdPayload.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.usesParticipantInKey != null && message.hasOwnProperty("usesParticipantInKey")) + if (typeof message.usesParticipantInKey !== "boolean") + return "usesParticipantInKey: boolean expected"; + if (message.supportsStarredMessages != null && message.hasOwnProperty("supportsStarredMessages")) + if (typeof message.supportsStarredMessages !== "boolean") + return "supportsStarredMessages: boolean expected"; + if (message.supportsDocumentMessages != null && message.hasOwnProperty("supportsDocumentMessages")) + if (typeof message.supportsDocumentMessages !== "boolean") + return "supportsDocumentMessages: boolean expected"; + if (message.supportsUrlMessages != null && message.hasOwnProperty("supportsUrlMessages")) + if (typeof message.supportsUrlMessages !== "boolean") + return "supportsUrlMessages: boolean expected"; + if (message.supportsMediaRetry != null && message.hasOwnProperty("supportsMediaRetry")) + if (typeof message.supportsMediaRetry !== "boolean") + return "supportsMediaRetry: boolean expected"; + if (message.supportsE2EImage != null && message.hasOwnProperty("supportsE2EImage")) + if (typeof message.supportsE2EImage !== "boolean") + return "supportsE2EImage: boolean expected"; + if (message.supportsE2EVideo != null && message.hasOwnProperty("supportsE2EVideo")) + if (typeof message.supportsE2EVideo !== "boolean") + return "supportsE2EVideo: boolean expected"; + if (message.supportsE2EAudio != null && message.hasOwnProperty("supportsE2EAudio")) + if (typeof message.supportsE2EAudio !== "boolean") + return "supportsE2EAudio: boolean expected"; + if (message.supportsE2EDocument != null && message.hasOwnProperty("supportsE2EDocument")) + if (typeof message.supportsE2EDocument !== "boolean") + return "supportsE2EDocument: boolean expected"; + if (message.documentTypes != null && message.hasOwnProperty("documentTypes")) + if (!$util.isString(message.documentTypes)) + return "documentTypes: string expected"; + if (message.features != null && message.hasOwnProperty("features")) + if (!(message.features && typeof message.features.length === "number" || $util.isString(message.features))) + return "features: buffer expected"; + return null; + }; + + /** + * Creates a WebdPayload message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.WebdPayload + * @static + * @param {Object.} object Plain object + * @returns {proto.WebdPayload} WebdPayload + */ + WebdPayload.fromObject = function fromObject(object) { + if (object instanceof $root.proto.WebdPayload) + return object; + var message = new $root.proto.WebdPayload(); + if (object.usesParticipantInKey != null) + message.usesParticipantInKey = Boolean(object.usesParticipantInKey); + if (object.supportsStarredMessages != null) + message.supportsStarredMessages = Boolean(object.supportsStarredMessages); + if (object.supportsDocumentMessages != null) + message.supportsDocumentMessages = Boolean(object.supportsDocumentMessages); + if (object.supportsUrlMessages != null) + message.supportsUrlMessages = Boolean(object.supportsUrlMessages); + if (object.supportsMediaRetry != null) + message.supportsMediaRetry = Boolean(object.supportsMediaRetry); + if (object.supportsE2EImage != null) + message.supportsE2EImage = Boolean(object.supportsE2EImage); + if (object.supportsE2EVideo != null) + message.supportsE2EVideo = Boolean(object.supportsE2EVideo); + if (object.supportsE2EAudio != null) + message.supportsE2EAudio = Boolean(object.supportsE2EAudio); + if (object.supportsE2EDocument != null) + message.supportsE2EDocument = Boolean(object.supportsE2EDocument); + if (object.documentTypes != null) + message.documentTypes = String(object.documentTypes); + if (object.features != null) + if (typeof object.features === "string") + $util.base64.decode(object.features, message.features = $util.newBuffer($util.base64.length(object.features)), 0); + else if (object.features.length) + message.features = object.features; + return message; + }; + + /** + * Creates a plain object from a WebdPayload message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.WebdPayload + * @static + * @param {proto.WebdPayload} message WebdPayload + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + WebdPayload.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.usesParticipantInKey = false; + object.supportsStarredMessages = false; + object.supportsDocumentMessages = false; + object.supportsUrlMessages = false; + object.supportsMediaRetry = false; + object.supportsE2EImage = false; + object.supportsE2EVideo = false; + object.supportsE2EAudio = false; + object.supportsE2EDocument = false; + object.documentTypes = ""; + if (options.bytes === String) + object.features = ""; + else { + object.features = []; + if (options.bytes !== Array) + object.features = $util.newBuffer(object.features); + } + } + if (message.usesParticipantInKey != null && message.hasOwnProperty("usesParticipantInKey")) + object.usesParticipantInKey = message.usesParticipantInKey; + if (message.supportsStarredMessages != null && message.hasOwnProperty("supportsStarredMessages")) + object.supportsStarredMessages = message.supportsStarredMessages; + if (message.supportsDocumentMessages != null && message.hasOwnProperty("supportsDocumentMessages")) + object.supportsDocumentMessages = message.supportsDocumentMessages; + if (message.supportsUrlMessages != null && message.hasOwnProperty("supportsUrlMessages")) + object.supportsUrlMessages = message.supportsUrlMessages; + if (message.supportsMediaRetry != null && message.hasOwnProperty("supportsMediaRetry")) + object.supportsMediaRetry = message.supportsMediaRetry; + if (message.supportsE2EImage != null && message.hasOwnProperty("supportsE2EImage")) + object.supportsE2EImage = message.supportsE2EImage; + if (message.supportsE2EVideo != null && message.hasOwnProperty("supportsE2EVideo")) + object.supportsE2EVideo = message.supportsE2EVideo; + if (message.supportsE2EAudio != null && message.hasOwnProperty("supportsE2EAudio")) + object.supportsE2EAudio = message.supportsE2EAudio; + if (message.supportsE2EDocument != null && message.hasOwnProperty("supportsE2EDocument")) + object.supportsE2EDocument = message.supportsE2EDocument; + if (message.documentTypes != null && message.hasOwnProperty("documentTypes")) + object.documentTypes = message.documentTypes; + if (message.features != null && message.hasOwnProperty("features")) + object.features = options.bytes === String ? $util.base64.encode(message.features, 0, message.features.length) : options.bytes === Array ? Array.prototype.slice.call(message.features) : message.features; + return object; + }; + + /** + * Converts this WebdPayload to JSON. + * @function toJSON + * @memberof proto.WebdPayload + * @instance + * @returns {Object.} JSON object + */ + WebdPayload.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return WebdPayload; + })(); + + proto.WebInfo = (function() { + + /** + * Properties of a WebInfo. + * @memberof proto + * @interface IWebInfo + * @property {string|null} [refToken] WebInfo refToken + * @property {string|null} [version] WebInfo version + * @property {proto.IWebdPayload|null} [webdPayload] WebInfo webdPayload + * @property {proto.WebInfo.WebInfoWebSubPlatform|null} [webSubPlatform] WebInfo webSubPlatform + */ + + /** + * Constructs a new WebInfo. + * @memberof proto + * @classdesc Represents a WebInfo. + * @implements IWebInfo + * @constructor + * @param {proto.IWebInfo=} [properties] Properties to set + */ + function WebInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * WebInfo refToken. + * @member {string} refToken + * @memberof proto.WebInfo + * @instance + */ + WebInfo.prototype.refToken = ""; + + /** + * WebInfo version. + * @member {string} version + * @memberof proto.WebInfo + * @instance + */ + WebInfo.prototype.version = ""; + + /** + * WebInfo webdPayload. + * @member {proto.IWebdPayload|null|undefined} webdPayload + * @memberof proto.WebInfo + * @instance + */ + WebInfo.prototype.webdPayload = null; + + /** + * WebInfo webSubPlatform. + * @member {proto.WebInfo.WebInfoWebSubPlatform} webSubPlatform + * @memberof proto.WebInfo + * @instance + */ + WebInfo.prototype.webSubPlatform = 0; + + /** + * Creates a new WebInfo instance using the specified properties. + * @function create + * @memberof proto.WebInfo + * @static + * @param {proto.IWebInfo=} [properties] Properties to set + * @returns {proto.WebInfo} WebInfo instance + */ + WebInfo.create = function create(properties) { + return new WebInfo(properties); + }; + + /** + * Encodes the specified WebInfo message. Does not implicitly {@link proto.WebInfo.verify|verify} messages. + * @function encode + * @memberof proto.WebInfo + * @static + * @param {proto.IWebInfo} message WebInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WebInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.refToken != null && Object.hasOwnProperty.call(message, "refToken")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.refToken); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.version); + if (message.webdPayload != null && Object.hasOwnProperty.call(message, "webdPayload")) + $root.proto.WebdPayload.encode(message.webdPayload, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.webSubPlatform != null && Object.hasOwnProperty.call(message, "webSubPlatform")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.webSubPlatform); + return writer; + }; + + /** + * Encodes the specified WebInfo message, length delimited. Does not implicitly {@link proto.WebInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.WebInfo + * @static + * @param {proto.IWebInfo} message WebInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WebInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a WebInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.WebInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.WebInfo} WebInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.refToken = reader.string(); + break; + case 2: + message.version = reader.string(); + break; + case 3: + message.webdPayload = $root.proto.WebdPayload.decode(reader, reader.uint32()); + break; + case 4: + message.webSubPlatform = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a WebInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.WebInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.WebInfo} WebInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a WebInfo message. + * @function verify + * @memberof proto.WebInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + WebInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.refToken != null && message.hasOwnProperty("refToken")) + if (!$util.isString(message.refToken)) + return "refToken: string expected"; + if (message.version != null && message.hasOwnProperty("version")) + if (!$util.isString(message.version)) + return "version: string expected"; + if (message.webdPayload != null && message.hasOwnProperty("webdPayload")) { + var error = $root.proto.WebdPayload.verify(message.webdPayload); + if (error) + return "webdPayload." + error; + } + if (message.webSubPlatform != null && message.hasOwnProperty("webSubPlatform")) + switch (message.webSubPlatform) { + default: + return "webSubPlatform: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + break; + } + return null; + }; + + /** + * Creates a WebInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.WebInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.WebInfo} WebInfo + */ + WebInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.WebInfo) + return object; + var message = new $root.proto.WebInfo(); + if (object.refToken != null) + message.refToken = String(object.refToken); + if (object.version != null) + message.version = String(object.version); + if (object.webdPayload != null) { + if (typeof object.webdPayload !== "object") + throw TypeError(".proto.WebInfo.webdPayload: object expected"); + message.webdPayload = $root.proto.WebdPayload.fromObject(object.webdPayload); + } + switch (object.webSubPlatform) { + case "WEB_BROWSER": + case 0: + message.webSubPlatform = 0; + break; + case "APP_STORE": + case 1: + message.webSubPlatform = 1; + break; + case "WIN_STORE": + case 2: + message.webSubPlatform = 2; + break; + case "DARWIN": + case 3: + message.webSubPlatform = 3; + break; + case "WIN32": + case 4: + message.webSubPlatform = 4; + break; + } + return message; + }; + + /** + * Creates a plain object from a WebInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.WebInfo + * @static + * @param {proto.WebInfo} message WebInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + WebInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.refToken = ""; + object.version = ""; + object.webdPayload = null; + object.webSubPlatform = options.enums === String ? "WEB_BROWSER" : 0; + } + if (message.refToken != null && message.hasOwnProperty("refToken")) + object.refToken = message.refToken; + if (message.version != null && message.hasOwnProperty("version")) + object.version = message.version; + if (message.webdPayload != null && message.hasOwnProperty("webdPayload")) + object.webdPayload = $root.proto.WebdPayload.toObject(message.webdPayload, options); + if (message.webSubPlatform != null && message.hasOwnProperty("webSubPlatform")) + object.webSubPlatform = options.enums === String ? $root.proto.WebInfo.WebInfoWebSubPlatform[message.webSubPlatform] : message.webSubPlatform; + return object; + }; + + /** + * Converts this WebInfo to JSON. + * @function toJSON + * @memberof proto.WebInfo + * @instance + * @returns {Object.} JSON object + */ + WebInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * WebInfoWebSubPlatform enum. + * @name proto.WebInfo.WebInfoWebSubPlatform + * @enum {number} + * @property {number} WEB_BROWSER=0 WEB_BROWSER value + * @property {number} APP_STORE=1 APP_STORE value + * @property {number} WIN_STORE=2 WIN_STORE value + * @property {number} DARWIN=3 DARWIN value + * @property {number} WIN32=4 WIN32 value + */ + WebInfo.WebInfoWebSubPlatform = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "WEB_BROWSER"] = 0; + values[valuesById[1] = "APP_STORE"] = 1; + values[valuesById[2] = "WIN_STORE"] = 2; + values[valuesById[3] = "DARWIN"] = 3; + values[valuesById[4] = "WIN32"] = 4; + return values; + })(); + + return WebInfo; + })(); + + proto.DNSSource = (function() { + + /** + * Properties of a DNSSource. + * @memberof proto + * @interface IDNSSource + * @property {proto.DNSSource.DNSSourceDNSResolutionMethod|null} [dnsMethod] DNSSource dnsMethod + * @property {boolean|null} [appCached] DNSSource appCached + */ + + /** + * Constructs a new DNSSource. + * @memberof proto + * @classdesc Represents a DNSSource. + * @implements IDNSSource + * @constructor + * @param {proto.IDNSSource=} [properties] Properties to set + */ + function DNSSource(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * DNSSource dnsMethod. + * @member {proto.DNSSource.DNSSourceDNSResolutionMethod} dnsMethod + * @memberof proto.DNSSource + * @instance + */ + DNSSource.prototype.dnsMethod = 0; + + /** + * DNSSource appCached. + * @member {boolean} appCached + * @memberof proto.DNSSource + * @instance + */ + DNSSource.prototype.appCached = false; + + /** + * Creates a new DNSSource instance using the specified properties. + * @function create + * @memberof proto.DNSSource + * @static + * @param {proto.IDNSSource=} [properties] Properties to set + * @returns {proto.DNSSource} DNSSource instance + */ + DNSSource.create = function create(properties) { + return new DNSSource(properties); + }; + + /** + * Encodes the specified DNSSource message. Does not implicitly {@link proto.DNSSource.verify|verify} messages. + * @function encode + * @memberof proto.DNSSource + * @static + * @param {proto.IDNSSource} message DNSSource message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DNSSource.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.dnsMethod != null && Object.hasOwnProperty.call(message, "dnsMethod")) + writer.uint32(/* id 15, wireType 0 =*/120).int32(message.dnsMethod); + if (message.appCached != null && Object.hasOwnProperty.call(message, "appCached")) + writer.uint32(/* id 16, wireType 0 =*/128).bool(message.appCached); + return writer; + }; + + /** + * Encodes the specified DNSSource message, length delimited. Does not implicitly {@link proto.DNSSource.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.DNSSource + * @static + * @param {proto.IDNSSource} message DNSSource message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DNSSource.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a DNSSource message from the specified reader or buffer. + * @function decode + * @memberof proto.DNSSource + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.DNSSource} DNSSource + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DNSSource.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DNSSource(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 15: + message.dnsMethod = reader.int32(); break; case 16: - message.ignore = reader.bool(); + message.appCached = reader.bool(); break; - case 17: - message.starred = reader.bool(); + default: + reader.skipType(tag & 7); break; - case 18: - message.broadcast = reader.bool(); + } + } + return message; + }; + + /** + * Decodes a DNSSource message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.DNSSource + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.DNSSource} DNSSource + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DNSSource.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a DNSSource message. + * @function verify + * @memberof proto.DNSSource + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + DNSSource.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.dnsMethod != null && message.hasOwnProperty("dnsMethod")) + switch (message.dnsMethod) { + default: + return "dnsMethod: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: break; - case 19: + } + if (message.appCached != null && message.hasOwnProperty("appCached")) + if (typeof message.appCached !== "boolean") + return "appCached: boolean expected"; + return null; + }; + + /** + * Creates a DNSSource message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.DNSSource + * @static + * @param {Object.} object Plain object + * @returns {proto.DNSSource} DNSSource + */ + DNSSource.fromObject = function fromObject(object) { + if (object instanceof $root.proto.DNSSource) + return object; + var message = new $root.proto.DNSSource(); + switch (object.dnsMethod) { + case "SYSTEM": + case 0: + message.dnsMethod = 0; + break; + case "GOOGLE": + case 1: + message.dnsMethod = 1; + break; + case "HARDCODED": + case 2: + message.dnsMethod = 2; + break; + case "OVERRIDE": + case 3: + message.dnsMethod = 3; + break; + case "FALLBACK": + case 4: + message.dnsMethod = 4; + break; + } + if (object.appCached != null) + message.appCached = Boolean(object.appCached); + return message; + }; + + /** + * Creates a plain object from a DNSSource message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.DNSSource + * @static + * @param {proto.DNSSource} message DNSSource + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + DNSSource.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.dnsMethod = options.enums === String ? "SYSTEM" : 0; + object.appCached = false; + } + if (message.dnsMethod != null && message.hasOwnProperty("dnsMethod")) + object.dnsMethod = options.enums === String ? $root.proto.DNSSource.DNSSourceDNSResolutionMethod[message.dnsMethod] : message.dnsMethod; + if (message.appCached != null && message.hasOwnProperty("appCached")) + object.appCached = message.appCached; + return object; + }; + + /** + * Converts this DNSSource to JSON. + * @function toJSON + * @memberof proto.DNSSource + * @instance + * @returns {Object.} JSON object + */ + DNSSource.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * DNSSourceDNSResolutionMethod enum. + * @name proto.DNSSource.DNSSourceDNSResolutionMethod + * @enum {number} + * @property {number} SYSTEM=0 SYSTEM value + * @property {number} GOOGLE=1 GOOGLE value + * @property {number} HARDCODED=2 HARDCODED value + * @property {number} OVERRIDE=3 OVERRIDE value + * @property {number} FALLBACK=4 FALLBACK value + */ + DNSSource.DNSSourceDNSResolutionMethod = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "SYSTEM"] = 0; + values[valuesById[1] = "GOOGLE"] = 1; + values[valuesById[2] = "HARDCODED"] = 2; + values[valuesById[3] = "OVERRIDE"] = 3; + values[valuesById[4] = "FALLBACK"] = 4; + return values; + })(); + + return DNSSource; + })(); + + proto.CompanionRegData = (function() { + + /** + * Properties of a CompanionRegData. + * @memberof proto + * @interface ICompanionRegData + * @property {Uint8Array|null} [eRegid] CompanionRegData eRegid + * @property {Uint8Array|null} [eKeytype] CompanionRegData eKeytype + * @property {Uint8Array|null} [eIdent] CompanionRegData eIdent + * @property {Uint8Array|null} [eSkeyId] CompanionRegData eSkeyId + * @property {Uint8Array|null} [eSkeyVal] CompanionRegData eSkeyVal + * @property {Uint8Array|null} [eSkeySig] CompanionRegData eSkeySig + * @property {Uint8Array|null} [buildHash] CompanionRegData buildHash + * @property {Uint8Array|null} [companionProps] CompanionRegData companionProps + */ + + /** + * Constructs a new CompanionRegData. + * @memberof proto + * @classdesc Represents a CompanionRegData. + * @implements ICompanionRegData + * @constructor + * @param {proto.ICompanionRegData=} [properties] Properties to set + */ + function CompanionRegData(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * CompanionRegData eRegid. + * @member {Uint8Array} eRegid + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.eRegid = $util.newBuffer([]); + + /** + * CompanionRegData eKeytype. + * @member {Uint8Array} eKeytype + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.eKeytype = $util.newBuffer([]); + + /** + * CompanionRegData eIdent. + * @member {Uint8Array} eIdent + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.eIdent = $util.newBuffer([]); + + /** + * CompanionRegData eSkeyId. + * @member {Uint8Array} eSkeyId + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.eSkeyId = $util.newBuffer([]); + + /** + * CompanionRegData eSkeyVal. + * @member {Uint8Array} eSkeyVal + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.eSkeyVal = $util.newBuffer([]); + + /** + * CompanionRegData eSkeySig. + * @member {Uint8Array} eSkeySig + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.eSkeySig = $util.newBuffer([]); + + /** + * CompanionRegData buildHash. + * @member {Uint8Array} buildHash + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.buildHash = $util.newBuffer([]); + + /** + * CompanionRegData companionProps. + * @member {Uint8Array} companionProps + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.companionProps = $util.newBuffer([]); + + /** + * Creates a new CompanionRegData instance using the specified properties. + * @function create + * @memberof proto.CompanionRegData + * @static + * @param {proto.ICompanionRegData=} [properties] Properties to set + * @returns {proto.CompanionRegData} CompanionRegData instance + */ + CompanionRegData.create = function create(properties) { + return new CompanionRegData(properties); + }; + + /** + * Encodes the specified CompanionRegData message. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages. + * @function encode + * @memberof proto.CompanionRegData + * @static + * @param {proto.ICompanionRegData} message CompanionRegData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CompanionRegData.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.eRegid != null && Object.hasOwnProperty.call(message, "eRegid")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.eRegid); + if (message.eKeytype != null && Object.hasOwnProperty.call(message, "eKeytype")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.eKeytype); + if (message.eIdent != null && Object.hasOwnProperty.call(message, "eIdent")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.eIdent); + if (message.eSkeyId != null && Object.hasOwnProperty.call(message, "eSkeyId")) + writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.eSkeyId); + if (message.eSkeyVal != null && Object.hasOwnProperty.call(message, "eSkeyVal")) + writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.eSkeyVal); + if (message.eSkeySig != null && Object.hasOwnProperty.call(message, "eSkeySig")) + writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.eSkeySig); + if (message.buildHash != null && Object.hasOwnProperty.call(message, "buildHash")) + writer.uint32(/* id 7, wireType 2 =*/58).bytes(message.buildHash); + if (message.companionProps != null && Object.hasOwnProperty.call(message, "companionProps")) + writer.uint32(/* id 8, wireType 2 =*/66).bytes(message.companionProps); + return writer; + }; + + /** + * Encodes the specified CompanionRegData message, length delimited. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.CompanionRegData + * @static + * @param {proto.ICompanionRegData} message CompanionRegData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CompanionRegData.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a CompanionRegData message from the specified reader or buffer. + * @function decode + * @memberof proto.CompanionRegData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.CompanionRegData} CompanionRegData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CompanionRegData.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CompanionRegData(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.eRegid = reader.bytes(); + break; + case 2: + message.eKeytype = reader.bytes(); + break; + case 3: + message.eIdent = reader.bytes(); + break; + case 4: + message.eSkeyId = reader.bytes(); + break; + case 5: + message.eSkeyVal = reader.bytes(); + break; + case 6: + message.eSkeySig = reader.bytes(); + break; + case 7: + message.buildHash = reader.bytes(); + break; + case 8: + message.companionProps = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a CompanionRegData message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.CompanionRegData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.CompanionRegData} CompanionRegData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CompanionRegData.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a CompanionRegData message. + * @function verify + * @memberof proto.CompanionRegData + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + CompanionRegData.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.eRegid != null && message.hasOwnProperty("eRegid")) + if (!(message.eRegid && typeof message.eRegid.length === "number" || $util.isString(message.eRegid))) + return "eRegid: buffer expected"; + if (message.eKeytype != null && message.hasOwnProperty("eKeytype")) + if (!(message.eKeytype && typeof message.eKeytype.length === "number" || $util.isString(message.eKeytype))) + return "eKeytype: buffer expected"; + if (message.eIdent != null && message.hasOwnProperty("eIdent")) + if (!(message.eIdent && typeof message.eIdent.length === "number" || $util.isString(message.eIdent))) + return "eIdent: buffer expected"; + if (message.eSkeyId != null && message.hasOwnProperty("eSkeyId")) + if (!(message.eSkeyId && typeof message.eSkeyId.length === "number" || $util.isString(message.eSkeyId))) + return "eSkeyId: buffer expected"; + if (message.eSkeyVal != null && message.hasOwnProperty("eSkeyVal")) + if (!(message.eSkeyVal && typeof message.eSkeyVal.length === "number" || $util.isString(message.eSkeyVal))) + return "eSkeyVal: buffer expected"; + if (message.eSkeySig != null && message.hasOwnProperty("eSkeySig")) + if (!(message.eSkeySig && typeof message.eSkeySig.length === "number" || $util.isString(message.eSkeySig))) + return "eSkeySig: buffer expected"; + if (message.buildHash != null && message.hasOwnProperty("buildHash")) + if (!(message.buildHash && typeof message.buildHash.length === "number" || $util.isString(message.buildHash))) + return "buildHash: buffer expected"; + if (message.companionProps != null && message.hasOwnProperty("companionProps")) + if (!(message.companionProps && typeof message.companionProps.length === "number" || $util.isString(message.companionProps))) + return "companionProps: buffer expected"; + return null; + }; + + /** + * Creates a CompanionRegData message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.CompanionRegData + * @static + * @param {Object.} object Plain object + * @returns {proto.CompanionRegData} CompanionRegData + */ + CompanionRegData.fromObject = function fromObject(object) { + if (object instanceof $root.proto.CompanionRegData) + return object; + var message = new $root.proto.CompanionRegData(); + if (object.eRegid != null) + if (typeof object.eRegid === "string") + $util.base64.decode(object.eRegid, message.eRegid = $util.newBuffer($util.base64.length(object.eRegid)), 0); + else if (object.eRegid.length) + message.eRegid = object.eRegid; + if (object.eKeytype != null) + if (typeof object.eKeytype === "string") + $util.base64.decode(object.eKeytype, message.eKeytype = $util.newBuffer($util.base64.length(object.eKeytype)), 0); + else if (object.eKeytype.length) + message.eKeytype = object.eKeytype; + if (object.eIdent != null) + if (typeof object.eIdent === "string") + $util.base64.decode(object.eIdent, message.eIdent = $util.newBuffer($util.base64.length(object.eIdent)), 0); + else if (object.eIdent.length) + message.eIdent = object.eIdent; + if (object.eSkeyId != null) + if (typeof object.eSkeyId === "string") + $util.base64.decode(object.eSkeyId, message.eSkeyId = $util.newBuffer($util.base64.length(object.eSkeyId)), 0); + else if (object.eSkeyId.length) + message.eSkeyId = object.eSkeyId; + if (object.eSkeyVal != null) + if (typeof object.eSkeyVal === "string") + $util.base64.decode(object.eSkeyVal, message.eSkeyVal = $util.newBuffer($util.base64.length(object.eSkeyVal)), 0); + else if (object.eSkeyVal.length) + message.eSkeyVal = object.eSkeyVal; + if (object.eSkeySig != null) + if (typeof object.eSkeySig === "string") + $util.base64.decode(object.eSkeySig, message.eSkeySig = $util.newBuffer($util.base64.length(object.eSkeySig)), 0); + else if (object.eSkeySig.length) + message.eSkeySig = object.eSkeySig; + if (object.buildHash != null) + if (typeof object.buildHash === "string") + $util.base64.decode(object.buildHash, message.buildHash = $util.newBuffer($util.base64.length(object.buildHash)), 0); + else if (object.buildHash.length) + message.buildHash = object.buildHash; + if (object.companionProps != null) + if (typeof object.companionProps === "string") + $util.base64.decode(object.companionProps, message.companionProps = $util.newBuffer($util.base64.length(object.companionProps)), 0); + else if (object.companionProps.length) + message.companionProps = object.companionProps; + return message; + }; + + /** + * Creates a plain object from a CompanionRegData message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.CompanionRegData + * @static + * @param {proto.CompanionRegData} message CompanionRegData + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + CompanionRegData.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.eRegid = ""; + else { + object.eRegid = []; + if (options.bytes !== Array) + object.eRegid = $util.newBuffer(object.eRegid); + } + if (options.bytes === String) + object.eKeytype = ""; + else { + object.eKeytype = []; + if (options.bytes !== Array) + object.eKeytype = $util.newBuffer(object.eKeytype); + } + if (options.bytes === String) + object.eIdent = ""; + else { + object.eIdent = []; + if (options.bytes !== Array) + object.eIdent = $util.newBuffer(object.eIdent); + } + if (options.bytes === String) + object.eSkeyId = ""; + else { + object.eSkeyId = []; + if (options.bytes !== Array) + object.eSkeyId = $util.newBuffer(object.eSkeyId); + } + if (options.bytes === String) + object.eSkeyVal = ""; + else { + object.eSkeyVal = []; + if (options.bytes !== Array) + object.eSkeyVal = $util.newBuffer(object.eSkeyVal); + } + if (options.bytes === String) + object.eSkeySig = ""; + else { + object.eSkeySig = []; + if (options.bytes !== Array) + object.eSkeySig = $util.newBuffer(object.eSkeySig); + } + if (options.bytes === String) + object.buildHash = ""; + else { + object.buildHash = []; + if (options.bytes !== Array) + object.buildHash = $util.newBuffer(object.buildHash); + } + if (options.bytes === String) + object.companionProps = ""; + else { + object.companionProps = []; + if (options.bytes !== Array) + object.companionProps = $util.newBuffer(object.companionProps); + } + } + if (message.eRegid != null && message.hasOwnProperty("eRegid")) + object.eRegid = options.bytes === String ? $util.base64.encode(message.eRegid, 0, message.eRegid.length) : options.bytes === Array ? Array.prototype.slice.call(message.eRegid) : message.eRegid; + if (message.eKeytype != null && message.hasOwnProperty("eKeytype")) + object.eKeytype = options.bytes === String ? $util.base64.encode(message.eKeytype, 0, message.eKeytype.length) : options.bytes === Array ? Array.prototype.slice.call(message.eKeytype) : message.eKeytype; + if (message.eIdent != null && message.hasOwnProperty("eIdent")) + object.eIdent = options.bytes === String ? $util.base64.encode(message.eIdent, 0, message.eIdent.length) : options.bytes === Array ? Array.prototype.slice.call(message.eIdent) : message.eIdent; + if (message.eSkeyId != null && message.hasOwnProperty("eSkeyId")) + object.eSkeyId = options.bytes === String ? $util.base64.encode(message.eSkeyId, 0, message.eSkeyId.length) : options.bytes === Array ? Array.prototype.slice.call(message.eSkeyId) : message.eSkeyId; + if (message.eSkeyVal != null && message.hasOwnProperty("eSkeyVal")) + object.eSkeyVal = options.bytes === String ? $util.base64.encode(message.eSkeyVal, 0, message.eSkeyVal.length) : options.bytes === Array ? Array.prototype.slice.call(message.eSkeyVal) : message.eSkeyVal; + if (message.eSkeySig != null && message.hasOwnProperty("eSkeySig")) + object.eSkeySig = options.bytes === String ? $util.base64.encode(message.eSkeySig, 0, message.eSkeySig.length) : options.bytes === Array ? Array.prototype.slice.call(message.eSkeySig) : message.eSkeySig; + if (message.buildHash != null && message.hasOwnProperty("buildHash")) + object.buildHash = options.bytes === String ? $util.base64.encode(message.buildHash, 0, message.buildHash.length) : options.bytes === Array ? Array.prototype.slice.call(message.buildHash) : message.buildHash; + if (message.companionProps != null && message.hasOwnProperty("companionProps")) + object.companionProps = options.bytes === String ? $util.base64.encode(message.companionProps, 0, message.companionProps.length) : options.bytes === Array ? Array.prototype.slice.call(message.companionProps) : message.companionProps; + return object; + }; + + /** + * Converts this CompanionRegData to JSON. + * @function toJSON + * @memberof proto.CompanionRegData + * @instance + * @returns {Object.} JSON object + */ + CompanionRegData.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return CompanionRegData; + })(); + + proto.ClientPayload = (function() { + + /** + * Properties of a ClientPayload. + * @memberof proto + * @interface IClientPayload + * @property {number|Long|null} [username] ClientPayload username + * @property {boolean|null} [passive] ClientPayload passive + * @property {Array.|null} [clientFeatures] ClientPayload clientFeatures + * @property {proto.IUserAgent|null} [userAgent] ClientPayload userAgent + * @property {proto.IWebInfo|null} [webInfo] ClientPayload webInfo + * @property {string|null} [pushName] ClientPayload pushName + * @property {number|null} [sessionId] ClientPayload sessionId + * @property {boolean|null} [shortConnect] ClientPayload shortConnect + * @property {proto.ClientPayload.ClientPayloadIOSAppExtension|null} [iosAppExtension] ClientPayload iosAppExtension + * @property {proto.ClientPayload.ClientPayloadConnectType|null} [connectType] ClientPayload connectType + * @property {proto.ClientPayload.ClientPayloadConnectReason|null} [connectReason] ClientPayload connectReason + * @property {Array.|null} [shards] ClientPayload shards + * @property {proto.IDNSSource|null} [dnsSource] ClientPayload dnsSource + * @property {number|null} [connectAttemptCount] ClientPayload connectAttemptCount + * @property {number|null} [agent] ClientPayload agent + * @property {number|null} [device] ClientPayload device + * @property {proto.ICompanionRegData|null} [regData] ClientPayload regData + * @property {proto.ClientPayload.ClientPayloadProduct|null} [product] ClientPayload product + * @property {Uint8Array|null} [fbCat] ClientPayload fbCat + * @property {Uint8Array|null} [fbUserAgent] ClientPayload fbUserAgent + * @property {boolean|null} [oc] ClientPayload oc + */ + + /** + * Constructs a new ClientPayload. + * @memberof proto + * @classdesc Represents a ClientPayload. + * @implements IClientPayload + * @constructor + * @param {proto.IClientPayload=} [properties] Properties to set + */ + function ClientPayload(properties) { + this.clientFeatures = []; + this.shards = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ClientPayload username. + * @member {number|Long} username + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.username = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * ClientPayload passive. + * @member {boolean} passive + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.passive = false; + + /** + * ClientPayload clientFeatures. + * @member {Array.} clientFeatures + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.clientFeatures = $util.emptyArray; + + /** + * ClientPayload userAgent. + * @member {proto.IUserAgent|null|undefined} userAgent + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.userAgent = null; + + /** + * ClientPayload webInfo. + * @member {proto.IWebInfo|null|undefined} webInfo + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.webInfo = null; + + /** + * ClientPayload pushName. + * @member {string} pushName + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.pushName = ""; + + /** + * ClientPayload sessionId. + * @member {number} sessionId + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.sessionId = 0; + + /** + * ClientPayload shortConnect. + * @member {boolean} shortConnect + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.shortConnect = false; + + /** + * ClientPayload iosAppExtension. + * @member {proto.ClientPayload.ClientPayloadIOSAppExtension} iosAppExtension + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.iosAppExtension = 0; + + /** + * ClientPayload connectType. + * @member {proto.ClientPayload.ClientPayloadConnectType} connectType + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.connectType = 0; + + /** + * ClientPayload connectReason. + * @member {proto.ClientPayload.ClientPayloadConnectReason} connectReason + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.connectReason = 0; + + /** + * ClientPayload shards. + * @member {Array.} shards + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.shards = $util.emptyArray; + + /** + * ClientPayload dnsSource. + * @member {proto.IDNSSource|null|undefined} dnsSource + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.dnsSource = null; + + /** + * ClientPayload connectAttemptCount. + * @member {number} connectAttemptCount + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.connectAttemptCount = 0; + + /** + * ClientPayload agent. + * @member {number} agent + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.agent = 0; + + /** + * ClientPayload device. + * @member {number} device + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.device = 0; + + /** + * ClientPayload regData. + * @member {proto.ICompanionRegData|null|undefined} regData + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.regData = null; + + /** + * ClientPayload product. + * @member {proto.ClientPayload.ClientPayloadProduct} product + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.product = 0; + + /** + * ClientPayload fbCat. + * @member {Uint8Array} fbCat + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.fbCat = $util.newBuffer([]); + + /** + * ClientPayload fbUserAgent. + * @member {Uint8Array} fbUserAgent + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.fbUserAgent = $util.newBuffer([]); + + /** + * ClientPayload oc. + * @member {boolean} oc + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.oc = false; + + /** + * Creates a new ClientPayload instance using the specified properties. + * @function create + * @memberof proto.ClientPayload + * @static + * @param {proto.IClientPayload=} [properties] Properties to set + * @returns {proto.ClientPayload} ClientPayload instance + */ + ClientPayload.create = function create(properties) { + return new ClientPayload(properties); + }; + + /** + * Encodes the specified ClientPayload message. Does not implicitly {@link proto.ClientPayload.verify|verify} messages. + * @function encode + * @memberof proto.ClientPayload + * @static + * @param {proto.IClientPayload} message ClientPayload message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClientPayload.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.username != null && Object.hasOwnProperty.call(message, "username")) + writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.username); + if (message.passive != null && Object.hasOwnProperty.call(message, "passive")) + writer.uint32(/* id 3, wireType 0 =*/24).bool(message.passive); + if (message.clientFeatures != null && message.clientFeatures.length) + for (var i = 0; i < message.clientFeatures.length; ++i) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.clientFeatures[i]); + if (message.userAgent != null && Object.hasOwnProperty.call(message, "userAgent")) + $root.proto.UserAgent.encode(message.userAgent, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + if (message.webInfo != null && Object.hasOwnProperty.call(message, "webInfo")) + $root.proto.WebInfo.encode(message.webInfo, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.pushName != null && Object.hasOwnProperty.call(message, "pushName")) + writer.uint32(/* id 7, wireType 2 =*/58).string(message.pushName); + if (message.sessionId != null && Object.hasOwnProperty.call(message, "sessionId")) + writer.uint32(/* id 9, wireType 5 =*/77).sfixed32(message.sessionId); + if (message.shortConnect != null && Object.hasOwnProperty.call(message, "shortConnect")) + writer.uint32(/* id 10, wireType 0 =*/80).bool(message.shortConnect); + if (message.connectType != null && Object.hasOwnProperty.call(message, "connectType")) + writer.uint32(/* id 12, wireType 0 =*/96).int32(message.connectType); + if (message.connectReason != null && Object.hasOwnProperty.call(message, "connectReason")) + writer.uint32(/* id 13, wireType 0 =*/104).int32(message.connectReason); + if (message.shards != null && message.shards.length) + for (var i = 0; i < message.shards.length; ++i) + writer.uint32(/* id 14, wireType 0 =*/112).int32(message.shards[i]); + if (message.dnsSource != null && Object.hasOwnProperty.call(message, "dnsSource")) + $root.proto.DNSSource.encode(message.dnsSource, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim(); + if (message.connectAttemptCount != null && Object.hasOwnProperty.call(message, "connectAttemptCount")) + writer.uint32(/* id 16, wireType 0 =*/128).uint32(message.connectAttemptCount); + if (message.agent != null && Object.hasOwnProperty.call(message, "agent")) + writer.uint32(/* id 17, wireType 0 =*/136).uint32(message.agent); + if (message.device != null && Object.hasOwnProperty.call(message, "device")) + writer.uint32(/* id 18, wireType 0 =*/144).uint32(message.device); + if (message.regData != null && Object.hasOwnProperty.call(message, "regData")) + $root.proto.CompanionRegData.encode(message.regData, writer.uint32(/* id 19, wireType 2 =*/154).fork()).ldelim(); + if (message.product != null && Object.hasOwnProperty.call(message, "product")) + writer.uint32(/* id 20, wireType 0 =*/160).int32(message.product); + if (message.fbCat != null && Object.hasOwnProperty.call(message, "fbCat")) + writer.uint32(/* id 21, wireType 2 =*/170).bytes(message.fbCat); + if (message.fbUserAgent != null && Object.hasOwnProperty.call(message, "fbUserAgent")) + writer.uint32(/* id 22, wireType 2 =*/178).bytes(message.fbUserAgent); + if (message.oc != null && Object.hasOwnProperty.call(message, "oc")) + writer.uint32(/* id 23, wireType 0 =*/184).bool(message.oc); + if (message.iosAppExtension != null && Object.hasOwnProperty.call(message, "iosAppExtension")) + writer.uint32(/* id 30, wireType 0 =*/240).int32(message.iosAppExtension); + return writer; + }; + + /** + * Encodes the specified ClientPayload message, length delimited. Does not implicitly {@link proto.ClientPayload.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ClientPayload + * @static + * @param {proto.IClientPayload} message ClientPayload message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClientPayload.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ClientPayload message from the specified reader or buffer. + * @function decode + * @memberof proto.ClientPayload + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ClientPayload} ClientPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClientPayload.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClientPayload(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.username = reader.uint64(); + break; + case 3: + message.passive = reader.bool(); + break; + case 4: + if (!(message.clientFeatures && message.clientFeatures.length)) + message.clientFeatures = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.clientFeatures.push(reader.int32()); + } else + message.clientFeatures.push(reader.int32()); + break; + case 5: + message.userAgent = $root.proto.UserAgent.decode(reader, reader.uint32()); + break; + case 6: + message.webInfo = $root.proto.WebInfo.decode(reader, reader.uint32()); + break; + case 7: message.pushName = reader.string(); break; - case 20: - message.mediaCiphertextSha256 = reader.bytes(); + case 9: + message.sessionId = reader.sfixed32(); break; - case 21: - message.multicast = reader.bool(); - break; - case 22: - message.urlText = reader.bool(); - break; - case 23: - message.urlNumber = reader.bool(); - break; - case 24: - message.messageStubType = reader.int32(); - break; - case 25: - message.clearMedia = reader.bool(); - break; - case 26: - if (!(message.messageStubParameters && message.messageStubParameters.length)) - message.messageStubParameters = []; - message.messageStubParameters.push(reader.string()); - break; - case 27: - message.duration = reader.uint32(); - break; - case 28: - if (!(message.labels && message.labels.length)) - message.labels = []; - message.labels.push(reader.string()); - break; - case 29: - message.paymentInfo = $root.proto.PaymentInfo.decode(reader, reader.uint32()); + case 10: + message.shortConnect = reader.bool(); break; case 30: - message.finalLiveLocation = $root.proto.LiveLocationMessage.decode(reader, reader.uint32()); + message.iosAppExtension = reader.int32(); break; - case 31: - message.quotedPaymentInfo = $root.proto.PaymentInfo.decode(reader, reader.uint32()); + case 12: + message.connectType = reader.int32(); break; - case 32: - message.ephemeralStartTimestamp = reader.uint64(); + case 13: + message.connectReason = reader.int32(); break; - case 33: - message.ephemeralDuration = reader.uint32(); + case 14: + if (!(message.shards && message.shards.length)) + message.shards = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.shards.push(reader.int32()); + } else + message.shards.push(reader.int32()); break; - case 34: - message.ephemeralOffToOn = reader.bool(); + case 15: + message.dnsSource = $root.proto.DNSSource.decode(reader, reader.uint32()); break; - case 35: - message.ephemeralOutOfSync = reader.bool(); + case 16: + message.connectAttemptCount = reader.uint32(); break; - case 36: - message.bizPrivacyStatus = reader.int32(); + case 17: + message.agent = reader.uint32(); break; - case 37: - message.verifiedBizName = reader.string(); + case 18: + message.device = reader.uint32(); + break; + case 19: + message.regData = $root.proto.CompanionRegData.decode(reader, reader.uint32()); + break; + case 20: + message.product = reader.int32(); + break; + case 21: + message.fbCat = reader.bytes(); + break; + case 22: + message.fbUserAgent = reader.bytes(); + break; + case 23: + message.oc = reader.bool(); break; default: reader.skipType(tag & 7); break; } } - if (!message.hasOwnProperty("key")) - throw $util.ProtocolError("missing required 'key'", { instance: message }); return message; }; /** - * Decodes a WebMessageInfo message from the specified reader or buffer, length delimited. + * Decodes a ClientPayload message from the specified reader or buffer, length delimited. * @function decodeDelimited - * @memberof proto.WebMessageInfo + * @memberof proto.ClientPayload * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.WebMessageInfo} WebMessageInfo + * @returns {proto.ClientPayload} ClientPayload * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - WebMessageInfo.decodeDelimited = function decodeDelimited(reader) { + ClientPayload.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; /** - * Verifies a WebMessageInfo message. + * Verifies a ClientPayload message. * @function verify - * @memberof proto.WebMessageInfo + * @memberof proto.ClientPayload * @static * @param {Object.} message Plain object to verify * @returns {string|null} `null` if valid, otherwise the reason why it is not */ - WebMessageInfo.verify = function verify(message) { + ClientPayload.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - { - var error = $root.proto.MessageKey.verify(message.key); - if (error) - return "key." + error; + if (message.username != null && message.hasOwnProperty("username")) + if (!$util.isInteger(message.username) && !(message.username && $util.isInteger(message.username.low) && $util.isInteger(message.username.high))) + return "username: integer|Long expected"; + if (message.passive != null && message.hasOwnProperty("passive")) + if (typeof message.passive !== "boolean") + return "passive: boolean expected"; + if (message.clientFeatures != null && message.hasOwnProperty("clientFeatures")) { + if (!Array.isArray(message.clientFeatures)) + return "clientFeatures: array expected"; + for (var i = 0; i < message.clientFeatures.length; ++i) + switch (message.clientFeatures[i]) { + default: + return "clientFeatures: enum value[] expected"; + case 0: + break; + } } - if (message.message != null && message.hasOwnProperty("message")) { - var error = $root.proto.Message.verify(message.message); + if (message.userAgent != null && message.hasOwnProperty("userAgent")) { + var error = $root.proto.UserAgent.verify(message.userAgent); if (error) - return "message." + error; + return "userAgent." + error; + } + if (message.webInfo != null && message.hasOwnProperty("webInfo")) { + var error = $root.proto.WebInfo.verify(message.webInfo); + if (error) + return "webInfo." + error; } - if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) - if (!$util.isInteger(message.messageTimestamp) && !(message.messageTimestamp && $util.isInteger(message.messageTimestamp.low) && $util.isInteger(message.messageTimestamp.high))) - return "messageTimestamp: integer|Long expected"; - if (message.status != null && message.hasOwnProperty("status")) - switch (message.status) { - default: - return "status: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - break; - } - if (message.participant != null && message.hasOwnProperty("participant")) - if (!$util.isString(message.participant)) - return "participant: string expected"; - if (message.ignore != null && message.hasOwnProperty("ignore")) - if (typeof message.ignore !== "boolean") - return "ignore: boolean expected"; - if (message.starred != null && message.hasOwnProperty("starred")) - if (typeof message.starred !== "boolean") - return "starred: boolean expected"; - if (message.broadcast != null && message.hasOwnProperty("broadcast")) - if (typeof message.broadcast !== "boolean") - return "broadcast: boolean expected"; if (message.pushName != null && message.hasOwnProperty("pushName")) if (!$util.isString(message.pushName)) return "pushName: string expected"; - if (message.mediaCiphertextSha256 != null && message.hasOwnProperty("mediaCiphertextSha256")) - if (!(message.mediaCiphertextSha256 && typeof message.mediaCiphertextSha256.length === "number" || $util.isString(message.mediaCiphertextSha256))) - return "mediaCiphertextSha256: buffer expected"; - if (message.multicast != null && message.hasOwnProperty("multicast")) - if (typeof message.multicast !== "boolean") - return "multicast: boolean expected"; - if (message.urlText != null && message.hasOwnProperty("urlText")) - if (typeof message.urlText !== "boolean") - return "urlText: boolean expected"; - if (message.urlNumber != null && message.hasOwnProperty("urlNumber")) - if (typeof message.urlNumber !== "boolean") - return "urlNumber: boolean expected"; - if (message.messageStubType != null && message.hasOwnProperty("messageStubType")) - switch (message.messageStubType) { + if (message.sessionId != null && message.hasOwnProperty("sessionId")) + if (!$util.isInteger(message.sessionId)) + return "sessionId: integer expected"; + if (message.shortConnect != null && message.hasOwnProperty("shortConnect")) + if (typeof message.shortConnect !== "boolean") + return "shortConnect: boolean expected"; + if (message.iosAppExtension != null && message.hasOwnProperty("iosAppExtension")) + switch (message.iosAppExtension) { default: - return "messageStubType: enum value expected"; + return "iosAppExtension: enum value expected"; case 0: case 1: case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: - case 20: - case 21: - case 22: - case 23: - case 24: - case 25: - case 26: - case 27: - case 28: - case 29: - case 30: - case 31: - case 32: - case 33: - case 34: - case 35: - case 36: - case 37: - case 38: - case 39: - case 40: - case 41: - case 42: - case 43: - case 44: - case 45: - case 46: - case 47: - case 48: - case 49: - case 50: - case 51: - case 52: - case 53: - case 54: - case 55: - case 56: - case 57: - case 58: - case 59: - case 60: - case 61: - case 62: - case 63: - case 64: - case 65: - case 66: - case 67: - case 68: - case 69: - case 70: - case 71: - case 72: - case 73: - case 74: - case 75: - case 76: - case 77: - case 78: - case 79: - case 80: - case 81: - case 82: - case 83: - case 84: - case 85: - case 86: - case 87: - case 88: - case 89: - case 90: - case 91: - case 92: - case 93: - case 94: - case 95: - case 96: - case 97: - case 98: - case 99: + break; + } + if (message.connectType != null && message.hasOwnProperty("connectType")) + switch (message.connectType) { + default: + return "connectType: enum value expected"; + case 0: + case 1: case 100: case 101: case 102: @@ -3873,1131 +2875,15497 @@ $root.proto = (function() { case 110: case 111: case 112: - case 113: - case 114: - case 115: - case 116: - case 117: - case 118: break; } - if (message.clearMedia != null && message.hasOwnProperty("clearMedia")) - if (typeof message.clearMedia !== "boolean") - return "clearMedia: boolean expected"; - if (message.messageStubParameters != null && message.hasOwnProperty("messageStubParameters")) { - if (!Array.isArray(message.messageStubParameters)) - return "messageStubParameters: array expected"; - for (var i = 0; i < message.messageStubParameters.length; ++i) - if (!$util.isString(message.messageStubParameters[i])) - return "messageStubParameters: string[] expected"; - } - if (message.duration != null && message.hasOwnProperty("duration")) - if (!$util.isInteger(message.duration)) - return "duration: integer expected"; - if (message.labels != null && message.hasOwnProperty("labels")) { - if (!Array.isArray(message.labels)) - return "labels: array expected"; - for (var i = 0; i < message.labels.length; ++i) - if (!$util.isString(message.labels[i])) - return "labels: string[] expected"; - } - if (message.paymentInfo != null && message.hasOwnProperty("paymentInfo")) { - var error = $root.proto.PaymentInfo.verify(message.paymentInfo); - if (error) - return "paymentInfo." + error; - } - if (message.finalLiveLocation != null && message.hasOwnProperty("finalLiveLocation")) { - var error = $root.proto.LiveLocationMessage.verify(message.finalLiveLocation); - if (error) - return "finalLiveLocation." + error; - } - if (message.quotedPaymentInfo != null && message.hasOwnProperty("quotedPaymentInfo")) { - var error = $root.proto.PaymentInfo.verify(message.quotedPaymentInfo); - if (error) - return "quotedPaymentInfo." + error; - } - if (message.ephemeralStartTimestamp != null && message.hasOwnProperty("ephemeralStartTimestamp")) - if (!$util.isInteger(message.ephemeralStartTimestamp) && !(message.ephemeralStartTimestamp && $util.isInteger(message.ephemeralStartTimestamp.low) && $util.isInteger(message.ephemeralStartTimestamp.high))) - return "ephemeralStartTimestamp: integer|Long expected"; - if (message.ephemeralDuration != null && message.hasOwnProperty("ephemeralDuration")) - if (!$util.isInteger(message.ephemeralDuration)) - return "ephemeralDuration: integer expected"; - if (message.ephemeralOffToOn != null && message.hasOwnProperty("ephemeralOffToOn")) - if (typeof message.ephemeralOffToOn !== "boolean") - return "ephemeralOffToOn: boolean expected"; - if (message.ephemeralOutOfSync != null && message.hasOwnProperty("ephemeralOutOfSync")) - if (typeof message.ephemeralOutOfSync !== "boolean") - return "ephemeralOutOfSync: boolean expected"; - if (message.bizPrivacyStatus != null && message.hasOwnProperty("bizPrivacyStatus")) - switch (message.bizPrivacyStatus) { + if (message.connectReason != null && message.hasOwnProperty("connectReason")) + switch (message.connectReason) { default: - return "bizPrivacyStatus: enum value expected"; + return "connectReason: enum value expected"; case 0: - case 2: case 1: + case 2: case 3: + case 4: + case 5: break; } - if (message.verifiedBizName != null && message.hasOwnProperty("verifiedBizName")) - if (!$util.isString(message.verifiedBizName)) - return "verifiedBizName: string expected"; + if (message.shards != null && message.hasOwnProperty("shards")) { + if (!Array.isArray(message.shards)) + return "shards: array expected"; + for (var i = 0; i < message.shards.length; ++i) + if (!$util.isInteger(message.shards[i])) + return "shards: integer[] expected"; + } + if (message.dnsSource != null && message.hasOwnProperty("dnsSource")) { + var error = $root.proto.DNSSource.verify(message.dnsSource); + if (error) + return "dnsSource." + error; + } + if (message.connectAttemptCount != null && message.hasOwnProperty("connectAttemptCount")) + if (!$util.isInteger(message.connectAttemptCount)) + return "connectAttemptCount: integer expected"; + if (message.agent != null && message.hasOwnProperty("agent")) + if (!$util.isInteger(message.agent)) + return "agent: integer expected"; + if (message.device != null && message.hasOwnProperty("device")) + if (!$util.isInteger(message.device)) + return "device: integer expected"; + if (message.regData != null && message.hasOwnProperty("regData")) { + var error = $root.proto.CompanionRegData.verify(message.regData); + if (error) + return "regData." + error; + } + if (message.product != null && message.hasOwnProperty("product")) + switch (message.product) { + default: + return "product: enum value expected"; + case 0: + case 1: + break; + } + if (message.fbCat != null && message.hasOwnProperty("fbCat")) + if (!(message.fbCat && typeof message.fbCat.length === "number" || $util.isString(message.fbCat))) + return "fbCat: buffer expected"; + if (message.fbUserAgent != null && message.hasOwnProperty("fbUserAgent")) + if (!(message.fbUserAgent && typeof message.fbUserAgent.length === "number" || $util.isString(message.fbUserAgent))) + return "fbUserAgent: buffer expected"; + if (message.oc != null && message.hasOwnProperty("oc")) + if (typeof message.oc !== "boolean") + return "oc: boolean expected"; return null; }; /** - * Creates a WebMessageInfo message from a plain object. Also converts values to their respective internal types. + * Creates a ClientPayload message from a plain object. Also converts values to their respective internal types. * @function fromObject - * @memberof proto.WebMessageInfo + * @memberof proto.ClientPayload * @static * @param {Object.} object Plain object - * @returns {proto.WebMessageInfo} WebMessageInfo + * @returns {proto.ClientPayload} ClientPayload */ - WebMessageInfo.fromObject = function fromObject(object) { - if (object instanceof $root.proto.WebMessageInfo) + ClientPayload.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ClientPayload) return object; - var message = new $root.proto.WebMessageInfo(); - if (object.key != null) { - if (typeof object.key !== "object") - throw TypeError(".proto.WebMessageInfo.key: object expected"); - message.key = $root.proto.MessageKey.fromObject(object.key); + var message = new $root.proto.ClientPayload(); + if (object.username != null) + if ($util.Long) + (message.username = $util.Long.fromValue(object.username)).unsigned = true; + else if (typeof object.username === "string") + message.username = parseInt(object.username, 10); + else if (typeof object.username === "number") + message.username = object.username; + else if (typeof object.username === "object") + message.username = new $util.LongBits(object.username.low >>> 0, object.username.high >>> 0).toNumber(true); + if (object.passive != null) + message.passive = Boolean(object.passive); + if (object.clientFeatures) { + if (!Array.isArray(object.clientFeatures)) + throw TypeError(".proto.ClientPayload.clientFeatures: array expected"); + message.clientFeatures = []; + for (var i = 0; i < object.clientFeatures.length; ++i) + switch (object.clientFeatures[i]) { + default: + case "NONE": + case 0: + message.clientFeatures[i] = 0; + break; + } } - if (object.message != null) { - if (typeof object.message !== "object") - throw TypeError(".proto.WebMessageInfo.message: object expected"); - message.message = $root.proto.Message.fromObject(object.message); + if (object.userAgent != null) { + if (typeof object.userAgent !== "object") + throw TypeError(".proto.ClientPayload.userAgent: object expected"); + message.userAgent = $root.proto.UserAgent.fromObject(object.userAgent); } + if (object.webInfo != null) { + if (typeof object.webInfo !== "object") + throw TypeError(".proto.ClientPayload.webInfo: object expected"); + message.webInfo = $root.proto.WebInfo.fromObject(object.webInfo); + } + if (object.pushName != null) + message.pushName = String(object.pushName); + if (object.sessionId != null) + message.sessionId = object.sessionId | 0; + if (object.shortConnect != null) + message.shortConnect = Boolean(object.shortConnect); + switch (object.iosAppExtension) { + case "SHARE_EXTENSION": + case 0: + message.iosAppExtension = 0; + break; + case "SERVICE_EXTENSION": + case 1: + message.iosAppExtension = 1; + break; + case "INTENTS_EXTENSION": + case 2: + message.iosAppExtension = 2; + break; + } + switch (object.connectType) { + case "CELLULAR_UNKNOWN": + case 0: + message.connectType = 0; + break; + case "WIFI_UNKNOWN": + case 1: + message.connectType = 1; + break; + case "CELLULAR_EDGE": + case 100: + message.connectType = 100; + break; + case "CELLULAR_IDEN": + case 101: + message.connectType = 101; + break; + case "CELLULAR_UMTS": + case 102: + message.connectType = 102; + break; + case "CELLULAR_EVDO": + case 103: + message.connectType = 103; + break; + case "CELLULAR_GPRS": + case 104: + message.connectType = 104; + break; + case "CELLULAR_HSDPA": + case 105: + message.connectType = 105; + break; + case "CELLULAR_HSUPA": + case 106: + message.connectType = 106; + break; + case "CELLULAR_HSPA": + case 107: + message.connectType = 107; + break; + case "CELLULAR_CDMA": + case 108: + message.connectType = 108; + break; + case "CELLULAR_1XRTT": + case 109: + message.connectType = 109; + break; + case "CELLULAR_EHRPD": + case 110: + message.connectType = 110; + break; + case "CELLULAR_LTE": + case 111: + message.connectType = 111; + break; + case "CELLULAR_HSPAP": + case 112: + message.connectType = 112; + break; + } + switch (object.connectReason) { + case "PUSH": + case 0: + message.connectReason = 0; + break; + case "USER_ACTIVATED": + case 1: + message.connectReason = 1; + break; + case "SCHEDULED": + case 2: + message.connectReason = 2; + break; + case "ERROR_RECONNECT": + case 3: + message.connectReason = 3; + break; + case "NETWORK_SWITCH": + case 4: + message.connectReason = 4; + break; + case "PING_RECONNECT": + case 5: + message.connectReason = 5; + break; + } + if (object.shards) { + if (!Array.isArray(object.shards)) + throw TypeError(".proto.ClientPayload.shards: array expected"); + message.shards = []; + for (var i = 0; i < object.shards.length; ++i) + message.shards[i] = object.shards[i] | 0; + } + if (object.dnsSource != null) { + if (typeof object.dnsSource !== "object") + throw TypeError(".proto.ClientPayload.dnsSource: object expected"); + message.dnsSource = $root.proto.DNSSource.fromObject(object.dnsSource); + } + if (object.connectAttemptCount != null) + message.connectAttemptCount = object.connectAttemptCount >>> 0; + if (object.agent != null) + message.agent = object.agent >>> 0; + if (object.device != null) + message.device = object.device >>> 0; + if (object.regData != null) { + if (typeof object.regData !== "object") + throw TypeError(".proto.ClientPayload.regData: object expected"); + message.regData = $root.proto.CompanionRegData.fromObject(object.regData); + } + switch (object.product) { + case "WHATSAPP": + case 0: + message.product = 0; + break; + case "MESSENGER": + case 1: + message.product = 1; + break; + } + if (object.fbCat != null) + if (typeof object.fbCat === "string") + $util.base64.decode(object.fbCat, message.fbCat = $util.newBuffer($util.base64.length(object.fbCat)), 0); + else if (object.fbCat.length) + message.fbCat = object.fbCat; + if (object.fbUserAgent != null) + if (typeof object.fbUserAgent === "string") + $util.base64.decode(object.fbUserAgent, message.fbUserAgent = $util.newBuffer($util.base64.length(object.fbUserAgent)), 0); + else if (object.fbUserAgent.length) + message.fbUserAgent = object.fbUserAgent; + if (object.oc != null) + message.oc = Boolean(object.oc); + return message; + }; + + /** + * Creates a plain object from a ClientPayload message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ClientPayload + * @static + * @param {proto.ClientPayload} message ClientPayload + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ClientPayload.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.clientFeatures = []; + object.shards = []; + } + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.username = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.username = options.longs === String ? "0" : 0; + object.passive = false; + object.userAgent = null; + object.webInfo = null; + object.pushName = ""; + object.sessionId = 0; + object.shortConnect = false; + object.connectType = options.enums === String ? "CELLULAR_UNKNOWN" : 0; + object.connectReason = options.enums === String ? "PUSH" : 0; + object.dnsSource = null; + object.connectAttemptCount = 0; + object.agent = 0; + object.device = 0; + object.regData = null; + object.product = options.enums === String ? "WHATSAPP" : 0; + if (options.bytes === String) + object.fbCat = ""; + else { + object.fbCat = []; + if (options.bytes !== Array) + object.fbCat = $util.newBuffer(object.fbCat); + } + if (options.bytes === String) + object.fbUserAgent = ""; + else { + object.fbUserAgent = []; + if (options.bytes !== Array) + object.fbUserAgent = $util.newBuffer(object.fbUserAgent); + } + object.oc = false; + object.iosAppExtension = options.enums === String ? "SHARE_EXTENSION" : 0; + } + if (message.username != null && message.hasOwnProperty("username")) + if (typeof message.username === "number") + object.username = options.longs === String ? String(message.username) : message.username; + else + object.username = options.longs === String ? $util.Long.prototype.toString.call(message.username) : options.longs === Number ? new $util.LongBits(message.username.low >>> 0, message.username.high >>> 0).toNumber(true) : message.username; + if (message.passive != null && message.hasOwnProperty("passive")) + object.passive = message.passive; + if (message.clientFeatures && message.clientFeatures.length) { + object.clientFeatures = []; + for (var j = 0; j < message.clientFeatures.length; ++j) + object.clientFeatures[j] = options.enums === String ? $root.proto.ClientPayload.ClientPayloadClientFeature[message.clientFeatures[j]] : message.clientFeatures[j]; + } + if (message.userAgent != null && message.hasOwnProperty("userAgent")) + object.userAgent = $root.proto.UserAgent.toObject(message.userAgent, options); + if (message.webInfo != null && message.hasOwnProperty("webInfo")) + object.webInfo = $root.proto.WebInfo.toObject(message.webInfo, options); + if (message.pushName != null && message.hasOwnProperty("pushName")) + object.pushName = message.pushName; + if (message.sessionId != null && message.hasOwnProperty("sessionId")) + object.sessionId = message.sessionId; + if (message.shortConnect != null && message.hasOwnProperty("shortConnect")) + object.shortConnect = message.shortConnect; + if (message.connectType != null && message.hasOwnProperty("connectType")) + object.connectType = options.enums === String ? $root.proto.ClientPayload.ClientPayloadConnectType[message.connectType] : message.connectType; + if (message.connectReason != null && message.hasOwnProperty("connectReason")) + object.connectReason = options.enums === String ? $root.proto.ClientPayload.ClientPayloadConnectReason[message.connectReason] : message.connectReason; + if (message.shards && message.shards.length) { + object.shards = []; + for (var j = 0; j < message.shards.length; ++j) + object.shards[j] = message.shards[j]; + } + if (message.dnsSource != null && message.hasOwnProperty("dnsSource")) + object.dnsSource = $root.proto.DNSSource.toObject(message.dnsSource, options); + if (message.connectAttemptCount != null && message.hasOwnProperty("connectAttemptCount")) + object.connectAttemptCount = message.connectAttemptCount; + if (message.agent != null && message.hasOwnProperty("agent")) + object.agent = message.agent; + if (message.device != null && message.hasOwnProperty("device")) + object.device = message.device; + if (message.regData != null && message.hasOwnProperty("regData")) + object.regData = $root.proto.CompanionRegData.toObject(message.regData, options); + if (message.product != null && message.hasOwnProperty("product")) + object.product = options.enums === String ? $root.proto.ClientPayload.ClientPayloadProduct[message.product] : message.product; + if (message.fbCat != null && message.hasOwnProperty("fbCat")) + object.fbCat = options.bytes === String ? $util.base64.encode(message.fbCat, 0, message.fbCat.length) : options.bytes === Array ? Array.prototype.slice.call(message.fbCat) : message.fbCat; + if (message.fbUserAgent != null && message.hasOwnProperty("fbUserAgent")) + object.fbUserAgent = options.bytes === String ? $util.base64.encode(message.fbUserAgent, 0, message.fbUserAgent.length) : options.bytes === Array ? Array.prototype.slice.call(message.fbUserAgent) : message.fbUserAgent; + if (message.oc != null && message.hasOwnProperty("oc")) + object.oc = message.oc; + if (message.iosAppExtension != null && message.hasOwnProperty("iosAppExtension")) + object.iosAppExtension = options.enums === String ? $root.proto.ClientPayload.ClientPayloadIOSAppExtension[message.iosAppExtension] : message.iosAppExtension; + return object; + }; + + /** + * Converts this ClientPayload to JSON. + * @function toJSON + * @memberof proto.ClientPayload + * @instance + * @returns {Object.} JSON object + */ + ClientPayload.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * ClientPayloadClientFeature enum. + * @name proto.ClientPayload.ClientPayloadClientFeature + * @enum {number} + * @property {number} NONE=0 NONE value + */ + ClientPayload.ClientPayloadClientFeature = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "NONE"] = 0; + return values; + })(); + + /** + * ClientPayloadIOSAppExtension enum. + * @name proto.ClientPayload.ClientPayloadIOSAppExtension + * @enum {number} + * @property {number} SHARE_EXTENSION=0 SHARE_EXTENSION value + * @property {number} SERVICE_EXTENSION=1 SERVICE_EXTENSION value + * @property {number} INTENTS_EXTENSION=2 INTENTS_EXTENSION value + */ + ClientPayload.ClientPayloadIOSAppExtension = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "SHARE_EXTENSION"] = 0; + values[valuesById[1] = "SERVICE_EXTENSION"] = 1; + values[valuesById[2] = "INTENTS_EXTENSION"] = 2; + return values; + })(); + + /** + * ClientPayloadConnectType enum. + * @name proto.ClientPayload.ClientPayloadConnectType + * @enum {number} + * @property {number} CELLULAR_UNKNOWN=0 CELLULAR_UNKNOWN value + * @property {number} WIFI_UNKNOWN=1 WIFI_UNKNOWN value + * @property {number} CELLULAR_EDGE=100 CELLULAR_EDGE value + * @property {number} CELLULAR_IDEN=101 CELLULAR_IDEN value + * @property {number} CELLULAR_UMTS=102 CELLULAR_UMTS value + * @property {number} CELLULAR_EVDO=103 CELLULAR_EVDO value + * @property {number} CELLULAR_GPRS=104 CELLULAR_GPRS value + * @property {number} CELLULAR_HSDPA=105 CELLULAR_HSDPA value + * @property {number} CELLULAR_HSUPA=106 CELLULAR_HSUPA value + * @property {number} CELLULAR_HSPA=107 CELLULAR_HSPA value + * @property {number} CELLULAR_CDMA=108 CELLULAR_CDMA value + * @property {number} CELLULAR_1XRTT=109 CELLULAR_1XRTT value + * @property {number} CELLULAR_EHRPD=110 CELLULAR_EHRPD value + * @property {number} CELLULAR_LTE=111 CELLULAR_LTE value + * @property {number} CELLULAR_HSPAP=112 CELLULAR_HSPAP value + */ + ClientPayload.ClientPayloadConnectType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "CELLULAR_UNKNOWN"] = 0; + values[valuesById[1] = "WIFI_UNKNOWN"] = 1; + values[valuesById[100] = "CELLULAR_EDGE"] = 100; + values[valuesById[101] = "CELLULAR_IDEN"] = 101; + values[valuesById[102] = "CELLULAR_UMTS"] = 102; + values[valuesById[103] = "CELLULAR_EVDO"] = 103; + values[valuesById[104] = "CELLULAR_GPRS"] = 104; + values[valuesById[105] = "CELLULAR_HSDPA"] = 105; + values[valuesById[106] = "CELLULAR_HSUPA"] = 106; + values[valuesById[107] = "CELLULAR_HSPA"] = 107; + values[valuesById[108] = "CELLULAR_CDMA"] = 108; + values[valuesById[109] = "CELLULAR_1XRTT"] = 109; + values[valuesById[110] = "CELLULAR_EHRPD"] = 110; + values[valuesById[111] = "CELLULAR_LTE"] = 111; + values[valuesById[112] = "CELLULAR_HSPAP"] = 112; + return values; + })(); + + /** + * ClientPayloadConnectReason enum. + * @name proto.ClientPayload.ClientPayloadConnectReason + * @enum {number} + * @property {number} PUSH=0 PUSH value + * @property {number} USER_ACTIVATED=1 USER_ACTIVATED value + * @property {number} SCHEDULED=2 SCHEDULED value + * @property {number} ERROR_RECONNECT=3 ERROR_RECONNECT value + * @property {number} NETWORK_SWITCH=4 NETWORK_SWITCH value + * @property {number} PING_RECONNECT=5 PING_RECONNECT value + */ + ClientPayload.ClientPayloadConnectReason = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "PUSH"] = 0; + values[valuesById[1] = "USER_ACTIVATED"] = 1; + values[valuesById[2] = "SCHEDULED"] = 2; + values[valuesById[3] = "ERROR_RECONNECT"] = 3; + values[valuesById[4] = "NETWORK_SWITCH"] = 4; + values[valuesById[5] = "PING_RECONNECT"] = 5; + return values; + })(); + + /** + * ClientPayloadProduct enum. + * @name proto.ClientPayload.ClientPayloadProduct + * @enum {number} + * @property {number} WHATSAPP=0 WHATSAPP value + * @property {number} MESSENGER=1 MESSENGER value + */ + ClientPayload.ClientPayloadProduct = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "WHATSAPP"] = 0; + values[valuesById[1] = "MESSENGER"] = 1; + return values; + })(); + + return ClientPayload; + })(); + + proto.NoiseCertificate = (function() { + + /** + * Properties of a NoiseCertificate. + * @memberof proto + * @interface INoiseCertificate + * @property {Uint8Array|null} [details] NoiseCertificate details + * @property {Uint8Array|null} [signature] NoiseCertificate signature + */ + + /** + * Constructs a new NoiseCertificate. + * @memberof proto + * @classdesc Represents a NoiseCertificate. + * @implements INoiseCertificate + * @constructor + * @param {proto.INoiseCertificate=} [properties] Properties to set + */ + function NoiseCertificate(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * NoiseCertificate details. + * @member {Uint8Array} details + * @memberof proto.NoiseCertificate + * @instance + */ + NoiseCertificate.prototype.details = $util.newBuffer([]); + + /** + * NoiseCertificate signature. + * @member {Uint8Array} signature + * @memberof proto.NoiseCertificate + * @instance + */ + NoiseCertificate.prototype.signature = $util.newBuffer([]); + + /** + * Creates a new NoiseCertificate instance using the specified properties. + * @function create + * @memberof proto.NoiseCertificate + * @static + * @param {proto.INoiseCertificate=} [properties] Properties to set + * @returns {proto.NoiseCertificate} NoiseCertificate instance + */ + NoiseCertificate.create = function create(properties) { + return new NoiseCertificate(properties); + }; + + /** + * Encodes the specified NoiseCertificate message. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages. + * @function encode + * @memberof proto.NoiseCertificate + * @static + * @param {proto.INoiseCertificate} message NoiseCertificate message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + NoiseCertificate.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.details != null && Object.hasOwnProperty.call(message, "details")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); + if (message.signature != null && Object.hasOwnProperty.call(message, "signature")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.signature); + return writer; + }; + + /** + * Encodes the specified NoiseCertificate message, length delimited. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.NoiseCertificate + * @static + * @param {proto.INoiseCertificate} message NoiseCertificate message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + NoiseCertificate.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a NoiseCertificate message from the specified reader or buffer. + * @function decode + * @memberof proto.NoiseCertificate + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.NoiseCertificate} NoiseCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + NoiseCertificate.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NoiseCertificate(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.details = reader.bytes(); + break; + case 2: + message.signature = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a NoiseCertificate message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.NoiseCertificate + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.NoiseCertificate} NoiseCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + NoiseCertificate.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a NoiseCertificate message. + * @function verify + * @memberof proto.NoiseCertificate + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + NoiseCertificate.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.details != null && message.hasOwnProperty("details")) + if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) + return "details: buffer expected"; + if (message.signature != null && message.hasOwnProperty("signature")) + if (!(message.signature && typeof message.signature.length === "number" || $util.isString(message.signature))) + return "signature: buffer expected"; + return null; + }; + + /** + * Creates a NoiseCertificate message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.NoiseCertificate + * @static + * @param {Object.} object Plain object + * @returns {proto.NoiseCertificate} NoiseCertificate + */ + NoiseCertificate.fromObject = function fromObject(object) { + if (object instanceof $root.proto.NoiseCertificate) + return object; + var message = new $root.proto.NoiseCertificate(); + if (object.details != null) + if (typeof object.details === "string") + $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); + else if (object.details.length) + message.details = object.details; + if (object.signature != null) + if (typeof object.signature === "string") + $util.base64.decode(object.signature, message.signature = $util.newBuffer($util.base64.length(object.signature)), 0); + else if (object.signature.length) + message.signature = object.signature; + return message; + }; + + /** + * Creates a plain object from a NoiseCertificate message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.NoiseCertificate + * @static + * @param {proto.NoiseCertificate} message NoiseCertificate + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + NoiseCertificate.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.details = ""; + else { + object.details = []; + if (options.bytes !== Array) + object.details = $util.newBuffer(object.details); + } + if (options.bytes === String) + object.signature = ""; + else { + object.signature = []; + if (options.bytes !== Array) + object.signature = $util.newBuffer(object.signature); + } + } + if (message.details != null && message.hasOwnProperty("details")) + object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; + if (message.signature != null && message.hasOwnProperty("signature")) + object.signature = options.bytes === String ? $util.base64.encode(message.signature, 0, message.signature.length) : options.bytes === Array ? Array.prototype.slice.call(message.signature) : message.signature; + return object; + }; + + /** + * Converts this NoiseCertificate to JSON. + * @function toJSON + * @memberof proto.NoiseCertificate + * @instance + * @returns {Object.} JSON object + */ + NoiseCertificate.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return NoiseCertificate; + })(); + + proto.ClientHello = (function() { + + /** + * Properties of a ClientHello. + * @memberof proto + * @interface IClientHello + * @property {Uint8Array|null} [ephemeral] ClientHello ephemeral + * @property {Uint8Array|null} ["static"] ClientHello static + * @property {Uint8Array|null} [payload] ClientHello payload + */ + + /** + * Constructs a new ClientHello. + * @memberof proto + * @classdesc Represents a ClientHello. + * @implements IClientHello + * @constructor + * @param {proto.IClientHello=} [properties] Properties to set + */ + function ClientHello(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ClientHello ephemeral. + * @member {Uint8Array} ephemeral + * @memberof proto.ClientHello + * @instance + */ + ClientHello.prototype.ephemeral = $util.newBuffer([]); + + /** + * ClientHello static. + * @member {Uint8Array} static + * @memberof proto.ClientHello + * @instance + */ + ClientHello.prototype["static"] = $util.newBuffer([]); + + /** + * ClientHello payload. + * @member {Uint8Array} payload + * @memberof proto.ClientHello + * @instance + */ + ClientHello.prototype.payload = $util.newBuffer([]); + + /** + * Creates a new ClientHello instance using the specified properties. + * @function create + * @memberof proto.ClientHello + * @static + * @param {proto.IClientHello=} [properties] Properties to set + * @returns {proto.ClientHello} ClientHello instance + */ + ClientHello.create = function create(properties) { + return new ClientHello(properties); + }; + + /** + * Encodes the specified ClientHello message. Does not implicitly {@link proto.ClientHello.verify|verify} messages. + * @function encode + * @memberof proto.ClientHello + * @static + * @param {proto.IClientHello} message ClientHello message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClientHello.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.ephemeral != null && Object.hasOwnProperty.call(message, "ephemeral")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.ephemeral); + if (message["static"] != null && Object.hasOwnProperty.call(message, "static")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message["static"]); + if (message.payload != null && Object.hasOwnProperty.call(message, "payload")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.payload); + return writer; + }; + + /** + * Encodes the specified ClientHello message, length delimited. Does not implicitly {@link proto.ClientHello.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ClientHello + * @static + * @param {proto.IClientHello} message ClientHello message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClientHello.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ClientHello message from the specified reader or buffer. + * @function decode + * @memberof proto.ClientHello + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ClientHello} ClientHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClientHello.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClientHello(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.ephemeral = reader.bytes(); + break; + case 2: + message["static"] = reader.bytes(); + break; + case 3: + message.payload = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ClientHello message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ClientHello + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ClientHello} ClientHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClientHello.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ClientHello message. + * @function verify + * @memberof proto.ClientHello + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ClientHello.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.ephemeral != null && message.hasOwnProperty("ephemeral")) + if (!(message.ephemeral && typeof message.ephemeral.length === "number" || $util.isString(message.ephemeral))) + return "ephemeral: buffer expected"; + if (message["static"] != null && message.hasOwnProperty("static")) + if (!(message["static"] && typeof message["static"].length === "number" || $util.isString(message["static"]))) + return "static: buffer expected"; + if (message.payload != null && message.hasOwnProperty("payload")) + if (!(message.payload && typeof message.payload.length === "number" || $util.isString(message.payload))) + return "payload: buffer expected"; + return null; + }; + + /** + * Creates a ClientHello message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ClientHello + * @static + * @param {Object.} object Plain object + * @returns {proto.ClientHello} ClientHello + */ + ClientHello.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ClientHello) + return object; + var message = new $root.proto.ClientHello(); + if (object.ephemeral != null) + if (typeof object.ephemeral === "string") + $util.base64.decode(object.ephemeral, message.ephemeral = $util.newBuffer($util.base64.length(object.ephemeral)), 0); + else if (object.ephemeral.length) + message.ephemeral = object.ephemeral; + if (object["static"] != null) + if (typeof object["static"] === "string") + $util.base64.decode(object["static"], message["static"] = $util.newBuffer($util.base64.length(object["static"])), 0); + else if (object["static"].length) + message["static"] = object["static"]; + if (object.payload != null) + if (typeof object.payload === "string") + $util.base64.decode(object.payload, message.payload = $util.newBuffer($util.base64.length(object.payload)), 0); + else if (object.payload.length) + message.payload = object.payload; + return message; + }; + + /** + * Creates a plain object from a ClientHello message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ClientHello + * @static + * @param {proto.ClientHello} message ClientHello + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ClientHello.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.ephemeral = ""; + else { + object.ephemeral = []; + if (options.bytes !== Array) + object.ephemeral = $util.newBuffer(object.ephemeral); + } + if (options.bytes === String) + object["static"] = ""; + else { + object["static"] = []; + if (options.bytes !== Array) + object["static"] = $util.newBuffer(object["static"]); + } + if (options.bytes === String) + object.payload = ""; + else { + object.payload = []; + if (options.bytes !== Array) + object.payload = $util.newBuffer(object.payload); + } + } + if (message.ephemeral != null && message.hasOwnProperty("ephemeral")) + object.ephemeral = options.bytes === String ? $util.base64.encode(message.ephemeral, 0, message.ephemeral.length) : options.bytes === Array ? Array.prototype.slice.call(message.ephemeral) : message.ephemeral; + if (message["static"] != null && message.hasOwnProperty("static")) + object["static"] = options.bytes === String ? $util.base64.encode(message["static"], 0, message["static"].length) : options.bytes === Array ? Array.prototype.slice.call(message["static"]) : message["static"]; + if (message.payload != null && message.hasOwnProperty("payload")) + object.payload = options.bytes === String ? $util.base64.encode(message.payload, 0, message.payload.length) : options.bytes === Array ? Array.prototype.slice.call(message.payload) : message.payload; + return object; + }; + + /** + * Converts this ClientHello to JSON. + * @function toJSON + * @memberof proto.ClientHello + * @instance + * @returns {Object.} JSON object + */ + ClientHello.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ClientHello; + })(); + + proto.ServerHello = (function() { + + /** + * Properties of a ServerHello. + * @memberof proto + * @interface IServerHello + * @property {Uint8Array|null} [ephemeral] ServerHello ephemeral + * @property {Uint8Array|null} ["static"] ServerHello static + * @property {Uint8Array|null} [payload] ServerHello payload + */ + + /** + * Constructs a new ServerHello. + * @memberof proto + * @classdesc Represents a ServerHello. + * @implements IServerHello + * @constructor + * @param {proto.IServerHello=} [properties] Properties to set + */ + function ServerHello(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ServerHello ephemeral. + * @member {Uint8Array} ephemeral + * @memberof proto.ServerHello + * @instance + */ + ServerHello.prototype.ephemeral = $util.newBuffer([]); + + /** + * ServerHello static. + * @member {Uint8Array} static + * @memberof proto.ServerHello + * @instance + */ + ServerHello.prototype["static"] = $util.newBuffer([]); + + /** + * ServerHello payload. + * @member {Uint8Array} payload + * @memberof proto.ServerHello + * @instance + */ + ServerHello.prototype.payload = $util.newBuffer([]); + + /** + * Creates a new ServerHello instance using the specified properties. + * @function create + * @memberof proto.ServerHello + * @static + * @param {proto.IServerHello=} [properties] Properties to set + * @returns {proto.ServerHello} ServerHello instance + */ + ServerHello.create = function create(properties) { + return new ServerHello(properties); + }; + + /** + * Encodes the specified ServerHello message. Does not implicitly {@link proto.ServerHello.verify|verify} messages. + * @function encode + * @memberof proto.ServerHello + * @static + * @param {proto.IServerHello} message ServerHello message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ServerHello.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.ephemeral != null && Object.hasOwnProperty.call(message, "ephemeral")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.ephemeral); + if (message["static"] != null && Object.hasOwnProperty.call(message, "static")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message["static"]); + if (message.payload != null && Object.hasOwnProperty.call(message, "payload")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.payload); + return writer; + }; + + /** + * Encodes the specified ServerHello message, length delimited. Does not implicitly {@link proto.ServerHello.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ServerHello + * @static + * @param {proto.IServerHello} message ServerHello message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ServerHello.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ServerHello message from the specified reader or buffer. + * @function decode + * @memberof proto.ServerHello + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ServerHello} ServerHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ServerHello.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ServerHello(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.ephemeral = reader.bytes(); + break; + case 2: + message["static"] = reader.bytes(); + break; + case 3: + message.payload = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ServerHello message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ServerHello + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ServerHello} ServerHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ServerHello.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ServerHello message. + * @function verify + * @memberof proto.ServerHello + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ServerHello.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.ephemeral != null && message.hasOwnProperty("ephemeral")) + if (!(message.ephemeral && typeof message.ephemeral.length === "number" || $util.isString(message.ephemeral))) + return "ephemeral: buffer expected"; + if (message["static"] != null && message.hasOwnProperty("static")) + if (!(message["static"] && typeof message["static"].length === "number" || $util.isString(message["static"]))) + return "static: buffer expected"; + if (message.payload != null && message.hasOwnProperty("payload")) + if (!(message.payload && typeof message.payload.length === "number" || $util.isString(message.payload))) + return "payload: buffer expected"; + return null; + }; + + /** + * Creates a ServerHello message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ServerHello + * @static + * @param {Object.} object Plain object + * @returns {proto.ServerHello} ServerHello + */ + ServerHello.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ServerHello) + return object; + var message = new $root.proto.ServerHello(); + if (object.ephemeral != null) + if (typeof object.ephemeral === "string") + $util.base64.decode(object.ephemeral, message.ephemeral = $util.newBuffer($util.base64.length(object.ephemeral)), 0); + else if (object.ephemeral.length) + message.ephemeral = object.ephemeral; + if (object["static"] != null) + if (typeof object["static"] === "string") + $util.base64.decode(object["static"], message["static"] = $util.newBuffer($util.base64.length(object["static"])), 0); + else if (object["static"].length) + message["static"] = object["static"]; + if (object.payload != null) + if (typeof object.payload === "string") + $util.base64.decode(object.payload, message.payload = $util.newBuffer($util.base64.length(object.payload)), 0); + else if (object.payload.length) + message.payload = object.payload; + return message; + }; + + /** + * Creates a plain object from a ServerHello message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ServerHello + * @static + * @param {proto.ServerHello} message ServerHello + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ServerHello.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.ephemeral = ""; + else { + object.ephemeral = []; + if (options.bytes !== Array) + object.ephemeral = $util.newBuffer(object.ephemeral); + } + if (options.bytes === String) + object["static"] = ""; + else { + object["static"] = []; + if (options.bytes !== Array) + object["static"] = $util.newBuffer(object["static"]); + } + if (options.bytes === String) + object.payload = ""; + else { + object.payload = []; + if (options.bytes !== Array) + object.payload = $util.newBuffer(object.payload); + } + } + if (message.ephemeral != null && message.hasOwnProperty("ephemeral")) + object.ephemeral = options.bytes === String ? $util.base64.encode(message.ephemeral, 0, message.ephemeral.length) : options.bytes === Array ? Array.prototype.slice.call(message.ephemeral) : message.ephemeral; + if (message["static"] != null && message.hasOwnProperty("static")) + object["static"] = options.bytes === String ? $util.base64.encode(message["static"], 0, message["static"].length) : options.bytes === Array ? Array.prototype.slice.call(message["static"]) : message["static"]; + if (message.payload != null && message.hasOwnProperty("payload")) + object.payload = options.bytes === String ? $util.base64.encode(message.payload, 0, message.payload.length) : options.bytes === Array ? Array.prototype.slice.call(message.payload) : message.payload; + return object; + }; + + /** + * Converts this ServerHello to JSON. + * @function toJSON + * @memberof proto.ServerHello + * @instance + * @returns {Object.} JSON object + */ + ServerHello.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ServerHello; + })(); + + proto.ClientFinish = (function() { + + /** + * Properties of a ClientFinish. + * @memberof proto + * @interface IClientFinish + * @property {Uint8Array|null} ["static"] ClientFinish static + * @property {Uint8Array|null} [payload] ClientFinish payload + */ + + /** + * Constructs a new ClientFinish. + * @memberof proto + * @classdesc Represents a ClientFinish. + * @implements IClientFinish + * @constructor + * @param {proto.IClientFinish=} [properties] Properties to set + */ + function ClientFinish(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ClientFinish static. + * @member {Uint8Array} static + * @memberof proto.ClientFinish + * @instance + */ + ClientFinish.prototype["static"] = $util.newBuffer([]); + + /** + * ClientFinish payload. + * @member {Uint8Array} payload + * @memberof proto.ClientFinish + * @instance + */ + ClientFinish.prototype.payload = $util.newBuffer([]); + + /** + * Creates a new ClientFinish instance using the specified properties. + * @function create + * @memberof proto.ClientFinish + * @static + * @param {proto.IClientFinish=} [properties] Properties to set + * @returns {proto.ClientFinish} ClientFinish instance + */ + ClientFinish.create = function create(properties) { + return new ClientFinish(properties); + }; + + /** + * Encodes the specified ClientFinish message. Does not implicitly {@link proto.ClientFinish.verify|verify} messages. + * @function encode + * @memberof proto.ClientFinish + * @static + * @param {proto.IClientFinish} message ClientFinish message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClientFinish.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message["static"] != null && Object.hasOwnProperty.call(message, "static")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message["static"]); + if (message.payload != null && Object.hasOwnProperty.call(message, "payload")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.payload); + return writer; + }; + + /** + * Encodes the specified ClientFinish message, length delimited. Does not implicitly {@link proto.ClientFinish.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ClientFinish + * @static + * @param {proto.IClientFinish} message ClientFinish message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClientFinish.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ClientFinish message from the specified reader or buffer. + * @function decode + * @memberof proto.ClientFinish + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ClientFinish} ClientFinish + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClientFinish.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClientFinish(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message["static"] = reader.bytes(); + break; + case 2: + message.payload = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ClientFinish message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ClientFinish + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ClientFinish} ClientFinish + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClientFinish.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ClientFinish message. + * @function verify + * @memberof proto.ClientFinish + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ClientFinish.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message["static"] != null && message.hasOwnProperty("static")) + if (!(message["static"] && typeof message["static"].length === "number" || $util.isString(message["static"]))) + return "static: buffer expected"; + if (message.payload != null && message.hasOwnProperty("payload")) + if (!(message.payload && typeof message.payload.length === "number" || $util.isString(message.payload))) + return "payload: buffer expected"; + return null; + }; + + /** + * Creates a ClientFinish message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ClientFinish + * @static + * @param {Object.} object Plain object + * @returns {proto.ClientFinish} ClientFinish + */ + ClientFinish.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ClientFinish) + return object; + var message = new $root.proto.ClientFinish(); + if (object["static"] != null) + if (typeof object["static"] === "string") + $util.base64.decode(object["static"], message["static"] = $util.newBuffer($util.base64.length(object["static"])), 0); + else if (object["static"].length) + message["static"] = object["static"]; + if (object.payload != null) + if (typeof object.payload === "string") + $util.base64.decode(object.payload, message.payload = $util.newBuffer($util.base64.length(object.payload)), 0); + else if (object.payload.length) + message.payload = object.payload; + return message; + }; + + /** + * Creates a plain object from a ClientFinish message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ClientFinish + * @static + * @param {proto.ClientFinish} message ClientFinish + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ClientFinish.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object["static"] = ""; + else { + object["static"] = []; + if (options.bytes !== Array) + object["static"] = $util.newBuffer(object["static"]); + } + if (options.bytes === String) + object.payload = ""; + else { + object.payload = []; + if (options.bytes !== Array) + object.payload = $util.newBuffer(object.payload); + } + } + if (message["static"] != null && message.hasOwnProperty("static")) + object["static"] = options.bytes === String ? $util.base64.encode(message["static"], 0, message["static"].length) : options.bytes === Array ? Array.prototype.slice.call(message["static"]) : message["static"]; + if (message.payload != null && message.hasOwnProperty("payload")) + object.payload = options.bytes === String ? $util.base64.encode(message.payload, 0, message.payload.length) : options.bytes === Array ? Array.prototype.slice.call(message.payload) : message.payload; + return object; + }; + + /** + * Converts this ClientFinish to JSON. + * @function toJSON + * @memberof proto.ClientFinish + * @instance + * @returns {Object.} JSON object + */ + ClientFinish.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ClientFinish; + })(); + + proto.HandshakeMessage = (function() { + + /** + * Properties of a HandshakeMessage. + * @memberof proto + * @interface IHandshakeMessage + * @property {proto.IClientHello|null} [clientHello] HandshakeMessage clientHello + * @property {proto.IServerHello|null} [serverHello] HandshakeMessage serverHello + * @property {proto.IClientFinish|null} [clientFinish] HandshakeMessage clientFinish + */ + + /** + * Constructs a new HandshakeMessage. + * @memberof proto + * @classdesc Represents a HandshakeMessage. + * @implements IHandshakeMessage + * @constructor + * @param {proto.IHandshakeMessage=} [properties] Properties to set + */ + function HandshakeMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HandshakeMessage clientHello. + * @member {proto.IClientHello|null|undefined} clientHello + * @memberof proto.HandshakeMessage + * @instance + */ + HandshakeMessage.prototype.clientHello = null; + + /** + * HandshakeMessage serverHello. + * @member {proto.IServerHello|null|undefined} serverHello + * @memberof proto.HandshakeMessage + * @instance + */ + HandshakeMessage.prototype.serverHello = null; + + /** + * HandshakeMessage clientFinish. + * @member {proto.IClientFinish|null|undefined} clientFinish + * @memberof proto.HandshakeMessage + * @instance + */ + HandshakeMessage.prototype.clientFinish = null; + + /** + * Creates a new HandshakeMessage instance using the specified properties. + * @function create + * @memberof proto.HandshakeMessage + * @static + * @param {proto.IHandshakeMessage=} [properties] Properties to set + * @returns {proto.HandshakeMessage} HandshakeMessage instance + */ + HandshakeMessage.create = function create(properties) { + return new HandshakeMessage(properties); + }; + + /** + * Encodes the specified HandshakeMessage message. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages. + * @function encode + * @memberof proto.HandshakeMessage + * @static + * @param {proto.IHandshakeMessage} message HandshakeMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HandshakeMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.clientHello != null && Object.hasOwnProperty.call(message, "clientHello")) + $root.proto.ClientHello.encode(message.clientHello, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.serverHello != null && Object.hasOwnProperty.call(message, "serverHello")) + $root.proto.ServerHello.encode(message.serverHello, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.clientFinish != null && Object.hasOwnProperty.call(message, "clientFinish")) + $root.proto.ClientFinish.encode(message.clientFinish, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified HandshakeMessage message, length delimited. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HandshakeMessage + * @static + * @param {proto.IHandshakeMessage} message HandshakeMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HandshakeMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HandshakeMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.HandshakeMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HandshakeMessage} HandshakeMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HandshakeMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HandshakeMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + message.clientHello = $root.proto.ClientHello.decode(reader, reader.uint32()); + break; + case 3: + message.serverHello = $root.proto.ServerHello.decode(reader, reader.uint32()); + break; + case 4: + message.clientFinish = $root.proto.ClientFinish.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HandshakeMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HandshakeMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HandshakeMessage} HandshakeMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HandshakeMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HandshakeMessage message. + * @function verify + * @memberof proto.HandshakeMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HandshakeMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.clientHello != null && message.hasOwnProperty("clientHello")) { + var error = $root.proto.ClientHello.verify(message.clientHello); + if (error) + return "clientHello." + error; + } + if (message.serverHello != null && message.hasOwnProperty("serverHello")) { + var error = $root.proto.ServerHello.verify(message.serverHello); + if (error) + return "serverHello." + error; + } + if (message.clientFinish != null && message.hasOwnProperty("clientFinish")) { + var error = $root.proto.ClientFinish.verify(message.clientFinish); + if (error) + return "clientFinish." + error; + } + return null; + }; + + /** + * Creates a HandshakeMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HandshakeMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.HandshakeMessage} HandshakeMessage + */ + HandshakeMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HandshakeMessage) + return object; + var message = new $root.proto.HandshakeMessage(); + if (object.clientHello != null) { + if (typeof object.clientHello !== "object") + throw TypeError(".proto.HandshakeMessage.clientHello: object expected"); + message.clientHello = $root.proto.ClientHello.fromObject(object.clientHello); + } + if (object.serverHello != null) { + if (typeof object.serverHello !== "object") + throw TypeError(".proto.HandshakeMessage.serverHello: object expected"); + message.serverHello = $root.proto.ServerHello.fromObject(object.serverHello); + } + if (object.clientFinish != null) { + if (typeof object.clientFinish !== "object") + throw TypeError(".proto.HandshakeMessage.clientFinish: object expected"); + message.clientFinish = $root.proto.ClientFinish.fromObject(object.clientFinish); + } + return message; + }; + + /** + * Creates a plain object from a HandshakeMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HandshakeMessage + * @static + * @param {proto.HandshakeMessage} message HandshakeMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HandshakeMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.clientHello = null; + object.serverHello = null; + object.clientFinish = null; + } + if (message.clientHello != null && message.hasOwnProperty("clientHello")) + object.clientHello = $root.proto.ClientHello.toObject(message.clientHello, options); + if (message.serverHello != null && message.hasOwnProperty("serverHello")) + object.serverHello = $root.proto.ServerHello.toObject(message.serverHello, options); + if (message.clientFinish != null && message.hasOwnProperty("clientFinish")) + object.clientFinish = $root.proto.ClientFinish.toObject(message.clientFinish, options); + return object; + }; + + /** + * Converts this HandshakeMessage to JSON. + * @function toJSON + * @memberof proto.HandshakeMessage + * @instance + * @returns {Object.} JSON object + */ + HandshakeMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HandshakeMessage; + })(); + + proto.BizIdentityInfo = (function() { + + /** + * Properties of a BizIdentityInfo. + * @memberof proto + * @interface IBizIdentityInfo + * @property {proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue|null} [vlevel] BizIdentityInfo vlevel + * @property {proto.IVerifiedNameCertificate|null} [vnameCert] BizIdentityInfo vnameCert + * @property {boolean|null} [signed] BizIdentityInfo signed + * @property {boolean|null} [revoked] BizIdentityInfo revoked + * @property {proto.BizIdentityInfo.BizIdentityInfoHostStorageType|null} [hostStorage] BizIdentityInfo hostStorage + * @property {proto.BizIdentityInfo.BizIdentityInfoActualActorsType|null} [actualActors] BizIdentityInfo actualActors + * @property {number|Long|null} [privacyModeTs] BizIdentityInfo privacyModeTs + */ + + /** + * Constructs a new BizIdentityInfo. + * @memberof proto + * @classdesc Represents a BizIdentityInfo. + * @implements IBizIdentityInfo + * @constructor + * @param {proto.IBizIdentityInfo=} [properties] Properties to set + */ + function BizIdentityInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * BizIdentityInfo vlevel. + * @member {proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue} vlevel + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.vlevel = 0; + + /** + * BizIdentityInfo vnameCert. + * @member {proto.IVerifiedNameCertificate|null|undefined} vnameCert + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.vnameCert = null; + + /** + * BizIdentityInfo signed. + * @member {boolean} signed + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.signed = false; + + /** + * BizIdentityInfo revoked. + * @member {boolean} revoked + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.revoked = false; + + /** + * BizIdentityInfo hostStorage. + * @member {proto.BizIdentityInfo.BizIdentityInfoHostStorageType} hostStorage + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.hostStorage = 0; + + /** + * BizIdentityInfo actualActors. + * @member {proto.BizIdentityInfo.BizIdentityInfoActualActorsType} actualActors + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.actualActors = 0; + + /** + * BizIdentityInfo privacyModeTs. + * @member {number|Long} privacyModeTs + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.privacyModeTs = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Creates a new BizIdentityInfo instance using the specified properties. + * @function create + * @memberof proto.BizIdentityInfo + * @static + * @param {proto.IBizIdentityInfo=} [properties] Properties to set + * @returns {proto.BizIdentityInfo} BizIdentityInfo instance + */ + BizIdentityInfo.create = function create(properties) { + return new BizIdentityInfo(properties); + }; + + /** + * Encodes the specified BizIdentityInfo message. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages. + * @function encode + * @memberof proto.BizIdentityInfo + * @static + * @param {proto.IBizIdentityInfo} message BizIdentityInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + BizIdentityInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.vlevel != null && Object.hasOwnProperty.call(message, "vlevel")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.vlevel); + if (message.vnameCert != null && Object.hasOwnProperty.call(message, "vnameCert")) + $root.proto.VerifiedNameCertificate.encode(message.vnameCert, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.signed != null && Object.hasOwnProperty.call(message, "signed")) + writer.uint32(/* id 3, wireType 0 =*/24).bool(message.signed); + if (message.revoked != null && Object.hasOwnProperty.call(message, "revoked")) + writer.uint32(/* id 4, wireType 0 =*/32).bool(message.revoked); + if (message.hostStorage != null && Object.hasOwnProperty.call(message, "hostStorage")) + writer.uint32(/* id 5, wireType 0 =*/40).int32(message.hostStorage); + if (message.actualActors != null && Object.hasOwnProperty.call(message, "actualActors")) + writer.uint32(/* id 6, wireType 0 =*/48).int32(message.actualActors); + if (message.privacyModeTs != null && Object.hasOwnProperty.call(message, "privacyModeTs")) + writer.uint32(/* id 7, wireType 0 =*/56).uint64(message.privacyModeTs); + return writer; + }; + + /** + * Encodes the specified BizIdentityInfo message, length delimited. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.BizIdentityInfo + * @static + * @param {proto.IBizIdentityInfo} message BizIdentityInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + BizIdentityInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a BizIdentityInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.BizIdentityInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.BizIdentityInfo} BizIdentityInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + BizIdentityInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.BizIdentityInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.vlevel = reader.int32(); + break; + case 2: + message.vnameCert = $root.proto.VerifiedNameCertificate.decode(reader, reader.uint32()); + break; + case 3: + message.signed = reader.bool(); + break; + case 4: + message.revoked = reader.bool(); + break; + case 5: + message.hostStorage = reader.int32(); + break; + case 6: + message.actualActors = reader.int32(); + break; + case 7: + message.privacyModeTs = reader.uint64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a BizIdentityInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.BizIdentityInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.BizIdentityInfo} BizIdentityInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + BizIdentityInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a BizIdentityInfo message. + * @function verify + * @memberof proto.BizIdentityInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + BizIdentityInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.vlevel != null && message.hasOwnProperty("vlevel")) + switch (message.vlevel) { + default: + return "vlevel: enum value expected"; + case 0: + case 1: + case 2: + break; + } + if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) { + var error = $root.proto.VerifiedNameCertificate.verify(message.vnameCert); + if (error) + return "vnameCert." + error; + } + if (message.signed != null && message.hasOwnProperty("signed")) + if (typeof message.signed !== "boolean") + return "signed: boolean expected"; + if (message.revoked != null && message.hasOwnProperty("revoked")) + if (typeof message.revoked !== "boolean") + return "revoked: boolean expected"; + if (message.hostStorage != null && message.hasOwnProperty("hostStorage")) + switch (message.hostStorage) { + default: + return "hostStorage: enum value expected"; + case 0: + case 1: + break; + } + if (message.actualActors != null && message.hasOwnProperty("actualActors")) + switch (message.actualActors) { + default: + return "actualActors: enum value expected"; + case 0: + case 1: + break; + } + if (message.privacyModeTs != null && message.hasOwnProperty("privacyModeTs")) + if (!$util.isInteger(message.privacyModeTs) && !(message.privacyModeTs && $util.isInteger(message.privacyModeTs.low) && $util.isInteger(message.privacyModeTs.high))) + return "privacyModeTs: integer|Long expected"; + return null; + }; + + /** + * Creates a BizIdentityInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.BizIdentityInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.BizIdentityInfo} BizIdentityInfo + */ + BizIdentityInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.BizIdentityInfo) + return object; + var message = new $root.proto.BizIdentityInfo(); + switch (object.vlevel) { + case "UNKNOWN": + case 0: + message.vlevel = 0; + break; + case "LOW": + case 1: + message.vlevel = 1; + break; + case "HIGH": + case 2: + message.vlevel = 2; + break; + } + if (object.vnameCert != null) { + if (typeof object.vnameCert !== "object") + throw TypeError(".proto.BizIdentityInfo.vnameCert: object expected"); + message.vnameCert = $root.proto.VerifiedNameCertificate.fromObject(object.vnameCert); + } + if (object.signed != null) + message.signed = Boolean(object.signed); + if (object.revoked != null) + message.revoked = Boolean(object.revoked); + switch (object.hostStorage) { + case "ON_PREMISE": + case 0: + message.hostStorage = 0; + break; + case "FACEBOOK": + case 1: + message.hostStorage = 1; + break; + } + switch (object.actualActors) { + case "SELF": + case 0: + message.actualActors = 0; + break; + case "BSP": + case 1: + message.actualActors = 1; + break; + } + if (object.privacyModeTs != null) + if ($util.Long) + (message.privacyModeTs = $util.Long.fromValue(object.privacyModeTs)).unsigned = true; + else if (typeof object.privacyModeTs === "string") + message.privacyModeTs = parseInt(object.privacyModeTs, 10); + else if (typeof object.privacyModeTs === "number") + message.privacyModeTs = object.privacyModeTs; + else if (typeof object.privacyModeTs === "object") + message.privacyModeTs = new $util.LongBits(object.privacyModeTs.low >>> 0, object.privacyModeTs.high >>> 0).toNumber(true); + return message; + }; + + /** + * Creates a plain object from a BizIdentityInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.BizIdentityInfo + * @static + * @param {proto.BizIdentityInfo} message BizIdentityInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + BizIdentityInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.vlevel = options.enums === String ? "UNKNOWN" : 0; + object.vnameCert = null; + object.signed = false; + object.revoked = false; + object.hostStorage = options.enums === String ? "ON_PREMISE" : 0; + object.actualActors = options.enums === String ? "SELF" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.privacyModeTs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.privacyModeTs = options.longs === String ? "0" : 0; + } + if (message.vlevel != null && message.hasOwnProperty("vlevel")) + object.vlevel = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue[message.vlevel] : message.vlevel; + if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) + object.vnameCert = $root.proto.VerifiedNameCertificate.toObject(message.vnameCert, options); + if (message.signed != null && message.hasOwnProperty("signed")) + object.signed = message.signed; + if (message.revoked != null && message.hasOwnProperty("revoked")) + object.revoked = message.revoked; + if (message.hostStorage != null && message.hasOwnProperty("hostStorage")) + object.hostStorage = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoHostStorageType[message.hostStorage] : message.hostStorage; + if (message.actualActors != null && message.hasOwnProperty("actualActors")) + object.actualActors = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoActualActorsType[message.actualActors] : message.actualActors; + if (message.privacyModeTs != null && message.hasOwnProperty("privacyModeTs")) + if (typeof message.privacyModeTs === "number") + object.privacyModeTs = options.longs === String ? String(message.privacyModeTs) : message.privacyModeTs; + else + object.privacyModeTs = options.longs === String ? $util.Long.prototype.toString.call(message.privacyModeTs) : options.longs === Number ? new $util.LongBits(message.privacyModeTs.low >>> 0, message.privacyModeTs.high >>> 0).toNumber(true) : message.privacyModeTs; + return object; + }; + + /** + * Converts this BizIdentityInfo to JSON. + * @function toJSON + * @memberof proto.BizIdentityInfo + * @instance + * @returns {Object.} JSON object + */ + BizIdentityInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * BizIdentityInfoVerifiedLevelValue enum. + * @name proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue + * @enum {number} + * @property {number} UNKNOWN=0 UNKNOWN value + * @property {number} LOW=1 LOW value + * @property {number} HIGH=2 HIGH value + */ + BizIdentityInfo.BizIdentityInfoVerifiedLevelValue = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN"] = 0; + values[valuesById[1] = "LOW"] = 1; + values[valuesById[2] = "HIGH"] = 2; + return values; + })(); + + /** + * BizIdentityInfoHostStorageType enum. + * @name proto.BizIdentityInfo.BizIdentityInfoHostStorageType + * @enum {number} + * @property {number} ON_PREMISE=0 ON_PREMISE value + * @property {number} FACEBOOK=1 FACEBOOK value + */ + BizIdentityInfo.BizIdentityInfoHostStorageType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "ON_PREMISE"] = 0; + values[valuesById[1] = "FACEBOOK"] = 1; + return values; + })(); + + /** + * BizIdentityInfoActualActorsType enum. + * @name proto.BizIdentityInfo.BizIdentityInfoActualActorsType + * @enum {number} + * @property {number} SELF=0 SELF value + * @property {number} BSP=1 BSP value + */ + BizIdentityInfo.BizIdentityInfoActualActorsType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "SELF"] = 0; + values[valuesById[1] = "BSP"] = 1; + return values; + })(); + + return BizIdentityInfo; + })(); + + proto.BizAccountLinkInfo = (function() { + + /** + * Properties of a BizAccountLinkInfo. + * @memberof proto + * @interface IBizAccountLinkInfo + * @property {number|Long|null} [whatsappBizAcctFbid] BizAccountLinkInfo whatsappBizAcctFbid + * @property {string|null} [whatsappAcctNumber] BizAccountLinkInfo whatsappAcctNumber + * @property {number|Long|null} [issueTime] BizAccountLinkInfo issueTime + * @property {proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType|null} [hostStorage] BizAccountLinkInfo hostStorage + * @property {proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType|null} [accountType] BizAccountLinkInfo accountType + */ + + /** + * Constructs a new BizAccountLinkInfo. + * @memberof proto + * @classdesc Represents a BizAccountLinkInfo. + * @implements IBizAccountLinkInfo + * @constructor + * @param {proto.IBizAccountLinkInfo=} [properties] Properties to set + */ + function BizAccountLinkInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * BizAccountLinkInfo whatsappBizAcctFbid. + * @member {number|Long} whatsappBizAcctFbid + * @memberof proto.BizAccountLinkInfo + * @instance + */ + BizAccountLinkInfo.prototype.whatsappBizAcctFbid = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * BizAccountLinkInfo whatsappAcctNumber. + * @member {string} whatsappAcctNumber + * @memberof proto.BizAccountLinkInfo + * @instance + */ + BizAccountLinkInfo.prototype.whatsappAcctNumber = ""; + + /** + * BizAccountLinkInfo issueTime. + * @member {number|Long} issueTime + * @memberof proto.BizAccountLinkInfo + * @instance + */ + BizAccountLinkInfo.prototype.issueTime = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * BizAccountLinkInfo hostStorage. + * @member {proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType} hostStorage + * @memberof proto.BizAccountLinkInfo + * @instance + */ + BizAccountLinkInfo.prototype.hostStorage = 0; + + /** + * BizAccountLinkInfo accountType. + * @member {proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType} accountType + * @memberof proto.BizAccountLinkInfo + * @instance + */ + BizAccountLinkInfo.prototype.accountType = 0; + + /** + * Creates a new BizAccountLinkInfo instance using the specified properties. + * @function create + * @memberof proto.BizAccountLinkInfo + * @static + * @param {proto.IBizAccountLinkInfo=} [properties] Properties to set + * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo instance + */ + BizAccountLinkInfo.create = function create(properties) { + return new BizAccountLinkInfo(properties); + }; + + /** + * Encodes the specified BizAccountLinkInfo message. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages. + * @function encode + * @memberof proto.BizAccountLinkInfo + * @static + * @param {proto.IBizAccountLinkInfo} message BizAccountLinkInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + BizAccountLinkInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.whatsappBizAcctFbid != null && Object.hasOwnProperty.call(message, "whatsappBizAcctFbid")) + writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.whatsappBizAcctFbid); + if (message.whatsappAcctNumber != null && Object.hasOwnProperty.call(message, "whatsappAcctNumber")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.whatsappAcctNumber); + if (message.issueTime != null && Object.hasOwnProperty.call(message, "issueTime")) + writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.issueTime); + if (message.hostStorage != null && Object.hasOwnProperty.call(message, "hostStorage")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.hostStorage); + if (message.accountType != null && Object.hasOwnProperty.call(message, "accountType")) + writer.uint32(/* id 5, wireType 0 =*/40).int32(message.accountType); + return writer; + }; + + /** + * Encodes the specified BizAccountLinkInfo message, length delimited. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.BizAccountLinkInfo + * @static + * @param {proto.IBizAccountLinkInfo} message BizAccountLinkInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + BizAccountLinkInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a BizAccountLinkInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.BizAccountLinkInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + BizAccountLinkInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.BizAccountLinkInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.whatsappBizAcctFbid = reader.uint64(); + break; + case 2: + message.whatsappAcctNumber = reader.string(); + break; + case 3: + message.issueTime = reader.uint64(); + break; + case 4: + message.hostStorage = reader.int32(); + break; + case 5: + message.accountType = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a BizAccountLinkInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.BizAccountLinkInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + BizAccountLinkInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a BizAccountLinkInfo message. + * @function verify + * @memberof proto.BizAccountLinkInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + BizAccountLinkInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.whatsappBizAcctFbid != null && message.hasOwnProperty("whatsappBizAcctFbid")) + if (!$util.isInteger(message.whatsappBizAcctFbid) && !(message.whatsappBizAcctFbid && $util.isInteger(message.whatsappBizAcctFbid.low) && $util.isInteger(message.whatsappBizAcctFbid.high))) + return "whatsappBizAcctFbid: integer|Long expected"; + if (message.whatsappAcctNumber != null && message.hasOwnProperty("whatsappAcctNumber")) + if (!$util.isString(message.whatsappAcctNumber)) + return "whatsappAcctNumber: string expected"; + if (message.issueTime != null && message.hasOwnProperty("issueTime")) + if (!$util.isInteger(message.issueTime) && !(message.issueTime && $util.isInteger(message.issueTime.low) && $util.isInteger(message.issueTime.high))) + return "issueTime: integer|Long expected"; + if (message.hostStorage != null && message.hasOwnProperty("hostStorage")) + switch (message.hostStorage) { + default: + return "hostStorage: enum value expected"; + case 0: + case 1: + break; + } + if (message.accountType != null && message.hasOwnProperty("accountType")) + switch (message.accountType) { + default: + return "accountType: enum value expected"; + case 0: + case 1: + break; + } + return null; + }; + + /** + * Creates a BizAccountLinkInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.BizAccountLinkInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo + */ + BizAccountLinkInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.BizAccountLinkInfo) + return object; + var message = new $root.proto.BizAccountLinkInfo(); + if (object.whatsappBizAcctFbid != null) + if ($util.Long) + (message.whatsappBizAcctFbid = $util.Long.fromValue(object.whatsappBizAcctFbid)).unsigned = true; + else if (typeof object.whatsappBizAcctFbid === "string") + message.whatsappBizAcctFbid = parseInt(object.whatsappBizAcctFbid, 10); + else if (typeof object.whatsappBizAcctFbid === "number") + message.whatsappBizAcctFbid = object.whatsappBizAcctFbid; + else if (typeof object.whatsappBizAcctFbid === "object") + message.whatsappBizAcctFbid = new $util.LongBits(object.whatsappBizAcctFbid.low >>> 0, object.whatsappBizAcctFbid.high >>> 0).toNumber(true); + if (object.whatsappAcctNumber != null) + message.whatsappAcctNumber = String(object.whatsappAcctNumber); + if (object.issueTime != null) + if ($util.Long) + (message.issueTime = $util.Long.fromValue(object.issueTime)).unsigned = true; + else if (typeof object.issueTime === "string") + message.issueTime = parseInt(object.issueTime, 10); + else if (typeof object.issueTime === "number") + message.issueTime = object.issueTime; + else if (typeof object.issueTime === "object") + message.issueTime = new $util.LongBits(object.issueTime.low >>> 0, object.issueTime.high >>> 0).toNumber(true); + switch (object.hostStorage) { + case "ON_PREMISE": + case 0: + message.hostStorage = 0; + break; + case "FACEBOOK": + case 1: + message.hostStorage = 1; + break; + } + switch (object.accountType) { + case "ENTERPRISE": + case 0: + message.accountType = 0; + break; + case "PAGE": + case 1: + message.accountType = 1; + break; + } + return message; + }; + + /** + * Creates a plain object from a BizAccountLinkInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.BizAccountLinkInfo + * @static + * @param {proto.BizAccountLinkInfo} message BizAccountLinkInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + BizAccountLinkInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.whatsappBizAcctFbid = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.whatsappBizAcctFbid = options.longs === String ? "0" : 0; + object.whatsappAcctNumber = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.issueTime = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.issueTime = options.longs === String ? "0" : 0; + object.hostStorage = options.enums === String ? "ON_PREMISE" : 0; + object.accountType = options.enums === String ? "ENTERPRISE" : 0; + } + if (message.whatsappBizAcctFbid != null && message.hasOwnProperty("whatsappBizAcctFbid")) + if (typeof message.whatsappBizAcctFbid === "number") + object.whatsappBizAcctFbid = options.longs === String ? String(message.whatsappBizAcctFbid) : message.whatsappBizAcctFbid; + else + object.whatsappBizAcctFbid = options.longs === String ? $util.Long.prototype.toString.call(message.whatsappBizAcctFbid) : options.longs === Number ? new $util.LongBits(message.whatsappBizAcctFbid.low >>> 0, message.whatsappBizAcctFbid.high >>> 0).toNumber(true) : message.whatsappBizAcctFbid; + if (message.whatsappAcctNumber != null && message.hasOwnProperty("whatsappAcctNumber")) + object.whatsappAcctNumber = message.whatsappAcctNumber; + if (message.issueTime != null && message.hasOwnProperty("issueTime")) + if (typeof message.issueTime === "number") + object.issueTime = options.longs === String ? String(message.issueTime) : message.issueTime; + else + object.issueTime = options.longs === String ? $util.Long.prototype.toString.call(message.issueTime) : options.longs === Number ? new $util.LongBits(message.issueTime.low >>> 0, message.issueTime.high >>> 0).toNumber(true) : message.issueTime; + if (message.hostStorage != null && message.hasOwnProperty("hostStorage")) + object.hostStorage = options.enums === String ? $root.proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType[message.hostStorage] : message.hostStorage; + if (message.accountType != null && message.hasOwnProperty("accountType")) + object.accountType = options.enums === String ? $root.proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType[message.accountType] : message.accountType; + return object; + }; + + /** + * Converts this BizAccountLinkInfo to JSON. + * @function toJSON + * @memberof proto.BizAccountLinkInfo + * @instance + * @returns {Object.} JSON object + */ + BizAccountLinkInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * BizAccountLinkInfoHostStorageType enum. + * @name proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType + * @enum {number} + * @property {number} ON_PREMISE=0 ON_PREMISE value + * @property {number} FACEBOOK=1 FACEBOOK value + */ + BizAccountLinkInfo.BizAccountLinkInfoHostStorageType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "ON_PREMISE"] = 0; + values[valuesById[1] = "FACEBOOK"] = 1; + return values; + })(); + + /** + * BizAccountLinkInfoAccountType enum. + * @name proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType + * @enum {number} + * @property {number} ENTERPRISE=0 ENTERPRISE value + * @property {number} PAGE=1 PAGE value + */ + BizAccountLinkInfo.BizAccountLinkInfoAccountType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "ENTERPRISE"] = 0; + values[valuesById[1] = "PAGE"] = 1; + return values; + })(); + + return BizAccountLinkInfo; + })(); + + proto.BizAccountPayload = (function() { + + /** + * Properties of a BizAccountPayload. + * @memberof proto + * @interface IBizAccountPayload + * @property {proto.IVerifiedNameCertificate|null} [vnameCert] BizAccountPayload vnameCert + * @property {Uint8Array|null} [bizAcctLinkInfo] BizAccountPayload bizAcctLinkInfo + */ + + /** + * Constructs a new BizAccountPayload. + * @memberof proto + * @classdesc Represents a BizAccountPayload. + * @implements IBizAccountPayload + * @constructor + * @param {proto.IBizAccountPayload=} [properties] Properties to set + */ + function BizAccountPayload(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * BizAccountPayload vnameCert. + * @member {proto.IVerifiedNameCertificate|null|undefined} vnameCert + * @memberof proto.BizAccountPayload + * @instance + */ + BizAccountPayload.prototype.vnameCert = null; + + /** + * BizAccountPayload bizAcctLinkInfo. + * @member {Uint8Array} bizAcctLinkInfo + * @memberof proto.BizAccountPayload + * @instance + */ + BizAccountPayload.prototype.bizAcctLinkInfo = $util.newBuffer([]); + + /** + * Creates a new BizAccountPayload instance using the specified properties. + * @function create + * @memberof proto.BizAccountPayload + * @static + * @param {proto.IBizAccountPayload=} [properties] Properties to set + * @returns {proto.BizAccountPayload} BizAccountPayload instance + */ + BizAccountPayload.create = function create(properties) { + return new BizAccountPayload(properties); + }; + + /** + * Encodes the specified BizAccountPayload message. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages. + * @function encode + * @memberof proto.BizAccountPayload + * @static + * @param {proto.IBizAccountPayload} message BizAccountPayload message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + BizAccountPayload.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.vnameCert != null && Object.hasOwnProperty.call(message, "vnameCert")) + $root.proto.VerifiedNameCertificate.encode(message.vnameCert, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.bizAcctLinkInfo != null && Object.hasOwnProperty.call(message, "bizAcctLinkInfo")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.bizAcctLinkInfo); + return writer; + }; + + /** + * Encodes the specified BizAccountPayload message, length delimited. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.BizAccountPayload + * @static + * @param {proto.IBizAccountPayload} message BizAccountPayload message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + BizAccountPayload.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a BizAccountPayload message from the specified reader or buffer. + * @function decode + * @memberof proto.BizAccountPayload + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.BizAccountPayload} BizAccountPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + BizAccountPayload.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.BizAccountPayload(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.vnameCert = $root.proto.VerifiedNameCertificate.decode(reader, reader.uint32()); + break; + case 2: + message.bizAcctLinkInfo = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a BizAccountPayload message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.BizAccountPayload + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.BizAccountPayload} BizAccountPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + BizAccountPayload.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a BizAccountPayload message. + * @function verify + * @memberof proto.BizAccountPayload + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + BizAccountPayload.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) { + var error = $root.proto.VerifiedNameCertificate.verify(message.vnameCert); + if (error) + return "vnameCert." + error; + } + if (message.bizAcctLinkInfo != null && message.hasOwnProperty("bizAcctLinkInfo")) + if (!(message.bizAcctLinkInfo && typeof message.bizAcctLinkInfo.length === "number" || $util.isString(message.bizAcctLinkInfo))) + return "bizAcctLinkInfo: buffer expected"; + return null; + }; + + /** + * Creates a BizAccountPayload message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.BizAccountPayload + * @static + * @param {Object.} object Plain object + * @returns {proto.BizAccountPayload} BizAccountPayload + */ + BizAccountPayload.fromObject = function fromObject(object) { + if (object instanceof $root.proto.BizAccountPayload) + return object; + var message = new $root.proto.BizAccountPayload(); + if (object.vnameCert != null) { + if (typeof object.vnameCert !== "object") + throw TypeError(".proto.BizAccountPayload.vnameCert: object expected"); + message.vnameCert = $root.proto.VerifiedNameCertificate.fromObject(object.vnameCert); + } + if (object.bizAcctLinkInfo != null) + if (typeof object.bizAcctLinkInfo === "string") + $util.base64.decode(object.bizAcctLinkInfo, message.bizAcctLinkInfo = $util.newBuffer($util.base64.length(object.bizAcctLinkInfo)), 0); + else if (object.bizAcctLinkInfo.length) + message.bizAcctLinkInfo = object.bizAcctLinkInfo; + return message; + }; + + /** + * Creates a plain object from a BizAccountPayload message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.BizAccountPayload + * @static + * @param {proto.BizAccountPayload} message BizAccountPayload + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + BizAccountPayload.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.vnameCert = null; + if (options.bytes === String) + object.bizAcctLinkInfo = ""; + else { + object.bizAcctLinkInfo = []; + if (options.bytes !== Array) + object.bizAcctLinkInfo = $util.newBuffer(object.bizAcctLinkInfo); + } + } + if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) + object.vnameCert = $root.proto.VerifiedNameCertificate.toObject(message.vnameCert, options); + if (message.bizAcctLinkInfo != null && message.hasOwnProperty("bizAcctLinkInfo")) + object.bizAcctLinkInfo = options.bytes === String ? $util.base64.encode(message.bizAcctLinkInfo, 0, message.bizAcctLinkInfo.length) : options.bytes === Array ? Array.prototype.slice.call(message.bizAcctLinkInfo) : message.bizAcctLinkInfo; + return object; + }; + + /** + * Converts this BizAccountPayload to JSON. + * @function toJSON + * @memberof proto.BizAccountPayload + * @instance + * @returns {Object.} JSON object + */ + BizAccountPayload.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return BizAccountPayload; + })(); + + proto.VerifiedNameCertificate = (function() { + + /** + * Properties of a VerifiedNameCertificate. + * @memberof proto + * @interface IVerifiedNameCertificate + * @property {Uint8Array|null} [details] VerifiedNameCertificate details + * @property {Uint8Array|null} [signature] VerifiedNameCertificate signature + * @property {Uint8Array|null} [serverSignature] VerifiedNameCertificate serverSignature + */ + + /** + * Constructs a new VerifiedNameCertificate. + * @memberof proto + * @classdesc Represents a VerifiedNameCertificate. + * @implements IVerifiedNameCertificate + * @constructor + * @param {proto.IVerifiedNameCertificate=} [properties] Properties to set + */ + function VerifiedNameCertificate(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * VerifiedNameCertificate details. + * @member {Uint8Array} details + * @memberof proto.VerifiedNameCertificate + * @instance + */ + VerifiedNameCertificate.prototype.details = $util.newBuffer([]); + + /** + * VerifiedNameCertificate signature. + * @member {Uint8Array} signature + * @memberof proto.VerifiedNameCertificate + * @instance + */ + VerifiedNameCertificate.prototype.signature = $util.newBuffer([]); + + /** + * VerifiedNameCertificate serverSignature. + * @member {Uint8Array} serverSignature + * @memberof proto.VerifiedNameCertificate + * @instance + */ + VerifiedNameCertificate.prototype.serverSignature = $util.newBuffer([]); + + /** + * Creates a new VerifiedNameCertificate instance using the specified properties. + * @function create + * @memberof proto.VerifiedNameCertificate + * @static + * @param {proto.IVerifiedNameCertificate=} [properties] Properties to set + * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate instance + */ + VerifiedNameCertificate.create = function create(properties) { + return new VerifiedNameCertificate(properties); + }; + + /** + * Encodes the specified VerifiedNameCertificate message. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages. + * @function encode + * @memberof proto.VerifiedNameCertificate + * @static + * @param {proto.IVerifiedNameCertificate} message VerifiedNameCertificate message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + VerifiedNameCertificate.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.details != null && Object.hasOwnProperty.call(message, "details")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); + if (message.signature != null && Object.hasOwnProperty.call(message, "signature")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.signature); + if (message.serverSignature != null && Object.hasOwnProperty.call(message, "serverSignature")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.serverSignature); + return writer; + }; + + /** + * Encodes the specified VerifiedNameCertificate message, length delimited. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.VerifiedNameCertificate + * @static + * @param {proto.IVerifiedNameCertificate} message VerifiedNameCertificate message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + VerifiedNameCertificate.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a VerifiedNameCertificate message from the specified reader or buffer. + * @function decode + * @memberof proto.VerifiedNameCertificate + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + VerifiedNameCertificate.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.VerifiedNameCertificate(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.details = reader.bytes(); + break; + case 2: + message.signature = reader.bytes(); + break; + case 3: + message.serverSignature = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a VerifiedNameCertificate message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.VerifiedNameCertificate + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + VerifiedNameCertificate.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a VerifiedNameCertificate message. + * @function verify + * @memberof proto.VerifiedNameCertificate + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + VerifiedNameCertificate.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.details != null && message.hasOwnProperty("details")) + if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) + return "details: buffer expected"; + if (message.signature != null && message.hasOwnProperty("signature")) + if (!(message.signature && typeof message.signature.length === "number" || $util.isString(message.signature))) + return "signature: buffer expected"; + if (message.serverSignature != null && message.hasOwnProperty("serverSignature")) + if (!(message.serverSignature && typeof message.serverSignature.length === "number" || $util.isString(message.serverSignature))) + return "serverSignature: buffer expected"; + return null; + }; + + /** + * Creates a VerifiedNameCertificate message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.VerifiedNameCertificate + * @static + * @param {Object.} object Plain object + * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate + */ + VerifiedNameCertificate.fromObject = function fromObject(object) { + if (object instanceof $root.proto.VerifiedNameCertificate) + return object; + var message = new $root.proto.VerifiedNameCertificate(); + if (object.details != null) + if (typeof object.details === "string") + $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); + else if (object.details.length) + message.details = object.details; + if (object.signature != null) + if (typeof object.signature === "string") + $util.base64.decode(object.signature, message.signature = $util.newBuffer($util.base64.length(object.signature)), 0); + else if (object.signature.length) + message.signature = object.signature; + if (object.serverSignature != null) + if (typeof object.serverSignature === "string") + $util.base64.decode(object.serverSignature, message.serverSignature = $util.newBuffer($util.base64.length(object.serverSignature)), 0); + else if (object.serverSignature.length) + message.serverSignature = object.serverSignature; + return message; + }; + + /** + * Creates a plain object from a VerifiedNameCertificate message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.VerifiedNameCertificate + * @static + * @param {proto.VerifiedNameCertificate} message VerifiedNameCertificate + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + VerifiedNameCertificate.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.details = ""; + else { + object.details = []; + if (options.bytes !== Array) + object.details = $util.newBuffer(object.details); + } + if (options.bytes === String) + object.signature = ""; + else { + object.signature = []; + if (options.bytes !== Array) + object.signature = $util.newBuffer(object.signature); + } + if (options.bytes === String) + object.serverSignature = ""; + else { + object.serverSignature = []; + if (options.bytes !== Array) + object.serverSignature = $util.newBuffer(object.serverSignature); + } + } + if (message.details != null && message.hasOwnProperty("details")) + object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; + if (message.signature != null && message.hasOwnProperty("signature")) + object.signature = options.bytes === String ? $util.base64.encode(message.signature, 0, message.signature.length) : options.bytes === Array ? Array.prototype.slice.call(message.signature) : message.signature; + if (message.serverSignature != null && message.hasOwnProperty("serverSignature")) + object.serverSignature = options.bytes === String ? $util.base64.encode(message.serverSignature, 0, message.serverSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.serverSignature) : message.serverSignature; + return object; + }; + + /** + * Converts this VerifiedNameCertificate to JSON. + * @function toJSON + * @memberof proto.VerifiedNameCertificate + * @instance + * @returns {Object.} JSON object + */ + VerifiedNameCertificate.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return VerifiedNameCertificate; + })(); + + proto.LocalizedName = (function() { + + /** + * Properties of a LocalizedName. + * @memberof proto + * @interface ILocalizedName + * @property {string|null} [lg] LocalizedName lg + * @property {string|null} [lc] LocalizedName lc + * @property {string|null} [verifiedName] LocalizedName verifiedName + */ + + /** + * Constructs a new LocalizedName. + * @memberof proto + * @classdesc Represents a LocalizedName. + * @implements ILocalizedName + * @constructor + * @param {proto.ILocalizedName=} [properties] Properties to set + */ + function LocalizedName(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * LocalizedName lg. + * @member {string} lg + * @memberof proto.LocalizedName + * @instance + */ + LocalizedName.prototype.lg = ""; + + /** + * LocalizedName lc. + * @member {string} lc + * @memberof proto.LocalizedName + * @instance + */ + LocalizedName.prototype.lc = ""; + + /** + * LocalizedName verifiedName. + * @member {string} verifiedName + * @memberof proto.LocalizedName + * @instance + */ + LocalizedName.prototype.verifiedName = ""; + + /** + * Creates a new LocalizedName instance using the specified properties. + * @function create + * @memberof proto.LocalizedName + * @static + * @param {proto.ILocalizedName=} [properties] Properties to set + * @returns {proto.LocalizedName} LocalizedName instance + */ + LocalizedName.create = function create(properties) { + return new LocalizedName(properties); + }; + + /** + * Encodes the specified LocalizedName message. Does not implicitly {@link proto.LocalizedName.verify|verify} messages. + * @function encode + * @memberof proto.LocalizedName + * @static + * @param {proto.ILocalizedName} message LocalizedName message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LocalizedName.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.lg != null && Object.hasOwnProperty.call(message, "lg")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.lg); + if (message.lc != null && Object.hasOwnProperty.call(message, "lc")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.lc); + if (message.verifiedName != null && Object.hasOwnProperty.call(message, "verifiedName")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.verifiedName); + return writer; + }; + + /** + * Encodes the specified LocalizedName message, length delimited. Does not implicitly {@link proto.LocalizedName.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.LocalizedName + * @static + * @param {proto.ILocalizedName} message LocalizedName message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LocalizedName.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a LocalizedName message from the specified reader or buffer. + * @function decode + * @memberof proto.LocalizedName + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.LocalizedName} LocalizedName + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LocalizedName.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LocalizedName(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.lg = reader.string(); + break; + case 2: + message.lc = reader.string(); + break; + case 3: + message.verifiedName = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a LocalizedName message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.LocalizedName + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.LocalizedName} LocalizedName + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LocalizedName.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a LocalizedName message. + * @function verify + * @memberof proto.LocalizedName + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + LocalizedName.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.lg != null && message.hasOwnProperty("lg")) + if (!$util.isString(message.lg)) + return "lg: string expected"; + if (message.lc != null && message.hasOwnProperty("lc")) + if (!$util.isString(message.lc)) + return "lc: string expected"; + if (message.verifiedName != null && message.hasOwnProperty("verifiedName")) + if (!$util.isString(message.verifiedName)) + return "verifiedName: string expected"; + return null; + }; + + /** + * Creates a LocalizedName message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.LocalizedName + * @static + * @param {Object.} object Plain object + * @returns {proto.LocalizedName} LocalizedName + */ + LocalizedName.fromObject = function fromObject(object) { + if (object instanceof $root.proto.LocalizedName) + return object; + var message = new $root.proto.LocalizedName(); + if (object.lg != null) + message.lg = String(object.lg); + if (object.lc != null) + message.lc = String(object.lc); + if (object.verifiedName != null) + message.verifiedName = String(object.verifiedName); + return message; + }; + + /** + * Creates a plain object from a LocalizedName message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.LocalizedName + * @static + * @param {proto.LocalizedName} message LocalizedName + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + LocalizedName.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.lg = ""; + object.lc = ""; + object.verifiedName = ""; + } + if (message.lg != null && message.hasOwnProperty("lg")) + object.lg = message.lg; + if (message.lc != null && message.hasOwnProperty("lc")) + object.lc = message.lc; + if (message.verifiedName != null && message.hasOwnProperty("verifiedName")) + object.verifiedName = message.verifiedName; + return object; + }; + + /** + * Converts this LocalizedName to JSON. + * @function toJSON + * @memberof proto.LocalizedName + * @instance + * @returns {Object.} JSON object + */ + LocalizedName.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return LocalizedName; + })(); + + proto.SyncActionData = (function() { + + /** + * Properties of a SyncActionData. + * @memberof proto + * @interface ISyncActionData + * @property {Uint8Array|null} [index] SyncActionData index + * @property {proto.ISyncActionValue|null} [value] SyncActionData value + * @property {Uint8Array|null} [padding] SyncActionData padding + * @property {number|null} [version] SyncActionData version + */ + + /** + * Constructs a new SyncActionData. + * @memberof proto + * @classdesc Represents a SyncActionData. + * @implements ISyncActionData + * @constructor + * @param {proto.ISyncActionData=} [properties] Properties to set + */ + function SyncActionData(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncActionData index. + * @member {Uint8Array} index + * @memberof proto.SyncActionData + * @instance + */ + SyncActionData.prototype.index = $util.newBuffer([]); + + /** + * SyncActionData value. + * @member {proto.ISyncActionValue|null|undefined} value + * @memberof proto.SyncActionData + * @instance + */ + SyncActionData.prototype.value = null; + + /** + * SyncActionData padding. + * @member {Uint8Array} padding + * @memberof proto.SyncActionData + * @instance + */ + SyncActionData.prototype.padding = $util.newBuffer([]); + + /** + * SyncActionData version. + * @member {number} version + * @memberof proto.SyncActionData + * @instance + */ + SyncActionData.prototype.version = 0; + + /** + * Creates a new SyncActionData instance using the specified properties. + * @function create + * @memberof proto.SyncActionData + * @static + * @param {proto.ISyncActionData=} [properties] Properties to set + * @returns {proto.SyncActionData} SyncActionData instance + */ + SyncActionData.create = function create(properties) { + return new SyncActionData(properties); + }; + + /** + * Encodes the specified SyncActionData message. Does not implicitly {@link proto.SyncActionData.verify|verify} messages. + * @function encode + * @memberof proto.SyncActionData + * @static + * @param {proto.ISyncActionData} message SyncActionData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionData.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.index != null && Object.hasOwnProperty.call(message, "index")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.index); + if (message.value != null && Object.hasOwnProperty.call(message, "value")) + $root.proto.SyncActionValue.encode(message.value, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.padding != null && Object.hasOwnProperty.call(message, "padding")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.padding); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.version); + return writer; + }; + + /** + * Encodes the specified SyncActionData message, length delimited. Does not implicitly {@link proto.SyncActionData.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncActionData + * @static + * @param {proto.ISyncActionData} message SyncActionData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionData.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncActionData message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncActionData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncActionData} SyncActionData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionData.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionData(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.index = reader.bytes(); + break; + case 2: + message.value = $root.proto.SyncActionValue.decode(reader, reader.uint32()); + break; + case 3: + message.padding = reader.bytes(); + break; + case 4: + message.version = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncActionData message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncActionData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncActionData} SyncActionData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionData.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncActionData message. + * @function verify + * @memberof proto.SyncActionData + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncActionData.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.index != null && message.hasOwnProperty("index")) + if (!(message.index && typeof message.index.length === "number" || $util.isString(message.index))) + return "index: buffer expected"; + if (message.value != null && message.hasOwnProperty("value")) { + var error = $root.proto.SyncActionValue.verify(message.value); + if (error) + return "value." + error; + } + if (message.padding != null && message.hasOwnProperty("padding")) + if (!(message.padding && typeof message.padding.length === "number" || $util.isString(message.padding))) + return "padding: buffer expected"; + if (message.version != null && message.hasOwnProperty("version")) + if (!$util.isInteger(message.version)) + return "version: integer expected"; + return null; + }; + + /** + * Creates a SyncActionData message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncActionData + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncActionData} SyncActionData + */ + SyncActionData.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncActionData) + return object; + var message = new $root.proto.SyncActionData(); + if (object.index != null) + if (typeof object.index === "string") + $util.base64.decode(object.index, message.index = $util.newBuffer($util.base64.length(object.index)), 0); + else if (object.index.length) + message.index = object.index; + if (object.value != null) { + if (typeof object.value !== "object") + throw TypeError(".proto.SyncActionData.value: object expected"); + message.value = $root.proto.SyncActionValue.fromObject(object.value); + } + if (object.padding != null) + if (typeof object.padding === "string") + $util.base64.decode(object.padding, message.padding = $util.newBuffer($util.base64.length(object.padding)), 0); + else if (object.padding.length) + message.padding = object.padding; + if (object.version != null) + message.version = object.version | 0; + return message; + }; + + /** + * Creates a plain object from a SyncActionData message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncActionData + * @static + * @param {proto.SyncActionData} message SyncActionData + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncActionData.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.index = ""; + else { + object.index = []; + if (options.bytes !== Array) + object.index = $util.newBuffer(object.index); + } + object.value = null; + if (options.bytes === String) + object.padding = ""; + else { + object.padding = []; + if (options.bytes !== Array) + object.padding = $util.newBuffer(object.padding); + } + object.version = 0; + } + if (message.index != null && message.hasOwnProperty("index")) + object.index = options.bytes === String ? $util.base64.encode(message.index, 0, message.index.length) : options.bytes === Array ? Array.prototype.slice.call(message.index) : message.index; + if (message.value != null && message.hasOwnProperty("value")) + object.value = $root.proto.SyncActionValue.toObject(message.value, options); + if (message.padding != null && message.hasOwnProperty("padding")) + object.padding = options.bytes === String ? $util.base64.encode(message.padding, 0, message.padding.length) : options.bytes === Array ? Array.prototype.slice.call(message.padding) : message.padding; + if (message.version != null && message.hasOwnProperty("version")) + object.version = message.version; + return object; + }; + + /** + * Converts this SyncActionData to JSON. + * @function toJSON + * @memberof proto.SyncActionData + * @instance + * @returns {Object.} JSON object + */ + SyncActionData.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncActionData; + })(); + + proto.StarAction = (function() { + + /** + * Properties of a StarAction. + * @memberof proto + * @interface IStarAction + * @property {boolean|null} [starred] StarAction starred + */ + + /** + * Constructs a new StarAction. + * @memberof proto + * @classdesc Represents a StarAction. + * @implements IStarAction + * @constructor + * @param {proto.IStarAction=} [properties] Properties to set + */ + function StarAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * StarAction starred. + * @member {boolean} starred + * @memberof proto.StarAction + * @instance + */ + StarAction.prototype.starred = false; + + /** + * Creates a new StarAction instance using the specified properties. + * @function create + * @memberof proto.StarAction + * @static + * @param {proto.IStarAction=} [properties] Properties to set + * @returns {proto.StarAction} StarAction instance + */ + StarAction.create = function create(properties) { + return new StarAction(properties); + }; + + /** + * Encodes the specified StarAction message. Does not implicitly {@link proto.StarAction.verify|verify} messages. + * @function encode + * @memberof proto.StarAction + * @static + * @param {proto.IStarAction} message StarAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + StarAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.starred != null && Object.hasOwnProperty.call(message, "starred")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.starred); + return writer; + }; + + /** + * Encodes the specified StarAction message, length delimited. Does not implicitly {@link proto.StarAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.StarAction + * @static + * @param {proto.IStarAction} message StarAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + StarAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a StarAction message from the specified reader or buffer. + * @function decode + * @memberof proto.StarAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.StarAction} StarAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + StarAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.StarAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.starred = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a StarAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.StarAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.StarAction} StarAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + StarAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a StarAction message. + * @function verify + * @memberof proto.StarAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + StarAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.starred != null && message.hasOwnProperty("starred")) + if (typeof message.starred !== "boolean") + return "starred: boolean expected"; + return null; + }; + + /** + * Creates a StarAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.StarAction + * @static + * @param {Object.} object Plain object + * @returns {proto.StarAction} StarAction + */ + StarAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.StarAction) + return object; + var message = new $root.proto.StarAction(); + if (object.starred != null) + message.starred = Boolean(object.starred); + return message; + }; + + /** + * Creates a plain object from a StarAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.StarAction + * @static + * @param {proto.StarAction} message StarAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + StarAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.starred = false; + if (message.starred != null && message.hasOwnProperty("starred")) + object.starred = message.starred; + return object; + }; + + /** + * Converts this StarAction to JSON. + * @function toJSON + * @memberof proto.StarAction + * @instance + * @returns {Object.} JSON object + */ + StarAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return StarAction; + })(); + + proto.ContactAction = (function() { + + /** + * Properties of a ContactAction. + * @memberof proto + * @interface IContactAction + * @property {string|null} [fullName] ContactAction fullName + * @property {string|null} [firstName] ContactAction firstName + */ + + /** + * Constructs a new ContactAction. + * @memberof proto + * @classdesc Represents a ContactAction. + * @implements IContactAction + * @constructor + * @param {proto.IContactAction=} [properties] Properties to set + */ + function ContactAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ContactAction fullName. + * @member {string} fullName + * @memberof proto.ContactAction + * @instance + */ + ContactAction.prototype.fullName = ""; + + /** + * ContactAction firstName. + * @member {string} firstName + * @memberof proto.ContactAction + * @instance + */ + ContactAction.prototype.firstName = ""; + + /** + * Creates a new ContactAction instance using the specified properties. + * @function create + * @memberof proto.ContactAction + * @static + * @param {proto.IContactAction=} [properties] Properties to set + * @returns {proto.ContactAction} ContactAction instance + */ + ContactAction.create = function create(properties) { + return new ContactAction(properties); + }; + + /** + * Encodes the specified ContactAction message. Does not implicitly {@link proto.ContactAction.verify|verify} messages. + * @function encode + * @memberof proto.ContactAction + * @static + * @param {proto.IContactAction} message ContactAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ContactAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.fullName != null && Object.hasOwnProperty.call(message, "fullName")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.fullName); + if (message.firstName != null && Object.hasOwnProperty.call(message, "firstName")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.firstName); + return writer; + }; + + /** + * Encodes the specified ContactAction message, length delimited. Does not implicitly {@link proto.ContactAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ContactAction + * @static + * @param {proto.IContactAction} message ContactAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ContactAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ContactAction message from the specified reader or buffer. + * @function decode + * @memberof proto.ContactAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ContactAction} ContactAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ContactAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ContactAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.fullName = reader.string(); + break; + case 2: + message.firstName = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ContactAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ContactAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ContactAction} ContactAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ContactAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ContactAction message. + * @function verify + * @memberof proto.ContactAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ContactAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.fullName != null && message.hasOwnProperty("fullName")) + if (!$util.isString(message.fullName)) + return "fullName: string expected"; + if (message.firstName != null && message.hasOwnProperty("firstName")) + if (!$util.isString(message.firstName)) + return "firstName: string expected"; + return null; + }; + + /** + * Creates a ContactAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ContactAction + * @static + * @param {Object.} object Plain object + * @returns {proto.ContactAction} ContactAction + */ + ContactAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ContactAction) + return object; + var message = new $root.proto.ContactAction(); + if (object.fullName != null) + message.fullName = String(object.fullName); + if (object.firstName != null) + message.firstName = String(object.firstName); + return message; + }; + + /** + * Creates a plain object from a ContactAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ContactAction + * @static + * @param {proto.ContactAction} message ContactAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ContactAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.fullName = ""; + object.firstName = ""; + } + if (message.fullName != null && message.hasOwnProperty("fullName")) + object.fullName = message.fullName; + if (message.firstName != null && message.hasOwnProperty("firstName")) + object.firstName = message.firstName; + return object; + }; + + /** + * Converts this ContactAction to JSON. + * @function toJSON + * @memberof proto.ContactAction + * @instance + * @returns {Object.} JSON object + */ + ContactAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ContactAction; + })(); + + proto.MuteAction = (function() { + + /** + * Properties of a MuteAction. + * @memberof proto + * @interface IMuteAction + * @property {boolean|null} [muted] MuteAction muted + * @property {number|Long|null} [muteEndTimestamp] MuteAction muteEndTimestamp + */ + + /** + * Constructs a new MuteAction. + * @memberof proto + * @classdesc Represents a MuteAction. + * @implements IMuteAction + * @constructor + * @param {proto.IMuteAction=} [properties] Properties to set + */ + function MuteAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MuteAction muted. + * @member {boolean} muted + * @memberof proto.MuteAction + * @instance + */ + MuteAction.prototype.muted = false; + + /** + * MuteAction muteEndTimestamp. + * @member {number|Long} muteEndTimestamp + * @memberof proto.MuteAction + * @instance + */ + MuteAction.prototype.muteEndTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new MuteAction instance using the specified properties. + * @function create + * @memberof proto.MuteAction + * @static + * @param {proto.IMuteAction=} [properties] Properties to set + * @returns {proto.MuteAction} MuteAction instance + */ + MuteAction.create = function create(properties) { + return new MuteAction(properties); + }; + + /** + * Encodes the specified MuteAction message. Does not implicitly {@link proto.MuteAction.verify|verify} messages. + * @function encode + * @memberof proto.MuteAction + * @static + * @param {proto.IMuteAction} message MuteAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MuteAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.muted != null && Object.hasOwnProperty.call(message, "muted")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.muted); + if (message.muteEndTimestamp != null && Object.hasOwnProperty.call(message, "muteEndTimestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.muteEndTimestamp); + return writer; + }; + + /** + * Encodes the specified MuteAction message, length delimited. Does not implicitly {@link proto.MuteAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MuteAction + * @static + * @param {proto.IMuteAction} message MuteAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MuteAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MuteAction message from the specified reader or buffer. + * @function decode + * @memberof proto.MuteAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MuteAction} MuteAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MuteAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MuteAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.muted = reader.bool(); + break; + case 2: + message.muteEndTimestamp = reader.int64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MuteAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MuteAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MuteAction} MuteAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MuteAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MuteAction message. + * @function verify + * @memberof proto.MuteAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MuteAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.muted != null && message.hasOwnProperty("muted")) + if (typeof message.muted !== "boolean") + return "muted: boolean expected"; + if (message.muteEndTimestamp != null && message.hasOwnProperty("muteEndTimestamp")) + if (!$util.isInteger(message.muteEndTimestamp) && !(message.muteEndTimestamp && $util.isInteger(message.muteEndTimestamp.low) && $util.isInteger(message.muteEndTimestamp.high))) + return "muteEndTimestamp: integer|Long expected"; + return null; + }; + + /** + * Creates a MuteAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MuteAction + * @static + * @param {Object.} object Plain object + * @returns {proto.MuteAction} MuteAction + */ + MuteAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MuteAction) + return object; + var message = new $root.proto.MuteAction(); + if (object.muted != null) + message.muted = Boolean(object.muted); + if (object.muteEndTimestamp != null) + if ($util.Long) + (message.muteEndTimestamp = $util.Long.fromValue(object.muteEndTimestamp)).unsigned = false; + else if (typeof object.muteEndTimestamp === "string") + message.muteEndTimestamp = parseInt(object.muteEndTimestamp, 10); + else if (typeof object.muteEndTimestamp === "number") + message.muteEndTimestamp = object.muteEndTimestamp; + else if (typeof object.muteEndTimestamp === "object") + message.muteEndTimestamp = new $util.LongBits(object.muteEndTimestamp.low >>> 0, object.muteEndTimestamp.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from a MuteAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MuteAction + * @static + * @param {proto.MuteAction} message MuteAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MuteAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.muted = false; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.muteEndTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.muteEndTimestamp = options.longs === String ? "0" : 0; + } + if (message.muted != null && message.hasOwnProperty("muted")) + object.muted = message.muted; + if (message.muteEndTimestamp != null && message.hasOwnProperty("muteEndTimestamp")) + if (typeof message.muteEndTimestamp === "number") + object.muteEndTimestamp = options.longs === String ? String(message.muteEndTimestamp) : message.muteEndTimestamp; + else + object.muteEndTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.muteEndTimestamp) : options.longs === Number ? new $util.LongBits(message.muteEndTimestamp.low >>> 0, message.muteEndTimestamp.high >>> 0).toNumber() : message.muteEndTimestamp; + return object; + }; + + /** + * Converts this MuteAction to JSON. + * @function toJSON + * @memberof proto.MuteAction + * @instance + * @returns {Object.} JSON object + */ + MuteAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MuteAction; + })(); + + proto.PinAction = (function() { + + /** + * Properties of a PinAction. + * @memberof proto + * @interface IPinAction + * @property {boolean|null} [pinned] PinAction pinned + */ + + /** + * Constructs a new PinAction. + * @memberof proto + * @classdesc Represents a PinAction. + * @implements IPinAction + * @constructor + * @param {proto.IPinAction=} [properties] Properties to set + */ + function PinAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * PinAction pinned. + * @member {boolean} pinned + * @memberof proto.PinAction + * @instance + */ + PinAction.prototype.pinned = false; + + /** + * Creates a new PinAction instance using the specified properties. + * @function create + * @memberof proto.PinAction + * @static + * @param {proto.IPinAction=} [properties] Properties to set + * @returns {proto.PinAction} PinAction instance + */ + PinAction.create = function create(properties) { + return new PinAction(properties); + }; + + /** + * Encodes the specified PinAction message. Does not implicitly {@link proto.PinAction.verify|verify} messages. + * @function encode + * @memberof proto.PinAction + * @static + * @param {proto.IPinAction} message PinAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PinAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.pinned != null && Object.hasOwnProperty.call(message, "pinned")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.pinned); + return writer; + }; + + /** + * Encodes the specified PinAction message, length delimited. Does not implicitly {@link proto.PinAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.PinAction + * @static + * @param {proto.IPinAction} message PinAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PinAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a PinAction message from the specified reader or buffer. + * @function decode + * @memberof proto.PinAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.PinAction} PinAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PinAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PinAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.pinned = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a PinAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.PinAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.PinAction} PinAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PinAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a PinAction message. + * @function verify + * @memberof proto.PinAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + PinAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.pinned != null && message.hasOwnProperty("pinned")) + if (typeof message.pinned !== "boolean") + return "pinned: boolean expected"; + return null; + }; + + /** + * Creates a PinAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.PinAction + * @static + * @param {Object.} object Plain object + * @returns {proto.PinAction} PinAction + */ + PinAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.PinAction) + return object; + var message = new $root.proto.PinAction(); + if (object.pinned != null) + message.pinned = Boolean(object.pinned); + return message; + }; + + /** + * Creates a plain object from a PinAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.PinAction + * @static + * @param {proto.PinAction} message PinAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + PinAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.pinned = false; + if (message.pinned != null && message.hasOwnProperty("pinned")) + object.pinned = message.pinned; + return object; + }; + + /** + * Converts this PinAction to JSON. + * @function toJSON + * @memberof proto.PinAction + * @instance + * @returns {Object.} JSON object + */ + PinAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return PinAction; + })(); + + proto.SecurityNotificationSetting = (function() { + + /** + * Properties of a SecurityNotificationSetting. + * @memberof proto + * @interface ISecurityNotificationSetting + * @property {boolean|null} [showNotification] SecurityNotificationSetting showNotification + */ + + /** + * Constructs a new SecurityNotificationSetting. + * @memberof proto + * @classdesc Represents a SecurityNotificationSetting. + * @implements ISecurityNotificationSetting + * @constructor + * @param {proto.ISecurityNotificationSetting=} [properties] Properties to set + */ + function SecurityNotificationSetting(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SecurityNotificationSetting showNotification. + * @member {boolean} showNotification + * @memberof proto.SecurityNotificationSetting + * @instance + */ + SecurityNotificationSetting.prototype.showNotification = false; + + /** + * Creates a new SecurityNotificationSetting instance using the specified properties. + * @function create + * @memberof proto.SecurityNotificationSetting + * @static + * @param {proto.ISecurityNotificationSetting=} [properties] Properties to set + * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting instance + */ + SecurityNotificationSetting.create = function create(properties) { + return new SecurityNotificationSetting(properties); + }; + + /** + * Encodes the specified SecurityNotificationSetting message. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages. + * @function encode + * @memberof proto.SecurityNotificationSetting + * @static + * @param {proto.ISecurityNotificationSetting} message SecurityNotificationSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SecurityNotificationSetting.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.showNotification != null && Object.hasOwnProperty.call(message, "showNotification")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.showNotification); + return writer; + }; + + /** + * Encodes the specified SecurityNotificationSetting message, length delimited. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SecurityNotificationSetting + * @static + * @param {proto.ISecurityNotificationSetting} message SecurityNotificationSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SecurityNotificationSetting.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SecurityNotificationSetting message from the specified reader or buffer. + * @function decode + * @memberof proto.SecurityNotificationSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SecurityNotificationSetting.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SecurityNotificationSetting(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.showNotification = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SecurityNotificationSetting message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SecurityNotificationSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SecurityNotificationSetting.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SecurityNotificationSetting message. + * @function verify + * @memberof proto.SecurityNotificationSetting + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SecurityNotificationSetting.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.showNotification != null && message.hasOwnProperty("showNotification")) + if (typeof message.showNotification !== "boolean") + return "showNotification: boolean expected"; + return null; + }; + + /** + * Creates a SecurityNotificationSetting message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SecurityNotificationSetting + * @static + * @param {Object.} object Plain object + * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting + */ + SecurityNotificationSetting.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SecurityNotificationSetting) + return object; + var message = new $root.proto.SecurityNotificationSetting(); + if (object.showNotification != null) + message.showNotification = Boolean(object.showNotification); + return message; + }; + + /** + * Creates a plain object from a SecurityNotificationSetting message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SecurityNotificationSetting + * @static + * @param {proto.SecurityNotificationSetting} message SecurityNotificationSetting + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SecurityNotificationSetting.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.showNotification = false; + if (message.showNotification != null && message.hasOwnProperty("showNotification")) + object.showNotification = message.showNotification; + return object; + }; + + /** + * Converts this SecurityNotificationSetting to JSON. + * @function toJSON + * @memberof proto.SecurityNotificationSetting + * @instance + * @returns {Object.} JSON object + */ + SecurityNotificationSetting.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SecurityNotificationSetting; + })(); + + proto.PushNameSetting = (function() { + + /** + * Properties of a PushNameSetting. + * @memberof proto + * @interface IPushNameSetting + * @property {string|null} [name] PushNameSetting name + */ + + /** + * Constructs a new PushNameSetting. + * @memberof proto + * @classdesc Represents a PushNameSetting. + * @implements IPushNameSetting + * @constructor + * @param {proto.IPushNameSetting=} [properties] Properties to set + */ + function PushNameSetting(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * PushNameSetting name. + * @member {string} name + * @memberof proto.PushNameSetting + * @instance + */ + PushNameSetting.prototype.name = ""; + + /** + * Creates a new PushNameSetting instance using the specified properties. + * @function create + * @memberof proto.PushNameSetting + * @static + * @param {proto.IPushNameSetting=} [properties] Properties to set + * @returns {proto.PushNameSetting} PushNameSetting instance + */ + PushNameSetting.create = function create(properties) { + return new PushNameSetting(properties); + }; + + /** + * Encodes the specified PushNameSetting message. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages. + * @function encode + * @memberof proto.PushNameSetting + * @static + * @param {proto.IPushNameSetting} message PushNameSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PushNameSetting.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.name); + return writer; + }; + + /** + * Encodes the specified PushNameSetting message, length delimited. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.PushNameSetting + * @static + * @param {proto.IPushNameSetting} message PushNameSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PushNameSetting.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a PushNameSetting message from the specified reader or buffer. + * @function decode + * @memberof proto.PushNameSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.PushNameSetting} PushNameSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PushNameSetting.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PushNameSetting(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.name = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a PushNameSetting message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.PushNameSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.PushNameSetting} PushNameSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PushNameSetting.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a PushNameSetting message. + * @function verify + * @memberof proto.PushNameSetting + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + PushNameSetting.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + return null; + }; + + /** + * Creates a PushNameSetting message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.PushNameSetting + * @static + * @param {Object.} object Plain object + * @returns {proto.PushNameSetting} PushNameSetting + */ + PushNameSetting.fromObject = function fromObject(object) { + if (object instanceof $root.proto.PushNameSetting) + return object; + var message = new $root.proto.PushNameSetting(); + if (object.name != null) + message.name = String(object.name); + return message; + }; + + /** + * Creates a plain object from a PushNameSetting message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.PushNameSetting + * @static + * @param {proto.PushNameSetting} message PushNameSetting + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + PushNameSetting.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.name = ""; + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + return object; + }; + + /** + * Converts this PushNameSetting to JSON. + * @function toJSON + * @memberof proto.PushNameSetting + * @instance + * @returns {Object.} JSON object + */ + PushNameSetting.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return PushNameSetting; + })(); + + proto.LocaleSetting = (function() { + + /** + * Properties of a LocaleSetting. + * @memberof proto + * @interface ILocaleSetting + * @property {string|null} [locale] LocaleSetting locale + */ + + /** + * Constructs a new LocaleSetting. + * @memberof proto + * @classdesc Represents a LocaleSetting. + * @implements ILocaleSetting + * @constructor + * @param {proto.ILocaleSetting=} [properties] Properties to set + */ + function LocaleSetting(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * LocaleSetting locale. + * @member {string} locale + * @memberof proto.LocaleSetting + * @instance + */ + LocaleSetting.prototype.locale = ""; + + /** + * Creates a new LocaleSetting instance using the specified properties. + * @function create + * @memberof proto.LocaleSetting + * @static + * @param {proto.ILocaleSetting=} [properties] Properties to set + * @returns {proto.LocaleSetting} LocaleSetting instance + */ + LocaleSetting.create = function create(properties) { + return new LocaleSetting(properties); + }; + + /** + * Encodes the specified LocaleSetting message. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages. + * @function encode + * @memberof proto.LocaleSetting + * @static + * @param {proto.ILocaleSetting} message LocaleSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LocaleSetting.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.locale != null && Object.hasOwnProperty.call(message, "locale")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.locale); + return writer; + }; + + /** + * Encodes the specified LocaleSetting message, length delimited. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.LocaleSetting + * @static + * @param {proto.ILocaleSetting} message LocaleSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LocaleSetting.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a LocaleSetting message from the specified reader or buffer. + * @function decode + * @memberof proto.LocaleSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.LocaleSetting} LocaleSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LocaleSetting.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LocaleSetting(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.locale = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a LocaleSetting message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.LocaleSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.LocaleSetting} LocaleSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LocaleSetting.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a LocaleSetting message. + * @function verify + * @memberof proto.LocaleSetting + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + LocaleSetting.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.locale != null && message.hasOwnProperty("locale")) + if (!$util.isString(message.locale)) + return "locale: string expected"; + return null; + }; + + /** + * Creates a LocaleSetting message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.LocaleSetting + * @static + * @param {Object.} object Plain object + * @returns {proto.LocaleSetting} LocaleSetting + */ + LocaleSetting.fromObject = function fromObject(object) { + if (object instanceof $root.proto.LocaleSetting) + return object; + var message = new $root.proto.LocaleSetting(); + if (object.locale != null) + message.locale = String(object.locale); + return message; + }; + + /** + * Creates a plain object from a LocaleSetting message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.LocaleSetting + * @static + * @param {proto.LocaleSetting} message LocaleSetting + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + LocaleSetting.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.locale = ""; + if (message.locale != null && message.hasOwnProperty("locale")) + object.locale = message.locale; + return object; + }; + + /** + * Converts this LocaleSetting to JSON. + * @function toJSON + * @memberof proto.LocaleSetting + * @instance + * @returns {Object.} JSON object + */ + LocaleSetting.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return LocaleSetting; + })(); + + proto.QuickReplyAction = (function() { + + /** + * Properties of a QuickReplyAction. + * @memberof proto + * @interface IQuickReplyAction + * @property {string|null} [shortcut] QuickReplyAction shortcut + * @property {string|null} [message] QuickReplyAction message + * @property {Array.|null} [keywords] QuickReplyAction keywords + * @property {number|null} [count] QuickReplyAction count + * @property {boolean|null} [deleted] QuickReplyAction deleted + */ + + /** + * Constructs a new QuickReplyAction. + * @memberof proto + * @classdesc Represents a QuickReplyAction. + * @implements IQuickReplyAction + * @constructor + * @param {proto.IQuickReplyAction=} [properties] Properties to set + */ + function QuickReplyAction(properties) { + this.keywords = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * QuickReplyAction shortcut. + * @member {string} shortcut + * @memberof proto.QuickReplyAction + * @instance + */ + QuickReplyAction.prototype.shortcut = ""; + + /** + * QuickReplyAction message. + * @member {string} message + * @memberof proto.QuickReplyAction + * @instance + */ + QuickReplyAction.prototype.message = ""; + + /** + * QuickReplyAction keywords. + * @member {Array.} keywords + * @memberof proto.QuickReplyAction + * @instance + */ + QuickReplyAction.prototype.keywords = $util.emptyArray; + + /** + * QuickReplyAction count. + * @member {number} count + * @memberof proto.QuickReplyAction + * @instance + */ + QuickReplyAction.prototype.count = 0; + + /** + * QuickReplyAction deleted. + * @member {boolean} deleted + * @memberof proto.QuickReplyAction + * @instance + */ + QuickReplyAction.prototype.deleted = false; + + /** + * Creates a new QuickReplyAction instance using the specified properties. + * @function create + * @memberof proto.QuickReplyAction + * @static + * @param {proto.IQuickReplyAction=} [properties] Properties to set + * @returns {proto.QuickReplyAction} QuickReplyAction instance + */ + QuickReplyAction.create = function create(properties) { + return new QuickReplyAction(properties); + }; + + /** + * Encodes the specified QuickReplyAction message. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages. + * @function encode + * @memberof proto.QuickReplyAction + * @static + * @param {proto.IQuickReplyAction} message QuickReplyAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + QuickReplyAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.shortcut != null && Object.hasOwnProperty.call(message, "shortcut")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.shortcut); + if (message.message != null && Object.hasOwnProperty.call(message, "message")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.message); + if (message.keywords != null && message.keywords.length) + for (var i = 0; i < message.keywords.length; ++i) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.keywords[i]); + if (message.count != null && Object.hasOwnProperty.call(message, "count")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.count); + if (message.deleted != null && Object.hasOwnProperty.call(message, "deleted")) + writer.uint32(/* id 5, wireType 0 =*/40).bool(message.deleted); + return writer; + }; + + /** + * Encodes the specified QuickReplyAction message, length delimited. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.QuickReplyAction + * @static + * @param {proto.IQuickReplyAction} message QuickReplyAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + QuickReplyAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a QuickReplyAction message from the specified reader or buffer. + * @function decode + * @memberof proto.QuickReplyAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.QuickReplyAction} QuickReplyAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + QuickReplyAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.QuickReplyAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.shortcut = reader.string(); + break; + case 2: + message.message = reader.string(); + break; + case 3: + if (!(message.keywords && message.keywords.length)) + message.keywords = []; + message.keywords.push(reader.string()); + break; + case 4: + message.count = reader.int32(); + break; + case 5: + message.deleted = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a QuickReplyAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.QuickReplyAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.QuickReplyAction} QuickReplyAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + QuickReplyAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a QuickReplyAction message. + * @function verify + * @memberof proto.QuickReplyAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + QuickReplyAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.shortcut != null && message.hasOwnProperty("shortcut")) + if (!$util.isString(message.shortcut)) + return "shortcut: string expected"; + if (message.message != null && message.hasOwnProperty("message")) + if (!$util.isString(message.message)) + return "message: string expected"; + if (message.keywords != null && message.hasOwnProperty("keywords")) { + if (!Array.isArray(message.keywords)) + return "keywords: array expected"; + for (var i = 0; i < message.keywords.length; ++i) + if (!$util.isString(message.keywords[i])) + return "keywords: string[] expected"; + } + if (message.count != null && message.hasOwnProperty("count")) + if (!$util.isInteger(message.count)) + return "count: integer expected"; + if (message.deleted != null && message.hasOwnProperty("deleted")) + if (typeof message.deleted !== "boolean") + return "deleted: boolean expected"; + return null; + }; + + /** + * Creates a QuickReplyAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.QuickReplyAction + * @static + * @param {Object.} object Plain object + * @returns {proto.QuickReplyAction} QuickReplyAction + */ + QuickReplyAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.QuickReplyAction) + return object; + var message = new $root.proto.QuickReplyAction(); + if (object.shortcut != null) + message.shortcut = String(object.shortcut); + if (object.message != null) + message.message = String(object.message); + if (object.keywords) { + if (!Array.isArray(object.keywords)) + throw TypeError(".proto.QuickReplyAction.keywords: array expected"); + message.keywords = []; + for (var i = 0; i < object.keywords.length; ++i) + message.keywords[i] = String(object.keywords[i]); + } + if (object.count != null) + message.count = object.count | 0; + if (object.deleted != null) + message.deleted = Boolean(object.deleted); + return message; + }; + + /** + * Creates a plain object from a QuickReplyAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.QuickReplyAction + * @static + * @param {proto.QuickReplyAction} message QuickReplyAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + QuickReplyAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.keywords = []; + if (options.defaults) { + object.shortcut = ""; + object.message = ""; + object.count = 0; + object.deleted = false; + } + if (message.shortcut != null && message.hasOwnProperty("shortcut")) + object.shortcut = message.shortcut; + if (message.message != null && message.hasOwnProperty("message")) + object.message = message.message; + if (message.keywords && message.keywords.length) { + object.keywords = []; + for (var j = 0; j < message.keywords.length; ++j) + object.keywords[j] = message.keywords[j]; + } + if (message.count != null && message.hasOwnProperty("count")) + object.count = message.count; + if (message.deleted != null && message.hasOwnProperty("deleted")) + object.deleted = message.deleted; + return object; + }; + + /** + * Converts this QuickReplyAction to JSON. + * @function toJSON + * @memberof proto.QuickReplyAction + * @instance + * @returns {Object.} JSON object + */ + QuickReplyAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return QuickReplyAction; + })(); + + proto.LabelAssociationAction = (function() { + + /** + * Properties of a LabelAssociationAction. + * @memberof proto + * @interface ILabelAssociationAction + * @property {boolean|null} [labeled] LabelAssociationAction labeled + */ + + /** + * Constructs a new LabelAssociationAction. + * @memberof proto + * @classdesc Represents a LabelAssociationAction. + * @implements ILabelAssociationAction + * @constructor + * @param {proto.ILabelAssociationAction=} [properties] Properties to set + */ + function LabelAssociationAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * LabelAssociationAction labeled. + * @member {boolean} labeled + * @memberof proto.LabelAssociationAction + * @instance + */ + LabelAssociationAction.prototype.labeled = false; + + /** + * Creates a new LabelAssociationAction instance using the specified properties. + * @function create + * @memberof proto.LabelAssociationAction + * @static + * @param {proto.ILabelAssociationAction=} [properties] Properties to set + * @returns {proto.LabelAssociationAction} LabelAssociationAction instance + */ + LabelAssociationAction.create = function create(properties) { + return new LabelAssociationAction(properties); + }; + + /** + * Encodes the specified LabelAssociationAction message. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages. + * @function encode + * @memberof proto.LabelAssociationAction + * @static + * @param {proto.ILabelAssociationAction} message LabelAssociationAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LabelAssociationAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.labeled != null && Object.hasOwnProperty.call(message, "labeled")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.labeled); + return writer; + }; + + /** + * Encodes the specified LabelAssociationAction message, length delimited. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.LabelAssociationAction + * @static + * @param {proto.ILabelAssociationAction} message LabelAssociationAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LabelAssociationAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a LabelAssociationAction message from the specified reader or buffer. + * @function decode + * @memberof proto.LabelAssociationAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.LabelAssociationAction} LabelAssociationAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LabelAssociationAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LabelAssociationAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.labeled = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a LabelAssociationAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.LabelAssociationAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.LabelAssociationAction} LabelAssociationAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LabelAssociationAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a LabelAssociationAction message. + * @function verify + * @memberof proto.LabelAssociationAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + LabelAssociationAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.labeled != null && message.hasOwnProperty("labeled")) + if (typeof message.labeled !== "boolean") + return "labeled: boolean expected"; + return null; + }; + + /** + * Creates a LabelAssociationAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.LabelAssociationAction + * @static + * @param {Object.} object Plain object + * @returns {proto.LabelAssociationAction} LabelAssociationAction + */ + LabelAssociationAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.LabelAssociationAction) + return object; + var message = new $root.proto.LabelAssociationAction(); + if (object.labeled != null) + message.labeled = Boolean(object.labeled); + return message; + }; + + /** + * Creates a plain object from a LabelAssociationAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.LabelAssociationAction + * @static + * @param {proto.LabelAssociationAction} message LabelAssociationAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + LabelAssociationAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.labeled = false; + if (message.labeled != null && message.hasOwnProperty("labeled")) + object.labeled = message.labeled; + return object; + }; + + /** + * Converts this LabelAssociationAction to JSON. + * @function toJSON + * @memberof proto.LabelAssociationAction + * @instance + * @returns {Object.} JSON object + */ + LabelAssociationAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return LabelAssociationAction; + })(); + + proto.LabelEditAction = (function() { + + /** + * Properties of a LabelEditAction. + * @memberof proto + * @interface ILabelEditAction + * @property {string|null} [name] LabelEditAction name + * @property {number|null} [color] LabelEditAction color + * @property {number|null} [predefinedId] LabelEditAction predefinedId + * @property {boolean|null} [deleted] LabelEditAction deleted + */ + + /** + * Constructs a new LabelEditAction. + * @memberof proto + * @classdesc Represents a LabelEditAction. + * @implements ILabelEditAction + * @constructor + * @param {proto.ILabelEditAction=} [properties] Properties to set + */ + function LabelEditAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * LabelEditAction name. + * @member {string} name + * @memberof proto.LabelEditAction + * @instance + */ + LabelEditAction.prototype.name = ""; + + /** + * LabelEditAction color. + * @member {number} color + * @memberof proto.LabelEditAction + * @instance + */ + LabelEditAction.prototype.color = 0; + + /** + * LabelEditAction predefinedId. + * @member {number} predefinedId + * @memberof proto.LabelEditAction + * @instance + */ + LabelEditAction.prototype.predefinedId = 0; + + /** + * LabelEditAction deleted. + * @member {boolean} deleted + * @memberof proto.LabelEditAction + * @instance + */ + LabelEditAction.prototype.deleted = false; + + /** + * Creates a new LabelEditAction instance using the specified properties. + * @function create + * @memberof proto.LabelEditAction + * @static + * @param {proto.ILabelEditAction=} [properties] Properties to set + * @returns {proto.LabelEditAction} LabelEditAction instance + */ + LabelEditAction.create = function create(properties) { + return new LabelEditAction(properties); + }; + + /** + * Encodes the specified LabelEditAction message. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages. + * @function encode + * @memberof proto.LabelEditAction + * @static + * @param {proto.ILabelEditAction} message LabelEditAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LabelEditAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.name); + if (message.color != null && Object.hasOwnProperty.call(message, "color")) + writer.uint32(/* id 2, wireType 0 =*/16).int32(message.color); + if (message.predefinedId != null && Object.hasOwnProperty.call(message, "predefinedId")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.predefinedId); + if (message.deleted != null && Object.hasOwnProperty.call(message, "deleted")) + writer.uint32(/* id 4, wireType 0 =*/32).bool(message.deleted); + return writer; + }; + + /** + * Encodes the specified LabelEditAction message, length delimited. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.LabelEditAction + * @static + * @param {proto.ILabelEditAction} message LabelEditAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LabelEditAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a LabelEditAction message from the specified reader or buffer. + * @function decode + * @memberof proto.LabelEditAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.LabelEditAction} LabelEditAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LabelEditAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LabelEditAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.name = reader.string(); + break; + case 2: + message.color = reader.int32(); + break; + case 3: + message.predefinedId = reader.int32(); + break; + case 4: + message.deleted = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a LabelEditAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.LabelEditAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.LabelEditAction} LabelEditAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LabelEditAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a LabelEditAction message. + * @function verify + * @memberof proto.LabelEditAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + LabelEditAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + if (message.color != null && message.hasOwnProperty("color")) + if (!$util.isInteger(message.color)) + return "color: integer expected"; + if (message.predefinedId != null && message.hasOwnProperty("predefinedId")) + if (!$util.isInteger(message.predefinedId)) + return "predefinedId: integer expected"; + if (message.deleted != null && message.hasOwnProperty("deleted")) + if (typeof message.deleted !== "boolean") + return "deleted: boolean expected"; + return null; + }; + + /** + * Creates a LabelEditAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.LabelEditAction + * @static + * @param {Object.} object Plain object + * @returns {proto.LabelEditAction} LabelEditAction + */ + LabelEditAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.LabelEditAction) + return object; + var message = new $root.proto.LabelEditAction(); + if (object.name != null) + message.name = String(object.name); + if (object.color != null) + message.color = object.color | 0; + if (object.predefinedId != null) + message.predefinedId = object.predefinedId | 0; + if (object.deleted != null) + message.deleted = Boolean(object.deleted); + return message; + }; + + /** + * Creates a plain object from a LabelEditAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.LabelEditAction + * @static + * @param {proto.LabelEditAction} message LabelEditAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + LabelEditAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.name = ""; + object.color = 0; + object.predefinedId = 0; + object.deleted = false; + } + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.color != null && message.hasOwnProperty("color")) + object.color = message.color; + if (message.predefinedId != null && message.hasOwnProperty("predefinedId")) + object.predefinedId = message.predefinedId; + if (message.deleted != null && message.hasOwnProperty("deleted")) + object.deleted = message.deleted; + return object; + }; + + /** + * Converts this LabelEditAction to JSON. + * @function toJSON + * @memberof proto.LabelEditAction + * @instance + * @returns {Object.} JSON object + */ + LabelEditAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return LabelEditAction; + })(); + + proto.RecentStickerWeightsAction = (function() { + + /** + * Properties of a RecentStickerWeightsAction. + * @memberof proto + * @interface IRecentStickerWeightsAction + * @property {Array.|null} [weights] RecentStickerWeightsAction weights + */ + + /** + * Constructs a new RecentStickerWeightsAction. + * @memberof proto + * @classdesc Represents a RecentStickerWeightsAction. + * @implements IRecentStickerWeightsAction + * @constructor + * @param {proto.IRecentStickerWeightsAction=} [properties] Properties to set + */ + function RecentStickerWeightsAction(properties) { + this.weights = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RecentStickerWeightsAction weights. + * @member {Array.} weights + * @memberof proto.RecentStickerWeightsAction + * @instance + */ + RecentStickerWeightsAction.prototype.weights = $util.emptyArray; + + /** + * Creates a new RecentStickerWeightsAction instance using the specified properties. + * @function create + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {proto.IRecentStickerWeightsAction=} [properties] Properties to set + * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction instance + */ + RecentStickerWeightsAction.create = function create(properties) { + return new RecentStickerWeightsAction(properties); + }; + + /** + * Encodes the specified RecentStickerWeightsAction message. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages. + * @function encode + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {proto.IRecentStickerWeightsAction} message RecentStickerWeightsAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentStickerWeightsAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.weights != null && message.weights.length) + for (var i = 0; i < message.weights.length; ++i) + $root.proto.RecentStickerWeight.encode(message.weights[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified RecentStickerWeightsAction message, length delimited. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {proto.IRecentStickerWeightsAction} message RecentStickerWeightsAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentStickerWeightsAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RecentStickerWeightsAction message from the specified reader or buffer. + * @function decode + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentStickerWeightsAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentStickerWeightsAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.weights && message.weights.length)) + message.weights = []; + message.weights.push($root.proto.RecentStickerWeight.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RecentStickerWeightsAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentStickerWeightsAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RecentStickerWeightsAction message. + * @function verify + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RecentStickerWeightsAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.weights != null && message.hasOwnProperty("weights")) { + if (!Array.isArray(message.weights)) + return "weights: array expected"; + for (var i = 0; i < message.weights.length; ++i) { + var error = $root.proto.RecentStickerWeight.verify(message.weights[i]); + if (error) + return "weights." + error; + } + } + return null; + }; + + /** + * Creates a RecentStickerWeightsAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {Object.} object Plain object + * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction + */ + RecentStickerWeightsAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.RecentStickerWeightsAction) + return object; + var message = new $root.proto.RecentStickerWeightsAction(); + if (object.weights) { + if (!Array.isArray(object.weights)) + throw TypeError(".proto.RecentStickerWeightsAction.weights: array expected"); + message.weights = []; + for (var i = 0; i < object.weights.length; ++i) { + if (typeof object.weights[i] !== "object") + throw TypeError(".proto.RecentStickerWeightsAction.weights: object expected"); + message.weights[i] = $root.proto.RecentStickerWeight.fromObject(object.weights[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a RecentStickerWeightsAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {proto.RecentStickerWeightsAction} message RecentStickerWeightsAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RecentStickerWeightsAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.weights = []; + if (message.weights && message.weights.length) { + object.weights = []; + for (var j = 0; j < message.weights.length; ++j) + object.weights[j] = $root.proto.RecentStickerWeight.toObject(message.weights[j], options); + } + return object; + }; + + /** + * Converts this RecentStickerWeightsAction to JSON. + * @function toJSON + * @memberof proto.RecentStickerWeightsAction + * @instance + * @returns {Object.} JSON object + */ + RecentStickerWeightsAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RecentStickerWeightsAction; + })(); + + proto.RecentStickerMetadata = (function() { + + /** + * Properties of a RecentStickerMetadata. + * @memberof proto + * @interface IRecentStickerMetadata + * @property {string|null} [directPath] RecentStickerMetadata directPath + * @property {string|null} [encFilehash] RecentStickerMetadata encFilehash + * @property {string|null} [mediaKey] RecentStickerMetadata mediaKey + * @property {string|null} [stanzaId] RecentStickerMetadata stanzaId + * @property {string|null} [chatJid] RecentStickerMetadata chatJid + * @property {string|null} [participant] RecentStickerMetadata participant + * @property {boolean|null} [isSentByMe] RecentStickerMetadata isSentByMe + */ + + /** + * Constructs a new RecentStickerMetadata. + * @memberof proto + * @classdesc Represents a RecentStickerMetadata. + * @implements IRecentStickerMetadata + * @constructor + * @param {proto.IRecentStickerMetadata=} [properties] Properties to set + */ + function RecentStickerMetadata(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RecentStickerMetadata directPath. + * @member {string} directPath + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.directPath = ""; + + /** + * RecentStickerMetadata encFilehash. + * @member {string} encFilehash + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.encFilehash = ""; + + /** + * RecentStickerMetadata mediaKey. + * @member {string} mediaKey + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.mediaKey = ""; + + /** + * RecentStickerMetadata stanzaId. + * @member {string} stanzaId + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.stanzaId = ""; + + /** + * RecentStickerMetadata chatJid. + * @member {string} chatJid + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.chatJid = ""; + + /** + * RecentStickerMetadata participant. + * @member {string} participant + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.participant = ""; + + /** + * RecentStickerMetadata isSentByMe. + * @member {boolean} isSentByMe + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.isSentByMe = false; + + /** + * Creates a new RecentStickerMetadata instance using the specified properties. + * @function create + * @memberof proto.RecentStickerMetadata + * @static + * @param {proto.IRecentStickerMetadata=} [properties] Properties to set + * @returns {proto.RecentStickerMetadata} RecentStickerMetadata instance + */ + RecentStickerMetadata.create = function create(properties) { + return new RecentStickerMetadata(properties); + }; + + /** + * Encodes the specified RecentStickerMetadata message. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages. + * @function encode + * @memberof proto.RecentStickerMetadata + * @static + * @param {proto.IRecentStickerMetadata} message RecentStickerMetadata message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentStickerMetadata.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.directPath); + if (message.encFilehash != null && Object.hasOwnProperty.call(message, "encFilehash")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.encFilehash); + if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.mediaKey); + if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.stanzaId); + if (message.chatJid != null && Object.hasOwnProperty.call(message, "chatJid")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.chatJid); + if (message.participant != null && Object.hasOwnProperty.call(message, "participant")) + writer.uint32(/* id 6, wireType 2 =*/50).string(message.participant); + if (message.isSentByMe != null && Object.hasOwnProperty.call(message, "isSentByMe")) + writer.uint32(/* id 7, wireType 0 =*/56).bool(message.isSentByMe); + return writer; + }; + + /** + * Encodes the specified RecentStickerMetadata message, length delimited. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.RecentStickerMetadata + * @static + * @param {proto.IRecentStickerMetadata} message RecentStickerMetadata message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentStickerMetadata.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RecentStickerMetadata message from the specified reader or buffer. + * @function decode + * @memberof proto.RecentStickerMetadata + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.RecentStickerMetadata} RecentStickerMetadata + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentStickerMetadata.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentStickerMetadata(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.directPath = reader.string(); + break; + case 2: + message.encFilehash = reader.string(); + break; + case 3: + message.mediaKey = reader.string(); + break; + case 4: + message.stanzaId = reader.string(); + break; + case 5: + message.chatJid = reader.string(); + break; + case 6: + message.participant = reader.string(); + break; + case 7: + message.isSentByMe = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RecentStickerMetadata message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.RecentStickerMetadata + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.RecentStickerMetadata} RecentStickerMetadata + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentStickerMetadata.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RecentStickerMetadata message. + * @function verify + * @memberof proto.RecentStickerMetadata + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RecentStickerMetadata.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.directPath != null && message.hasOwnProperty("directPath")) + if (!$util.isString(message.directPath)) + return "directPath: string expected"; + if (message.encFilehash != null && message.hasOwnProperty("encFilehash")) + if (!$util.isString(message.encFilehash)) + return "encFilehash: string expected"; + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + if (!$util.isString(message.mediaKey)) + return "mediaKey: string expected"; + if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) + if (!$util.isString(message.stanzaId)) + return "stanzaId: string expected"; + if (message.chatJid != null && message.hasOwnProperty("chatJid")) + if (!$util.isString(message.chatJid)) + return "chatJid: string expected"; + if (message.participant != null && message.hasOwnProperty("participant")) + if (!$util.isString(message.participant)) + return "participant: string expected"; + if (message.isSentByMe != null && message.hasOwnProperty("isSentByMe")) + if (typeof message.isSentByMe !== "boolean") + return "isSentByMe: boolean expected"; + return null; + }; + + /** + * Creates a RecentStickerMetadata message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.RecentStickerMetadata + * @static + * @param {Object.} object Plain object + * @returns {proto.RecentStickerMetadata} RecentStickerMetadata + */ + RecentStickerMetadata.fromObject = function fromObject(object) { + if (object instanceof $root.proto.RecentStickerMetadata) + return object; + var message = new $root.proto.RecentStickerMetadata(); + if (object.directPath != null) + message.directPath = String(object.directPath); + if (object.encFilehash != null) + message.encFilehash = String(object.encFilehash); + if (object.mediaKey != null) + message.mediaKey = String(object.mediaKey); + if (object.stanzaId != null) + message.stanzaId = String(object.stanzaId); + if (object.chatJid != null) + message.chatJid = String(object.chatJid); + if (object.participant != null) + message.participant = String(object.participant); + if (object.isSentByMe != null) + message.isSentByMe = Boolean(object.isSentByMe); + return message; + }; + + /** + * Creates a plain object from a RecentStickerMetadata message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.RecentStickerMetadata + * @static + * @param {proto.RecentStickerMetadata} message RecentStickerMetadata + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RecentStickerMetadata.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.directPath = ""; + object.encFilehash = ""; + object.mediaKey = ""; + object.stanzaId = ""; + object.chatJid = ""; + object.participant = ""; + object.isSentByMe = false; + } + if (message.directPath != null && message.hasOwnProperty("directPath")) + object.directPath = message.directPath; + if (message.encFilehash != null && message.hasOwnProperty("encFilehash")) + object.encFilehash = message.encFilehash; + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + object.mediaKey = message.mediaKey; + if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) + object.stanzaId = message.stanzaId; + if (message.chatJid != null && message.hasOwnProperty("chatJid")) + object.chatJid = message.chatJid; + if (message.participant != null && message.hasOwnProperty("participant")) + object.participant = message.participant; + if (message.isSentByMe != null && message.hasOwnProperty("isSentByMe")) + object.isSentByMe = message.isSentByMe; + return object; + }; + + /** + * Converts this RecentStickerMetadata to JSON. + * @function toJSON + * @memberof proto.RecentStickerMetadata + * @instance + * @returns {Object.} JSON object + */ + RecentStickerMetadata.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RecentStickerMetadata; + })(); + + proto.RecentEmojiWeightsAction = (function() { + + /** + * Properties of a RecentEmojiWeightsAction. + * @memberof proto + * @interface IRecentEmojiWeightsAction + * @property {Array.|null} [weights] RecentEmojiWeightsAction weights + */ + + /** + * Constructs a new RecentEmojiWeightsAction. + * @memberof proto + * @classdesc Represents a RecentEmojiWeightsAction. + * @implements IRecentEmojiWeightsAction + * @constructor + * @param {proto.IRecentEmojiWeightsAction=} [properties] Properties to set + */ + function RecentEmojiWeightsAction(properties) { + this.weights = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RecentEmojiWeightsAction weights. + * @member {Array.} weights + * @memberof proto.RecentEmojiWeightsAction + * @instance + */ + RecentEmojiWeightsAction.prototype.weights = $util.emptyArray; + + /** + * Creates a new RecentEmojiWeightsAction instance using the specified properties. + * @function create + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {proto.IRecentEmojiWeightsAction=} [properties] Properties to set + * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction instance + */ + RecentEmojiWeightsAction.create = function create(properties) { + return new RecentEmojiWeightsAction(properties); + }; + + /** + * Encodes the specified RecentEmojiWeightsAction message. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages. + * @function encode + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {proto.IRecentEmojiWeightsAction} message RecentEmojiWeightsAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentEmojiWeightsAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.weights != null && message.weights.length) + for (var i = 0; i < message.weights.length; ++i) + $root.proto.RecentEmojiWeight.encode(message.weights[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified RecentEmojiWeightsAction message, length delimited. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {proto.IRecentEmojiWeightsAction} message RecentEmojiWeightsAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentEmojiWeightsAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer. + * @function decode + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentEmojiWeightsAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentEmojiWeightsAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.weights && message.weights.length)) + message.weights = []; + message.weights.push($root.proto.RecentEmojiWeight.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentEmojiWeightsAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RecentEmojiWeightsAction message. + * @function verify + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RecentEmojiWeightsAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.weights != null && message.hasOwnProperty("weights")) { + if (!Array.isArray(message.weights)) + return "weights: array expected"; + for (var i = 0; i < message.weights.length; ++i) { + var error = $root.proto.RecentEmojiWeight.verify(message.weights[i]); + if (error) + return "weights." + error; + } + } + return null; + }; + + /** + * Creates a RecentEmojiWeightsAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {Object.} object Plain object + * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction + */ + RecentEmojiWeightsAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.RecentEmojiWeightsAction) + return object; + var message = new $root.proto.RecentEmojiWeightsAction(); + if (object.weights) { + if (!Array.isArray(object.weights)) + throw TypeError(".proto.RecentEmojiWeightsAction.weights: array expected"); + message.weights = []; + for (var i = 0; i < object.weights.length; ++i) { + if (typeof object.weights[i] !== "object") + throw TypeError(".proto.RecentEmojiWeightsAction.weights: object expected"); + message.weights[i] = $root.proto.RecentEmojiWeight.fromObject(object.weights[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a RecentEmojiWeightsAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {proto.RecentEmojiWeightsAction} message RecentEmojiWeightsAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RecentEmojiWeightsAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.weights = []; + if (message.weights && message.weights.length) { + object.weights = []; + for (var j = 0; j < message.weights.length; ++j) + object.weights[j] = $root.proto.RecentEmojiWeight.toObject(message.weights[j], options); + } + return object; + }; + + /** + * Converts this RecentEmojiWeightsAction to JSON. + * @function toJSON + * @memberof proto.RecentEmojiWeightsAction + * @instance + * @returns {Object.} JSON object + */ + RecentEmojiWeightsAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RecentEmojiWeightsAction; + })(); + + proto.ArchiveChatAction = (function() { + + /** + * Properties of an ArchiveChatAction. + * @memberof proto + * @interface IArchiveChatAction + * @property {boolean|null} [archived] ArchiveChatAction archived + * @property {proto.ISyncActionMessageRange|null} [messageRange] ArchiveChatAction messageRange + */ + + /** + * Constructs a new ArchiveChatAction. + * @memberof proto + * @classdesc Represents an ArchiveChatAction. + * @implements IArchiveChatAction + * @constructor + * @param {proto.IArchiveChatAction=} [properties] Properties to set + */ + function ArchiveChatAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ArchiveChatAction archived. + * @member {boolean} archived + * @memberof proto.ArchiveChatAction + * @instance + */ + ArchiveChatAction.prototype.archived = false; + + /** + * ArchiveChatAction messageRange. + * @member {proto.ISyncActionMessageRange|null|undefined} messageRange + * @memberof proto.ArchiveChatAction + * @instance + */ + ArchiveChatAction.prototype.messageRange = null; + + /** + * Creates a new ArchiveChatAction instance using the specified properties. + * @function create + * @memberof proto.ArchiveChatAction + * @static + * @param {proto.IArchiveChatAction=} [properties] Properties to set + * @returns {proto.ArchiveChatAction} ArchiveChatAction instance + */ + ArchiveChatAction.create = function create(properties) { + return new ArchiveChatAction(properties); + }; + + /** + * Encodes the specified ArchiveChatAction message. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages. + * @function encode + * @memberof proto.ArchiveChatAction + * @static + * @param {proto.IArchiveChatAction} message ArchiveChatAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ArchiveChatAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.archived != null && Object.hasOwnProperty.call(message, "archived")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.archived); + if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange")) + $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified ArchiveChatAction message, length delimited. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ArchiveChatAction + * @static + * @param {proto.IArchiveChatAction} message ArchiveChatAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ArchiveChatAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an ArchiveChatAction message from the specified reader or buffer. + * @function decode + * @memberof proto.ArchiveChatAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ArchiveChatAction} ArchiveChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ArchiveChatAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ArchiveChatAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.archived = reader.bool(); + break; + case 2: + message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an ArchiveChatAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ArchiveChatAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ArchiveChatAction} ArchiveChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ArchiveChatAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an ArchiveChatAction message. + * @function verify + * @memberof proto.ArchiveChatAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ArchiveChatAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.archived != null && message.hasOwnProperty("archived")) + if (typeof message.archived !== "boolean") + return "archived: boolean expected"; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) { + var error = $root.proto.SyncActionMessageRange.verify(message.messageRange); + if (error) + return "messageRange." + error; + } + return null; + }; + + /** + * Creates an ArchiveChatAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ArchiveChatAction + * @static + * @param {Object.} object Plain object + * @returns {proto.ArchiveChatAction} ArchiveChatAction + */ + ArchiveChatAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ArchiveChatAction) + return object; + var message = new $root.proto.ArchiveChatAction(); + if (object.archived != null) + message.archived = Boolean(object.archived); + if (object.messageRange != null) { + if (typeof object.messageRange !== "object") + throw TypeError(".proto.ArchiveChatAction.messageRange: object expected"); + message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange); + } + return message; + }; + + /** + * Creates a plain object from an ArchiveChatAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ArchiveChatAction + * @static + * @param {proto.ArchiveChatAction} message ArchiveChatAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ArchiveChatAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.archived = false; + object.messageRange = null; + } + if (message.archived != null && message.hasOwnProperty("archived")) + object.archived = message.archived; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) + object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options); + return object; + }; + + /** + * Converts this ArchiveChatAction to JSON. + * @function toJSON + * @memberof proto.ArchiveChatAction + * @instance + * @returns {Object.} JSON object + */ + ArchiveChatAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ArchiveChatAction; + })(); + + proto.DeleteMessageForMeAction = (function() { + + /** + * Properties of a DeleteMessageForMeAction. + * @memberof proto + * @interface IDeleteMessageForMeAction + * @property {boolean|null} [deleteMedia] DeleteMessageForMeAction deleteMedia + * @property {number|Long|null} [messageTimestamp] DeleteMessageForMeAction messageTimestamp + */ + + /** + * Constructs a new DeleteMessageForMeAction. + * @memberof proto + * @classdesc Represents a DeleteMessageForMeAction. + * @implements IDeleteMessageForMeAction + * @constructor + * @param {proto.IDeleteMessageForMeAction=} [properties] Properties to set + */ + function DeleteMessageForMeAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * DeleteMessageForMeAction deleteMedia. + * @member {boolean} deleteMedia + * @memberof proto.DeleteMessageForMeAction + * @instance + */ + DeleteMessageForMeAction.prototype.deleteMedia = false; + + /** + * DeleteMessageForMeAction messageTimestamp. + * @member {number|Long} messageTimestamp + * @memberof proto.DeleteMessageForMeAction + * @instance + */ + DeleteMessageForMeAction.prototype.messageTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new DeleteMessageForMeAction instance using the specified properties. + * @function create + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {proto.IDeleteMessageForMeAction=} [properties] Properties to set + * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction instance + */ + DeleteMessageForMeAction.create = function create(properties) { + return new DeleteMessageForMeAction(properties); + }; + + /** + * Encodes the specified DeleteMessageForMeAction message. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages. + * @function encode + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {proto.IDeleteMessageForMeAction} message DeleteMessageForMeAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DeleteMessageForMeAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.deleteMedia != null && Object.hasOwnProperty.call(message, "deleteMedia")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.deleteMedia); + if (message.messageTimestamp != null && Object.hasOwnProperty.call(message, "messageTimestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.messageTimestamp); + return writer; + }; + + /** + * Encodes the specified DeleteMessageForMeAction message, length delimited. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {proto.IDeleteMessageForMeAction} message DeleteMessageForMeAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DeleteMessageForMeAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a DeleteMessageForMeAction message from the specified reader or buffer. + * @function decode + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DeleteMessageForMeAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DeleteMessageForMeAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.deleteMedia = reader.bool(); + break; + case 2: + message.messageTimestamp = reader.int64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a DeleteMessageForMeAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DeleteMessageForMeAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a DeleteMessageForMeAction message. + * @function verify + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + DeleteMessageForMeAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.deleteMedia != null && message.hasOwnProperty("deleteMedia")) + if (typeof message.deleteMedia !== "boolean") + return "deleteMedia: boolean expected"; + if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) + if (!$util.isInteger(message.messageTimestamp) && !(message.messageTimestamp && $util.isInteger(message.messageTimestamp.low) && $util.isInteger(message.messageTimestamp.high))) + return "messageTimestamp: integer|Long expected"; + return null; + }; + + /** + * Creates a DeleteMessageForMeAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {Object.} object Plain object + * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction + */ + DeleteMessageForMeAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.DeleteMessageForMeAction) + return object; + var message = new $root.proto.DeleteMessageForMeAction(); + if (object.deleteMedia != null) + message.deleteMedia = Boolean(object.deleteMedia); if (object.messageTimestamp != null) if ($util.Long) - (message.messageTimestamp = $util.Long.fromValue(object.messageTimestamp)).unsigned = true; + (message.messageTimestamp = $util.Long.fromValue(object.messageTimestamp)).unsigned = false; else if (typeof object.messageTimestamp === "string") message.messageTimestamp = parseInt(object.messageTimestamp, 10); else if (typeof object.messageTimestamp === "number") message.messageTimestamp = object.messageTimestamp; else if (typeof object.messageTimestamp === "object") - message.messageTimestamp = new $util.LongBits(object.messageTimestamp.low >>> 0, object.messageTimestamp.high >>> 0).toNumber(true); - switch (object.status) { - case "ERROR": - case 0: - message.status = 0; - break; - case "PENDING": - case 1: - message.status = 1; - break; - case "SERVER_ACK": - case 2: - message.status = 2; - break; - case "DELIVERY_ACK": - case 3: - message.status = 3; - break; - case "READ": - case 4: - message.status = 4; - break; - case "PLAYED": - case 5: - message.status = 5; - break; - } - if (object.participant != null) - message.participant = String(object.participant); - if (object.ignore != null) - message.ignore = Boolean(object.ignore); - if (object.starred != null) - message.starred = Boolean(object.starred); - if (object.broadcast != null) - message.broadcast = Boolean(object.broadcast); - if (object.pushName != null) - message.pushName = String(object.pushName); - if (object.mediaCiphertextSha256 != null) - if (typeof object.mediaCiphertextSha256 === "string") - $util.base64.decode(object.mediaCiphertextSha256, message.mediaCiphertextSha256 = $util.newBuffer($util.base64.length(object.mediaCiphertextSha256)), 0); - else if (object.mediaCiphertextSha256.length) - message.mediaCiphertextSha256 = object.mediaCiphertextSha256; - if (object.multicast != null) - message.multicast = Boolean(object.multicast); - if (object.urlText != null) - message.urlText = Boolean(object.urlText); - if (object.urlNumber != null) - message.urlNumber = Boolean(object.urlNumber); - switch (object.messageStubType) { - case "UNKNOWN": - case 0: - message.messageStubType = 0; - break; - case "REVOKE": - case 1: - message.messageStubType = 1; - break; - case "CIPHERTEXT": - case 2: - message.messageStubType = 2; - break; - case "FUTUREPROOF": - case 3: - message.messageStubType = 3; - break; - case "NON_VERIFIED_TRANSITION": - case 4: - message.messageStubType = 4; - break; - case "UNVERIFIED_TRANSITION": - case 5: - message.messageStubType = 5; - break; - case "VERIFIED_TRANSITION": - case 6: - message.messageStubType = 6; - break; - case "VERIFIED_LOW_UNKNOWN": - case 7: - message.messageStubType = 7; - break; - case "VERIFIED_HIGH": - case 8: - message.messageStubType = 8; - break; - case "VERIFIED_INITIAL_UNKNOWN": - case 9: - message.messageStubType = 9; - break; - case "VERIFIED_INITIAL_LOW": - case 10: - message.messageStubType = 10; - break; - case "VERIFIED_INITIAL_HIGH": - case 11: - message.messageStubType = 11; - break; - case "VERIFIED_TRANSITION_ANY_TO_NONE": - case 12: - message.messageStubType = 12; - break; - case "VERIFIED_TRANSITION_ANY_TO_HIGH": - case 13: - message.messageStubType = 13; - break; - case "VERIFIED_TRANSITION_HIGH_TO_LOW": - case 14: - message.messageStubType = 14; - break; - case "VERIFIED_TRANSITION_HIGH_TO_UNKNOWN": - case 15: - message.messageStubType = 15; - break; - case "VERIFIED_TRANSITION_UNKNOWN_TO_LOW": - case 16: - message.messageStubType = 16; - break; - case "VERIFIED_TRANSITION_LOW_TO_UNKNOWN": - case 17: - message.messageStubType = 17; - break; - case "VERIFIED_TRANSITION_NONE_TO_LOW": - case 18: - message.messageStubType = 18; - break; - case "VERIFIED_TRANSITION_NONE_TO_UNKNOWN": - case 19: - message.messageStubType = 19; - break; - case "GROUP_CREATE": - case 20: - message.messageStubType = 20; - break; - case "GROUP_CHANGE_SUBJECT": - case 21: - message.messageStubType = 21; - break; - case "GROUP_CHANGE_ICON": - case 22: - message.messageStubType = 22; - break; - case "GROUP_CHANGE_INVITE_LINK": - case 23: - message.messageStubType = 23; - break; - case "GROUP_CHANGE_DESCRIPTION": - case 24: - message.messageStubType = 24; - break; - case "GROUP_CHANGE_RESTRICT": - case 25: - message.messageStubType = 25; - break; - case "GROUP_CHANGE_ANNOUNCE": - case 26: - message.messageStubType = 26; - break; - case "GROUP_PARTICIPANT_ADD": - case 27: - message.messageStubType = 27; - break; - case "GROUP_PARTICIPANT_REMOVE": - case 28: - message.messageStubType = 28; - break; - case "GROUP_PARTICIPANT_PROMOTE": - case 29: - message.messageStubType = 29; - break; - case "GROUP_PARTICIPANT_DEMOTE": - case 30: - message.messageStubType = 30; - break; - case "GROUP_PARTICIPANT_INVITE": - case 31: - message.messageStubType = 31; - break; - case "GROUP_PARTICIPANT_LEAVE": - case 32: - message.messageStubType = 32; - break; - case "GROUP_PARTICIPANT_CHANGE_NUMBER": - case 33: - message.messageStubType = 33; - break; - case "BROADCAST_CREATE": - case 34: - message.messageStubType = 34; - break; - case "BROADCAST_ADD": - case 35: - message.messageStubType = 35; - break; - case "BROADCAST_REMOVE": - case 36: - message.messageStubType = 36; - break; - case "GENERIC_NOTIFICATION": - case 37: - message.messageStubType = 37; - break; - case "E2E_IDENTITY_CHANGED": - case 38: - message.messageStubType = 38; - break; - case "E2E_ENCRYPTED": - case 39: - message.messageStubType = 39; - break; - case "CALL_MISSED_VOICE": - case 40: - message.messageStubType = 40; - break; - case "CALL_MISSED_VIDEO": - case 41: - message.messageStubType = 41; - break; - case "INDIVIDUAL_CHANGE_NUMBER": - case 42: - message.messageStubType = 42; - break; - case "GROUP_DELETE": - case 43: - message.messageStubType = 43; - break; - case "GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE": - case 44: - message.messageStubType = 44; - break; - case "CALL_MISSED_GROUP_VOICE": - case 45: - message.messageStubType = 45; - break; - case "CALL_MISSED_GROUP_VIDEO": - case 46: - message.messageStubType = 46; - break; - case "PAYMENT_CIPHERTEXT": - case 47: - message.messageStubType = 47; - break; - case "PAYMENT_FUTUREPROOF": - case 48: - message.messageStubType = 48; - break; - case "PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED": - case 49: - message.messageStubType = 49; - break; - case "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED": - case 50: - message.messageStubType = 50; - break; - case "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED": - case 51: - message.messageStubType = 51; - break; - case "PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP": - case 52: - message.messageStubType = 52; - break; - case "PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP": - case 53: - message.messageStubType = 53; - break; - case "PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER": - case 54: - message.messageStubType = 54; - break; - case "PAYMENT_ACTION_SEND_PAYMENT_REMINDER": - case 55: - message.messageStubType = 55; - break; - case "PAYMENT_ACTION_SEND_PAYMENT_INVITATION": - case 56: - message.messageStubType = 56; - break; - case "PAYMENT_ACTION_REQUEST_DECLINED": - case 57: - message.messageStubType = 57; - break; - case "PAYMENT_ACTION_REQUEST_EXPIRED": - case 58: - message.messageStubType = 58; - break; - case "PAYMENT_ACTION_REQUEST_CANCELLED": - case 59: - message.messageStubType = 59; - break; - case "BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM": - case 60: - message.messageStubType = 60; - break; - case "BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP": - case 61: - message.messageStubType = 61; - break; - case "BIZ_INTRO_TOP": - case 62: - message.messageStubType = 62; - break; - case "BIZ_INTRO_BOTTOM": - case 63: - message.messageStubType = 63; - break; - case "BIZ_NAME_CHANGE": - case 64: - message.messageStubType = 64; - break; - case "BIZ_MOVE_TO_CONSUMER_APP": - case 65: - message.messageStubType = 65; - break; - case "BIZ_TWO_TIER_MIGRATION_TOP": - case 66: - message.messageStubType = 66; - break; - case "BIZ_TWO_TIER_MIGRATION_BOTTOM": - case 67: - message.messageStubType = 67; - break; - case "OVERSIZED": - case 68: - message.messageStubType = 68; - break; - case "GROUP_CHANGE_NO_FREQUENTLY_FORWARDED": - case 69: - message.messageStubType = 69; - break; - case "GROUP_V4_ADD_INVITE_SENT": - case 70: - message.messageStubType = 70; - break; - case "GROUP_PARTICIPANT_ADD_REQUEST_JOIN": - case 71: - message.messageStubType = 71; - break; - case "CHANGE_EPHEMERAL_SETTING": - case 72: - message.messageStubType = 72; - break; - case "E2E_DEVICE_CHANGED": - case 73: - message.messageStubType = 73; - break; - case "VIEWED_ONCE": - case 74: - message.messageStubType = 74; - break; - case "E2E_ENCRYPTED_NOW": - case 75: - message.messageStubType = 75; - break; - case "BLUE_MSG_BSP_FB_TO_BSP_PREMISE": - case 76: - message.messageStubType = 76; - break; - case "BLUE_MSG_BSP_FB_TO_SELF_FB": - case 77: - message.messageStubType = 77; - break; - case "BLUE_MSG_BSP_FB_TO_SELF_PREMISE": - case 78: - message.messageStubType = 78; - break; - case "BLUE_MSG_BSP_FB_UNVERIFIED": - case 79: - message.messageStubType = 79; - break; - case "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED": - case 80: - message.messageStubType = 80; - break; - case "BLUE_MSG_BSP_FB_VERIFIED": - case 81: - message.messageStubType = 81; - break; - case "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED": - case 82: - message.messageStubType = 82; - break; - case "BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE": - case 83: - message.messageStubType = 83; - break; - case "BLUE_MSG_BSP_PREMISE_UNVERIFIED": - case 84: - message.messageStubType = 84; - break; - case "BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED": - case 85: - message.messageStubType = 85; - break; - case "BLUE_MSG_BSP_PREMISE_VERIFIED": - case 86: - message.messageStubType = 86; - break; - case "BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED": - case 87: - message.messageStubType = 87; - break; - case "BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED": - case 88: - message.messageStubType = 88; - break; - case "BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED": - case 89: - message.messageStubType = 89; - break; - case "BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED": - case 90: - message.messageStubType = 90; - break; - case "BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED": - case 91: - message.messageStubType = 91; - break; - case "BLUE_MSG_SELF_FB_TO_BSP_PREMISE": - case 92: - message.messageStubType = 92; - break; - case "BLUE_MSG_SELF_FB_TO_SELF_PREMISE": - case 93: - message.messageStubType = 93; - break; - case "BLUE_MSG_SELF_FB_UNVERIFIED": - case 94: - message.messageStubType = 94; - break; - case "BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED": - case 95: - message.messageStubType = 95; - break; - case "BLUE_MSG_SELF_FB_VERIFIED": - case 96: - message.messageStubType = 96; - break; - case "BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED": - case 97: - message.messageStubType = 97; - break; - case "BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE": - case 98: - message.messageStubType = 98; - break; - case "BLUE_MSG_SELF_PREMISE_UNVERIFIED": - case 99: - message.messageStubType = 99; - break; - case "BLUE_MSG_SELF_PREMISE_VERIFIED": - case 100: - message.messageStubType = 100; - break; - case "BLUE_MSG_TO_BSP_FB": - case 101: - message.messageStubType = 101; - break; - case "BLUE_MSG_TO_CONSUMER": - case 102: - message.messageStubType = 102; - break; - case "BLUE_MSG_TO_SELF_FB": - case 103: - message.messageStubType = 103; - break; - case "BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED": - case 104: - message.messageStubType = 104; - break; - case "BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED": - case 105: - message.messageStubType = 105; - break; - case "BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED": - case 106: - message.messageStubType = 106; - break; - case "BLUE_MSG_UNVERIFIED_TO_VERIFIED": - case 107: - message.messageStubType = 107; - break; - case "BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED": - case 108: - message.messageStubType = 108; - break; - case "BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED": - case 109: - message.messageStubType = 109; - break; - case "BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED": - case 110: - message.messageStubType = 110; - break; - case "BLUE_MSG_VERIFIED_TO_UNVERIFIED": - case 111: - message.messageStubType = 111; - break; - case "BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED": - case 112: - message.messageStubType = 112; - break; - case "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED": - case 113: - message.messageStubType = 113; - break; - case "BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED": - case 114: - message.messageStubType = 114; - break; - case "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED": - case 115: - message.messageStubType = 115; - break; - case "BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED": - case 116: - message.messageStubType = 116; - break; - case "BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED": - case 117: - message.messageStubType = 117; - break; - case "E2E_IDENTITY_UNAVAILABLE": - case 118: - message.messageStubType = 118; - break; - } - if (object.clearMedia != null) - message.clearMedia = Boolean(object.clearMedia); - if (object.messageStubParameters) { - if (!Array.isArray(object.messageStubParameters)) - throw TypeError(".proto.WebMessageInfo.messageStubParameters: array expected"); - message.messageStubParameters = []; - for (var i = 0; i < object.messageStubParameters.length; ++i) - message.messageStubParameters[i] = String(object.messageStubParameters[i]); - } - if (object.duration != null) - message.duration = object.duration >>> 0; - if (object.labels) { - if (!Array.isArray(object.labels)) - throw TypeError(".proto.WebMessageInfo.labels: array expected"); - message.labels = []; - for (var i = 0; i < object.labels.length; ++i) - message.labels[i] = String(object.labels[i]); - } - if (object.paymentInfo != null) { - if (typeof object.paymentInfo !== "object") - throw TypeError(".proto.WebMessageInfo.paymentInfo: object expected"); - message.paymentInfo = $root.proto.PaymentInfo.fromObject(object.paymentInfo); - } - if (object.finalLiveLocation != null) { - if (typeof object.finalLiveLocation !== "object") - throw TypeError(".proto.WebMessageInfo.finalLiveLocation: object expected"); - message.finalLiveLocation = $root.proto.LiveLocationMessage.fromObject(object.finalLiveLocation); - } - if (object.quotedPaymentInfo != null) { - if (typeof object.quotedPaymentInfo !== "object") - throw TypeError(".proto.WebMessageInfo.quotedPaymentInfo: object expected"); - message.quotedPaymentInfo = $root.proto.PaymentInfo.fromObject(object.quotedPaymentInfo); - } - if (object.ephemeralStartTimestamp != null) - if ($util.Long) - (message.ephemeralStartTimestamp = $util.Long.fromValue(object.ephemeralStartTimestamp)).unsigned = true; - else if (typeof object.ephemeralStartTimestamp === "string") - message.ephemeralStartTimestamp = parseInt(object.ephemeralStartTimestamp, 10); - else if (typeof object.ephemeralStartTimestamp === "number") - message.ephemeralStartTimestamp = object.ephemeralStartTimestamp; - else if (typeof object.ephemeralStartTimestamp === "object") - message.ephemeralStartTimestamp = new $util.LongBits(object.ephemeralStartTimestamp.low >>> 0, object.ephemeralStartTimestamp.high >>> 0).toNumber(true); - if (object.ephemeralDuration != null) - message.ephemeralDuration = object.ephemeralDuration >>> 0; - if (object.ephemeralOffToOn != null) - message.ephemeralOffToOn = Boolean(object.ephemeralOffToOn); - if (object.ephemeralOutOfSync != null) - message.ephemeralOutOfSync = Boolean(object.ephemeralOutOfSync); - switch (object.bizPrivacyStatus) { - case "E2EE": - case 0: - message.bizPrivacyStatus = 0; - break; - case "FB": - case 2: - message.bizPrivacyStatus = 2; - break; - case "BSP": - case 1: - message.bizPrivacyStatus = 1; - break; - case "BSP_AND_FB": - case 3: - message.bizPrivacyStatus = 3; - break; - } - if (object.verifiedBizName != null) - message.verifiedBizName = String(object.verifiedBizName); + message.messageTimestamp = new $util.LongBits(object.messageTimestamp.low >>> 0, object.messageTimestamp.high >>> 0).toNumber(); return message; }; /** - * Creates a plain object from a WebMessageInfo message. Also converts values to other types if specified. + * Creates a plain object from a DeleteMessageForMeAction message. Also converts values to other types if specified. * @function toObject - * @memberof proto.WebMessageInfo + * @memberof proto.DeleteMessageForMeAction * @static - * @param {proto.WebMessageInfo} message WebMessageInfo + * @param {proto.DeleteMessageForMeAction} message DeleteMessageForMeAction * @param {$protobuf.IConversionOptions} [options] Conversion options * @returns {Object.} Plain object */ - WebMessageInfo.toObject = function toObject(message, options) { + DeleteMessageForMeAction.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; - if (options.arrays || options.defaults) { - object.messageStubParameters = []; - object.labels = []; - } if (options.defaults) { - object.key = null; - object.message = null; + object.deleteMedia = false; if ($util.Long) { - var long = new $util.Long(0, 0, true); + var long = new $util.Long(0, 0, false); object.messageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; } else object.messageTimestamp = options.longs === String ? "0" : 0; - object.status = options.enums === String ? "ERROR" : 0; - object.participant = ""; - object.ignore = false; - object.starred = false; - object.broadcast = false; - object.pushName = ""; - if (options.bytes === String) - object.mediaCiphertextSha256 = ""; - else { - object.mediaCiphertextSha256 = []; - if (options.bytes !== Array) - object.mediaCiphertextSha256 = $util.newBuffer(object.mediaCiphertextSha256); - } - object.multicast = false; - object.urlText = false; - object.urlNumber = false; - object.messageStubType = options.enums === String ? "UNKNOWN" : 0; - object.clearMedia = false; - object.duration = 0; - object.paymentInfo = null; - object.finalLiveLocation = null; - object.quotedPaymentInfo = null; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.ephemeralStartTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.ephemeralStartTimestamp = options.longs === String ? "0" : 0; - object.ephemeralDuration = 0; - object.ephemeralOffToOn = false; - object.ephemeralOutOfSync = false; - object.bizPrivacyStatus = options.enums === String ? "E2EE" : 0; - object.verifiedBizName = ""; } - if (message.key != null && message.hasOwnProperty("key")) - object.key = $root.proto.MessageKey.toObject(message.key, options); - if (message.message != null && message.hasOwnProperty("message")) - object.message = $root.proto.Message.toObject(message.message, options); + if (message.deleteMedia != null && message.hasOwnProperty("deleteMedia")) + object.deleteMedia = message.deleteMedia; if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) if (typeof message.messageTimestamp === "number") object.messageTimestamp = options.longs === String ? String(message.messageTimestamp) : message.messageTimestamp; else - object.messageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.messageTimestamp) : options.longs === Number ? new $util.LongBits(message.messageTimestamp.low >>> 0, message.messageTimestamp.high >>> 0).toNumber(true) : message.messageTimestamp; - if (message.status != null && message.hasOwnProperty("status")) - object.status = options.enums === String ? $root.proto.WebMessageInfo.WebMessageInfoStatus[message.status] : message.status; - if (message.participant != null && message.hasOwnProperty("participant")) - object.participant = message.participant; - if (message.ignore != null && message.hasOwnProperty("ignore")) - object.ignore = message.ignore; - if (message.starred != null && message.hasOwnProperty("starred")) - object.starred = message.starred; - if (message.broadcast != null && message.hasOwnProperty("broadcast")) - object.broadcast = message.broadcast; - if (message.pushName != null && message.hasOwnProperty("pushName")) - object.pushName = message.pushName; - if (message.mediaCiphertextSha256 != null && message.hasOwnProperty("mediaCiphertextSha256")) - object.mediaCiphertextSha256 = options.bytes === String ? $util.base64.encode(message.mediaCiphertextSha256, 0, message.mediaCiphertextSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaCiphertextSha256) : message.mediaCiphertextSha256; - if (message.multicast != null && message.hasOwnProperty("multicast")) - object.multicast = message.multicast; - if (message.urlText != null && message.hasOwnProperty("urlText")) - object.urlText = message.urlText; - if (message.urlNumber != null && message.hasOwnProperty("urlNumber")) - object.urlNumber = message.urlNumber; - if (message.messageStubType != null && message.hasOwnProperty("messageStubType")) - object.messageStubType = options.enums === String ? $root.proto.WebMessageInfo.WebMessageInfoStubType[message.messageStubType] : message.messageStubType; - if (message.clearMedia != null && message.hasOwnProperty("clearMedia")) - object.clearMedia = message.clearMedia; - if (message.messageStubParameters && message.messageStubParameters.length) { - object.messageStubParameters = []; - for (var j = 0; j < message.messageStubParameters.length; ++j) - object.messageStubParameters[j] = message.messageStubParameters[j]; - } - if (message.duration != null && message.hasOwnProperty("duration")) - object.duration = message.duration; - if (message.labels && message.labels.length) { - object.labels = []; - for (var j = 0; j < message.labels.length; ++j) - object.labels[j] = message.labels[j]; - } - if (message.paymentInfo != null && message.hasOwnProperty("paymentInfo")) - object.paymentInfo = $root.proto.PaymentInfo.toObject(message.paymentInfo, options); - if (message.finalLiveLocation != null && message.hasOwnProperty("finalLiveLocation")) - object.finalLiveLocation = $root.proto.LiveLocationMessage.toObject(message.finalLiveLocation, options); - if (message.quotedPaymentInfo != null && message.hasOwnProperty("quotedPaymentInfo")) - object.quotedPaymentInfo = $root.proto.PaymentInfo.toObject(message.quotedPaymentInfo, options); - if (message.ephemeralStartTimestamp != null && message.hasOwnProperty("ephemeralStartTimestamp")) - if (typeof message.ephemeralStartTimestamp === "number") - object.ephemeralStartTimestamp = options.longs === String ? String(message.ephemeralStartTimestamp) : message.ephemeralStartTimestamp; - else - object.ephemeralStartTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.ephemeralStartTimestamp) : options.longs === Number ? new $util.LongBits(message.ephemeralStartTimestamp.low >>> 0, message.ephemeralStartTimestamp.high >>> 0).toNumber(true) : message.ephemeralStartTimestamp; - if (message.ephemeralDuration != null && message.hasOwnProperty("ephemeralDuration")) - object.ephemeralDuration = message.ephemeralDuration; - if (message.ephemeralOffToOn != null && message.hasOwnProperty("ephemeralOffToOn")) - object.ephemeralOffToOn = message.ephemeralOffToOn; - if (message.ephemeralOutOfSync != null && message.hasOwnProperty("ephemeralOutOfSync")) - object.ephemeralOutOfSync = message.ephemeralOutOfSync; - if (message.bizPrivacyStatus != null && message.hasOwnProperty("bizPrivacyStatus")) - object.bizPrivacyStatus = options.enums === String ? $root.proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus[message.bizPrivacyStatus] : message.bizPrivacyStatus; - if (message.verifiedBizName != null && message.hasOwnProperty("verifiedBizName")) - object.verifiedBizName = message.verifiedBizName; + object.messageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.messageTimestamp) : options.longs === Number ? new $util.LongBits(message.messageTimestamp.low >>> 0, message.messageTimestamp.high >>> 0).toNumber() : message.messageTimestamp; return object; }; /** - * Converts this WebMessageInfo to JSON. + * Converts this DeleteMessageForMeAction to JSON. * @function toJSON - * @memberof proto.WebMessageInfo + * @memberof proto.DeleteMessageForMeAction * @instance * @returns {Object.} JSON object */ - WebMessageInfo.prototype.toJSON = function toJSON() { + DeleteMessageForMeAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return DeleteMessageForMeAction; + })(); + + proto.MarkChatAsReadAction = (function() { + + /** + * Properties of a MarkChatAsReadAction. + * @memberof proto + * @interface IMarkChatAsReadAction + * @property {boolean|null} [read] MarkChatAsReadAction read + * @property {proto.ISyncActionMessageRange|null} [messageRange] MarkChatAsReadAction messageRange + */ + + /** + * Constructs a new MarkChatAsReadAction. + * @memberof proto + * @classdesc Represents a MarkChatAsReadAction. + * @implements IMarkChatAsReadAction + * @constructor + * @param {proto.IMarkChatAsReadAction=} [properties] Properties to set + */ + function MarkChatAsReadAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MarkChatAsReadAction read. + * @member {boolean} read + * @memberof proto.MarkChatAsReadAction + * @instance + */ + MarkChatAsReadAction.prototype.read = false; + + /** + * MarkChatAsReadAction messageRange. + * @member {proto.ISyncActionMessageRange|null|undefined} messageRange + * @memberof proto.MarkChatAsReadAction + * @instance + */ + MarkChatAsReadAction.prototype.messageRange = null; + + /** + * Creates a new MarkChatAsReadAction instance using the specified properties. + * @function create + * @memberof proto.MarkChatAsReadAction + * @static + * @param {proto.IMarkChatAsReadAction=} [properties] Properties to set + * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction instance + */ + MarkChatAsReadAction.create = function create(properties) { + return new MarkChatAsReadAction(properties); + }; + + /** + * Encodes the specified MarkChatAsReadAction message. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages. + * @function encode + * @memberof proto.MarkChatAsReadAction + * @static + * @param {proto.IMarkChatAsReadAction} message MarkChatAsReadAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MarkChatAsReadAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.read != null && Object.hasOwnProperty.call(message, "read")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.read); + if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange")) + $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified MarkChatAsReadAction message, length delimited. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MarkChatAsReadAction + * @static + * @param {proto.IMarkChatAsReadAction} message MarkChatAsReadAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MarkChatAsReadAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MarkChatAsReadAction message from the specified reader or buffer. + * @function decode + * @memberof proto.MarkChatAsReadAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MarkChatAsReadAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MarkChatAsReadAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.read = reader.bool(); + break; + case 2: + message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MarkChatAsReadAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MarkChatAsReadAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MarkChatAsReadAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MarkChatAsReadAction message. + * @function verify + * @memberof proto.MarkChatAsReadAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MarkChatAsReadAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.read != null && message.hasOwnProperty("read")) + if (typeof message.read !== "boolean") + return "read: boolean expected"; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) { + var error = $root.proto.SyncActionMessageRange.verify(message.messageRange); + if (error) + return "messageRange." + error; + } + return null; + }; + + /** + * Creates a MarkChatAsReadAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MarkChatAsReadAction + * @static + * @param {Object.} object Plain object + * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction + */ + MarkChatAsReadAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MarkChatAsReadAction) + return object; + var message = new $root.proto.MarkChatAsReadAction(); + if (object.read != null) + message.read = Boolean(object.read); + if (object.messageRange != null) { + if (typeof object.messageRange !== "object") + throw TypeError(".proto.MarkChatAsReadAction.messageRange: object expected"); + message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange); + } + return message; + }; + + /** + * Creates a plain object from a MarkChatAsReadAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MarkChatAsReadAction + * @static + * @param {proto.MarkChatAsReadAction} message MarkChatAsReadAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MarkChatAsReadAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.read = false; + object.messageRange = null; + } + if (message.read != null && message.hasOwnProperty("read")) + object.read = message.read; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) + object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options); + return object; + }; + + /** + * Converts this MarkChatAsReadAction to JSON. + * @function toJSON + * @memberof proto.MarkChatAsReadAction + * @instance + * @returns {Object.} JSON object + */ + MarkChatAsReadAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MarkChatAsReadAction; + })(); + + proto.ClearChatAction = (function() { + + /** + * Properties of a ClearChatAction. + * @memberof proto + * @interface IClearChatAction + * @property {proto.ISyncActionMessageRange|null} [messageRange] ClearChatAction messageRange + */ + + /** + * Constructs a new ClearChatAction. + * @memberof proto + * @classdesc Represents a ClearChatAction. + * @implements IClearChatAction + * @constructor + * @param {proto.IClearChatAction=} [properties] Properties to set + */ + function ClearChatAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ClearChatAction messageRange. + * @member {proto.ISyncActionMessageRange|null|undefined} messageRange + * @memberof proto.ClearChatAction + * @instance + */ + ClearChatAction.prototype.messageRange = null; + + /** + * Creates a new ClearChatAction instance using the specified properties. + * @function create + * @memberof proto.ClearChatAction + * @static + * @param {proto.IClearChatAction=} [properties] Properties to set + * @returns {proto.ClearChatAction} ClearChatAction instance + */ + ClearChatAction.create = function create(properties) { + return new ClearChatAction(properties); + }; + + /** + * Encodes the specified ClearChatAction message. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages. + * @function encode + * @memberof proto.ClearChatAction + * @static + * @param {proto.IClearChatAction} message ClearChatAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClearChatAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange")) + $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified ClearChatAction message, length delimited. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ClearChatAction + * @static + * @param {proto.IClearChatAction} message ClearChatAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClearChatAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ClearChatAction message from the specified reader or buffer. + * @function decode + * @memberof proto.ClearChatAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ClearChatAction} ClearChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClearChatAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClearChatAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ClearChatAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ClearChatAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ClearChatAction} ClearChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClearChatAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ClearChatAction message. + * @function verify + * @memberof proto.ClearChatAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ClearChatAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) { + var error = $root.proto.SyncActionMessageRange.verify(message.messageRange); + if (error) + return "messageRange." + error; + } + return null; + }; + + /** + * Creates a ClearChatAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ClearChatAction + * @static + * @param {Object.} object Plain object + * @returns {proto.ClearChatAction} ClearChatAction + */ + ClearChatAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ClearChatAction) + return object; + var message = new $root.proto.ClearChatAction(); + if (object.messageRange != null) { + if (typeof object.messageRange !== "object") + throw TypeError(".proto.ClearChatAction.messageRange: object expected"); + message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange); + } + return message; + }; + + /** + * Creates a plain object from a ClearChatAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ClearChatAction + * @static + * @param {proto.ClearChatAction} message ClearChatAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ClearChatAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.messageRange = null; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) + object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options); + return object; + }; + + /** + * Converts this ClearChatAction to JSON. + * @function toJSON + * @memberof proto.ClearChatAction + * @instance + * @returns {Object.} JSON object + */ + ClearChatAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ClearChatAction; + })(); + + proto.DeleteChatAction = (function() { + + /** + * Properties of a DeleteChatAction. + * @memberof proto + * @interface IDeleteChatAction + * @property {proto.ISyncActionMessageRange|null} [messageRange] DeleteChatAction messageRange + */ + + /** + * Constructs a new DeleteChatAction. + * @memberof proto + * @classdesc Represents a DeleteChatAction. + * @implements IDeleteChatAction + * @constructor + * @param {proto.IDeleteChatAction=} [properties] Properties to set + */ + function DeleteChatAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * DeleteChatAction messageRange. + * @member {proto.ISyncActionMessageRange|null|undefined} messageRange + * @memberof proto.DeleteChatAction + * @instance + */ + DeleteChatAction.prototype.messageRange = null; + + /** + * Creates a new DeleteChatAction instance using the specified properties. + * @function create + * @memberof proto.DeleteChatAction + * @static + * @param {proto.IDeleteChatAction=} [properties] Properties to set + * @returns {proto.DeleteChatAction} DeleteChatAction instance + */ + DeleteChatAction.create = function create(properties) { + return new DeleteChatAction(properties); + }; + + /** + * Encodes the specified DeleteChatAction message. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages. + * @function encode + * @memberof proto.DeleteChatAction + * @static + * @param {proto.IDeleteChatAction} message DeleteChatAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DeleteChatAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange")) + $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified DeleteChatAction message, length delimited. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.DeleteChatAction + * @static + * @param {proto.IDeleteChatAction} message DeleteChatAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DeleteChatAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a DeleteChatAction message from the specified reader or buffer. + * @function decode + * @memberof proto.DeleteChatAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.DeleteChatAction} DeleteChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DeleteChatAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DeleteChatAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a DeleteChatAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.DeleteChatAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.DeleteChatAction} DeleteChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DeleteChatAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a DeleteChatAction message. + * @function verify + * @memberof proto.DeleteChatAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + DeleteChatAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) { + var error = $root.proto.SyncActionMessageRange.verify(message.messageRange); + if (error) + return "messageRange." + error; + } + return null; + }; + + /** + * Creates a DeleteChatAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.DeleteChatAction + * @static + * @param {Object.} object Plain object + * @returns {proto.DeleteChatAction} DeleteChatAction + */ + DeleteChatAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.DeleteChatAction) + return object; + var message = new $root.proto.DeleteChatAction(); + if (object.messageRange != null) { + if (typeof object.messageRange !== "object") + throw TypeError(".proto.DeleteChatAction.messageRange: object expected"); + message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange); + } + return message; + }; + + /** + * Creates a plain object from a DeleteChatAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.DeleteChatAction + * @static + * @param {proto.DeleteChatAction} message DeleteChatAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + DeleteChatAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.messageRange = null; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) + object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options); + return object; + }; + + /** + * Converts this DeleteChatAction to JSON. + * @function toJSON + * @memberof proto.DeleteChatAction + * @instance + * @returns {Object.} JSON object + */ + DeleteChatAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return DeleteChatAction; + })(); + + proto.UnarchiveChatsSetting = (function() { + + /** + * Properties of an UnarchiveChatsSetting. + * @memberof proto + * @interface IUnarchiveChatsSetting + * @property {boolean|null} [unarchiveChats] UnarchiveChatsSetting unarchiveChats + */ + + /** + * Constructs a new UnarchiveChatsSetting. + * @memberof proto + * @classdesc Represents an UnarchiveChatsSetting. + * @implements IUnarchiveChatsSetting + * @constructor + * @param {proto.IUnarchiveChatsSetting=} [properties] Properties to set + */ + function UnarchiveChatsSetting(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * UnarchiveChatsSetting unarchiveChats. + * @member {boolean} unarchiveChats + * @memberof proto.UnarchiveChatsSetting + * @instance + */ + UnarchiveChatsSetting.prototype.unarchiveChats = false; + + /** + * Creates a new UnarchiveChatsSetting instance using the specified properties. + * @function create + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {proto.IUnarchiveChatsSetting=} [properties] Properties to set + * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting instance + */ + UnarchiveChatsSetting.create = function create(properties) { + return new UnarchiveChatsSetting(properties); + }; + + /** + * Encodes the specified UnarchiveChatsSetting message. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages. + * @function encode + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {proto.IUnarchiveChatsSetting} message UnarchiveChatsSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UnarchiveChatsSetting.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.unarchiveChats != null && Object.hasOwnProperty.call(message, "unarchiveChats")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.unarchiveChats); + return writer; + }; + + /** + * Encodes the specified UnarchiveChatsSetting message, length delimited. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {proto.IUnarchiveChatsSetting} message UnarchiveChatsSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UnarchiveChatsSetting.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an UnarchiveChatsSetting message from the specified reader or buffer. + * @function decode + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UnarchiveChatsSetting.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.UnarchiveChatsSetting(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.unarchiveChats = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an UnarchiveChatsSetting message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UnarchiveChatsSetting.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an UnarchiveChatsSetting message. + * @function verify + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + UnarchiveChatsSetting.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.unarchiveChats != null && message.hasOwnProperty("unarchiveChats")) + if (typeof message.unarchiveChats !== "boolean") + return "unarchiveChats: boolean expected"; + return null; + }; + + /** + * Creates an UnarchiveChatsSetting message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {Object.} object Plain object + * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting + */ + UnarchiveChatsSetting.fromObject = function fromObject(object) { + if (object instanceof $root.proto.UnarchiveChatsSetting) + return object; + var message = new $root.proto.UnarchiveChatsSetting(); + if (object.unarchiveChats != null) + message.unarchiveChats = Boolean(object.unarchiveChats); + return message; + }; + + /** + * Creates a plain object from an UnarchiveChatsSetting message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {proto.UnarchiveChatsSetting} message UnarchiveChatsSetting + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + UnarchiveChatsSetting.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.unarchiveChats = false; + if (message.unarchiveChats != null && message.hasOwnProperty("unarchiveChats")) + object.unarchiveChats = message.unarchiveChats; + return object; + }; + + /** + * Converts this UnarchiveChatsSetting to JSON. + * @function toJSON + * @memberof proto.UnarchiveChatsSetting + * @instance + * @returns {Object.} JSON object + */ + UnarchiveChatsSetting.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return UnarchiveChatsSetting; + })(); + + proto.SyncActionMessageRange = (function() { + + /** + * Properties of a SyncActionMessageRange. + * @memberof proto + * @interface ISyncActionMessageRange + * @property {number|Long|null} [lastMessageTimestamp] SyncActionMessageRange lastMessageTimestamp + * @property {number|Long|null} [lastSystemMessageTimestamp] SyncActionMessageRange lastSystemMessageTimestamp + * @property {Array.|null} [messages] SyncActionMessageRange messages + */ + + /** + * Constructs a new SyncActionMessageRange. + * @memberof proto + * @classdesc Represents a SyncActionMessageRange. + * @implements ISyncActionMessageRange + * @constructor + * @param {proto.ISyncActionMessageRange=} [properties] Properties to set + */ + function SyncActionMessageRange(properties) { + this.messages = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncActionMessageRange lastMessageTimestamp. + * @member {number|Long} lastMessageTimestamp + * @memberof proto.SyncActionMessageRange + * @instance + */ + SyncActionMessageRange.prototype.lastMessageTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * SyncActionMessageRange lastSystemMessageTimestamp. + * @member {number|Long} lastSystemMessageTimestamp + * @memberof proto.SyncActionMessageRange + * @instance + */ + SyncActionMessageRange.prototype.lastSystemMessageTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * SyncActionMessageRange messages. + * @member {Array.} messages + * @memberof proto.SyncActionMessageRange + * @instance + */ + SyncActionMessageRange.prototype.messages = $util.emptyArray; + + /** + * Creates a new SyncActionMessageRange instance using the specified properties. + * @function create + * @memberof proto.SyncActionMessageRange + * @static + * @param {proto.ISyncActionMessageRange=} [properties] Properties to set + * @returns {proto.SyncActionMessageRange} SyncActionMessageRange instance + */ + SyncActionMessageRange.create = function create(properties) { + return new SyncActionMessageRange(properties); + }; + + /** + * Encodes the specified SyncActionMessageRange message. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages. + * @function encode + * @memberof proto.SyncActionMessageRange + * @static + * @param {proto.ISyncActionMessageRange} message SyncActionMessageRange message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionMessageRange.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.lastMessageTimestamp != null && Object.hasOwnProperty.call(message, "lastMessageTimestamp")) + writer.uint32(/* id 1, wireType 0 =*/8).int64(message.lastMessageTimestamp); + if (message.lastSystemMessageTimestamp != null && Object.hasOwnProperty.call(message, "lastSystemMessageTimestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.lastSystemMessageTimestamp); + if (message.messages != null && message.messages.length) + for (var i = 0; i < message.messages.length; ++i) + $root.proto.SyncActionMessage.encode(message.messages[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SyncActionMessageRange message, length delimited. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncActionMessageRange + * @static + * @param {proto.ISyncActionMessageRange} message SyncActionMessageRange message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionMessageRange.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncActionMessageRange message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncActionMessageRange + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncActionMessageRange} SyncActionMessageRange + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionMessageRange.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionMessageRange(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.lastMessageTimestamp = reader.int64(); + break; + case 2: + message.lastSystemMessageTimestamp = reader.int64(); + break; + case 3: + if (!(message.messages && message.messages.length)) + message.messages = []; + message.messages.push($root.proto.SyncActionMessage.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncActionMessageRange message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncActionMessageRange + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncActionMessageRange} SyncActionMessageRange + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionMessageRange.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncActionMessageRange message. + * @function verify + * @memberof proto.SyncActionMessageRange + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncActionMessageRange.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.lastMessageTimestamp != null && message.hasOwnProperty("lastMessageTimestamp")) + if (!$util.isInteger(message.lastMessageTimestamp) && !(message.lastMessageTimestamp && $util.isInteger(message.lastMessageTimestamp.low) && $util.isInteger(message.lastMessageTimestamp.high))) + return "lastMessageTimestamp: integer|Long expected"; + if (message.lastSystemMessageTimestamp != null && message.hasOwnProperty("lastSystemMessageTimestamp")) + if (!$util.isInteger(message.lastSystemMessageTimestamp) && !(message.lastSystemMessageTimestamp && $util.isInteger(message.lastSystemMessageTimestamp.low) && $util.isInteger(message.lastSystemMessageTimestamp.high))) + return "lastSystemMessageTimestamp: integer|Long expected"; + if (message.messages != null && message.hasOwnProperty("messages")) { + if (!Array.isArray(message.messages)) + return "messages: array expected"; + for (var i = 0; i < message.messages.length; ++i) { + var error = $root.proto.SyncActionMessage.verify(message.messages[i]); + if (error) + return "messages." + error; + } + } + return null; + }; + + /** + * Creates a SyncActionMessageRange message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncActionMessageRange + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncActionMessageRange} SyncActionMessageRange + */ + SyncActionMessageRange.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncActionMessageRange) + return object; + var message = new $root.proto.SyncActionMessageRange(); + if (object.lastMessageTimestamp != null) + if ($util.Long) + (message.lastMessageTimestamp = $util.Long.fromValue(object.lastMessageTimestamp)).unsigned = false; + else if (typeof object.lastMessageTimestamp === "string") + message.lastMessageTimestamp = parseInt(object.lastMessageTimestamp, 10); + else if (typeof object.lastMessageTimestamp === "number") + message.lastMessageTimestamp = object.lastMessageTimestamp; + else if (typeof object.lastMessageTimestamp === "object") + message.lastMessageTimestamp = new $util.LongBits(object.lastMessageTimestamp.low >>> 0, object.lastMessageTimestamp.high >>> 0).toNumber(); + if (object.lastSystemMessageTimestamp != null) + if ($util.Long) + (message.lastSystemMessageTimestamp = $util.Long.fromValue(object.lastSystemMessageTimestamp)).unsigned = false; + else if (typeof object.lastSystemMessageTimestamp === "string") + message.lastSystemMessageTimestamp = parseInt(object.lastSystemMessageTimestamp, 10); + else if (typeof object.lastSystemMessageTimestamp === "number") + message.lastSystemMessageTimestamp = object.lastSystemMessageTimestamp; + else if (typeof object.lastSystemMessageTimestamp === "object") + message.lastSystemMessageTimestamp = new $util.LongBits(object.lastSystemMessageTimestamp.low >>> 0, object.lastSystemMessageTimestamp.high >>> 0).toNumber(); + if (object.messages) { + if (!Array.isArray(object.messages)) + throw TypeError(".proto.SyncActionMessageRange.messages: array expected"); + message.messages = []; + for (var i = 0; i < object.messages.length; ++i) { + if (typeof object.messages[i] !== "object") + throw TypeError(".proto.SyncActionMessageRange.messages: object expected"); + message.messages[i] = $root.proto.SyncActionMessage.fromObject(object.messages[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a SyncActionMessageRange message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncActionMessageRange + * @static + * @param {proto.SyncActionMessageRange} message SyncActionMessageRange + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncActionMessageRange.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.messages = []; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.lastMessageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.lastMessageTimestamp = options.longs === String ? "0" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.lastSystemMessageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.lastSystemMessageTimestamp = options.longs === String ? "0" : 0; + } + if (message.lastMessageTimestamp != null && message.hasOwnProperty("lastMessageTimestamp")) + if (typeof message.lastMessageTimestamp === "number") + object.lastMessageTimestamp = options.longs === String ? String(message.lastMessageTimestamp) : message.lastMessageTimestamp; + else + object.lastMessageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.lastMessageTimestamp) : options.longs === Number ? new $util.LongBits(message.lastMessageTimestamp.low >>> 0, message.lastMessageTimestamp.high >>> 0).toNumber() : message.lastMessageTimestamp; + if (message.lastSystemMessageTimestamp != null && message.hasOwnProperty("lastSystemMessageTimestamp")) + if (typeof message.lastSystemMessageTimestamp === "number") + object.lastSystemMessageTimestamp = options.longs === String ? String(message.lastSystemMessageTimestamp) : message.lastSystemMessageTimestamp; + else + object.lastSystemMessageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.lastSystemMessageTimestamp) : options.longs === Number ? new $util.LongBits(message.lastSystemMessageTimestamp.low >>> 0, message.lastSystemMessageTimestamp.high >>> 0).toNumber() : message.lastSystemMessageTimestamp; + if (message.messages && message.messages.length) { + object.messages = []; + for (var j = 0; j < message.messages.length; ++j) + object.messages[j] = $root.proto.SyncActionMessage.toObject(message.messages[j], options); + } + return object; + }; + + /** + * Converts this SyncActionMessageRange to JSON. + * @function toJSON + * @memberof proto.SyncActionMessageRange + * @instance + * @returns {Object.} JSON object + */ + SyncActionMessageRange.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncActionMessageRange; + })(); + + proto.SyncActionMessage = (function() { + + /** + * Properties of a SyncActionMessage. + * @memberof proto + * @interface ISyncActionMessage + * @property {proto.IMessageKey|null} [key] SyncActionMessage key + * @property {number|Long|null} [timestamp] SyncActionMessage timestamp + */ + + /** + * Constructs a new SyncActionMessage. + * @memberof proto + * @classdesc Represents a SyncActionMessage. + * @implements ISyncActionMessage + * @constructor + * @param {proto.ISyncActionMessage=} [properties] Properties to set + */ + function SyncActionMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncActionMessage key. + * @member {proto.IMessageKey|null|undefined} key + * @memberof proto.SyncActionMessage + * @instance + */ + SyncActionMessage.prototype.key = null; + + /** + * SyncActionMessage timestamp. + * @member {number|Long} timestamp + * @memberof proto.SyncActionMessage + * @instance + */ + SyncActionMessage.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new SyncActionMessage instance using the specified properties. + * @function create + * @memberof proto.SyncActionMessage + * @static + * @param {proto.ISyncActionMessage=} [properties] Properties to set + * @returns {proto.SyncActionMessage} SyncActionMessage instance + */ + SyncActionMessage.create = function create(properties) { + return new SyncActionMessage(properties); + }; + + /** + * Encodes the specified SyncActionMessage message. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages. + * @function encode + * @memberof proto.SyncActionMessage + * @static + * @param {proto.ISyncActionMessage} message SyncActionMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.key != null && Object.hasOwnProperty.call(message, "key")) + $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.timestamp); + return writer; + }; + + /** + * Encodes the specified SyncActionMessage message, length delimited. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncActionMessage + * @static + * @param {proto.ISyncActionMessage} message SyncActionMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncActionMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncActionMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncActionMessage} SyncActionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.key = $root.proto.MessageKey.decode(reader, reader.uint32()); + break; + case 2: + message.timestamp = reader.int64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncActionMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncActionMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncActionMessage} SyncActionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncActionMessage message. + * @function verify + * @memberof proto.SyncActionMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncActionMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.key != null && message.hasOwnProperty("key")) { + var error = $root.proto.MessageKey.verify(message.key); + if (error) + return "key." + error; + } + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) + return "timestamp: integer|Long expected"; + return null; + }; + + /** + * Creates a SyncActionMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncActionMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncActionMessage} SyncActionMessage + */ + SyncActionMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncActionMessage) + return object; + var message = new $root.proto.SyncActionMessage(); + if (object.key != null) { + if (typeof object.key !== "object") + throw TypeError(".proto.SyncActionMessage.key: object expected"); + message.key = $root.proto.MessageKey.fromObject(object.key); + } + if (object.timestamp != null) + if ($util.Long) + (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false; + else if (typeof object.timestamp === "string") + message.timestamp = parseInt(object.timestamp, 10); + else if (typeof object.timestamp === "number") + message.timestamp = object.timestamp; + else if (typeof object.timestamp === "object") + message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from a SyncActionMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncActionMessage + * @static + * @param {proto.SyncActionMessage} message SyncActionMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncActionMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.key = null; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.timestamp = options.longs === String ? "0" : 0; + } + if (message.key != null && message.hasOwnProperty("key")) + object.key = $root.proto.MessageKey.toObject(message.key, options); + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (typeof message.timestamp === "number") + object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; + else + object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp; + return object; + }; + + /** + * Converts this SyncActionMessage to JSON. + * @function toJSON + * @memberof proto.SyncActionMessage + * @instance + * @returns {Object.} JSON object + */ + SyncActionMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncActionMessage; + })(); + + proto.KeyExpiration = (function() { + + /** + * Properties of a KeyExpiration. + * @memberof proto + * @interface IKeyExpiration + * @property {number|null} [expiredKeyEpoch] KeyExpiration expiredKeyEpoch + */ + + /** + * Constructs a new KeyExpiration. + * @memberof proto + * @classdesc Represents a KeyExpiration. + * @implements IKeyExpiration + * @constructor + * @param {proto.IKeyExpiration=} [properties] Properties to set + */ + function KeyExpiration(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * KeyExpiration expiredKeyEpoch. + * @member {number} expiredKeyEpoch + * @memberof proto.KeyExpiration + * @instance + */ + KeyExpiration.prototype.expiredKeyEpoch = 0; + + /** + * Creates a new KeyExpiration instance using the specified properties. + * @function create + * @memberof proto.KeyExpiration + * @static + * @param {proto.IKeyExpiration=} [properties] Properties to set + * @returns {proto.KeyExpiration} KeyExpiration instance + */ + KeyExpiration.create = function create(properties) { + return new KeyExpiration(properties); + }; + + /** + * Encodes the specified KeyExpiration message. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages. + * @function encode + * @memberof proto.KeyExpiration + * @static + * @param {proto.IKeyExpiration} message KeyExpiration message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + KeyExpiration.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.expiredKeyEpoch != null && Object.hasOwnProperty.call(message, "expiredKeyEpoch")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.expiredKeyEpoch); + return writer; + }; + + /** + * Encodes the specified KeyExpiration message, length delimited. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.KeyExpiration + * @static + * @param {proto.IKeyExpiration} message KeyExpiration message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + KeyExpiration.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a KeyExpiration message from the specified reader or buffer. + * @function decode + * @memberof proto.KeyExpiration + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.KeyExpiration} KeyExpiration + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + KeyExpiration.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.KeyExpiration(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.expiredKeyEpoch = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a KeyExpiration message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.KeyExpiration + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.KeyExpiration} KeyExpiration + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + KeyExpiration.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a KeyExpiration message. + * @function verify + * @memberof proto.KeyExpiration + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + KeyExpiration.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.expiredKeyEpoch != null && message.hasOwnProperty("expiredKeyEpoch")) + if (!$util.isInteger(message.expiredKeyEpoch)) + return "expiredKeyEpoch: integer expected"; + return null; + }; + + /** + * Creates a KeyExpiration message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.KeyExpiration + * @static + * @param {Object.} object Plain object + * @returns {proto.KeyExpiration} KeyExpiration + */ + KeyExpiration.fromObject = function fromObject(object) { + if (object instanceof $root.proto.KeyExpiration) + return object; + var message = new $root.proto.KeyExpiration(); + if (object.expiredKeyEpoch != null) + message.expiredKeyEpoch = object.expiredKeyEpoch | 0; + return message; + }; + + /** + * Creates a plain object from a KeyExpiration message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.KeyExpiration + * @static + * @param {proto.KeyExpiration} message KeyExpiration + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + KeyExpiration.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.expiredKeyEpoch = 0; + if (message.expiredKeyEpoch != null && message.hasOwnProperty("expiredKeyEpoch")) + object.expiredKeyEpoch = message.expiredKeyEpoch; + return object; + }; + + /** + * Converts this KeyExpiration to JSON. + * @function toJSON + * @memberof proto.KeyExpiration + * @instance + * @returns {Object.} JSON object + */ + KeyExpiration.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return KeyExpiration; + })(); + + proto.SyncActionValue = (function() { + + /** + * Properties of a SyncActionValue. + * @memberof proto + * @interface ISyncActionValue + * @property {number|Long|null} [timestamp] SyncActionValue timestamp + * @property {proto.IStarAction|null} [starAction] SyncActionValue starAction + * @property {proto.IContactAction|null} [contactAction] SyncActionValue contactAction + * @property {proto.IMuteAction|null} [muteAction] SyncActionValue muteAction + * @property {proto.IPinAction|null} [pinAction] SyncActionValue pinAction + * @property {proto.ISecurityNotificationSetting|null} [securityNotificationSetting] SyncActionValue securityNotificationSetting + * @property {proto.IPushNameSetting|null} [pushNameSetting] SyncActionValue pushNameSetting + * @property {proto.IQuickReplyAction|null} [quickReplyAction] SyncActionValue quickReplyAction + * @property {proto.IRecentStickerWeightsAction|null} [recentStickerWeightsAction] SyncActionValue recentStickerWeightsAction + * @property {proto.IRecentStickerMetadata|null} [recentStickerMetadata] SyncActionValue recentStickerMetadata + * @property {proto.IRecentEmojiWeightsAction|null} [recentEmojiWeightsAction] SyncActionValue recentEmojiWeightsAction + * @property {proto.ILabelEditAction|null} [labelEditAction] SyncActionValue labelEditAction + * @property {proto.ILabelAssociationAction|null} [labelAssociationAction] SyncActionValue labelAssociationAction + * @property {proto.ILocaleSetting|null} [localeSetting] SyncActionValue localeSetting + * @property {proto.IArchiveChatAction|null} [archiveChatAction] SyncActionValue archiveChatAction + * @property {proto.IDeleteMessageForMeAction|null} [deleteMessageForMeAction] SyncActionValue deleteMessageForMeAction + * @property {proto.IKeyExpiration|null} [keyExpiration] SyncActionValue keyExpiration + * @property {proto.IMarkChatAsReadAction|null} [markChatAsReadAction] SyncActionValue markChatAsReadAction + * @property {proto.IClearChatAction|null} [clearChatAction] SyncActionValue clearChatAction + * @property {proto.IDeleteChatAction|null} [deleteChatAction] SyncActionValue deleteChatAction + * @property {proto.IUnarchiveChatsSetting|null} [unarchiveChatsSetting] SyncActionValue unarchiveChatsSetting + */ + + /** + * Constructs a new SyncActionValue. + * @memberof proto + * @classdesc Represents a SyncActionValue. + * @implements ISyncActionValue + * @constructor + * @param {proto.ISyncActionValue=} [properties] Properties to set + */ + function SyncActionValue(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncActionValue timestamp. + * @member {number|Long} timestamp + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * SyncActionValue starAction. + * @member {proto.IStarAction|null|undefined} starAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.starAction = null; + + /** + * SyncActionValue contactAction. + * @member {proto.IContactAction|null|undefined} contactAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.contactAction = null; + + /** + * SyncActionValue muteAction. + * @member {proto.IMuteAction|null|undefined} muteAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.muteAction = null; + + /** + * SyncActionValue pinAction. + * @member {proto.IPinAction|null|undefined} pinAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.pinAction = null; + + /** + * SyncActionValue securityNotificationSetting. + * @member {proto.ISecurityNotificationSetting|null|undefined} securityNotificationSetting + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.securityNotificationSetting = null; + + /** + * SyncActionValue pushNameSetting. + * @member {proto.IPushNameSetting|null|undefined} pushNameSetting + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.pushNameSetting = null; + + /** + * SyncActionValue quickReplyAction. + * @member {proto.IQuickReplyAction|null|undefined} quickReplyAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.quickReplyAction = null; + + /** + * SyncActionValue recentStickerWeightsAction. + * @member {proto.IRecentStickerWeightsAction|null|undefined} recentStickerWeightsAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.recentStickerWeightsAction = null; + + /** + * SyncActionValue recentStickerMetadata. + * @member {proto.IRecentStickerMetadata|null|undefined} recentStickerMetadata + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.recentStickerMetadata = null; + + /** + * SyncActionValue recentEmojiWeightsAction. + * @member {proto.IRecentEmojiWeightsAction|null|undefined} recentEmojiWeightsAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.recentEmojiWeightsAction = null; + + /** + * SyncActionValue labelEditAction. + * @member {proto.ILabelEditAction|null|undefined} labelEditAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.labelEditAction = null; + + /** + * SyncActionValue labelAssociationAction. + * @member {proto.ILabelAssociationAction|null|undefined} labelAssociationAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.labelAssociationAction = null; + + /** + * SyncActionValue localeSetting. + * @member {proto.ILocaleSetting|null|undefined} localeSetting + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.localeSetting = null; + + /** + * SyncActionValue archiveChatAction. + * @member {proto.IArchiveChatAction|null|undefined} archiveChatAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.archiveChatAction = null; + + /** + * SyncActionValue deleteMessageForMeAction. + * @member {proto.IDeleteMessageForMeAction|null|undefined} deleteMessageForMeAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.deleteMessageForMeAction = null; + + /** + * SyncActionValue keyExpiration. + * @member {proto.IKeyExpiration|null|undefined} keyExpiration + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.keyExpiration = null; + + /** + * SyncActionValue markChatAsReadAction. + * @member {proto.IMarkChatAsReadAction|null|undefined} markChatAsReadAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.markChatAsReadAction = null; + + /** + * SyncActionValue clearChatAction. + * @member {proto.IClearChatAction|null|undefined} clearChatAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.clearChatAction = null; + + /** + * SyncActionValue deleteChatAction. + * @member {proto.IDeleteChatAction|null|undefined} deleteChatAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.deleteChatAction = null; + + /** + * SyncActionValue unarchiveChatsSetting. + * @member {proto.IUnarchiveChatsSetting|null|undefined} unarchiveChatsSetting + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.unarchiveChatsSetting = null; + + /** + * Creates a new SyncActionValue instance using the specified properties. + * @function create + * @memberof proto.SyncActionValue + * @static + * @param {proto.ISyncActionValue=} [properties] Properties to set + * @returns {proto.SyncActionValue} SyncActionValue instance + */ + SyncActionValue.create = function create(properties) { + return new SyncActionValue(properties); + }; + + /** + * Encodes the specified SyncActionValue message. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages. + * @function encode + * @memberof proto.SyncActionValue + * @static + * @param {proto.ISyncActionValue} message SyncActionValue message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionValue.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) + writer.uint32(/* id 1, wireType 0 =*/8).int64(message.timestamp); + if (message.starAction != null && Object.hasOwnProperty.call(message, "starAction")) + $root.proto.StarAction.encode(message.starAction, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.contactAction != null && Object.hasOwnProperty.call(message, "contactAction")) + $root.proto.ContactAction.encode(message.contactAction, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.muteAction != null && Object.hasOwnProperty.call(message, "muteAction")) + $root.proto.MuteAction.encode(message.muteAction, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + if (message.pinAction != null && Object.hasOwnProperty.call(message, "pinAction")) + $root.proto.PinAction.encode(message.pinAction, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + if (message.securityNotificationSetting != null && Object.hasOwnProperty.call(message, "securityNotificationSetting")) + $root.proto.SecurityNotificationSetting.encode(message.securityNotificationSetting, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.pushNameSetting != null && Object.hasOwnProperty.call(message, "pushNameSetting")) + $root.proto.PushNameSetting.encode(message.pushNameSetting, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); + if (message.quickReplyAction != null && Object.hasOwnProperty.call(message, "quickReplyAction")) + $root.proto.QuickReplyAction.encode(message.quickReplyAction, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim(); + if (message.recentStickerWeightsAction != null && Object.hasOwnProperty.call(message, "recentStickerWeightsAction")) + $root.proto.RecentStickerWeightsAction.encode(message.recentStickerWeightsAction, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim(); + if (message.recentStickerMetadata != null && Object.hasOwnProperty.call(message, "recentStickerMetadata")) + $root.proto.RecentStickerMetadata.encode(message.recentStickerMetadata, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim(); + if (message.recentEmojiWeightsAction != null && Object.hasOwnProperty.call(message, "recentEmojiWeightsAction")) + $root.proto.RecentEmojiWeightsAction.encode(message.recentEmojiWeightsAction, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim(); + if (message.labelEditAction != null && Object.hasOwnProperty.call(message, "labelEditAction")) + $root.proto.LabelEditAction.encode(message.labelEditAction, writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim(); + if (message.labelAssociationAction != null && Object.hasOwnProperty.call(message, "labelAssociationAction")) + $root.proto.LabelAssociationAction.encode(message.labelAssociationAction, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim(); + if (message.localeSetting != null && Object.hasOwnProperty.call(message, "localeSetting")) + $root.proto.LocaleSetting.encode(message.localeSetting, writer.uint32(/* id 16, wireType 2 =*/130).fork()).ldelim(); + if (message.archiveChatAction != null && Object.hasOwnProperty.call(message, "archiveChatAction")) + $root.proto.ArchiveChatAction.encode(message.archiveChatAction, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim(); + if (message.deleteMessageForMeAction != null && Object.hasOwnProperty.call(message, "deleteMessageForMeAction")) + $root.proto.DeleteMessageForMeAction.encode(message.deleteMessageForMeAction, writer.uint32(/* id 18, wireType 2 =*/146).fork()).ldelim(); + if (message.keyExpiration != null && Object.hasOwnProperty.call(message, "keyExpiration")) + $root.proto.KeyExpiration.encode(message.keyExpiration, writer.uint32(/* id 19, wireType 2 =*/154).fork()).ldelim(); + if (message.markChatAsReadAction != null && Object.hasOwnProperty.call(message, "markChatAsReadAction")) + $root.proto.MarkChatAsReadAction.encode(message.markChatAsReadAction, writer.uint32(/* id 20, wireType 2 =*/162).fork()).ldelim(); + if (message.clearChatAction != null && Object.hasOwnProperty.call(message, "clearChatAction")) + $root.proto.ClearChatAction.encode(message.clearChatAction, writer.uint32(/* id 21, wireType 2 =*/170).fork()).ldelim(); + if (message.deleteChatAction != null && Object.hasOwnProperty.call(message, "deleteChatAction")) + $root.proto.DeleteChatAction.encode(message.deleteChatAction, writer.uint32(/* id 22, wireType 2 =*/178).fork()).ldelim(); + if (message.unarchiveChatsSetting != null && Object.hasOwnProperty.call(message, "unarchiveChatsSetting")) + $root.proto.UnarchiveChatsSetting.encode(message.unarchiveChatsSetting, writer.uint32(/* id 23, wireType 2 =*/186).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SyncActionValue message, length delimited. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncActionValue + * @static + * @param {proto.ISyncActionValue} message SyncActionValue message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionValue.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncActionValue message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncActionValue + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncActionValue} SyncActionValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionValue.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionValue(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.timestamp = reader.int64(); + break; + case 2: + message.starAction = $root.proto.StarAction.decode(reader, reader.uint32()); + break; + case 3: + message.contactAction = $root.proto.ContactAction.decode(reader, reader.uint32()); + break; + case 4: + message.muteAction = $root.proto.MuteAction.decode(reader, reader.uint32()); + break; + case 5: + message.pinAction = $root.proto.PinAction.decode(reader, reader.uint32()); + break; + case 6: + message.securityNotificationSetting = $root.proto.SecurityNotificationSetting.decode(reader, reader.uint32()); + break; + case 7: + message.pushNameSetting = $root.proto.PushNameSetting.decode(reader, reader.uint32()); + break; + case 8: + message.quickReplyAction = $root.proto.QuickReplyAction.decode(reader, reader.uint32()); + break; + case 9: + message.recentStickerWeightsAction = $root.proto.RecentStickerWeightsAction.decode(reader, reader.uint32()); + break; + case 10: + message.recentStickerMetadata = $root.proto.RecentStickerMetadata.decode(reader, reader.uint32()); + break; + case 11: + message.recentEmojiWeightsAction = $root.proto.RecentEmojiWeightsAction.decode(reader, reader.uint32()); + break; + case 14: + message.labelEditAction = $root.proto.LabelEditAction.decode(reader, reader.uint32()); + break; + case 15: + message.labelAssociationAction = $root.proto.LabelAssociationAction.decode(reader, reader.uint32()); + break; + case 16: + message.localeSetting = $root.proto.LocaleSetting.decode(reader, reader.uint32()); + break; + case 17: + message.archiveChatAction = $root.proto.ArchiveChatAction.decode(reader, reader.uint32()); + break; + case 18: + message.deleteMessageForMeAction = $root.proto.DeleteMessageForMeAction.decode(reader, reader.uint32()); + break; + case 19: + message.keyExpiration = $root.proto.KeyExpiration.decode(reader, reader.uint32()); + break; + case 20: + message.markChatAsReadAction = $root.proto.MarkChatAsReadAction.decode(reader, reader.uint32()); + break; + case 21: + message.clearChatAction = $root.proto.ClearChatAction.decode(reader, reader.uint32()); + break; + case 22: + message.deleteChatAction = $root.proto.DeleteChatAction.decode(reader, reader.uint32()); + break; + case 23: + message.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncActionValue message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncActionValue + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncActionValue} SyncActionValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionValue.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncActionValue message. + * @function verify + * @memberof proto.SyncActionValue + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncActionValue.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) + return "timestamp: integer|Long expected"; + if (message.starAction != null && message.hasOwnProperty("starAction")) { + var error = $root.proto.StarAction.verify(message.starAction); + if (error) + return "starAction." + error; + } + if (message.contactAction != null && message.hasOwnProperty("contactAction")) { + var error = $root.proto.ContactAction.verify(message.contactAction); + if (error) + return "contactAction." + error; + } + if (message.muteAction != null && message.hasOwnProperty("muteAction")) { + var error = $root.proto.MuteAction.verify(message.muteAction); + if (error) + return "muteAction." + error; + } + if (message.pinAction != null && message.hasOwnProperty("pinAction")) { + var error = $root.proto.PinAction.verify(message.pinAction); + if (error) + return "pinAction." + error; + } + if (message.securityNotificationSetting != null && message.hasOwnProperty("securityNotificationSetting")) { + var error = $root.proto.SecurityNotificationSetting.verify(message.securityNotificationSetting); + if (error) + return "securityNotificationSetting." + error; + } + if (message.pushNameSetting != null && message.hasOwnProperty("pushNameSetting")) { + var error = $root.proto.PushNameSetting.verify(message.pushNameSetting); + if (error) + return "pushNameSetting." + error; + } + if (message.quickReplyAction != null && message.hasOwnProperty("quickReplyAction")) { + var error = $root.proto.QuickReplyAction.verify(message.quickReplyAction); + if (error) + return "quickReplyAction." + error; + } + if (message.recentStickerWeightsAction != null && message.hasOwnProperty("recentStickerWeightsAction")) { + var error = $root.proto.RecentStickerWeightsAction.verify(message.recentStickerWeightsAction); + if (error) + return "recentStickerWeightsAction." + error; + } + if (message.recentStickerMetadata != null && message.hasOwnProperty("recentStickerMetadata")) { + var error = $root.proto.RecentStickerMetadata.verify(message.recentStickerMetadata); + if (error) + return "recentStickerMetadata." + error; + } + if (message.recentEmojiWeightsAction != null && message.hasOwnProperty("recentEmojiWeightsAction")) { + var error = $root.proto.RecentEmojiWeightsAction.verify(message.recentEmojiWeightsAction); + if (error) + return "recentEmojiWeightsAction." + error; + } + if (message.labelEditAction != null && message.hasOwnProperty("labelEditAction")) { + var error = $root.proto.LabelEditAction.verify(message.labelEditAction); + if (error) + return "labelEditAction." + error; + } + if (message.labelAssociationAction != null && message.hasOwnProperty("labelAssociationAction")) { + var error = $root.proto.LabelAssociationAction.verify(message.labelAssociationAction); + if (error) + return "labelAssociationAction." + error; + } + if (message.localeSetting != null && message.hasOwnProperty("localeSetting")) { + var error = $root.proto.LocaleSetting.verify(message.localeSetting); + if (error) + return "localeSetting." + error; + } + if (message.archiveChatAction != null && message.hasOwnProperty("archiveChatAction")) { + var error = $root.proto.ArchiveChatAction.verify(message.archiveChatAction); + if (error) + return "archiveChatAction." + error; + } + if (message.deleteMessageForMeAction != null && message.hasOwnProperty("deleteMessageForMeAction")) { + var error = $root.proto.DeleteMessageForMeAction.verify(message.deleteMessageForMeAction); + if (error) + return "deleteMessageForMeAction." + error; + } + if (message.keyExpiration != null && message.hasOwnProperty("keyExpiration")) { + var error = $root.proto.KeyExpiration.verify(message.keyExpiration); + if (error) + return "keyExpiration." + error; + } + if (message.markChatAsReadAction != null && message.hasOwnProperty("markChatAsReadAction")) { + var error = $root.proto.MarkChatAsReadAction.verify(message.markChatAsReadAction); + if (error) + return "markChatAsReadAction." + error; + } + if (message.clearChatAction != null && message.hasOwnProperty("clearChatAction")) { + var error = $root.proto.ClearChatAction.verify(message.clearChatAction); + if (error) + return "clearChatAction." + error; + } + if (message.deleteChatAction != null && message.hasOwnProperty("deleteChatAction")) { + var error = $root.proto.DeleteChatAction.verify(message.deleteChatAction); + if (error) + return "deleteChatAction." + error; + } + if (message.unarchiveChatsSetting != null && message.hasOwnProperty("unarchiveChatsSetting")) { + var error = $root.proto.UnarchiveChatsSetting.verify(message.unarchiveChatsSetting); + if (error) + return "unarchiveChatsSetting." + error; + } + return null; + }; + + /** + * Creates a SyncActionValue message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncActionValue + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncActionValue} SyncActionValue + */ + SyncActionValue.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncActionValue) + return object; + var message = new $root.proto.SyncActionValue(); + if (object.timestamp != null) + if ($util.Long) + (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false; + else if (typeof object.timestamp === "string") + message.timestamp = parseInt(object.timestamp, 10); + else if (typeof object.timestamp === "number") + message.timestamp = object.timestamp; + else if (typeof object.timestamp === "object") + message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(); + if (object.starAction != null) { + if (typeof object.starAction !== "object") + throw TypeError(".proto.SyncActionValue.starAction: object expected"); + message.starAction = $root.proto.StarAction.fromObject(object.starAction); + } + if (object.contactAction != null) { + if (typeof object.contactAction !== "object") + throw TypeError(".proto.SyncActionValue.contactAction: object expected"); + message.contactAction = $root.proto.ContactAction.fromObject(object.contactAction); + } + if (object.muteAction != null) { + if (typeof object.muteAction !== "object") + throw TypeError(".proto.SyncActionValue.muteAction: object expected"); + message.muteAction = $root.proto.MuteAction.fromObject(object.muteAction); + } + if (object.pinAction != null) { + if (typeof object.pinAction !== "object") + throw TypeError(".proto.SyncActionValue.pinAction: object expected"); + message.pinAction = $root.proto.PinAction.fromObject(object.pinAction); + } + if (object.securityNotificationSetting != null) { + if (typeof object.securityNotificationSetting !== "object") + throw TypeError(".proto.SyncActionValue.securityNotificationSetting: object expected"); + message.securityNotificationSetting = $root.proto.SecurityNotificationSetting.fromObject(object.securityNotificationSetting); + } + if (object.pushNameSetting != null) { + if (typeof object.pushNameSetting !== "object") + throw TypeError(".proto.SyncActionValue.pushNameSetting: object expected"); + message.pushNameSetting = $root.proto.PushNameSetting.fromObject(object.pushNameSetting); + } + if (object.quickReplyAction != null) { + if (typeof object.quickReplyAction !== "object") + throw TypeError(".proto.SyncActionValue.quickReplyAction: object expected"); + message.quickReplyAction = $root.proto.QuickReplyAction.fromObject(object.quickReplyAction); + } + if (object.recentStickerWeightsAction != null) { + if (typeof object.recentStickerWeightsAction !== "object") + throw TypeError(".proto.SyncActionValue.recentStickerWeightsAction: object expected"); + message.recentStickerWeightsAction = $root.proto.RecentStickerWeightsAction.fromObject(object.recentStickerWeightsAction); + } + if (object.recentStickerMetadata != null) { + if (typeof object.recentStickerMetadata !== "object") + throw TypeError(".proto.SyncActionValue.recentStickerMetadata: object expected"); + message.recentStickerMetadata = $root.proto.RecentStickerMetadata.fromObject(object.recentStickerMetadata); + } + if (object.recentEmojiWeightsAction != null) { + if (typeof object.recentEmojiWeightsAction !== "object") + throw TypeError(".proto.SyncActionValue.recentEmojiWeightsAction: object expected"); + message.recentEmojiWeightsAction = $root.proto.RecentEmojiWeightsAction.fromObject(object.recentEmojiWeightsAction); + } + if (object.labelEditAction != null) { + if (typeof object.labelEditAction !== "object") + throw TypeError(".proto.SyncActionValue.labelEditAction: object expected"); + message.labelEditAction = $root.proto.LabelEditAction.fromObject(object.labelEditAction); + } + if (object.labelAssociationAction != null) { + if (typeof object.labelAssociationAction !== "object") + throw TypeError(".proto.SyncActionValue.labelAssociationAction: object expected"); + message.labelAssociationAction = $root.proto.LabelAssociationAction.fromObject(object.labelAssociationAction); + } + if (object.localeSetting != null) { + if (typeof object.localeSetting !== "object") + throw TypeError(".proto.SyncActionValue.localeSetting: object expected"); + message.localeSetting = $root.proto.LocaleSetting.fromObject(object.localeSetting); + } + if (object.archiveChatAction != null) { + if (typeof object.archiveChatAction !== "object") + throw TypeError(".proto.SyncActionValue.archiveChatAction: object expected"); + message.archiveChatAction = $root.proto.ArchiveChatAction.fromObject(object.archiveChatAction); + } + if (object.deleteMessageForMeAction != null) { + if (typeof object.deleteMessageForMeAction !== "object") + throw TypeError(".proto.SyncActionValue.deleteMessageForMeAction: object expected"); + message.deleteMessageForMeAction = $root.proto.DeleteMessageForMeAction.fromObject(object.deleteMessageForMeAction); + } + if (object.keyExpiration != null) { + if (typeof object.keyExpiration !== "object") + throw TypeError(".proto.SyncActionValue.keyExpiration: object expected"); + message.keyExpiration = $root.proto.KeyExpiration.fromObject(object.keyExpiration); + } + if (object.markChatAsReadAction != null) { + if (typeof object.markChatAsReadAction !== "object") + throw TypeError(".proto.SyncActionValue.markChatAsReadAction: object expected"); + message.markChatAsReadAction = $root.proto.MarkChatAsReadAction.fromObject(object.markChatAsReadAction); + } + if (object.clearChatAction != null) { + if (typeof object.clearChatAction !== "object") + throw TypeError(".proto.SyncActionValue.clearChatAction: object expected"); + message.clearChatAction = $root.proto.ClearChatAction.fromObject(object.clearChatAction); + } + if (object.deleteChatAction != null) { + if (typeof object.deleteChatAction !== "object") + throw TypeError(".proto.SyncActionValue.deleteChatAction: object expected"); + message.deleteChatAction = $root.proto.DeleteChatAction.fromObject(object.deleteChatAction); + } + if (object.unarchiveChatsSetting != null) { + if (typeof object.unarchiveChatsSetting !== "object") + throw TypeError(".proto.SyncActionValue.unarchiveChatsSetting: object expected"); + message.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.fromObject(object.unarchiveChatsSetting); + } + return message; + }; + + /** + * Creates a plain object from a SyncActionValue message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncActionValue + * @static + * @param {proto.SyncActionValue} message SyncActionValue + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncActionValue.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.timestamp = options.longs === String ? "0" : 0; + object.starAction = null; + object.contactAction = null; + object.muteAction = null; + object.pinAction = null; + object.securityNotificationSetting = null; + object.pushNameSetting = null; + object.quickReplyAction = null; + object.recentStickerWeightsAction = null; + object.recentStickerMetadata = null; + object.recentEmojiWeightsAction = null; + object.labelEditAction = null; + object.labelAssociationAction = null; + object.localeSetting = null; + object.archiveChatAction = null; + object.deleteMessageForMeAction = null; + object.keyExpiration = null; + object.markChatAsReadAction = null; + object.clearChatAction = null; + object.deleteChatAction = null; + object.unarchiveChatsSetting = null; + } + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (typeof message.timestamp === "number") + object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; + else + object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp; + if (message.starAction != null && message.hasOwnProperty("starAction")) + object.starAction = $root.proto.StarAction.toObject(message.starAction, options); + if (message.contactAction != null && message.hasOwnProperty("contactAction")) + object.contactAction = $root.proto.ContactAction.toObject(message.contactAction, options); + if (message.muteAction != null && message.hasOwnProperty("muteAction")) + object.muteAction = $root.proto.MuteAction.toObject(message.muteAction, options); + if (message.pinAction != null && message.hasOwnProperty("pinAction")) + object.pinAction = $root.proto.PinAction.toObject(message.pinAction, options); + if (message.securityNotificationSetting != null && message.hasOwnProperty("securityNotificationSetting")) + object.securityNotificationSetting = $root.proto.SecurityNotificationSetting.toObject(message.securityNotificationSetting, options); + if (message.pushNameSetting != null && message.hasOwnProperty("pushNameSetting")) + object.pushNameSetting = $root.proto.PushNameSetting.toObject(message.pushNameSetting, options); + if (message.quickReplyAction != null && message.hasOwnProperty("quickReplyAction")) + object.quickReplyAction = $root.proto.QuickReplyAction.toObject(message.quickReplyAction, options); + if (message.recentStickerWeightsAction != null && message.hasOwnProperty("recentStickerWeightsAction")) + object.recentStickerWeightsAction = $root.proto.RecentStickerWeightsAction.toObject(message.recentStickerWeightsAction, options); + if (message.recentStickerMetadata != null && message.hasOwnProperty("recentStickerMetadata")) + object.recentStickerMetadata = $root.proto.RecentStickerMetadata.toObject(message.recentStickerMetadata, options); + if (message.recentEmojiWeightsAction != null && message.hasOwnProperty("recentEmojiWeightsAction")) + object.recentEmojiWeightsAction = $root.proto.RecentEmojiWeightsAction.toObject(message.recentEmojiWeightsAction, options); + if (message.labelEditAction != null && message.hasOwnProperty("labelEditAction")) + object.labelEditAction = $root.proto.LabelEditAction.toObject(message.labelEditAction, options); + if (message.labelAssociationAction != null && message.hasOwnProperty("labelAssociationAction")) + object.labelAssociationAction = $root.proto.LabelAssociationAction.toObject(message.labelAssociationAction, options); + if (message.localeSetting != null && message.hasOwnProperty("localeSetting")) + object.localeSetting = $root.proto.LocaleSetting.toObject(message.localeSetting, options); + if (message.archiveChatAction != null && message.hasOwnProperty("archiveChatAction")) + object.archiveChatAction = $root.proto.ArchiveChatAction.toObject(message.archiveChatAction, options); + if (message.deleteMessageForMeAction != null && message.hasOwnProperty("deleteMessageForMeAction")) + object.deleteMessageForMeAction = $root.proto.DeleteMessageForMeAction.toObject(message.deleteMessageForMeAction, options); + if (message.keyExpiration != null && message.hasOwnProperty("keyExpiration")) + object.keyExpiration = $root.proto.KeyExpiration.toObject(message.keyExpiration, options); + if (message.markChatAsReadAction != null && message.hasOwnProperty("markChatAsReadAction")) + object.markChatAsReadAction = $root.proto.MarkChatAsReadAction.toObject(message.markChatAsReadAction, options); + if (message.clearChatAction != null && message.hasOwnProperty("clearChatAction")) + object.clearChatAction = $root.proto.ClearChatAction.toObject(message.clearChatAction, options); + if (message.deleteChatAction != null && message.hasOwnProperty("deleteChatAction")) + object.deleteChatAction = $root.proto.DeleteChatAction.toObject(message.deleteChatAction, options); + if (message.unarchiveChatsSetting != null && message.hasOwnProperty("unarchiveChatsSetting")) + object.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.toObject(message.unarchiveChatsSetting, options); + return object; + }; + + /** + * Converts this SyncActionValue to JSON. + * @function toJSON + * @memberof proto.SyncActionValue + * @instance + * @returns {Object.} JSON object + */ + SyncActionValue.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncActionValue; + })(); + + proto.RecentEmojiWeight = (function() { + + /** + * Properties of a RecentEmojiWeight. + * @memberof proto + * @interface IRecentEmojiWeight + * @property {string|null} [emoji] RecentEmojiWeight emoji + * @property {number|null} [weight] RecentEmojiWeight weight + */ + + /** + * Constructs a new RecentEmojiWeight. + * @memberof proto + * @classdesc Represents a RecentEmojiWeight. + * @implements IRecentEmojiWeight + * @constructor + * @param {proto.IRecentEmojiWeight=} [properties] Properties to set + */ + function RecentEmojiWeight(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RecentEmojiWeight emoji. + * @member {string} emoji + * @memberof proto.RecentEmojiWeight + * @instance + */ + RecentEmojiWeight.prototype.emoji = ""; + + /** + * RecentEmojiWeight weight. + * @member {number} weight + * @memberof proto.RecentEmojiWeight + * @instance + */ + RecentEmojiWeight.prototype.weight = 0; + + /** + * Creates a new RecentEmojiWeight instance using the specified properties. + * @function create + * @memberof proto.RecentEmojiWeight + * @static + * @param {proto.IRecentEmojiWeight=} [properties] Properties to set + * @returns {proto.RecentEmojiWeight} RecentEmojiWeight instance + */ + RecentEmojiWeight.create = function create(properties) { + return new RecentEmojiWeight(properties); + }; + + /** + * Encodes the specified RecentEmojiWeight message. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages. + * @function encode + * @memberof proto.RecentEmojiWeight + * @static + * @param {proto.IRecentEmojiWeight} message RecentEmojiWeight message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentEmojiWeight.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.emoji != null && Object.hasOwnProperty.call(message, "emoji")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.emoji); + if (message.weight != null && Object.hasOwnProperty.call(message, "weight")) + writer.uint32(/* id 2, wireType 5 =*/21).float(message.weight); + return writer; + }; + + /** + * Encodes the specified RecentEmojiWeight message, length delimited. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.RecentEmojiWeight + * @static + * @param {proto.IRecentEmojiWeight} message RecentEmojiWeight message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentEmojiWeight.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RecentEmojiWeight message from the specified reader or buffer. + * @function decode + * @memberof proto.RecentEmojiWeight + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.RecentEmojiWeight} RecentEmojiWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentEmojiWeight.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentEmojiWeight(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.emoji = reader.string(); + break; + case 2: + message.weight = reader.float(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RecentEmojiWeight message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.RecentEmojiWeight + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.RecentEmojiWeight} RecentEmojiWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentEmojiWeight.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RecentEmojiWeight message. + * @function verify + * @memberof proto.RecentEmojiWeight + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RecentEmojiWeight.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.emoji != null && message.hasOwnProperty("emoji")) + if (!$util.isString(message.emoji)) + return "emoji: string expected"; + if (message.weight != null && message.hasOwnProperty("weight")) + if (typeof message.weight !== "number") + return "weight: number expected"; + return null; + }; + + /** + * Creates a RecentEmojiWeight message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.RecentEmojiWeight + * @static + * @param {Object.} object Plain object + * @returns {proto.RecentEmojiWeight} RecentEmojiWeight + */ + RecentEmojiWeight.fromObject = function fromObject(object) { + if (object instanceof $root.proto.RecentEmojiWeight) + return object; + var message = new $root.proto.RecentEmojiWeight(); + if (object.emoji != null) + message.emoji = String(object.emoji); + if (object.weight != null) + message.weight = Number(object.weight); + return message; + }; + + /** + * Creates a plain object from a RecentEmojiWeight message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.RecentEmojiWeight + * @static + * @param {proto.RecentEmojiWeight} message RecentEmojiWeight + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RecentEmojiWeight.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.emoji = ""; + object.weight = 0; + } + if (message.emoji != null && message.hasOwnProperty("emoji")) + object.emoji = message.emoji; + if (message.weight != null && message.hasOwnProperty("weight")) + object.weight = options.json && !isFinite(message.weight) ? String(message.weight) : message.weight; + return object; + }; + + /** + * Converts this RecentEmojiWeight to JSON. + * @function toJSON + * @memberof proto.RecentEmojiWeight + * @instance + * @returns {Object.} JSON object + */ + RecentEmojiWeight.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RecentEmojiWeight; + })(); + + proto.RecentStickerWeight = (function() { + + /** + * Properties of a RecentStickerWeight. + * @memberof proto + * @interface IRecentStickerWeight + * @property {string|null} [filehash] RecentStickerWeight filehash + * @property {number|null} [weight] RecentStickerWeight weight + */ + + /** + * Constructs a new RecentStickerWeight. + * @memberof proto + * @classdesc Represents a RecentStickerWeight. + * @implements IRecentStickerWeight + * @constructor + * @param {proto.IRecentStickerWeight=} [properties] Properties to set + */ + function RecentStickerWeight(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RecentStickerWeight filehash. + * @member {string} filehash + * @memberof proto.RecentStickerWeight + * @instance + */ + RecentStickerWeight.prototype.filehash = ""; + + /** + * RecentStickerWeight weight. + * @member {number} weight + * @memberof proto.RecentStickerWeight + * @instance + */ + RecentStickerWeight.prototype.weight = 0; + + /** + * Creates a new RecentStickerWeight instance using the specified properties. + * @function create + * @memberof proto.RecentStickerWeight + * @static + * @param {proto.IRecentStickerWeight=} [properties] Properties to set + * @returns {proto.RecentStickerWeight} RecentStickerWeight instance + */ + RecentStickerWeight.create = function create(properties) { + return new RecentStickerWeight(properties); + }; + + /** + * Encodes the specified RecentStickerWeight message. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages. + * @function encode + * @memberof proto.RecentStickerWeight + * @static + * @param {proto.IRecentStickerWeight} message RecentStickerWeight message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentStickerWeight.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.filehash != null && Object.hasOwnProperty.call(message, "filehash")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.filehash); + if (message.weight != null && Object.hasOwnProperty.call(message, "weight")) + writer.uint32(/* id 2, wireType 5 =*/21).float(message.weight); + return writer; + }; + + /** + * Encodes the specified RecentStickerWeight message, length delimited. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.RecentStickerWeight + * @static + * @param {proto.IRecentStickerWeight} message RecentStickerWeight message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentStickerWeight.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RecentStickerWeight message from the specified reader or buffer. + * @function decode + * @memberof proto.RecentStickerWeight + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.RecentStickerWeight} RecentStickerWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentStickerWeight.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentStickerWeight(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.filehash = reader.string(); + break; + case 2: + message.weight = reader.float(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RecentStickerWeight message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.RecentStickerWeight + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.RecentStickerWeight} RecentStickerWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentStickerWeight.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RecentStickerWeight message. + * @function verify + * @memberof proto.RecentStickerWeight + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RecentStickerWeight.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.filehash != null && message.hasOwnProperty("filehash")) + if (!$util.isString(message.filehash)) + return "filehash: string expected"; + if (message.weight != null && message.hasOwnProperty("weight")) + if (typeof message.weight !== "number") + return "weight: number expected"; + return null; + }; + + /** + * Creates a RecentStickerWeight message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.RecentStickerWeight + * @static + * @param {Object.} object Plain object + * @returns {proto.RecentStickerWeight} RecentStickerWeight + */ + RecentStickerWeight.fromObject = function fromObject(object) { + if (object instanceof $root.proto.RecentStickerWeight) + return object; + var message = new $root.proto.RecentStickerWeight(); + if (object.filehash != null) + message.filehash = String(object.filehash); + if (object.weight != null) + message.weight = Number(object.weight); + return message; + }; + + /** + * Creates a plain object from a RecentStickerWeight message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.RecentStickerWeight + * @static + * @param {proto.RecentStickerWeight} message RecentStickerWeight + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RecentStickerWeight.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.filehash = ""; + object.weight = 0; + } + if (message.filehash != null && message.hasOwnProperty("filehash")) + object.filehash = message.filehash; + if (message.weight != null && message.hasOwnProperty("weight")) + object.weight = options.json && !isFinite(message.weight) ? String(message.weight) : message.weight; + return object; + }; + + /** + * Converts this RecentStickerWeight to JSON. + * @function toJSON + * @memberof proto.RecentStickerWeight + * @instance + * @returns {Object.} JSON object + */ + RecentStickerWeight.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RecentStickerWeight; + })(); + + proto.SyncdPatch = (function() { + + /** + * Properties of a SyncdPatch. + * @memberof proto + * @interface ISyncdPatch + * @property {proto.ISyncdVersion|null} [version] SyncdPatch version + * @property {Array.|null} [mutations] SyncdPatch mutations + * @property {proto.IExternalBlobReference|null} [externalMutations] SyncdPatch externalMutations + * @property {Uint8Array|null} [snapshotMac] SyncdPatch snapshotMac + * @property {Uint8Array|null} [patchMac] SyncdPatch patchMac + * @property {proto.IKeyId|null} [keyId] SyncdPatch keyId + * @property {proto.IExitCode|null} [exitCode] SyncdPatch exitCode + * @property {number|null} [deviceIndex] SyncdPatch deviceIndex + */ + + /** + * Constructs a new SyncdPatch. + * @memberof proto + * @classdesc Represents a SyncdPatch. + * @implements ISyncdPatch + * @constructor + * @param {proto.ISyncdPatch=} [properties] Properties to set + */ + function SyncdPatch(properties) { + this.mutations = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdPatch version. + * @member {proto.ISyncdVersion|null|undefined} version + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.version = null; + + /** + * SyncdPatch mutations. + * @member {Array.} mutations + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.mutations = $util.emptyArray; + + /** + * SyncdPatch externalMutations. + * @member {proto.IExternalBlobReference|null|undefined} externalMutations + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.externalMutations = null; + + /** + * SyncdPatch snapshotMac. + * @member {Uint8Array} snapshotMac + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.snapshotMac = $util.newBuffer([]); + + /** + * SyncdPatch patchMac. + * @member {Uint8Array} patchMac + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.patchMac = $util.newBuffer([]); + + /** + * SyncdPatch keyId. + * @member {proto.IKeyId|null|undefined} keyId + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.keyId = null; + + /** + * SyncdPatch exitCode. + * @member {proto.IExitCode|null|undefined} exitCode + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.exitCode = null; + + /** + * SyncdPatch deviceIndex. + * @member {number} deviceIndex + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.deviceIndex = 0; + + /** + * Creates a new SyncdPatch instance using the specified properties. + * @function create + * @memberof proto.SyncdPatch + * @static + * @param {proto.ISyncdPatch=} [properties] Properties to set + * @returns {proto.SyncdPatch} SyncdPatch instance + */ + SyncdPatch.create = function create(properties) { + return new SyncdPatch(properties); + }; + + /** + * Encodes the specified SyncdPatch message. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages. + * @function encode + * @memberof proto.SyncdPatch + * @static + * @param {proto.ISyncdPatch} message SyncdPatch message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdPatch.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + $root.proto.SyncdVersion.encode(message.version, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.mutations != null && message.mutations.length) + for (var i = 0; i < message.mutations.length; ++i) + $root.proto.SyncdMutation.encode(message.mutations[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.externalMutations != null && Object.hasOwnProperty.call(message, "externalMutations")) + $root.proto.ExternalBlobReference.encode(message.externalMutations, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.snapshotMac != null && Object.hasOwnProperty.call(message, "snapshotMac")) + writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.snapshotMac); + if (message.patchMac != null && Object.hasOwnProperty.call(message, "patchMac")) + writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.patchMac); + if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId")) + $root.proto.KeyId.encode(message.keyId, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.exitCode != null && Object.hasOwnProperty.call(message, "exitCode")) + $root.proto.ExitCode.encode(message.exitCode, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); + if (message.deviceIndex != null && Object.hasOwnProperty.call(message, "deviceIndex")) + writer.uint32(/* id 8, wireType 0 =*/64).uint32(message.deviceIndex); + return writer; + }; + + /** + * Encodes the specified SyncdPatch message, length delimited. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdPatch + * @static + * @param {proto.ISyncdPatch} message SyncdPatch message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdPatch.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdPatch message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdPatch + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdPatch} SyncdPatch + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdPatch.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdPatch(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.version = $root.proto.SyncdVersion.decode(reader, reader.uint32()); + break; + case 2: + if (!(message.mutations && message.mutations.length)) + message.mutations = []; + message.mutations.push($root.proto.SyncdMutation.decode(reader, reader.uint32())); + break; + case 3: + message.externalMutations = $root.proto.ExternalBlobReference.decode(reader, reader.uint32()); + break; + case 4: + message.snapshotMac = reader.bytes(); + break; + case 5: + message.patchMac = reader.bytes(); + break; + case 6: + message.keyId = $root.proto.KeyId.decode(reader, reader.uint32()); + break; + case 7: + message.exitCode = $root.proto.ExitCode.decode(reader, reader.uint32()); + break; + case 8: + message.deviceIndex = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdPatch message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdPatch + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdPatch} SyncdPatch + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdPatch.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdPatch message. + * @function verify + * @memberof proto.SyncdPatch + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdPatch.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.version != null && message.hasOwnProperty("version")) { + var error = $root.proto.SyncdVersion.verify(message.version); + if (error) + return "version." + error; + } + if (message.mutations != null && message.hasOwnProperty("mutations")) { + if (!Array.isArray(message.mutations)) + return "mutations: array expected"; + for (var i = 0; i < message.mutations.length; ++i) { + var error = $root.proto.SyncdMutation.verify(message.mutations[i]); + if (error) + return "mutations." + error; + } + } + if (message.externalMutations != null && message.hasOwnProperty("externalMutations")) { + var error = $root.proto.ExternalBlobReference.verify(message.externalMutations); + if (error) + return "externalMutations." + error; + } + if (message.snapshotMac != null && message.hasOwnProperty("snapshotMac")) + if (!(message.snapshotMac && typeof message.snapshotMac.length === "number" || $util.isString(message.snapshotMac))) + return "snapshotMac: buffer expected"; + if (message.patchMac != null && message.hasOwnProperty("patchMac")) + if (!(message.patchMac && typeof message.patchMac.length === "number" || $util.isString(message.patchMac))) + return "patchMac: buffer expected"; + if (message.keyId != null && message.hasOwnProperty("keyId")) { + var error = $root.proto.KeyId.verify(message.keyId); + if (error) + return "keyId." + error; + } + if (message.exitCode != null && message.hasOwnProperty("exitCode")) { + var error = $root.proto.ExitCode.verify(message.exitCode); + if (error) + return "exitCode." + error; + } + if (message.deviceIndex != null && message.hasOwnProperty("deviceIndex")) + if (!$util.isInteger(message.deviceIndex)) + return "deviceIndex: integer expected"; + return null; + }; + + /** + * Creates a SyncdPatch message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdPatch + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdPatch} SyncdPatch + */ + SyncdPatch.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdPatch) + return object; + var message = new $root.proto.SyncdPatch(); + if (object.version != null) { + if (typeof object.version !== "object") + throw TypeError(".proto.SyncdPatch.version: object expected"); + message.version = $root.proto.SyncdVersion.fromObject(object.version); + } + if (object.mutations) { + if (!Array.isArray(object.mutations)) + throw TypeError(".proto.SyncdPatch.mutations: array expected"); + message.mutations = []; + for (var i = 0; i < object.mutations.length; ++i) { + if (typeof object.mutations[i] !== "object") + throw TypeError(".proto.SyncdPatch.mutations: object expected"); + message.mutations[i] = $root.proto.SyncdMutation.fromObject(object.mutations[i]); + } + } + if (object.externalMutations != null) { + if (typeof object.externalMutations !== "object") + throw TypeError(".proto.SyncdPatch.externalMutations: object expected"); + message.externalMutations = $root.proto.ExternalBlobReference.fromObject(object.externalMutations); + } + if (object.snapshotMac != null) + if (typeof object.snapshotMac === "string") + $util.base64.decode(object.snapshotMac, message.snapshotMac = $util.newBuffer($util.base64.length(object.snapshotMac)), 0); + else if (object.snapshotMac.length) + message.snapshotMac = object.snapshotMac; + if (object.patchMac != null) + if (typeof object.patchMac === "string") + $util.base64.decode(object.patchMac, message.patchMac = $util.newBuffer($util.base64.length(object.patchMac)), 0); + else if (object.patchMac.length) + message.patchMac = object.patchMac; + if (object.keyId != null) { + if (typeof object.keyId !== "object") + throw TypeError(".proto.SyncdPatch.keyId: object expected"); + message.keyId = $root.proto.KeyId.fromObject(object.keyId); + } + if (object.exitCode != null) { + if (typeof object.exitCode !== "object") + throw TypeError(".proto.SyncdPatch.exitCode: object expected"); + message.exitCode = $root.proto.ExitCode.fromObject(object.exitCode); + } + if (object.deviceIndex != null) + message.deviceIndex = object.deviceIndex >>> 0; + return message; + }; + + /** + * Creates a plain object from a SyncdPatch message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdPatch + * @static + * @param {proto.SyncdPatch} message SyncdPatch + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdPatch.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.mutations = []; + if (options.defaults) { + object.version = null; + object.externalMutations = null; + if (options.bytes === String) + object.snapshotMac = ""; + else { + object.snapshotMac = []; + if (options.bytes !== Array) + object.snapshotMac = $util.newBuffer(object.snapshotMac); + } + if (options.bytes === String) + object.patchMac = ""; + else { + object.patchMac = []; + if (options.bytes !== Array) + object.patchMac = $util.newBuffer(object.patchMac); + } + object.keyId = null; + object.exitCode = null; + object.deviceIndex = 0; + } + if (message.version != null && message.hasOwnProperty("version")) + object.version = $root.proto.SyncdVersion.toObject(message.version, options); + if (message.mutations && message.mutations.length) { + object.mutations = []; + for (var j = 0; j < message.mutations.length; ++j) + object.mutations[j] = $root.proto.SyncdMutation.toObject(message.mutations[j], options); + } + if (message.externalMutations != null && message.hasOwnProperty("externalMutations")) + object.externalMutations = $root.proto.ExternalBlobReference.toObject(message.externalMutations, options); + if (message.snapshotMac != null && message.hasOwnProperty("snapshotMac")) + object.snapshotMac = options.bytes === String ? $util.base64.encode(message.snapshotMac, 0, message.snapshotMac.length) : options.bytes === Array ? Array.prototype.slice.call(message.snapshotMac) : message.snapshotMac; + if (message.patchMac != null && message.hasOwnProperty("patchMac")) + object.patchMac = options.bytes === String ? $util.base64.encode(message.patchMac, 0, message.patchMac.length) : options.bytes === Array ? Array.prototype.slice.call(message.patchMac) : message.patchMac; + if (message.keyId != null && message.hasOwnProperty("keyId")) + object.keyId = $root.proto.KeyId.toObject(message.keyId, options); + if (message.exitCode != null && message.hasOwnProperty("exitCode")) + object.exitCode = $root.proto.ExitCode.toObject(message.exitCode, options); + if (message.deviceIndex != null && message.hasOwnProperty("deviceIndex")) + object.deviceIndex = message.deviceIndex; + return object; + }; + + /** + * Converts this SyncdPatch to JSON. + * @function toJSON + * @memberof proto.SyncdPatch + * @instance + * @returns {Object.} JSON object + */ + SyncdPatch.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdPatch; + })(); + + proto.SyncdMutation = (function() { + + /** + * Properties of a SyncdMutation. + * @memberof proto + * @interface ISyncdMutation + * @property {proto.SyncdMutation.SyncdMutationSyncdOperation|null} [operation] SyncdMutation operation + * @property {proto.ISyncdRecord|null} [record] SyncdMutation record + */ + + /** + * Constructs a new SyncdMutation. + * @memberof proto + * @classdesc Represents a SyncdMutation. + * @implements ISyncdMutation + * @constructor + * @param {proto.ISyncdMutation=} [properties] Properties to set + */ + function SyncdMutation(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdMutation operation. + * @member {proto.SyncdMutation.SyncdMutationSyncdOperation} operation + * @memberof proto.SyncdMutation + * @instance + */ + SyncdMutation.prototype.operation = 0; + + /** + * SyncdMutation record. + * @member {proto.ISyncdRecord|null|undefined} record + * @memberof proto.SyncdMutation + * @instance + */ + SyncdMutation.prototype.record = null; + + /** + * Creates a new SyncdMutation instance using the specified properties. + * @function create + * @memberof proto.SyncdMutation + * @static + * @param {proto.ISyncdMutation=} [properties] Properties to set + * @returns {proto.SyncdMutation} SyncdMutation instance + */ + SyncdMutation.create = function create(properties) { + return new SyncdMutation(properties); + }; + + /** + * Encodes the specified SyncdMutation message. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages. + * @function encode + * @memberof proto.SyncdMutation + * @static + * @param {proto.ISyncdMutation} message SyncdMutation message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdMutation.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.operation != null && Object.hasOwnProperty.call(message, "operation")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.operation); + if (message.record != null && Object.hasOwnProperty.call(message, "record")) + $root.proto.SyncdRecord.encode(message.record, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SyncdMutation message, length delimited. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdMutation + * @static + * @param {proto.ISyncdMutation} message SyncdMutation message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdMutation.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdMutation message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdMutation + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdMutation} SyncdMutation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdMutation.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdMutation(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.operation = reader.int32(); + break; + case 2: + message.record = $root.proto.SyncdRecord.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdMutation message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdMutation + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdMutation} SyncdMutation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdMutation.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdMutation message. + * @function verify + * @memberof proto.SyncdMutation + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdMutation.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.operation != null && message.hasOwnProperty("operation")) + switch (message.operation) { + default: + return "operation: enum value expected"; + case 0: + case 1: + break; + } + if (message.record != null && message.hasOwnProperty("record")) { + var error = $root.proto.SyncdRecord.verify(message.record); + if (error) + return "record." + error; + } + return null; + }; + + /** + * Creates a SyncdMutation message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdMutation + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdMutation} SyncdMutation + */ + SyncdMutation.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdMutation) + return object; + var message = new $root.proto.SyncdMutation(); + switch (object.operation) { + case "SET": + case 0: + message.operation = 0; + break; + case "REMOVE": + case 1: + message.operation = 1; + break; + } + if (object.record != null) { + if (typeof object.record !== "object") + throw TypeError(".proto.SyncdMutation.record: object expected"); + message.record = $root.proto.SyncdRecord.fromObject(object.record); + } + return message; + }; + + /** + * Creates a plain object from a SyncdMutation message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdMutation + * @static + * @param {proto.SyncdMutation} message SyncdMutation + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdMutation.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.operation = options.enums === String ? "SET" : 0; + object.record = null; + } + if (message.operation != null && message.hasOwnProperty("operation")) + object.operation = options.enums === String ? $root.proto.SyncdMutation.SyncdMutationSyncdOperation[message.operation] : message.operation; + if (message.record != null && message.hasOwnProperty("record")) + object.record = $root.proto.SyncdRecord.toObject(message.record, options); + return object; + }; + + /** + * Converts this SyncdMutation to JSON. + * @function toJSON + * @memberof proto.SyncdMutation + * @instance + * @returns {Object.} JSON object + */ + SyncdMutation.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; /** - * WebMessageInfoStatus enum. - * @name proto.WebMessageInfo.WebMessageInfoStatus + * SyncdMutationSyncdOperation enum. + * @name proto.SyncdMutation.SyncdMutationSyncdOperation * @enum {number} - * @property {number} ERROR=0 ERROR value - * @property {number} PENDING=1 PENDING value - * @property {number} SERVER_ACK=2 SERVER_ACK value - * @property {number} DELIVERY_ACK=3 DELIVERY_ACK value - * @property {number} READ=4 READ value - * @property {number} PLAYED=5 PLAYED value + * @property {number} SET=0 SET value + * @property {number} REMOVE=1 REMOVE value */ - WebMessageInfo.WebMessageInfoStatus = (function() { + SyncdMutation.SyncdMutationSyncdOperation = (function() { var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "ERROR"] = 0; - values[valuesById[1] = "PENDING"] = 1; - values[valuesById[2] = "SERVER_ACK"] = 2; - values[valuesById[3] = "DELIVERY_ACK"] = 3; - values[valuesById[4] = "READ"] = 4; - values[valuesById[5] = "PLAYED"] = 5; + values[valuesById[0] = "SET"] = 0; + values[valuesById[1] = "REMOVE"] = 1; return values; })(); + return SyncdMutation; + })(); + + proto.SyncdMutations = (function() { + /** - * WebMessageInfoStubType enum. - * @name proto.WebMessageInfo.WebMessageInfoStubType - * @enum {number} - * @property {number} UNKNOWN=0 UNKNOWN value - * @property {number} REVOKE=1 REVOKE value - * @property {number} CIPHERTEXT=2 CIPHERTEXT value - * @property {number} FUTUREPROOF=3 FUTUREPROOF value - * @property {number} NON_VERIFIED_TRANSITION=4 NON_VERIFIED_TRANSITION value - * @property {number} UNVERIFIED_TRANSITION=5 UNVERIFIED_TRANSITION value - * @property {number} VERIFIED_TRANSITION=6 VERIFIED_TRANSITION value - * @property {number} VERIFIED_LOW_UNKNOWN=7 VERIFIED_LOW_UNKNOWN value - * @property {number} VERIFIED_HIGH=8 VERIFIED_HIGH value - * @property {number} VERIFIED_INITIAL_UNKNOWN=9 VERIFIED_INITIAL_UNKNOWN value - * @property {number} VERIFIED_INITIAL_LOW=10 VERIFIED_INITIAL_LOW value - * @property {number} VERIFIED_INITIAL_HIGH=11 VERIFIED_INITIAL_HIGH value - * @property {number} VERIFIED_TRANSITION_ANY_TO_NONE=12 VERIFIED_TRANSITION_ANY_TO_NONE value - * @property {number} VERIFIED_TRANSITION_ANY_TO_HIGH=13 VERIFIED_TRANSITION_ANY_TO_HIGH value - * @property {number} VERIFIED_TRANSITION_HIGH_TO_LOW=14 VERIFIED_TRANSITION_HIGH_TO_LOW value - * @property {number} VERIFIED_TRANSITION_HIGH_TO_UNKNOWN=15 VERIFIED_TRANSITION_HIGH_TO_UNKNOWN value - * @property {number} VERIFIED_TRANSITION_UNKNOWN_TO_LOW=16 VERIFIED_TRANSITION_UNKNOWN_TO_LOW value - * @property {number} VERIFIED_TRANSITION_LOW_TO_UNKNOWN=17 VERIFIED_TRANSITION_LOW_TO_UNKNOWN value - * @property {number} VERIFIED_TRANSITION_NONE_TO_LOW=18 VERIFIED_TRANSITION_NONE_TO_LOW value - * @property {number} VERIFIED_TRANSITION_NONE_TO_UNKNOWN=19 VERIFIED_TRANSITION_NONE_TO_UNKNOWN value - * @property {number} GROUP_CREATE=20 GROUP_CREATE value - * @property {number} GROUP_CHANGE_SUBJECT=21 GROUP_CHANGE_SUBJECT value - * @property {number} GROUP_CHANGE_ICON=22 GROUP_CHANGE_ICON value - * @property {number} GROUP_CHANGE_INVITE_LINK=23 GROUP_CHANGE_INVITE_LINK value - * @property {number} GROUP_CHANGE_DESCRIPTION=24 GROUP_CHANGE_DESCRIPTION value - * @property {number} GROUP_CHANGE_RESTRICT=25 GROUP_CHANGE_RESTRICT value - * @property {number} GROUP_CHANGE_ANNOUNCE=26 GROUP_CHANGE_ANNOUNCE value - * @property {number} GROUP_PARTICIPANT_ADD=27 GROUP_PARTICIPANT_ADD value - * @property {number} GROUP_PARTICIPANT_REMOVE=28 GROUP_PARTICIPANT_REMOVE value - * @property {number} GROUP_PARTICIPANT_PROMOTE=29 GROUP_PARTICIPANT_PROMOTE value - * @property {number} GROUP_PARTICIPANT_DEMOTE=30 GROUP_PARTICIPANT_DEMOTE value - * @property {number} GROUP_PARTICIPANT_INVITE=31 GROUP_PARTICIPANT_INVITE value - * @property {number} GROUP_PARTICIPANT_LEAVE=32 GROUP_PARTICIPANT_LEAVE value - * @property {number} GROUP_PARTICIPANT_CHANGE_NUMBER=33 GROUP_PARTICIPANT_CHANGE_NUMBER value - * @property {number} BROADCAST_CREATE=34 BROADCAST_CREATE value - * @property {number} BROADCAST_ADD=35 BROADCAST_ADD value - * @property {number} BROADCAST_REMOVE=36 BROADCAST_REMOVE value - * @property {number} GENERIC_NOTIFICATION=37 GENERIC_NOTIFICATION value - * @property {number} E2E_IDENTITY_CHANGED=38 E2E_IDENTITY_CHANGED value - * @property {number} E2E_ENCRYPTED=39 E2E_ENCRYPTED value - * @property {number} CALL_MISSED_VOICE=40 CALL_MISSED_VOICE value - * @property {number} CALL_MISSED_VIDEO=41 CALL_MISSED_VIDEO value - * @property {number} INDIVIDUAL_CHANGE_NUMBER=42 INDIVIDUAL_CHANGE_NUMBER value - * @property {number} GROUP_DELETE=43 GROUP_DELETE value - * @property {number} GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE=44 GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE value - * @property {number} CALL_MISSED_GROUP_VOICE=45 CALL_MISSED_GROUP_VOICE value - * @property {number} CALL_MISSED_GROUP_VIDEO=46 CALL_MISSED_GROUP_VIDEO value - * @property {number} PAYMENT_CIPHERTEXT=47 PAYMENT_CIPHERTEXT value - * @property {number} PAYMENT_FUTUREPROOF=48 PAYMENT_FUTUREPROOF value - * @property {number} PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED=49 PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED value - * @property {number} PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED=50 PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED value - * @property {number} PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED=51 PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED value - * @property {number} PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP=52 PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP value - * @property {number} PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP=53 PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP value - * @property {number} PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER=54 PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER value - * @property {number} PAYMENT_ACTION_SEND_PAYMENT_REMINDER=55 PAYMENT_ACTION_SEND_PAYMENT_REMINDER value - * @property {number} PAYMENT_ACTION_SEND_PAYMENT_INVITATION=56 PAYMENT_ACTION_SEND_PAYMENT_INVITATION value - * @property {number} PAYMENT_ACTION_REQUEST_DECLINED=57 PAYMENT_ACTION_REQUEST_DECLINED value - * @property {number} PAYMENT_ACTION_REQUEST_EXPIRED=58 PAYMENT_ACTION_REQUEST_EXPIRED value - * @property {number} PAYMENT_ACTION_REQUEST_CANCELLED=59 PAYMENT_ACTION_REQUEST_CANCELLED value - * @property {number} BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM=60 BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM value - * @property {number} BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP=61 BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP value - * @property {number} BIZ_INTRO_TOP=62 BIZ_INTRO_TOP value - * @property {number} BIZ_INTRO_BOTTOM=63 BIZ_INTRO_BOTTOM value - * @property {number} BIZ_NAME_CHANGE=64 BIZ_NAME_CHANGE value - * @property {number} BIZ_MOVE_TO_CONSUMER_APP=65 BIZ_MOVE_TO_CONSUMER_APP value - * @property {number} BIZ_TWO_TIER_MIGRATION_TOP=66 BIZ_TWO_TIER_MIGRATION_TOP value - * @property {number} BIZ_TWO_TIER_MIGRATION_BOTTOM=67 BIZ_TWO_TIER_MIGRATION_BOTTOM value - * @property {number} OVERSIZED=68 OVERSIZED value - * @property {number} GROUP_CHANGE_NO_FREQUENTLY_FORWARDED=69 GROUP_CHANGE_NO_FREQUENTLY_FORWARDED value - * @property {number} GROUP_V4_ADD_INVITE_SENT=70 GROUP_V4_ADD_INVITE_SENT value - * @property {number} GROUP_PARTICIPANT_ADD_REQUEST_JOIN=71 GROUP_PARTICIPANT_ADD_REQUEST_JOIN value - * @property {number} CHANGE_EPHEMERAL_SETTING=72 CHANGE_EPHEMERAL_SETTING value - * @property {number} E2E_DEVICE_CHANGED=73 E2E_DEVICE_CHANGED value - * @property {number} VIEWED_ONCE=74 VIEWED_ONCE value - * @property {number} E2E_ENCRYPTED_NOW=75 E2E_ENCRYPTED_NOW value - * @property {number} BLUE_MSG_BSP_FB_TO_BSP_PREMISE=76 BLUE_MSG_BSP_FB_TO_BSP_PREMISE value - * @property {number} BLUE_MSG_BSP_FB_TO_SELF_FB=77 BLUE_MSG_BSP_FB_TO_SELF_FB value - * @property {number} BLUE_MSG_BSP_FB_TO_SELF_PREMISE=78 BLUE_MSG_BSP_FB_TO_SELF_PREMISE value - * @property {number} BLUE_MSG_BSP_FB_UNVERIFIED=79 BLUE_MSG_BSP_FB_UNVERIFIED value - * @property {number} BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED=80 BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED value - * @property {number} BLUE_MSG_BSP_FB_VERIFIED=81 BLUE_MSG_BSP_FB_VERIFIED value - * @property {number} BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED=82 BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED value - * @property {number} BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE=83 BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE value - * @property {number} BLUE_MSG_BSP_PREMISE_UNVERIFIED=84 BLUE_MSG_BSP_PREMISE_UNVERIFIED value - * @property {number} BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED=85 BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED value - * @property {number} BLUE_MSG_BSP_PREMISE_VERIFIED=86 BLUE_MSG_BSP_PREMISE_VERIFIED value - * @property {number} BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED=87 BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED value - * @property {number} BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED=88 BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED value - * @property {number} BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED=89 BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED value - * @property {number} BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED=90 BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED value - * @property {number} BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED=91 BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED value - * @property {number} BLUE_MSG_SELF_FB_TO_BSP_PREMISE=92 BLUE_MSG_SELF_FB_TO_BSP_PREMISE value - * @property {number} BLUE_MSG_SELF_FB_TO_SELF_PREMISE=93 BLUE_MSG_SELF_FB_TO_SELF_PREMISE value - * @property {number} BLUE_MSG_SELF_FB_UNVERIFIED=94 BLUE_MSG_SELF_FB_UNVERIFIED value - * @property {number} BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED=95 BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED value - * @property {number} BLUE_MSG_SELF_FB_VERIFIED=96 BLUE_MSG_SELF_FB_VERIFIED value - * @property {number} BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED=97 BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED value - * @property {number} BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE=98 BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE value - * @property {number} BLUE_MSG_SELF_PREMISE_UNVERIFIED=99 BLUE_MSG_SELF_PREMISE_UNVERIFIED value - * @property {number} BLUE_MSG_SELF_PREMISE_VERIFIED=100 BLUE_MSG_SELF_PREMISE_VERIFIED value - * @property {number} BLUE_MSG_TO_BSP_FB=101 BLUE_MSG_TO_BSP_FB value - * @property {number} BLUE_MSG_TO_CONSUMER=102 BLUE_MSG_TO_CONSUMER value - * @property {number} BLUE_MSG_TO_SELF_FB=103 BLUE_MSG_TO_SELF_FB value - * @property {number} BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED=104 BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED value - * @property {number} BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED=105 BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED value - * @property {number} BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED=106 BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED value - * @property {number} BLUE_MSG_UNVERIFIED_TO_VERIFIED=107 BLUE_MSG_UNVERIFIED_TO_VERIFIED value - * @property {number} BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED=108 BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED value - * @property {number} BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED=109 BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED value - * @property {number} BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED=110 BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED value - * @property {number} BLUE_MSG_VERIFIED_TO_UNVERIFIED=111 BLUE_MSG_VERIFIED_TO_UNVERIFIED value - * @property {number} BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED=112 BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED value - * @property {number} BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED=113 BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED value - * @property {number} BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED=114 BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED value - * @property {number} BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED=115 BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED value - * @property {number} BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED=116 BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED value - * @property {number} BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED=117 BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED value - * @property {number} E2E_IDENTITY_UNAVAILABLE=118 E2E_IDENTITY_UNAVAILABLE value + * Properties of a SyncdMutations. + * @memberof proto + * @interface ISyncdMutations + * @property {Array.|null} [mutations] SyncdMutations mutations */ - WebMessageInfo.WebMessageInfoStubType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "UNKNOWN"] = 0; - values[valuesById[1] = "REVOKE"] = 1; - values[valuesById[2] = "CIPHERTEXT"] = 2; - values[valuesById[3] = "FUTUREPROOF"] = 3; - values[valuesById[4] = "NON_VERIFIED_TRANSITION"] = 4; - values[valuesById[5] = "UNVERIFIED_TRANSITION"] = 5; - values[valuesById[6] = "VERIFIED_TRANSITION"] = 6; - values[valuesById[7] = "VERIFIED_LOW_UNKNOWN"] = 7; - values[valuesById[8] = "VERIFIED_HIGH"] = 8; - values[valuesById[9] = "VERIFIED_INITIAL_UNKNOWN"] = 9; - values[valuesById[10] = "VERIFIED_INITIAL_LOW"] = 10; - values[valuesById[11] = "VERIFIED_INITIAL_HIGH"] = 11; - values[valuesById[12] = "VERIFIED_TRANSITION_ANY_TO_NONE"] = 12; - values[valuesById[13] = "VERIFIED_TRANSITION_ANY_TO_HIGH"] = 13; - values[valuesById[14] = "VERIFIED_TRANSITION_HIGH_TO_LOW"] = 14; - values[valuesById[15] = "VERIFIED_TRANSITION_HIGH_TO_UNKNOWN"] = 15; - values[valuesById[16] = "VERIFIED_TRANSITION_UNKNOWN_TO_LOW"] = 16; - values[valuesById[17] = "VERIFIED_TRANSITION_LOW_TO_UNKNOWN"] = 17; - values[valuesById[18] = "VERIFIED_TRANSITION_NONE_TO_LOW"] = 18; - values[valuesById[19] = "VERIFIED_TRANSITION_NONE_TO_UNKNOWN"] = 19; - values[valuesById[20] = "GROUP_CREATE"] = 20; - values[valuesById[21] = "GROUP_CHANGE_SUBJECT"] = 21; - values[valuesById[22] = "GROUP_CHANGE_ICON"] = 22; - values[valuesById[23] = "GROUP_CHANGE_INVITE_LINK"] = 23; - values[valuesById[24] = "GROUP_CHANGE_DESCRIPTION"] = 24; - values[valuesById[25] = "GROUP_CHANGE_RESTRICT"] = 25; - values[valuesById[26] = "GROUP_CHANGE_ANNOUNCE"] = 26; - values[valuesById[27] = "GROUP_PARTICIPANT_ADD"] = 27; - values[valuesById[28] = "GROUP_PARTICIPANT_REMOVE"] = 28; - values[valuesById[29] = "GROUP_PARTICIPANT_PROMOTE"] = 29; - values[valuesById[30] = "GROUP_PARTICIPANT_DEMOTE"] = 30; - values[valuesById[31] = "GROUP_PARTICIPANT_INVITE"] = 31; - values[valuesById[32] = "GROUP_PARTICIPANT_LEAVE"] = 32; - values[valuesById[33] = "GROUP_PARTICIPANT_CHANGE_NUMBER"] = 33; - values[valuesById[34] = "BROADCAST_CREATE"] = 34; - values[valuesById[35] = "BROADCAST_ADD"] = 35; - values[valuesById[36] = "BROADCAST_REMOVE"] = 36; - values[valuesById[37] = "GENERIC_NOTIFICATION"] = 37; - values[valuesById[38] = "E2E_IDENTITY_CHANGED"] = 38; - values[valuesById[39] = "E2E_ENCRYPTED"] = 39; - values[valuesById[40] = "CALL_MISSED_VOICE"] = 40; - values[valuesById[41] = "CALL_MISSED_VIDEO"] = 41; - values[valuesById[42] = "INDIVIDUAL_CHANGE_NUMBER"] = 42; - values[valuesById[43] = "GROUP_DELETE"] = 43; - values[valuesById[44] = "GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE"] = 44; - values[valuesById[45] = "CALL_MISSED_GROUP_VOICE"] = 45; - values[valuesById[46] = "CALL_MISSED_GROUP_VIDEO"] = 46; - values[valuesById[47] = "PAYMENT_CIPHERTEXT"] = 47; - values[valuesById[48] = "PAYMENT_FUTUREPROOF"] = 48; - values[valuesById[49] = "PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED"] = 49; - values[valuesById[50] = "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED"] = 50; - values[valuesById[51] = "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED"] = 51; - values[valuesById[52] = "PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP"] = 52; - values[valuesById[53] = "PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP"] = 53; - values[valuesById[54] = "PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER"] = 54; - values[valuesById[55] = "PAYMENT_ACTION_SEND_PAYMENT_REMINDER"] = 55; - values[valuesById[56] = "PAYMENT_ACTION_SEND_PAYMENT_INVITATION"] = 56; - values[valuesById[57] = "PAYMENT_ACTION_REQUEST_DECLINED"] = 57; - values[valuesById[58] = "PAYMENT_ACTION_REQUEST_EXPIRED"] = 58; - values[valuesById[59] = "PAYMENT_ACTION_REQUEST_CANCELLED"] = 59; - values[valuesById[60] = "BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM"] = 60; - values[valuesById[61] = "BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP"] = 61; - values[valuesById[62] = "BIZ_INTRO_TOP"] = 62; - values[valuesById[63] = "BIZ_INTRO_BOTTOM"] = 63; - values[valuesById[64] = "BIZ_NAME_CHANGE"] = 64; - values[valuesById[65] = "BIZ_MOVE_TO_CONSUMER_APP"] = 65; - values[valuesById[66] = "BIZ_TWO_TIER_MIGRATION_TOP"] = 66; - values[valuesById[67] = "BIZ_TWO_TIER_MIGRATION_BOTTOM"] = 67; - values[valuesById[68] = "OVERSIZED"] = 68; - values[valuesById[69] = "GROUP_CHANGE_NO_FREQUENTLY_FORWARDED"] = 69; - values[valuesById[70] = "GROUP_V4_ADD_INVITE_SENT"] = 70; - values[valuesById[71] = "GROUP_PARTICIPANT_ADD_REQUEST_JOIN"] = 71; - values[valuesById[72] = "CHANGE_EPHEMERAL_SETTING"] = 72; - values[valuesById[73] = "E2E_DEVICE_CHANGED"] = 73; - values[valuesById[74] = "VIEWED_ONCE"] = 74; - values[valuesById[75] = "E2E_ENCRYPTED_NOW"] = 75; - values[valuesById[76] = "BLUE_MSG_BSP_FB_TO_BSP_PREMISE"] = 76; - values[valuesById[77] = "BLUE_MSG_BSP_FB_TO_SELF_FB"] = 77; - values[valuesById[78] = "BLUE_MSG_BSP_FB_TO_SELF_PREMISE"] = 78; - values[valuesById[79] = "BLUE_MSG_BSP_FB_UNVERIFIED"] = 79; - values[valuesById[80] = "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED"] = 80; - values[valuesById[81] = "BLUE_MSG_BSP_FB_VERIFIED"] = 81; - values[valuesById[82] = "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED"] = 82; - values[valuesById[83] = "BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE"] = 83; - values[valuesById[84] = "BLUE_MSG_BSP_PREMISE_UNVERIFIED"] = 84; - values[valuesById[85] = "BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED"] = 85; - values[valuesById[86] = "BLUE_MSG_BSP_PREMISE_VERIFIED"] = 86; - values[valuesById[87] = "BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED"] = 87; - values[valuesById[88] = "BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED"] = 88; - values[valuesById[89] = "BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED"] = 89; - values[valuesById[90] = "BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED"] = 90; - values[valuesById[91] = "BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED"] = 91; - values[valuesById[92] = "BLUE_MSG_SELF_FB_TO_BSP_PREMISE"] = 92; - values[valuesById[93] = "BLUE_MSG_SELF_FB_TO_SELF_PREMISE"] = 93; - values[valuesById[94] = "BLUE_MSG_SELF_FB_UNVERIFIED"] = 94; - values[valuesById[95] = "BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED"] = 95; - values[valuesById[96] = "BLUE_MSG_SELF_FB_VERIFIED"] = 96; - values[valuesById[97] = "BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED"] = 97; - values[valuesById[98] = "BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE"] = 98; - values[valuesById[99] = "BLUE_MSG_SELF_PREMISE_UNVERIFIED"] = 99; - values[valuesById[100] = "BLUE_MSG_SELF_PREMISE_VERIFIED"] = 100; - values[valuesById[101] = "BLUE_MSG_TO_BSP_FB"] = 101; - values[valuesById[102] = "BLUE_MSG_TO_CONSUMER"] = 102; - values[valuesById[103] = "BLUE_MSG_TO_SELF_FB"] = 103; - values[valuesById[104] = "BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED"] = 104; - values[valuesById[105] = "BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED"] = 105; - values[valuesById[106] = "BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED"] = 106; - values[valuesById[107] = "BLUE_MSG_UNVERIFIED_TO_VERIFIED"] = 107; - values[valuesById[108] = "BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED"] = 108; - values[valuesById[109] = "BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED"] = 109; - values[valuesById[110] = "BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED"] = 110; - values[valuesById[111] = "BLUE_MSG_VERIFIED_TO_UNVERIFIED"] = 111; - values[valuesById[112] = "BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED"] = 112; - values[valuesById[113] = "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED"] = 113; - values[valuesById[114] = "BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED"] = 114; - values[valuesById[115] = "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED"] = 115; - values[valuesById[116] = "BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED"] = 116; - values[valuesById[117] = "BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED"] = 117; - values[valuesById[118] = "E2E_IDENTITY_UNAVAILABLE"] = 118; - return values; - })(); /** - * WebMessageInfoBizPrivacyStatus enum. - * @name proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus - * @enum {number} - * @property {number} E2EE=0 E2EE value - * @property {number} FB=2 FB value - * @property {number} BSP=1 BSP value - * @property {number} BSP_AND_FB=3 BSP_AND_FB value + * Constructs a new SyncdMutations. + * @memberof proto + * @classdesc Represents a SyncdMutations. + * @implements ISyncdMutations + * @constructor + * @param {proto.ISyncdMutations=} [properties] Properties to set */ - WebMessageInfo.WebMessageInfoBizPrivacyStatus = (function() { + function SyncdMutations(properties) { + this.mutations = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdMutations mutations. + * @member {Array.} mutations + * @memberof proto.SyncdMutations + * @instance + */ + SyncdMutations.prototype.mutations = $util.emptyArray; + + /** + * Creates a new SyncdMutations instance using the specified properties. + * @function create + * @memberof proto.SyncdMutations + * @static + * @param {proto.ISyncdMutations=} [properties] Properties to set + * @returns {proto.SyncdMutations} SyncdMutations instance + */ + SyncdMutations.create = function create(properties) { + return new SyncdMutations(properties); + }; + + /** + * Encodes the specified SyncdMutations message. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages. + * @function encode + * @memberof proto.SyncdMutations + * @static + * @param {proto.ISyncdMutations} message SyncdMutations message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdMutations.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.mutations != null && message.mutations.length) + for (var i = 0; i < message.mutations.length; ++i) + $root.proto.SyncdMutation.encode(message.mutations[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SyncdMutations message, length delimited. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdMutations + * @static + * @param {proto.ISyncdMutations} message SyncdMutations message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdMutations.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdMutations message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdMutations + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdMutations} SyncdMutations + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdMutations.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdMutations(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.mutations && message.mutations.length)) + message.mutations = []; + message.mutations.push($root.proto.SyncdMutation.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdMutations message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdMutations + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdMutations} SyncdMutations + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdMutations.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdMutations message. + * @function verify + * @memberof proto.SyncdMutations + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdMutations.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.mutations != null && message.hasOwnProperty("mutations")) { + if (!Array.isArray(message.mutations)) + return "mutations: array expected"; + for (var i = 0; i < message.mutations.length; ++i) { + var error = $root.proto.SyncdMutation.verify(message.mutations[i]); + if (error) + return "mutations." + error; + } + } + return null; + }; + + /** + * Creates a SyncdMutations message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdMutations + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdMutations} SyncdMutations + */ + SyncdMutations.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdMutations) + return object; + var message = new $root.proto.SyncdMutations(); + if (object.mutations) { + if (!Array.isArray(object.mutations)) + throw TypeError(".proto.SyncdMutations.mutations: array expected"); + message.mutations = []; + for (var i = 0; i < object.mutations.length; ++i) { + if (typeof object.mutations[i] !== "object") + throw TypeError(".proto.SyncdMutations.mutations: object expected"); + message.mutations[i] = $root.proto.SyncdMutation.fromObject(object.mutations[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a SyncdMutations message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdMutations + * @static + * @param {proto.SyncdMutations} message SyncdMutations + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdMutations.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.mutations = []; + if (message.mutations && message.mutations.length) { + object.mutations = []; + for (var j = 0; j < message.mutations.length; ++j) + object.mutations[j] = $root.proto.SyncdMutation.toObject(message.mutations[j], options); + } + return object; + }; + + /** + * Converts this SyncdMutations to JSON. + * @function toJSON + * @memberof proto.SyncdMutations + * @instance + * @returns {Object.} JSON object + */ + SyncdMutations.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdMutations; + })(); + + proto.SyncdSnapshot = (function() { + + /** + * Properties of a SyncdSnapshot. + * @memberof proto + * @interface ISyncdSnapshot + * @property {proto.ISyncdVersion|null} [version] SyncdSnapshot version + * @property {Array.|null} [records] SyncdSnapshot records + * @property {Uint8Array|null} [mac] SyncdSnapshot mac + * @property {proto.IKeyId|null} [keyId] SyncdSnapshot keyId + */ + + /** + * Constructs a new SyncdSnapshot. + * @memberof proto + * @classdesc Represents a SyncdSnapshot. + * @implements ISyncdSnapshot + * @constructor + * @param {proto.ISyncdSnapshot=} [properties] Properties to set + */ + function SyncdSnapshot(properties) { + this.records = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdSnapshot version. + * @member {proto.ISyncdVersion|null|undefined} version + * @memberof proto.SyncdSnapshot + * @instance + */ + SyncdSnapshot.prototype.version = null; + + /** + * SyncdSnapshot records. + * @member {Array.} records + * @memberof proto.SyncdSnapshot + * @instance + */ + SyncdSnapshot.prototype.records = $util.emptyArray; + + /** + * SyncdSnapshot mac. + * @member {Uint8Array} mac + * @memberof proto.SyncdSnapshot + * @instance + */ + SyncdSnapshot.prototype.mac = $util.newBuffer([]); + + /** + * SyncdSnapshot keyId. + * @member {proto.IKeyId|null|undefined} keyId + * @memberof proto.SyncdSnapshot + * @instance + */ + SyncdSnapshot.prototype.keyId = null; + + /** + * Creates a new SyncdSnapshot instance using the specified properties. + * @function create + * @memberof proto.SyncdSnapshot + * @static + * @param {proto.ISyncdSnapshot=} [properties] Properties to set + * @returns {proto.SyncdSnapshot} SyncdSnapshot instance + */ + SyncdSnapshot.create = function create(properties) { + return new SyncdSnapshot(properties); + }; + + /** + * Encodes the specified SyncdSnapshot message. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages. + * @function encode + * @memberof proto.SyncdSnapshot + * @static + * @param {proto.ISyncdSnapshot} message SyncdSnapshot message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdSnapshot.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + $root.proto.SyncdVersion.encode(message.version, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.records != null && message.records.length) + for (var i = 0; i < message.records.length; ++i) + $root.proto.SyncdRecord.encode(message.records[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.mac != null && Object.hasOwnProperty.call(message, "mac")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.mac); + if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId")) + $root.proto.KeyId.encode(message.keyId, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SyncdSnapshot message, length delimited. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdSnapshot + * @static + * @param {proto.ISyncdSnapshot} message SyncdSnapshot message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdSnapshot.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdSnapshot message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdSnapshot + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdSnapshot} SyncdSnapshot + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdSnapshot.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdSnapshot(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.version = $root.proto.SyncdVersion.decode(reader, reader.uint32()); + break; + case 2: + if (!(message.records && message.records.length)) + message.records = []; + message.records.push($root.proto.SyncdRecord.decode(reader, reader.uint32())); + break; + case 3: + message.mac = reader.bytes(); + break; + case 4: + message.keyId = $root.proto.KeyId.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdSnapshot message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdSnapshot + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdSnapshot} SyncdSnapshot + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdSnapshot.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdSnapshot message. + * @function verify + * @memberof proto.SyncdSnapshot + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdSnapshot.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.version != null && message.hasOwnProperty("version")) { + var error = $root.proto.SyncdVersion.verify(message.version); + if (error) + return "version." + error; + } + if (message.records != null && message.hasOwnProperty("records")) { + if (!Array.isArray(message.records)) + return "records: array expected"; + for (var i = 0; i < message.records.length; ++i) { + var error = $root.proto.SyncdRecord.verify(message.records[i]); + if (error) + return "records." + error; + } + } + if (message.mac != null && message.hasOwnProperty("mac")) + if (!(message.mac && typeof message.mac.length === "number" || $util.isString(message.mac))) + return "mac: buffer expected"; + if (message.keyId != null && message.hasOwnProperty("keyId")) { + var error = $root.proto.KeyId.verify(message.keyId); + if (error) + return "keyId." + error; + } + return null; + }; + + /** + * Creates a SyncdSnapshot message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdSnapshot + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdSnapshot} SyncdSnapshot + */ + SyncdSnapshot.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdSnapshot) + return object; + var message = new $root.proto.SyncdSnapshot(); + if (object.version != null) { + if (typeof object.version !== "object") + throw TypeError(".proto.SyncdSnapshot.version: object expected"); + message.version = $root.proto.SyncdVersion.fromObject(object.version); + } + if (object.records) { + if (!Array.isArray(object.records)) + throw TypeError(".proto.SyncdSnapshot.records: array expected"); + message.records = []; + for (var i = 0; i < object.records.length; ++i) { + if (typeof object.records[i] !== "object") + throw TypeError(".proto.SyncdSnapshot.records: object expected"); + message.records[i] = $root.proto.SyncdRecord.fromObject(object.records[i]); + } + } + if (object.mac != null) + if (typeof object.mac === "string") + $util.base64.decode(object.mac, message.mac = $util.newBuffer($util.base64.length(object.mac)), 0); + else if (object.mac.length) + message.mac = object.mac; + if (object.keyId != null) { + if (typeof object.keyId !== "object") + throw TypeError(".proto.SyncdSnapshot.keyId: object expected"); + message.keyId = $root.proto.KeyId.fromObject(object.keyId); + } + return message; + }; + + /** + * Creates a plain object from a SyncdSnapshot message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdSnapshot + * @static + * @param {proto.SyncdSnapshot} message SyncdSnapshot + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdSnapshot.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.records = []; + if (options.defaults) { + object.version = null; + if (options.bytes === String) + object.mac = ""; + else { + object.mac = []; + if (options.bytes !== Array) + object.mac = $util.newBuffer(object.mac); + } + object.keyId = null; + } + if (message.version != null && message.hasOwnProperty("version")) + object.version = $root.proto.SyncdVersion.toObject(message.version, options); + if (message.records && message.records.length) { + object.records = []; + for (var j = 0; j < message.records.length; ++j) + object.records[j] = $root.proto.SyncdRecord.toObject(message.records[j], options); + } + if (message.mac != null && message.hasOwnProperty("mac")) + object.mac = options.bytes === String ? $util.base64.encode(message.mac, 0, message.mac.length) : options.bytes === Array ? Array.prototype.slice.call(message.mac) : message.mac; + if (message.keyId != null && message.hasOwnProperty("keyId")) + object.keyId = $root.proto.KeyId.toObject(message.keyId, options); + return object; + }; + + /** + * Converts this SyncdSnapshot to JSON. + * @function toJSON + * @memberof proto.SyncdSnapshot + * @instance + * @returns {Object.} JSON object + */ + SyncdSnapshot.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdSnapshot; + })(); + + proto.ExternalBlobReference = (function() { + + /** + * Properties of an ExternalBlobReference. + * @memberof proto + * @interface IExternalBlobReference + * @property {Uint8Array|null} [mediaKey] ExternalBlobReference mediaKey + * @property {string|null} [directPath] ExternalBlobReference directPath + * @property {string|null} [handle] ExternalBlobReference handle + * @property {number|Long|null} [fileSizeBytes] ExternalBlobReference fileSizeBytes + * @property {Uint8Array|null} [fileSha256] ExternalBlobReference fileSha256 + * @property {Uint8Array|null} [fileEncSha256] ExternalBlobReference fileEncSha256 + */ + + /** + * Constructs a new ExternalBlobReference. + * @memberof proto + * @classdesc Represents an ExternalBlobReference. + * @implements IExternalBlobReference + * @constructor + * @param {proto.IExternalBlobReference=} [properties] Properties to set + */ + function ExternalBlobReference(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ExternalBlobReference mediaKey. + * @member {Uint8Array} mediaKey + * @memberof proto.ExternalBlobReference + * @instance + */ + ExternalBlobReference.prototype.mediaKey = $util.newBuffer([]); + + /** + * ExternalBlobReference directPath. + * @member {string} directPath + * @memberof proto.ExternalBlobReference + * @instance + */ + ExternalBlobReference.prototype.directPath = ""; + + /** + * ExternalBlobReference handle. + * @member {string} handle + * @memberof proto.ExternalBlobReference + * @instance + */ + ExternalBlobReference.prototype.handle = ""; + + /** + * ExternalBlobReference fileSizeBytes. + * @member {number|Long} fileSizeBytes + * @memberof proto.ExternalBlobReference + * @instance + */ + ExternalBlobReference.prototype.fileSizeBytes = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * ExternalBlobReference fileSha256. + * @member {Uint8Array} fileSha256 + * @memberof proto.ExternalBlobReference + * @instance + */ + ExternalBlobReference.prototype.fileSha256 = $util.newBuffer([]); + + /** + * ExternalBlobReference fileEncSha256. + * @member {Uint8Array} fileEncSha256 + * @memberof proto.ExternalBlobReference + * @instance + */ + ExternalBlobReference.prototype.fileEncSha256 = $util.newBuffer([]); + + /** + * Creates a new ExternalBlobReference instance using the specified properties. + * @function create + * @memberof proto.ExternalBlobReference + * @static + * @param {proto.IExternalBlobReference=} [properties] Properties to set + * @returns {proto.ExternalBlobReference} ExternalBlobReference instance + */ + ExternalBlobReference.create = function create(properties) { + return new ExternalBlobReference(properties); + }; + + /** + * Encodes the specified ExternalBlobReference message. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages. + * @function encode + * @memberof proto.ExternalBlobReference + * @static + * @param {proto.IExternalBlobReference} message ExternalBlobReference message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ExternalBlobReference.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.mediaKey); + if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.directPath); + if (message.handle != null && Object.hasOwnProperty.call(message, "handle")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.handle); + if (message.fileSizeBytes != null && Object.hasOwnProperty.call(message, "fileSizeBytes")) + writer.uint32(/* id 4, wireType 0 =*/32).uint64(message.fileSizeBytes); + if (message.fileSha256 != null && Object.hasOwnProperty.call(message, "fileSha256")) + writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.fileSha256); + if (message.fileEncSha256 != null && Object.hasOwnProperty.call(message, "fileEncSha256")) + writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.fileEncSha256); + return writer; + }; + + /** + * Encodes the specified ExternalBlobReference message, length delimited. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ExternalBlobReference + * @static + * @param {proto.IExternalBlobReference} message ExternalBlobReference message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ExternalBlobReference.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an ExternalBlobReference message from the specified reader or buffer. + * @function decode + * @memberof proto.ExternalBlobReference + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ExternalBlobReference} ExternalBlobReference + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ExternalBlobReference.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ExternalBlobReference(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.mediaKey = reader.bytes(); + break; + case 2: + message.directPath = reader.string(); + break; + case 3: + message.handle = reader.string(); + break; + case 4: + message.fileSizeBytes = reader.uint64(); + break; + case 5: + message.fileSha256 = reader.bytes(); + break; + case 6: + message.fileEncSha256 = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an ExternalBlobReference message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ExternalBlobReference + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ExternalBlobReference} ExternalBlobReference + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ExternalBlobReference.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an ExternalBlobReference message. + * @function verify + * @memberof proto.ExternalBlobReference + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ExternalBlobReference.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey))) + return "mediaKey: buffer expected"; + if (message.directPath != null && message.hasOwnProperty("directPath")) + if (!$util.isString(message.directPath)) + return "directPath: string expected"; + if (message.handle != null && message.hasOwnProperty("handle")) + if (!$util.isString(message.handle)) + return "handle: string expected"; + if (message.fileSizeBytes != null && message.hasOwnProperty("fileSizeBytes")) + if (!$util.isInteger(message.fileSizeBytes) && !(message.fileSizeBytes && $util.isInteger(message.fileSizeBytes.low) && $util.isInteger(message.fileSizeBytes.high))) + return "fileSizeBytes: integer|Long expected"; + if (message.fileSha256 != null && message.hasOwnProperty("fileSha256")) + if (!(message.fileSha256 && typeof message.fileSha256.length === "number" || $util.isString(message.fileSha256))) + return "fileSha256: buffer expected"; + if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256")) + if (!(message.fileEncSha256 && typeof message.fileEncSha256.length === "number" || $util.isString(message.fileEncSha256))) + return "fileEncSha256: buffer expected"; + return null; + }; + + /** + * Creates an ExternalBlobReference message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ExternalBlobReference + * @static + * @param {Object.} object Plain object + * @returns {proto.ExternalBlobReference} ExternalBlobReference + */ + ExternalBlobReference.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ExternalBlobReference) + return object; + var message = new $root.proto.ExternalBlobReference(); + if (object.mediaKey != null) + if (typeof object.mediaKey === "string") + $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0); + else if (object.mediaKey.length) + message.mediaKey = object.mediaKey; + if (object.directPath != null) + message.directPath = String(object.directPath); + if (object.handle != null) + message.handle = String(object.handle); + if (object.fileSizeBytes != null) + if ($util.Long) + (message.fileSizeBytes = $util.Long.fromValue(object.fileSizeBytes)).unsigned = true; + else if (typeof object.fileSizeBytes === "string") + message.fileSizeBytes = parseInt(object.fileSizeBytes, 10); + else if (typeof object.fileSizeBytes === "number") + message.fileSizeBytes = object.fileSizeBytes; + else if (typeof object.fileSizeBytes === "object") + message.fileSizeBytes = new $util.LongBits(object.fileSizeBytes.low >>> 0, object.fileSizeBytes.high >>> 0).toNumber(true); + if (object.fileSha256 != null) + if (typeof object.fileSha256 === "string") + $util.base64.decode(object.fileSha256, message.fileSha256 = $util.newBuffer($util.base64.length(object.fileSha256)), 0); + else if (object.fileSha256.length) + message.fileSha256 = object.fileSha256; + if (object.fileEncSha256 != null) + if (typeof object.fileEncSha256 === "string") + $util.base64.decode(object.fileEncSha256, message.fileEncSha256 = $util.newBuffer($util.base64.length(object.fileEncSha256)), 0); + else if (object.fileEncSha256.length) + message.fileEncSha256 = object.fileEncSha256; + return message; + }; + + /** + * Creates a plain object from an ExternalBlobReference message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ExternalBlobReference + * @static + * @param {proto.ExternalBlobReference} message ExternalBlobReference + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ExternalBlobReference.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.mediaKey = ""; + else { + object.mediaKey = []; + if (options.bytes !== Array) + object.mediaKey = $util.newBuffer(object.mediaKey); + } + object.directPath = ""; + object.handle = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.fileSizeBytes = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.fileSizeBytes = options.longs === String ? "0" : 0; + if (options.bytes === String) + object.fileSha256 = ""; + else { + object.fileSha256 = []; + if (options.bytes !== Array) + object.fileSha256 = $util.newBuffer(object.fileSha256); + } + if (options.bytes === String) + object.fileEncSha256 = ""; + else { + object.fileEncSha256 = []; + if (options.bytes !== Array) + object.fileEncSha256 = $util.newBuffer(object.fileEncSha256); + } + } + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey; + if (message.directPath != null && message.hasOwnProperty("directPath")) + object.directPath = message.directPath; + if (message.handle != null && message.hasOwnProperty("handle")) + object.handle = message.handle; + if (message.fileSizeBytes != null && message.hasOwnProperty("fileSizeBytes")) + if (typeof message.fileSizeBytes === "number") + object.fileSizeBytes = options.longs === String ? String(message.fileSizeBytes) : message.fileSizeBytes; + else + object.fileSizeBytes = options.longs === String ? $util.Long.prototype.toString.call(message.fileSizeBytes) : options.longs === Number ? new $util.LongBits(message.fileSizeBytes.low >>> 0, message.fileSizeBytes.high >>> 0).toNumber(true) : message.fileSizeBytes; + if (message.fileSha256 != null && message.hasOwnProperty("fileSha256")) + object.fileSha256 = options.bytes === String ? $util.base64.encode(message.fileSha256, 0, message.fileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileSha256) : message.fileSha256; + if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256")) + object.fileEncSha256 = options.bytes === String ? $util.base64.encode(message.fileEncSha256, 0, message.fileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileEncSha256) : message.fileEncSha256; + return object; + }; + + /** + * Converts this ExternalBlobReference to JSON. + * @function toJSON + * @memberof proto.ExternalBlobReference + * @instance + * @returns {Object.} JSON object + */ + ExternalBlobReference.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ExternalBlobReference; + })(); + + proto.SyncdRecord = (function() { + + /** + * Properties of a SyncdRecord. + * @memberof proto + * @interface ISyncdRecord + * @property {proto.ISyncdIndex|null} [index] SyncdRecord index + * @property {proto.ISyncdValue|null} [value] SyncdRecord value + * @property {proto.IKeyId|null} [keyId] SyncdRecord keyId + */ + + /** + * Constructs a new SyncdRecord. + * @memberof proto + * @classdesc Represents a SyncdRecord. + * @implements ISyncdRecord + * @constructor + * @param {proto.ISyncdRecord=} [properties] Properties to set + */ + function SyncdRecord(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdRecord index. + * @member {proto.ISyncdIndex|null|undefined} index + * @memberof proto.SyncdRecord + * @instance + */ + SyncdRecord.prototype.index = null; + + /** + * SyncdRecord value. + * @member {proto.ISyncdValue|null|undefined} value + * @memberof proto.SyncdRecord + * @instance + */ + SyncdRecord.prototype.value = null; + + /** + * SyncdRecord keyId. + * @member {proto.IKeyId|null|undefined} keyId + * @memberof proto.SyncdRecord + * @instance + */ + SyncdRecord.prototype.keyId = null; + + /** + * Creates a new SyncdRecord instance using the specified properties. + * @function create + * @memberof proto.SyncdRecord + * @static + * @param {proto.ISyncdRecord=} [properties] Properties to set + * @returns {proto.SyncdRecord} SyncdRecord instance + */ + SyncdRecord.create = function create(properties) { + return new SyncdRecord(properties); + }; + + /** + * Encodes the specified SyncdRecord message. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages. + * @function encode + * @memberof proto.SyncdRecord + * @static + * @param {proto.ISyncdRecord} message SyncdRecord message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdRecord.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.index != null && Object.hasOwnProperty.call(message, "index")) + $root.proto.SyncdIndex.encode(message.index, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.value != null && Object.hasOwnProperty.call(message, "value")) + $root.proto.SyncdValue.encode(message.value, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId")) + $root.proto.KeyId.encode(message.keyId, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SyncdRecord message, length delimited. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdRecord + * @static + * @param {proto.ISyncdRecord} message SyncdRecord message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdRecord.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdRecord message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdRecord + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdRecord} SyncdRecord + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdRecord.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdRecord(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.index = $root.proto.SyncdIndex.decode(reader, reader.uint32()); + break; + case 2: + message.value = $root.proto.SyncdValue.decode(reader, reader.uint32()); + break; + case 3: + message.keyId = $root.proto.KeyId.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdRecord message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdRecord + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdRecord} SyncdRecord + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdRecord.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdRecord message. + * @function verify + * @memberof proto.SyncdRecord + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdRecord.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.index != null && message.hasOwnProperty("index")) { + var error = $root.proto.SyncdIndex.verify(message.index); + if (error) + return "index." + error; + } + if (message.value != null && message.hasOwnProperty("value")) { + var error = $root.proto.SyncdValue.verify(message.value); + if (error) + return "value." + error; + } + if (message.keyId != null && message.hasOwnProperty("keyId")) { + var error = $root.proto.KeyId.verify(message.keyId); + if (error) + return "keyId." + error; + } + return null; + }; + + /** + * Creates a SyncdRecord message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdRecord + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdRecord} SyncdRecord + */ + SyncdRecord.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdRecord) + return object; + var message = new $root.proto.SyncdRecord(); + if (object.index != null) { + if (typeof object.index !== "object") + throw TypeError(".proto.SyncdRecord.index: object expected"); + message.index = $root.proto.SyncdIndex.fromObject(object.index); + } + if (object.value != null) { + if (typeof object.value !== "object") + throw TypeError(".proto.SyncdRecord.value: object expected"); + message.value = $root.proto.SyncdValue.fromObject(object.value); + } + if (object.keyId != null) { + if (typeof object.keyId !== "object") + throw TypeError(".proto.SyncdRecord.keyId: object expected"); + message.keyId = $root.proto.KeyId.fromObject(object.keyId); + } + return message; + }; + + /** + * Creates a plain object from a SyncdRecord message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdRecord + * @static + * @param {proto.SyncdRecord} message SyncdRecord + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdRecord.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.index = null; + object.value = null; + object.keyId = null; + } + if (message.index != null && message.hasOwnProperty("index")) + object.index = $root.proto.SyncdIndex.toObject(message.index, options); + if (message.value != null && message.hasOwnProperty("value")) + object.value = $root.proto.SyncdValue.toObject(message.value, options); + if (message.keyId != null && message.hasOwnProperty("keyId")) + object.keyId = $root.proto.KeyId.toObject(message.keyId, options); + return object; + }; + + /** + * Converts this SyncdRecord to JSON. + * @function toJSON + * @memberof proto.SyncdRecord + * @instance + * @returns {Object.} JSON object + */ + SyncdRecord.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdRecord; + })(); + + proto.KeyId = (function() { + + /** + * Properties of a KeyId. + * @memberof proto + * @interface IKeyId + * @property {Uint8Array|null} [id] KeyId id + */ + + /** + * Constructs a new KeyId. + * @memberof proto + * @classdesc Represents a KeyId. + * @implements IKeyId + * @constructor + * @param {proto.IKeyId=} [properties] Properties to set + */ + function KeyId(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * KeyId id. + * @member {Uint8Array} id + * @memberof proto.KeyId + * @instance + */ + KeyId.prototype.id = $util.newBuffer([]); + + /** + * Creates a new KeyId instance using the specified properties. + * @function create + * @memberof proto.KeyId + * @static + * @param {proto.IKeyId=} [properties] Properties to set + * @returns {proto.KeyId} KeyId instance + */ + KeyId.create = function create(properties) { + return new KeyId(properties); + }; + + /** + * Encodes the specified KeyId message. Does not implicitly {@link proto.KeyId.verify|verify} messages. + * @function encode + * @memberof proto.KeyId + * @static + * @param {proto.IKeyId} message KeyId message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + KeyId.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.id); + return writer; + }; + + /** + * Encodes the specified KeyId message, length delimited. Does not implicitly {@link proto.KeyId.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.KeyId + * @static + * @param {proto.IKeyId} message KeyId message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + KeyId.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a KeyId message from the specified reader or buffer. + * @function decode + * @memberof proto.KeyId + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.KeyId} KeyId + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + KeyId.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.KeyId(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a KeyId message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.KeyId + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.KeyId} KeyId + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + KeyId.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a KeyId message. + * @function verify + * @memberof proto.KeyId + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + KeyId.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!(message.id && typeof message.id.length === "number" || $util.isString(message.id))) + return "id: buffer expected"; + return null; + }; + + /** + * Creates a KeyId message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.KeyId + * @static + * @param {Object.} object Plain object + * @returns {proto.KeyId} KeyId + */ + KeyId.fromObject = function fromObject(object) { + if (object instanceof $root.proto.KeyId) + return object; + var message = new $root.proto.KeyId(); + if (object.id != null) + if (typeof object.id === "string") + $util.base64.decode(object.id, message.id = $util.newBuffer($util.base64.length(object.id)), 0); + else if (object.id.length) + message.id = object.id; + return message; + }; + + /** + * Creates a plain object from a KeyId message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.KeyId + * @static + * @param {proto.KeyId} message KeyId + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + KeyId.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + if (options.bytes === String) + object.id = ""; + else { + object.id = []; + if (options.bytes !== Array) + object.id = $util.newBuffer(object.id); + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = options.bytes === String ? $util.base64.encode(message.id, 0, message.id.length) : options.bytes === Array ? Array.prototype.slice.call(message.id) : message.id; + return object; + }; + + /** + * Converts this KeyId to JSON. + * @function toJSON + * @memberof proto.KeyId + * @instance + * @returns {Object.} JSON object + */ + KeyId.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return KeyId; + })(); + + proto.SyncdValue = (function() { + + /** + * Properties of a SyncdValue. + * @memberof proto + * @interface ISyncdValue + * @property {Uint8Array|null} [blob] SyncdValue blob + */ + + /** + * Constructs a new SyncdValue. + * @memberof proto + * @classdesc Represents a SyncdValue. + * @implements ISyncdValue + * @constructor + * @param {proto.ISyncdValue=} [properties] Properties to set + */ + function SyncdValue(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdValue blob. + * @member {Uint8Array} blob + * @memberof proto.SyncdValue + * @instance + */ + SyncdValue.prototype.blob = $util.newBuffer([]); + + /** + * Creates a new SyncdValue instance using the specified properties. + * @function create + * @memberof proto.SyncdValue + * @static + * @param {proto.ISyncdValue=} [properties] Properties to set + * @returns {proto.SyncdValue} SyncdValue instance + */ + SyncdValue.create = function create(properties) { + return new SyncdValue(properties); + }; + + /** + * Encodes the specified SyncdValue message. Does not implicitly {@link proto.SyncdValue.verify|verify} messages. + * @function encode + * @memberof proto.SyncdValue + * @static + * @param {proto.ISyncdValue} message SyncdValue message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdValue.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.blob != null && Object.hasOwnProperty.call(message, "blob")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.blob); + return writer; + }; + + /** + * Encodes the specified SyncdValue message, length delimited. Does not implicitly {@link proto.SyncdValue.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdValue + * @static + * @param {proto.ISyncdValue} message SyncdValue message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdValue.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdValue message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdValue + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdValue} SyncdValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdValue.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdValue(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.blob = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdValue message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdValue + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdValue} SyncdValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdValue.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdValue message. + * @function verify + * @memberof proto.SyncdValue + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdValue.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.blob != null && message.hasOwnProperty("blob")) + if (!(message.blob && typeof message.blob.length === "number" || $util.isString(message.blob))) + return "blob: buffer expected"; + return null; + }; + + /** + * Creates a SyncdValue message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdValue + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdValue} SyncdValue + */ + SyncdValue.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdValue) + return object; + var message = new $root.proto.SyncdValue(); + if (object.blob != null) + if (typeof object.blob === "string") + $util.base64.decode(object.blob, message.blob = $util.newBuffer($util.base64.length(object.blob)), 0); + else if (object.blob.length) + message.blob = object.blob; + return message; + }; + + /** + * Creates a plain object from a SyncdValue message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdValue + * @static + * @param {proto.SyncdValue} message SyncdValue + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdValue.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + if (options.bytes === String) + object.blob = ""; + else { + object.blob = []; + if (options.bytes !== Array) + object.blob = $util.newBuffer(object.blob); + } + if (message.blob != null && message.hasOwnProperty("blob")) + object.blob = options.bytes === String ? $util.base64.encode(message.blob, 0, message.blob.length) : options.bytes === Array ? Array.prototype.slice.call(message.blob) : message.blob; + return object; + }; + + /** + * Converts this SyncdValue to JSON. + * @function toJSON + * @memberof proto.SyncdValue + * @instance + * @returns {Object.} JSON object + */ + SyncdValue.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdValue; + })(); + + proto.SyncdIndex = (function() { + + /** + * Properties of a SyncdIndex. + * @memberof proto + * @interface ISyncdIndex + * @property {Uint8Array|null} [blob] SyncdIndex blob + */ + + /** + * Constructs a new SyncdIndex. + * @memberof proto + * @classdesc Represents a SyncdIndex. + * @implements ISyncdIndex + * @constructor + * @param {proto.ISyncdIndex=} [properties] Properties to set + */ + function SyncdIndex(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdIndex blob. + * @member {Uint8Array} blob + * @memberof proto.SyncdIndex + * @instance + */ + SyncdIndex.prototype.blob = $util.newBuffer([]); + + /** + * Creates a new SyncdIndex instance using the specified properties. + * @function create + * @memberof proto.SyncdIndex + * @static + * @param {proto.ISyncdIndex=} [properties] Properties to set + * @returns {proto.SyncdIndex} SyncdIndex instance + */ + SyncdIndex.create = function create(properties) { + return new SyncdIndex(properties); + }; + + /** + * Encodes the specified SyncdIndex message. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages. + * @function encode + * @memberof proto.SyncdIndex + * @static + * @param {proto.ISyncdIndex} message SyncdIndex message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdIndex.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.blob != null && Object.hasOwnProperty.call(message, "blob")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.blob); + return writer; + }; + + /** + * Encodes the specified SyncdIndex message, length delimited. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdIndex + * @static + * @param {proto.ISyncdIndex} message SyncdIndex message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdIndex.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdIndex message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdIndex + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdIndex} SyncdIndex + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdIndex.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdIndex(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.blob = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdIndex message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdIndex + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdIndex} SyncdIndex + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdIndex.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdIndex message. + * @function verify + * @memberof proto.SyncdIndex + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdIndex.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.blob != null && message.hasOwnProperty("blob")) + if (!(message.blob && typeof message.blob.length === "number" || $util.isString(message.blob))) + return "blob: buffer expected"; + return null; + }; + + /** + * Creates a SyncdIndex message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdIndex + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdIndex} SyncdIndex + */ + SyncdIndex.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdIndex) + return object; + var message = new $root.proto.SyncdIndex(); + if (object.blob != null) + if (typeof object.blob === "string") + $util.base64.decode(object.blob, message.blob = $util.newBuffer($util.base64.length(object.blob)), 0); + else if (object.blob.length) + message.blob = object.blob; + return message; + }; + + /** + * Creates a plain object from a SyncdIndex message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdIndex + * @static + * @param {proto.SyncdIndex} message SyncdIndex + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdIndex.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + if (options.bytes === String) + object.blob = ""; + else { + object.blob = []; + if (options.bytes !== Array) + object.blob = $util.newBuffer(object.blob); + } + if (message.blob != null && message.hasOwnProperty("blob")) + object.blob = options.bytes === String ? $util.base64.encode(message.blob, 0, message.blob.length) : options.bytes === Array ? Array.prototype.slice.call(message.blob) : message.blob; + return object; + }; + + /** + * Converts this SyncdIndex to JSON. + * @function toJSON + * @memberof proto.SyncdIndex + * @instance + * @returns {Object.} JSON object + */ + SyncdIndex.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdIndex; + })(); + + proto.ExitCode = (function() { + + /** + * Properties of an ExitCode. + * @memberof proto + * @interface IExitCode + * @property {number|Long|null} [code] ExitCode code + * @property {string|null} [text] ExitCode text + */ + + /** + * Constructs a new ExitCode. + * @memberof proto + * @classdesc Represents an ExitCode. + * @implements IExitCode + * @constructor + * @param {proto.IExitCode=} [properties] Properties to set + */ + function ExitCode(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ExitCode code. + * @member {number|Long} code + * @memberof proto.ExitCode + * @instance + */ + ExitCode.prototype.code = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * ExitCode text. + * @member {string} text + * @memberof proto.ExitCode + * @instance + */ + ExitCode.prototype.text = ""; + + /** + * Creates a new ExitCode instance using the specified properties. + * @function create + * @memberof proto.ExitCode + * @static + * @param {proto.IExitCode=} [properties] Properties to set + * @returns {proto.ExitCode} ExitCode instance + */ + ExitCode.create = function create(properties) { + return new ExitCode(properties); + }; + + /** + * Encodes the specified ExitCode message. Does not implicitly {@link proto.ExitCode.verify|verify} messages. + * @function encode + * @memberof proto.ExitCode + * @static + * @param {proto.IExitCode} message ExitCode message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ExitCode.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.code != null && Object.hasOwnProperty.call(message, "code")) + writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.code); + if (message.text != null && Object.hasOwnProperty.call(message, "text")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.text); + return writer; + }; + + /** + * Encodes the specified ExitCode message, length delimited. Does not implicitly {@link proto.ExitCode.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ExitCode + * @static + * @param {proto.IExitCode} message ExitCode message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ExitCode.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an ExitCode message from the specified reader or buffer. + * @function decode + * @memberof proto.ExitCode + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ExitCode} ExitCode + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ExitCode.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ExitCode(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.code = reader.uint64(); + break; + case 2: + message.text = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an ExitCode message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ExitCode + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ExitCode} ExitCode + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ExitCode.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an ExitCode message. + * @function verify + * @memberof proto.ExitCode + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ExitCode.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.code != null && message.hasOwnProperty("code")) + if (!$util.isInteger(message.code) && !(message.code && $util.isInteger(message.code.low) && $util.isInteger(message.code.high))) + return "code: integer|Long expected"; + if (message.text != null && message.hasOwnProperty("text")) + if (!$util.isString(message.text)) + return "text: string expected"; + return null; + }; + + /** + * Creates an ExitCode message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ExitCode + * @static + * @param {Object.} object Plain object + * @returns {proto.ExitCode} ExitCode + */ + ExitCode.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ExitCode) + return object; + var message = new $root.proto.ExitCode(); + if (object.code != null) + if ($util.Long) + (message.code = $util.Long.fromValue(object.code)).unsigned = true; + else if (typeof object.code === "string") + message.code = parseInt(object.code, 10); + else if (typeof object.code === "number") + message.code = object.code; + else if (typeof object.code === "object") + message.code = new $util.LongBits(object.code.low >>> 0, object.code.high >>> 0).toNumber(true); + if (object.text != null) + message.text = String(object.text); + return message; + }; + + /** + * Creates a plain object from an ExitCode message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ExitCode + * @static + * @param {proto.ExitCode} message ExitCode + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ExitCode.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.code = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.code = options.longs === String ? "0" : 0; + object.text = ""; + } + if (message.code != null && message.hasOwnProperty("code")) + if (typeof message.code === "number") + object.code = options.longs === String ? String(message.code) : message.code; + else + object.code = options.longs === String ? $util.Long.prototype.toString.call(message.code) : options.longs === Number ? new $util.LongBits(message.code.low >>> 0, message.code.high >>> 0).toNumber(true) : message.code; + if (message.text != null && message.hasOwnProperty("text")) + object.text = message.text; + return object; + }; + + /** + * Converts this ExitCode to JSON. + * @function toJSON + * @memberof proto.ExitCode + * @instance + * @returns {Object.} JSON object + */ + ExitCode.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ExitCode; + })(); + + proto.SyncdVersion = (function() { + + /** + * Properties of a SyncdVersion. + * @memberof proto + * @interface ISyncdVersion + * @property {number|Long|null} [version] SyncdVersion version + */ + + /** + * Constructs a new SyncdVersion. + * @memberof proto + * @classdesc Represents a SyncdVersion. + * @implements ISyncdVersion + * @constructor + * @param {proto.ISyncdVersion=} [properties] Properties to set + */ + function SyncdVersion(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdVersion version. + * @member {number|Long} version + * @memberof proto.SyncdVersion + * @instance + */ + SyncdVersion.prototype.version = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Creates a new SyncdVersion instance using the specified properties. + * @function create + * @memberof proto.SyncdVersion + * @static + * @param {proto.ISyncdVersion=} [properties] Properties to set + * @returns {proto.SyncdVersion} SyncdVersion instance + */ + SyncdVersion.create = function create(properties) { + return new SyncdVersion(properties); + }; + + /** + * Encodes the specified SyncdVersion message. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages. + * @function encode + * @memberof proto.SyncdVersion + * @static + * @param {proto.ISyncdVersion} message SyncdVersion message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdVersion.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.version); + return writer; + }; + + /** + * Encodes the specified SyncdVersion message, length delimited. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdVersion + * @static + * @param {proto.ISyncdVersion} message SyncdVersion message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdVersion.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdVersion message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdVersion + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdVersion} SyncdVersion + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdVersion.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdVersion(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.version = reader.uint64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdVersion message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdVersion + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdVersion} SyncdVersion + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdVersion.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdVersion message. + * @function verify + * @memberof proto.SyncdVersion + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdVersion.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.version != null && message.hasOwnProperty("version")) + if (!$util.isInteger(message.version) && !(message.version && $util.isInteger(message.version.low) && $util.isInteger(message.version.high))) + return "version: integer|Long expected"; + return null; + }; + + /** + * Creates a SyncdVersion message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdVersion + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdVersion} SyncdVersion + */ + SyncdVersion.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdVersion) + return object; + var message = new $root.proto.SyncdVersion(); + if (object.version != null) + if ($util.Long) + (message.version = $util.Long.fromValue(object.version)).unsigned = true; + else if (typeof object.version === "string") + message.version = parseInt(object.version, 10); + else if (typeof object.version === "number") + message.version = object.version; + else if (typeof object.version === "object") + message.version = new $util.LongBits(object.version.low >>> 0, object.version.high >>> 0).toNumber(true); + return message; + }; + + /** + * Creates a plain object from a SyncdVersion message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdVersion + * @static + * @param {proto.SyncdVersion} message SyncdVersion + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdVersion.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.version = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.version = options.longs === String ? "0" : 0; + if (message.version != null && message.hasOwnProperty("version")) + if (typeof message.version === "number") + object.version = options.longs === String ? String(message.version) : message.version; + else + object.version = options.longs === String ? $util.Long.prototype.toString.call(message.version) : options.longs === Number ? new $util.LongBits(message.version.low >>> 0, message.version.high >>> 0).toNumber(true) : message.version; + return object; + }; + + /** + * Converts this SyncdVersion to JSON. + * @function toJSON + * @memberof proto.SyncdVersion + * @instance + * @returns {Object.} JSON object + */ + SyncdVersion.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdVersion; + })(); + + proto.ServerErrorReceipt = (function() { + + /** + * Properties of a ServerErrorReceipt. + * @memberof proto + * @interface IServerErrorReceipt + * @property {string|null} [stanzaId] ServerErrorReceipt stanzaId + */ + + /** + * Constructs a new ServerErrorReceipt. + * @memberof proto + * @classdesc Represents a ServerErrorReceipt. + * @implements IServerErrorReceipt + * @constructor + * @param {proto.IServerErrorReceipt=} [properties] Properties to set + */ + function ServerErrorReceipt(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ServerErrorReceipt stanzaId. + * @member {string} stanzaId + * @memberof proto.ServerErrorReceipt + * @instance + */ + ServerErrorReceipt.prototype.stanzaId = ""; + + /** + * Creates a new ServerErrorReceipt instance using the specified properties. + * @function create + * @memberof proto.ServerErrorReceipt + * @static + * @param {proto.IServerErrorReceipt=} [properties] Properties to set + * @returns {proto.ServerErrorReceipt} ServerErrorReceipt instance + */ + ServerErrorReceipt.create = function create(properties) { + return new ServerErrorReceipt(properties); + }; + + /** + * Encodes the specified ServerErrorReceipt message. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages. + * @function encode + * @memberof proto.ServerErrorReceipt + * @static + * @param {proto.IServerErrorReceipt} message ServerErrorReceipt message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ServerErrorReceipt.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.stanzaId); + return writer; + }; + + /** + * Encodes the specified ServerErrorReceipt message, length delimited. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ServerErrorReceipt + * @static + * @param {proto.IServerErrorReceipt} message ServerErrorReceipt message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ServerErrorReceipt.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ServerErrorReceipt message from the specified reader or buffer. + * @function decode + * @memberof proto.ServerErrorReceipt + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ServerErrorReceipt} ServerErrorReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ServerErrorReceipt.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ServerErrorReceipt(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.stanzaId = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ServerErrorReceipt message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ServerErrorReceipt + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ServerErrorReceipt} ServerErrorReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ServerErrorReceipt.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ServerErrorReceipt message. + * @function verify + * @memberof proto.ServerErrorReceipt + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ServerErrorReceipt.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) + if (!$util.isString(message.stanzaId)) + return "stanzaId: string expected"; + return null; + }; + + /** + * Creates a ServerErrorReceipt message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ServerErrorReceipt + * @static + * @param {Object.} object Plain object + * @returns {proto.ServerErrorReceipt} ServerErrorReceipt + */ + ServerErrorReceipt.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ServerErrorReceipt) + return object; + var message = new $root.proto.ServerErrorReceipt(); + if (object.stanzaId != null) + message.stanzaId = String(object.stanzaId); + return message; + }; + + /** + * Creates a plain object from a ServerErrorReceipt message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ServerErrorReceipt + * @static + * @param {proto.ServerErrorReceipt} message ServerErrorReceipt + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ServerErrorReceipt.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.stanzaId = ""; + if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) + object.stanzaId = message.stanzaId; + return object; + }; + + /** + * Converts this ServerErrorReceipt to JSON. + * @function toJSON + * @memberof proto.ServerErrorReceipt + * @instance + * @returns {Object.} JSON object + */ + ServerErrorReceipt.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ServerErrorReceipt; + })(); + + proto.MediaRetryNotification = (function() { + + /** + * Properties of a MediaRetryNotification. + * @memberof proto + * @interface IMediaRetryNotification + * @property {string|null} [stanzaId] MediaRetryNotification stanzaId + * @property {string|null} [directPath] MediaRetryNotification directPath + * @property {proto.MediaRetryNotification.MediaRetryNotificationResultType|null} [result] MediaRetryNotification result + */ + + /** + * Constructs a new MediaRetryNotification. + * @memberof proto + * @classdesc Represents a MediaRetryNotification. + * @implements IMediaRetryNotification + * @constructor + * @param {proto.IMediaRetryNotification=} [properties] Properties to set + */ + function MediaRetryNotification(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MediaRetryNotification stanzaId. + * @member {string} stanzaId + * @memberof proto.MediaRetryNotification + * @instance + */ + MediaRetryNotification.prototype.stanzaId = ""; + + /** + * MediaRetryNotification directPath. + * @member {string} directPath + * @memberof proto.MediaRetryNotification + * @instance + */ + MediaRetryNotification.prototype.directPath = ""; + + /** + * MediaRetryNotification result. + * @member {proto.MediaRetryNotification.MediaRetryNotificationResultType} result + * @memberof proto.MediaRetryNotification + * @instance + */ + MediaRetryNotification.prototype.result = 0; + + /** + * Creates a new MediaRetryNotification instance using the specified properties. + * @function create + * @memberof proto.MediaRetryNotification + * @static + * @param {proto.IMediaRetryNotification=} [properties] Properties to set + * @returns {proto.MediaRetryNotification} MediaRetryNotification instance + */ + MediaRetryNotification.create = function create(properties) { + return new MediaRetryNotification(properties); + }; + + /** + * Encodes the specified MediaRetryNotification message. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages. + * @function encode + * @memberof proto.MediaRetryNotification + * @static + * @param {proto.IMediaRetryNotification} message MediaRetryNotification message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MediaRetryNotification.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.stanzaId); + if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.directPath); + if (message.result != null && Object.hasOwnProperty.call(message, "result")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.result); + return writer; + }; + + /** + * Encodes the specified MediaRetryNotification message, length delimited. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MediaRetryNotification + * @static + * @param {proto.IMediaRetryNotification} message MediaRetryNotification message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MediaRetryNotification.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MediaRetryNotification message from the specified reader or buffer. + * @function decode + * @memberof proto.MediaRetryNotification + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MediaRetryNotification} MediaRetryNotification + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MediaRetryNotification.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MediaRetryNotification(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.stanzaId = reader.string(); + break; + case 2: + message.directPath = reader.string(); + break; + case 3: + message.result = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MediaRetryNotification message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MediaRetryNotification + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MediaRetryNotification} MediaRetryNotification + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MediaRetryNotification.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MediaRetryNotification message. + * @function verify + * @memberof proto.MediaRetryNotification + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MediaRetryNotification.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) + if (!$util.isString(message.stanzaId)) + return "stanzaId: string expected"; + if (message.directPath != null && message.hasOwnProperty("directPath")) + if (!$util.isString(message.directPath)) + return "directPath: string expected"; + if (message.result != null && message.hasOwnProperty("result")) + switch (message.result) { + default: + return "result: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + return null; + }; + + /** + * Creates a MediaRetryNotification message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MediaRetryNotification + * @static + * @param {Object.} object Plain object + * @returns {proto.MediaRetryNotification} MediaRetryNotification + */ + MediaRetryNotification.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MediaRetryNotification) + return object; + var message = new $root.proto.MediaRetryNotification(); + if (object.stanzaId != null) + message.stanzaId = String(object.stanzaId); + if (object.directPath != null) + message.directPath = String(object.directPath); + switch (object.result) { + case "GENERAL_ERROR": + case 0: + message.result = 0; + break; + case "SUCCESS": + case 1: + message.result = 1; + break; + case "NOT_FOUND": + case 2: + message.result = 2; + break; + case "DECRYPTION_ERROR": + case 3: + message.result = 3; + break; + } + return message; + }; + + /** + * Creates a plain object from a MediaRetryNotification message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MediaRetryNotification + * @static + * @param {proto.MediaRetryNotification} message MediaRetryNotification + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MediaRetryNotification.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.stanzaId = ""; + object.directPath = ""; + object.result = options.enums === String ? "GENERAL_ERROR" : 0; + } + if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) + object.stanzaId = message.stanzaId; + if (message.directPath != null && message.hasOwnProperty("directPath")) + object.directPath = message.directPath; + if (message.result != null && message.hasOwnProperty("result")) + object.result = options.enums === String ? $root.proto.MediaRetryNotification.MediaRetryNotificationResultType[message.result] : message.result; + return object; + }; + + /** + * Converts this MediaRetryNotification to JSON. + * @function toJSON + * @memberof proto.MediaRetryNotification + * @instance + * @returns {Object.} JSON object + */ + MediaRetryNotification.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * MediaRetryNotificationResultType enum. + * @name proto.MediaRetryNotification.MediaRetryNotificationResultType + * @enum {number} + * @property {number} GENERAL_ERROR=0 GENERAL_ERROR value + * @property {number} SUCCESS=1 SUCCESS value + * @property {number} NOT_FOUND=2 NOT_FOUND value + * @property {number} DECRYPTION_ERROR=3 DECRYPTION_ERROR value + */ + MediaRetryNotification.MediaRetryNotificationResultType = (function() { var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "E2EE"] = 0; - values[valuesById[2] = "FB"] = 2; - values[valuesById[1] = "BSP"] = 1; - values[valuesById[3] = "BSP_AND_FB"] = 3; + values[valuesById[0] = "GENERAL_ERROR"] = 0; + values[valuesById[1] = "SUCCESS"] = 1; + values[valuesById[2] = "NOT_FOUND"] = 2; + values[valuesById[3] = "DECRYPTION_ERROR"] = 3; return values; })(); - return WebMessageInfo; + return MediaRetryNotification; + })(); + + proto.MsgOpaqueData = (function() { + + /** + * Properties of a MsgOpaqueData. + * @memberof proto + * @interface IMsgOpaqueData + * @property {string|null} [body] MsgOpaqueData body + * @property {string|null} [caption] MsgOpaqueData caption + * @property {string|null} [clientUrl] MsgOpaqueData clientUrl + * @property {number|null} [lng] MsgOpaqueData lng + * @property {number|null} [lat] MsgOpaqueData lat + * @property {number|null} [paymentAmount1000] MsgOpaqueData paymentAmount1000 + * @property {string|null} [paymentNoteMsgBody] MsgOpaqueData paymentNoteMsgBody + * @property {string|null} [canonicalUrl] MsgOpaqueData canonicalUrl + * @property {string|null} [matchedText] MsgOpaqueData matchedText + * @property {string|null} [title] MsgOpaqueData title + * @property {string|null} [description] MsgOpaqueData description + */ + + /** + * Constructs a new MsgOpaqueData. + * @memberof proto + * @classdesc Represents a MsgOpaqueData. + * @implements IMsgOpaqueData + * @constructor + * @param {proto.IMsgOpaqueData=} [properties] Properties to set + */ + function MsgOpaqueData(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MsgOpaqueData body. + * @member {string} body + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.body = ""; + + /** + * MsgOpaqueData caption. + * @member {string} caption + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.caption = ""; + + /** + * MsgOpaqueData clientUrl. + * @member {string} clientUrl + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.clientUrl = ""; + + /** + * MsgOpaqueData lng. + * @member {number} lng + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.lng = 0; + + /** + * MsgOpaqueData lat. + * @member {number} lat + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.lat = 0; + + /** + * MsgOpaqueData paymentAmount1000. + * @member {number} paymentAmount1000 + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.paymentAmount1000 = 0; + + /** + * MsgOpaqueData paymentNoteMsgBody. + * @member {string} paymentNoteMsgBody + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.paymentNoteMsgBody = ""; + + /** + * MsgOpaqueData canonicalUrl. + * @member {string} canonicalUrl + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.canonicalUrl = ""; + + /** + * MsgOpaqueData matchedText. + * @member {string} matchedText + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.matchedText = ""; + + /** + * MsgOpaqueData title. + * @member {string} title + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.title = ""; + + /** + * MsgOpaqueData description. + * @member {string} description + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.description = ""; + + /** + * Creates a new MsgOpaqueData instance using the specified properties. + * @function create + * @memberof proto.MsgOpaqueData + * @static + * @param {proto.IMsgOpaqueData=} [properties] Properties to set + * @returns {proto.MsgOpaqueData} MsgOpaqueData instance + */ + MsgOpaqueData.create = function create(properties) { + return new MsgOpaqueData(properties); + }; + + /** + * Encodes the specified MsgOpaqueData message. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages. + * @function encode + * @memberof proto.MsgOpaqueData + * @static + * @param {proto.IMsgOpaqueData} message MsgOpaqueData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MsgOpaqueData.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.body != null && Object.hasOwnProperty.call(message, "body")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.body); + if (message.caption != null && Object.hasOwnProperty.call(message, "caption")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.caption); + if (message.clientUrl != null && Object.hasOwnProperty.call(message, "clientUrl")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.clientUrl); + if (message.lng != null && Object.hasOwnProperty.call(message, "lng")) + writer.uint32(/* id 5, wireType 1 =*/41).double(message.lng); + if (message.lat != null && Object.hasOwnProperty.call(message, "lat")) + writer.uint32(/* id 7, wireType 1 =*/57).double(message.lat); + if (message.paymentAmount1000 != null && Object.hasOwnProperty.call(message, "paymentAmount1000")) + writer.uint32(/* id 8, wireType 0 =*/64).int32(message.paymentAmount1000); + if (message.paymentNoteMsgBody != null && Object.hasOwnProperty.call(message, "paymentNoteMsgBody")) + writer.uint32(/* id 9, wireType 2 =*/74).string(message.paymentNoteMsgBody); + if (message.canonicalUrl != null && Object.hasOwnProperty.call(message, "canonicalUrl")) + writer.uint32(/* id 10, wireType 2 =*/82).string(message.canonicalUrl); + if (message.matchedText != null && Object.hasOwnProperty.call(message, "matchedText")) + writer.uint32(/* id 11, wireType 2 =*/90).string(message.matchedText); + if (message.title != null && Object.hasOwnProperty.call(message, "title")) + writer.uint32(/* id 12, wireType 2 =*/98).string(message.title); + if (message.description != null && Object.hasOwnProperty.call(message, "description")) + writer.uint32(/* id 13, wireType 2 =*/106).string(message.description); + return writer; + }; + + /** + * Encodes the specified MsgOpaqueData message, length delimited. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MsgOpaqueData + * @static + * @param {proto.IMsgOpaqueData} message MsgOpaqueData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MsgOpaqueData.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MsgOpaqueData message from the specified reader or buffer. + * @function decode + * @memberof proto.MsgOpaqueData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MsgOpaqueData} MsgOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MsgOpaqueData.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MsgOpaqueData(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.body = reader.string(); + break; + case 3: + message.caption = reader.string(); + break; + case 4: + message.clientUrl = reader.string(); + break; + case 5: + message.lng = reader.double(); + break; + case 7: + message.lat = reader.double(); + break; + case 8: + message.paymentAmount1000 = reader.int32(); + break; + case 9: + message.paymentNoteMsgBody = reader.string(); + break; + case 10: + message.canonicalUrl = reader.string(); + break; + case 11: + message.matchedText = reader.string(); + break; + case 12: + message.title = reader.string(); + break; + case 13: + message.description = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MsgOpaqueData message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MsgOpaqueData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MsgOpaqueData} MsgOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MsgOpaqueData.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MsgOpaqueData message. + * @function verify + * @memberof proto.MsgOpaqueData + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MsgOpaqueData.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.body != null && message.hasOwnProperty("body")) + if (!$util.isString(message.body)) + return "body: string expected"; + if (message.caption != null && message.hasOwnProperty("caption")) + if (!$util.isString(message.caption)) + return "caption: string expected"; + if (message.clientUrl != null && message.hasOwnProperty("clientUrl")) + if (!$util.isString(message.clientUrl)) + return "clientUrl: string expected"; + if (message.lng != null && message.hasOwnProperty("lng")) + if (typeof message.lng !== "number") + return "lng: number expected"; + if (message.lat != null && message.hasOwnProperty("lat")) + if (typeof message.lat !== "number") + return "lat: number expected"; + if (message.paymentAmount1000 != null && message.hasOwnProperty("paymentAmount1000")) + if (!$util.isInteger(message.paymentAmount1000)) + return "paymentAmount1000: integer expected"; + if (message.paymentNoteMsgBody != null && message.hasOwnProperty("paymentNoteMsgBody")) + if (!$util.isString(message.paymentNoteMsgBody)) + return "paymentNoteMsgBody: string expected"; + if (message.canonicalUrl != null && message.hasOwnProperty("canonicalUrl")) + if (!$util.isString(message.canonicalUrl)) + return "canonicalUrl: string expected"; + if (message.matchedText != null && message.hasOwnProperty("matchedText")) + if (!$util.isString(message.matchedText)) + return "matchedText: string expected"; + if (message.title != null && message.hasOwnProperty("title")) + if (!$util.isString(message.title)) + return "title: string expected"; + if (message.description != null && message.hasOwnProperty("description")) + if (!$util.isString(message.description)) + return "description: string expected"; + return null; + }; + + /** + * Creates a MsgOpaqueData message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MsgOpaqueData + * @static + * @param {Object.} object Plain object + * @returns {proto.MsgOpaqueData} MsgOpaqueData + */ + MsgOpaqueData.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MsgOpaqueData) + return object; + var message = new $root.proto.MsgOpaqueData(); + if (object.body != null) + message.body = String(object.body); + if (object.caption != null) + message.caption = String(object.caption); + if (object.clientUrl != null) + message.clientUrl = String(object.clientUrl); + if (object.lng != null) + message.lng = Number(object.lng); + if (object.lat != null) + message.lat = Number(object.lat); + if (object.paymentAmount1000 != null) + message.paymentAmount1000 = object.paymentAmount1000 | 0; + if (object.paymentNoteMsgBody != null) + message.paymentNoteMsgBody = String(object.paymentNoteMsgBody); + if (object.canonicalUrl != null) + message.canonicalUrl = String(object.canonicalUrl); + if (object.matchedText != null) + message.matchedText = String(object.matchedText); + if (object.title != null) + message.title = String(object.title); + if (object.description != null) + message.description = String(object.description); + return message; + }; + + /** + * Creates a plain object from a MsgOpaqueData message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MsgOpaqueData + * @static + * @param {proto.MsgOpaqueData} message MsgOpaqueData + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MsgOpaqueData.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.body = ""; + object.caption = ""; + object.clientUrl = ""; + object.lng = 0; + object.lat = 0; + object.paymentAmount1000 = 0; + object.paymentNoteMsgBody = ""; + object.canonicalUrl = ""; + object.matchedText = ""; + object.title = ""; + object.description = ""; + } + if (message.body != null && message.hasOwnProperty("body")) + object.body = message.body; + if (message.caption != null && message.hasOwnProperty("caption")) + object.caption = message.caption; + if (message.clientUrl != null && message.hasOwnProperty("clientUrl")) + object.clientUrl = message.clientUrl; + if (message.lng != null && message.hasOwnProperty("lng")) + object.lng = options.json && !isFinite(message.lng) ? String(message.lng) : message.lng; + if (message.lat != null && message.hasOwnProperty("lat")) + object.lat = options.json && !isFinite(message.lat) ? String(message.lat) : message.lat; + if (message.paymentAmount1000 != null && message.hasOwnProperty("paymentAmount1000")) + object.paymentAmount1000 = message.paymentAmount1000; + if (message.paymentNoteMsgBody != null && message.hasOwnProperty("paymentNoteMsgBody")) + object.paymentNoteMsgBody = message.paymentNoteMsgBody; + if (message.canonicalUrl != null && message.hasOwnProperty("canonicalUrl")) + object.canonicalUrl = message.canonicalUrl; + if (message.matchedText != null && message.hasOwnProperty("matchedText")) + object.matchedText = message.matchedText; + if (message.title != null && message.hasOwnProperty("title")) + object.title = message.title; + if (message.description != null && message.hasOwnProperty("description")) + object.description = message.description; + return object; + }; + + /** + * Converts this MsgOpaqueData to JSON. + * @function toJSON + * @memberof proto.MsgOpaqueData + * @instance + * @returns {Object.} JSON object + */ + MsgOpaqueData.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MsgOpaqueData; + })(); + + proto.MsgRowOpaqueData = (function() { + + /** + * Properties of a MsgRowOpaqueData. + * @memberof proto + * @interface IMsgRowOpaqueData + * @property {proto.IMsgOpaqueData|null} [currentMsg] MsgRowOpaqueData currentMsg + * @property {proto.IMsgOpaqueData|null} [quotedMsg] MsgRowOpaqueData quotedMsg + */ + + /** + * Constructs a new MsgRowOpaqueData. + * @memberof proto + * @classdesc Represents a MsgRowOpaqueData. + * @implements IMsgRowOpaqueData + * @constructor + * @param {proto.IMsgRowOpaqueData=} [properties] Properties to set + */ + function MsgRowOpaqueData(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MsgRowOpaqueData currentMsg. + * @member {proto.IMsgOpaqueData|null|undefined} currentMsg + * @memberof proto.MsgRowOpaqueData + * @instance + */ + MsgRowOpaqueData.prototype.currentMsg = null; + + /** + * MsgRowOpaqueData quotedMsg. + * @member {proto.IMsgOpaqueData|null|undefined} quotedMsg + * @memberof proto.MsgRowOpaqueData + * @instance + */ + MsgRowOpaqueData.prototype.quotedMsg = null; + + /** + * Creates a new MsgRowOpaqueData instance using the specified properties. + * @function create + * @memberof proto.MsgRowOpaqueData + * @static + * @param {proto.IMsgRowOpaqueData=} [properties] Properties to set + * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData instance + */ + MsgRowOpaqueData.create = function create(properties) { + return new MsgRowOpaqueData(properties); + }; + + /** + * Encodes the specified MsgRowOpaqueData message. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages. + * @function encode + * @memberof proto.MsgRowOpaqueData + * @static + * @param {proto.IMsgRowOpaqueData} message MsgRowOpaqueData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MsgRowOpaqueData.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.currentMsg != null && Object.hasOwnProperty.call(message, "currentMsg")) + $root.proto.MsgOpaqueData.encode(message.currentMsg, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.quotedMsg != null && Object.hasOwnProperty.call(message, "quotedMsg")) + $root.proto.MsgOpaqueData.encode(message.quotedMsg, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified MsgRowOpaqueData message, length delimited. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MsgRowOpaqueData + * @static + * @param {proto.IMsgRowOpaqueData} message MsgRowOpaqueData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MsgRowOpaqueData.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MsgRowOpaqueData message from the specified reader or buffer. + * @function decode + * @memberof proto.MsgRowOpaqueData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MsgRowOpaqueData.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MsgRowOpaqueData(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.currentMsg = $root.proto.MsgOpaqueData.decode(reader, reader.uint32()); + break; + case 2: + message.quotedMsg = $root.proto.MsgOpaqueData.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MsgRowOpaqueData message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MsgRowOpaqueData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MsgRowOpaqueData.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MsgRowOpaqueData message. + * @function verify + * @memberof proto.MsgRowOpaqueData + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MsgRowOpaqueData.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.currentMsg != null && message.hasOwnProperty("currentMsg")) { + var error = $root.proto.MsgOpaqueData.verify(message.currentMsg); + if (error) + return "currentMsg." + error; + } + if (message.quotedMsg != null && message.hasOwnProperty("quotedMsg")) { + var error = $root.proto.MsgOpaqueData.verify(message.quotedMsg); + if (error) + return "quotedMsg." + error; + } + return null; + }; + + /** + * Creates a MsgRowOpaqueData message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MsgRowOpaqueData + * @static + * @param {Object.} object Plain object + * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData + */ + MsgRowOpaqueData.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MsgRowOpaqueData) + return object; + var message = new $root.proto.MsgRowOpaqueData(); + if (object.currentMsg != null) { + if (typeof object.currentMsg !== "object") + throw TypeError(".proto.MsgRowOpaqueData.currentMsg: object expected"); + message.currentMsg = $root.proto.MsgOpaqueData.fromObject(object.currentMsg); + } + if (object.quotedMsg != null) { + if (typeof object.quotedMsg !== "object") + throw TypeError(".proto.MsgRowOpaqueData.quotedMsg: object expected"); + message.quotedMsg = $root.proto.MsgOpaqueData.fromObject(object.quotedMsg); + } + return message; + }; + + /** + * Creates a plain object from a MsgRowOpaqueData message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MsgRowOpaqueData + * @static + * @param {proto.MsgRowOpaqueData} message MsgRowOpaqueData + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MsgRowOpaqueData.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.currentMsg = null; + object.quotedMsg = null; + } + if (message.currentMsg != null && message.hasOwnProperty("currentMsg")) + object.currentMsg = $root.proto.MsgOpaqueData.toObject(message.currentMsg, options); + if (message.quotedMsg != null && message.hasOwnProperty("quotedMsg")) + object.quotedMsg = $root.proto.MsgOpaqueData.toObject(message.quotedMsg, options); + return object; + }; + + /** + * Converts this MsgRowOpaqueData to JSON. + * @function toJSON + * @memberof proto.MsgRowOpaqueData + * @instance + * @returns {Object.} JSON object + */ + MsgRowOpaqueData.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MsgRowOpaqueData; + })(); + + proto.Pushname = (function() { + + /** + * Properties of a Pushname. + * @memberof proto + * @interface IPushname + * @property {string|null} [id] Pushname id + * @property {string|null} [pushname] Pushname pushname + */ + + /** + * Constructs a new Pushname. + * @memberof proto + * @classdesc Represents a Pushname. + * @implements IPushname + * @constructor + * @param {proto.IPushname=} [properties] Properties to set + */ + function Pushname(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Pushname id. + * @member {string} id + * @memberof proto.Pushname + * @instance + */ + Pushname.prototype.id = ""; + + /** + * Pushname pushname. + * @member {string} pushname + * @memberof proto.Pushname + * @instance + */ + Pushname.prototype.pushname = ""; + + /** + * Creates a new Pushname instance using the specified properties. + * @function create + * @memberof proto.Pushname + * @static + * @param {proto.IPushname=} [properties] Properties to set + * @returns {proto.Pushname} Pushname instance + */ + Pushname.create = function create(properties) { + return new Pushname(properties); + }; + + /** + * Encodes the specified Pushname message. Does not implicitly {@link proto.Pushname.verify|verify} messages. + * @function encode + * @memberof proto.Pushname + * @static + * @param {proto.IPushname} message Pushname message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Pushname.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); + if (message.pushname != null && Object.hasOwnProperty.call(message, "pushname")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.pushname); + return writer; + }; + + /** + * Encodes the specified Pushname message, length delimited. Does not implicitly {@link proto.Pushname.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Pushname + * @static + * @param {proto.IPushname} message Pushname message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Pushname.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Pushname message from the specified reader or buffer. + * @function decode + * @memberof proto.Pushname + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Pushname} Pushname + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Pushname.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Pushname(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.pushname = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Pushname message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Pushname + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Pushname} Pushname + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Pushname.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Pushname message. + * @function verify + * @memberof proto.Pushname + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Pushname.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.pushname != null && message.hasOwnProperty("pushname")) + if (!$util.isString(message.pushname)) + return "pushname: string expected"; + return null; + }; + + /** + * Creates a Pushname message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Pushname + * @static + * @param {Object.} object Plain object + * @returns {proto.Pushname} Pushname + */ + Pushname.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Pushname) + return object; + var message = new $root.proto.Pushname(); + if (object.id != null) + message.id = String(object.id); + if (object.pushname != null) + message.pushname = String(object.pushname); + return message; + }; + + /** + * Creates a plain object from a Pushname message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Pushname + * @static + * @param {proto.Pushname} message Pushname + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Pushname.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.id = ""; + object.pushname = ""; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.pushname != null && message.hasOwnProperty("pushname")) + object.pushname = message.pushname; + return object; + }; + + /** + * Converts this Pushname to JSON. + * @function toJSON + * @memberof proto.Pushname + * @instance + * @returns {Object.} JSON object + */ + Pushname.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Pushname; + })(); + + proto.HistorySyncMsg = (function() { + + /** + * Properties of a HistorySyncMsg. + * @memberof proto + * @interface IHistorySyncMsg + * @property {proto.IWebMessageInfo|null} [message] HistorySyncMsg message + * @property {number|Long|null} [msgOrderId] HistorySyncMsg msgOrderId + */ + + /** + * Constructs a new HistorySyncMsg. + * @memberof proto + * @classdesc Represents a HistorySyncMsg. + * @implements IHistorySyncMsg + * @constructor + * @param {proto.IHistorySyncMsg=} [properties] Properties to set + */ + function HistorySyncMsg(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HistorySyncMsg message. + * @member {proto.IWebMessageInfo|null|undefined} message + * @memberof proto.HistorySyncMsg + * @instance + */ + HistorySyncMsg.prototype.message = null; + + /** + * HistorySyncMsg msgOrderId. + * @member {number|Long} msgOrderId + * @memberof proto.HistorySyncMsg + * @instance + */ + HistorySyncMsg.prototype.msgOrderId = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Creates a new HistorySyncMsg instance using the specified properties. + * @function create + * @memberof proto.HistorySyncMsg + * @static + * @param {proto.IHistorySyncMsg=} [properties] Properties to set + * @returns {proto.HistorySyncMsg} HistorySyncMsg instance + */ + HistorySyncMsg.create = function create(properties) { + return new HistorySyncMsg(properties); + }; + + /** + * Encodes the specified HistorySyncMsg message. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages. + * @function encode + * @memberof proto.HistorySyncMsg + * @static + * @param {proto.IHistorySyncMsg} message HistorySyncMsg message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HistorySyncMsg.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.message != null && Object.hasOwnProperty.call(message, "message")) + $root.proto.WebMessageInfo.encode(message.message, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.msgOrderId != null && Object.hasOwnProperty.call(message, "msgOrderId")) + writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.msgOrderId); + return writer; + }; + + /** + * Encodes the specified HistorySyncMsg message, length delimited. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HistorySyncMsg + * @static + * @param {proto.IHistorySyncMsg} message HistorySyncMsg message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HistorySyncMsg.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HistorySyncMsg message from the specified reader or buffer. + * @function decode + * @memberof proto.HistorySyncMsg + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HistorySyncMsg} HistorySyncMsg + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HistorySyncMsg.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HistorySyncMsg(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.message = $root.proto.WebMessageInfo.decode(reader, reader.uint32()); + break; + case 2: + message.msgOrderId = reader.uint64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HistorySyncMsg message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HistorySyncMsg + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HistorySyncMsg} HistorySyncMsg + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HistorySyncMsg.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HistorySyncMsg message. + * @function verify + * @memberof proto.HistorySyncMsg + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HistorySyncMsg.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.message != null && message.hasOwnProperty("message")) { + var error = $root.proto.WebMessageInfo.verify(message.message); + if (error) + return "message." + error; + } + if (message.msgOrderId != null && message.hasOwnProperty("msgOrderId")) + if (!$util.isInteger(message.msgOrderId) && !(message.msgOrderId && $util.isInteger(message.msgOrderId.low) && $util.isInteger(message.msgOrderId.high))) + return "msgOrderId: integer|Long expected"; + return null; + }; + + /** + * Creates a HistorySyncMsg message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HistorySyncMsg + * @static + * @param {Object.} object Plain object + * @returns {proto.HistorySyncMsg} HistorySyncMsg + */ + HistorySyncMsg.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HistorySyncMsg) + return object; + var message = new $root.proto.HistorySyncMsg(); + if (object.message != null) { + if (typeof object.message !== "object") + throw TypeError(".proto.HistorySyncMsg.message: object expected"); + message.message = $root.proto.WebMessageInfo.fromObject(object.message); + } + if (object.msgOrderId != null) + if ($util.Long) + (message.msgOrderId = $util.Long.fromValue(object.msgOrderId)).unsigned = true; + else if (typeof object.msgOrderId === "string") + message.msgOrderId = parseInt(object.msgOrderId, 10); + else if (typeof object.msgOrderId === "number") + message.msgOrderId = object.msgOrderId; + else if (typeof object.msgOrderId === "object") + message.msgOrderId = new $util.LongBits(object.msgOrderId.low >>> 0, object.msgOrderId.high >>> 0).toNumber(true); + return message; + }; + + /** + * Creates a plain object from a HistorySyncMsg message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HistorySyncMsg + * @static + * @param {proto.HistorySyncMsg} message HistorySyncMsg + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HistorySyncMsg.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.message = null; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.msgOrderId = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.msgOrderId = options.longs === String ? "0" : 0; + } + if (message.message != null && message.hasOwnProperty("message")) + object.message = $root.proto.WebMessageInfo.toObject(message.message, options); + if (message.msgOrderId != null && message.hasOwnProperty("msgOrderId")) + if (typeof message.msgOrderId === "number") + object.msgOrderId = options.longs === String ? String(message.msgOrderId) : message.msgOrderId; + else + object.msgOrderId = options.longs === String ? $util.Long.prototype.toString.call(message.msgOrderId) : options.longs === Number ? new $util.LongBits(message.msgOrderId.low >>> 0, message.msgOrderId.high >>> 0).toNumber(true) : message.msgOrderId; + return object; + }; + + /** + * Converts this HistorySyncMsg to JSON. + * @function toJSON + * @memberof proto.HistorySyncMsg + * @instance + * @returns {Object.} JSON object + */ + HistorySyncMsg.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HistorySyncMsg; + })(); + + proto.Conversation = (function() { + + /** + * Properties of a Conversation. + * @memberof proto + * @interface IConversation + * @property {string} id Conversation id + * @property {Array.|null} [messages] Conversation messages + * @property {string|null} [newJid] Conversation newJid + * @property {string|null} [oldJid] Conversation oldJid + * @property {number|Long|null} [lastMsgTimestamp] Conversation lastMsgTimestamp + * @property {number|null} [unreadCount] Conversation unreadCount + * @property {boolean|null} [readOnly] Conversation readOnly + * @property {boolean|null} [endOfHistoryTransfer] Conversation endOfHistoryTransfer + * @property {number|null} [ephemeralExpiration] Conversation ephemeralExpiration + * @property {number|Long|null} [ephemeralSettingTimestamp] Conversation ephemeralSettingTimestamp + * @property {proto.Conversation.ConversationEndOfHistoryTransferType|null} [endOfHistoryTransferType] Conversation endOfHistoryTransferType + * @property {number|Long|null} [conversationTimestamp] Conversation conversationTimestamp + * @property {string|null} [name] Conversation name + * @property {string|null} [pHash] Conversation pHash + * @property {boolean|null} [notSpam] Conversation notSpam + */ + + /** + * Constructs a new Conversation. + * @memberof proto + * @classdesc Represents a Conversation. + * @implements IConversation + * @constructor + * @param {proto.IConversation=} [properties] Properties to set + */ + function Conversation(properties) { + this.messages = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Conversation id. + * @member {string} id + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.id = ""; + + /** + * Conversation messages. + * @member {Array.} messages + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.messages = $util.emptyArray; + + /** + * Conversation newJid. + * @member {string} newJid + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.newJid = ""; + + /** + * Conversation oldJid. + * @member {string} oldJid + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.oldJid = ""; + + /** + * Conversation lastMsgTimestamp. + * @member {number|Long} lastMsgTimestamp + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.lastMsgTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Conversation unreadCount. + * @member {number} unreadCount + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.unreadCount = 0; + + /** + * Conversation readOnly. + * @member {boolean} readOnly + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.readOnly = false; + + /** + * Conversation endOfHistoryTransfer. + * @member {boolean} endOfHistoryTransfer + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.endOfHistoryTransfer = false; + + /** + * Conversation ephemeralExpiration. + * @member {number} ephemeralExpiration + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.ephemeralExpiration = 0; + + /** + * Conversation ephemeralSettingTimestamp. + * @member {number|Long} ephemeralSettingTimestamp + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.ephemeralSettingTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Conversation endOfHistoryTransferType. + * @member {proto.Conversation.ConversationEndOfHistoryTransferType} endOfHistoryTransferType + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.endOfHistoryTransferType = 0; + + /** + * Conversation conversationTimestamp. + * @member {number|Long} conversationTimestamp + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.conversationTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Conversation name. + * @member {string} name + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.name = ""; + + /** + * Conversation pHash. + * @member {string} pHash + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.pHash = ""; + + /** + * Conversation notSpam. + * @member {boolean} notSpam + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.notSpam = false; + + /** + * Creates a new Conversation instance using the specified properties. + * @function create + * @memberof proto.Conversation + * @static + * @param {proto.IConversation=} [properties] Properties to set + * @returns {proto.Conversation} Conversation instance + */ + Conversation.create = function create(properties) { + return new Conversation(properties); + }; + + /** + * Encodes the specified Conversation message. Does not implicitly {@link proto.Conversation.verify|verify} messages. + * @function encode + * @memberof proto.Conversation + * @static + * @param {proto.IConversation} message Conversation message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Conversation.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); + if (message.messages != null && message.messages.length) + for (var i = 0; i < message.messages.length; ++i) + $root.proto.HistorySyncMsg.encode(message.messages[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.newJid != null && Object.hasOwnProperty.call(message, "newJid")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.newJid); + if (message.oldJid != null && Object.hasOwnProperty.call(message, "oldJid")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.oldJid); + if (message.lastMsgTimestamp != null && Object.hasOwnProperty.call(message, "lastMsgTimestamp")) + writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.lastMsgTimestamp); + if (message.unreadCount != null && Object.hasOwnProperty.call(message, "unreadCount")) + writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.unreadCount); + if (message.readOnly != null && Object.hasOwnProperty.call(message, "readOnly")) + writer.uint32(/* id 7, wireType 0 =*/56).bool(message.readOnly); + if (message.endOfHistoryTransfer != null && Object.hasOwnProperty.call(message, "endOfHistoryTransfer")) + writer.uint32(/* id 8, wireType 0 =*/64).bool(message.endOfHistoryTransfer); + if (message.ephemeralExpiration != null && Object.hasOwnProperty.call(message, "ephemeralExpiration")) + writer.uint32(/* id 9, wireType 0 =*/72).uint32(message.ephemeralExpiration); + if (message.ephemeralSettingTimestamp != null && Object.hasOwnProperty.call(message, "ephemeralSettingTimestamp")) + writer.uint32(/* id 10, wireType 0 =*/80).int64(message.ephemeralSettingTimestamp); + if (message.endOfHistoryTransferType != null && Object.hasOwnProperty.call(message, "endOfHistoryTransferType")) + writer.uint32(/* id 11, wireType 0 =*/88).int32(message.endOfHistoryTransferType); + if (message.conversationTimestamp != null && Object.hasOwnProperty.call(message, "conversationTimestamp")) + writer.uint32(/* id 12, wireType 0 =*/96).uint64(message.conversationTimestamp); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 13, wireType 2 =*/106).string(message.name); + if (message.pHash != null && Object.hasOwnProperty.call(message, "pHash")) + writer.uint32(/* id 14, wireType 2 =*/114).string(message.pHash); + if (message.notSpam != null && Object.hasOwnProperty.call(message, "notSpam")) + writer.uint32(/* id 15, wireType 0 =*/120).bool(message.notSpam); + return writer; + }; + + /** + * Encodes the specified Conversation message, length delimited. Does not implicitly {@link proto.Conversation.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Conversation + * @static + * @param {proto.IConversation} message Conversation message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Conversation.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Conversation message from the specified reader or buffer. + * @function decode + * @memberof proto.Conversation + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Conversation} Conversation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Conversation.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Conversation(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + if (!(message.messages && message.messages.length)) + message.messages = []; + message.messages.push($root.proto.HistorySyncMsg.decode(reader, reader.uint32())); + break; + case 3: + message.newJid = reader.string(); + break; + case 4: + message.oldJid = reader.string(); + break; + case 5: + message.lastMsgTimestamp = reader.uint64(); + break; + case 6: + message.unreadCount = reader.uint32(); + break; + case 7: + message.readOnly = reader.bool(); + break; + case 8: + message.endOfHistoryTransfer = reader.bool(); + break; + case 9: + message.ephemeralExpiration = reader.uint32(); + break; + case 10: + message.ephemeralSettingTimestamp = reader.int64(); + break; + case 11: + message.endOfHistoryTransferType = reader.int32(); + break; + case 12: + message.conversationTimestamp = reader.uint64(); + break; + case 13: + message.name = reader.string(); + break; + case 14: + message.pHash = reader.string(); + break; + case 15: + message.notSpam = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + if (!message.hasOwnProperty("id")) + throw $util.ProtocolError("missing required 'id'", { instance: message }); + return message; + }; + + /** + * Decodes a Conversation message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Conversation + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Conversation} Conversation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Conversation.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Conversation message. + * @function verify + * @memberof proto.Conversation + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Conversation.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.messages != null && message.hasOwnProperty("messages")) { + if (!Array.isArray(message.messages)) + return "messages: array expected"; + for (var i = 0; i < message.messages.length; ++i) { + var error = $root.proto.HistorySyncMsg.verify(message.messages[i]); + if (error) + return "messages." + error; + } + } + if (message.newJid != null && message.hasOwnProperty("newJid")) + if (!$util.isString(message.newJid)) + return "newJid: string expected"; + if (message.oldJid != null && message.hasOwnProperty("oldJid")) + if (!$util.isString(message.oldJid)) + return "oldJid: string expected"; + if (message.lastMsgTimestamp != null && message.hasOwnProperty("lastMsgTimestamp")) + if (!$util.isInteger(message.lastMsgTimestamp) && !(message.lastMsgTimestamp && $util.isInteger(message.lastMsgTimestamp.low) && $util.isInteger(message.lastMsgTimestamp.high))) + return "lastMsgTimestamp: integer|Long expected"; + if (message.unreadCount != null && message.hasOwnProperty("unreadCount")) + if (!$util.isInteger(message.unreadCount)) + return "unreadCount: integer expected"; + if (message.readOnly != null && message.hasOwnProperty("readOnly")) + if (typeof message.readOnly !== "boolean") + return "readOnly: boolean expected"; + if (message.endOfHistoryTransfer != null && message.hasOwnProperty("endOfHistoryTransfer")) + if (typeof message.endOfHistoryTransfer !== "boolean") + return "endOfHistoryTransfer: boolean expected"; + if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration")) + if (!$util.isInteger(message.ephemeralExpiration)) + return "ephemeralExpiration: integer expected"; + if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp")) + if (!$util.isInteger(message.ephemeralSettingTimestamp) && !(message.ephemeralSettingTimestamp && $util.isInteger(message.ephemeralSettingTimestamp.low) && $util.isInteger(message.ephemeralSettingTimestamp.high))) + return "ephemeralSettingTimestamp: integer|Long expected"; + if (message.endOfHistoryTransferType != null && message.hasOwnProperty("endOfHistoryTransferType")) + switch (message.endOfHistoryTransferType) { + default: + return "endOfHistoryTransferType: enum value expected"; + case 0: + case 1: + break; + } + if (message.conversationTimestamp != null && message.hasOwnProperty("conversationTimestamp")) + if (!$util.isInteger(message.conversationTimestamp) && !(message.conversationTimestamp && $util.isInteger(message.conversationTimestamp.low) && $util.isInteger(message.conversationTimestamp.high))) + return "conversationTimestamp: integer|Long expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + if (message.pHash != null && message.hasOwnProperty("pHash")) + if (!$util.isString(message.pHash)) + return "pHash: string expected"; + if (message.notSpam != null && message.hasOwnProperty("notSpam")) + if (typeof message.notSpam !== "boolean") + return "notSpam: boolean expected"; + return null; + }; + + /** + * Creates a Conversation message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Conversation + * @static + * @param {Object.} object Plain object + * @returns {proto.Conversation} Conversation + */ + Conversation.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Conversation) + return object; + var message = new $root.proto.Conversation(); + if (object.id != null) + message.id = String(object.id); + if (object.messages) { + if (!Array.isArray(object.messages)) + throw TypeError(".proto.Conversation.messages: array expected"); + message.messages = []; + for (var i = 0; i < object.messages.length; ++i) { + if (typeof object.messages[i] !== "object") + throw TypeError(".proto.Conversation.messages: object expected"); + message.messages[i] = $root.proto.HistorySyncMsg.fromObject(object.messages[i]); + } + } + if (object.newJid != null) + message.newJid = String(object.newJid); + if (object.oldJid != null) + message.oldJid = String(object.oldJid); + if (object.lastMsgTimestamp != null) + if ($util.Long) + (message.lastMsgTimestamp = $util.Long.fromValue(object.lastMsgTimestamp)).unsigned = true; + else if (typeof object.lastMsgTimestamp === "string") + message.lastMsgTimestamp = parseInt(object.lastMsgTimestamp, 10); + else if (typeof object.lastMsgTimestamp === "number") + message.lastMsgTimestamp = object.lastMsgTimestamp; + else if (typeof object.lastMsgTimestamp === "object") + message.lastMsgTimestamp = new $util.LongBits(object.lastMsgTimestamp.low >>> 0, object.lastMsgTimestamp.high >>> 0).toNumber(true); + if (object.unreadCount != null) + message.unreadCount = object.unreadCount >>> 0; + if (object.readOnly != null) + message.readOnly = Boolean(object.readOnly); + if (object.endOfHistoryTransfer != null) + message.endOfHistoryTransfer = Boolean(object.endOfHistoryTransfer); + if (object.ephemeralExpiration != null) + message.ephemeralExpiration = object.ephemeralExpiration >>> 0; + if (object.ephemeralSettingTimestamp != null) + if ($util.Long) + (message.ephemeralSettingTimestamp = $util.Long.fromValue(object.ephemeralSettingTimestamp)).unsigned = false; + else if (typeof object.ephemeralSettingTimestamp === "string") + message.ephemeralSettingTimestamp = parseInt(object.ephemeralSettingTimestamp, 10); + else if (typeof object.ephemeralSettingTimestamp === "number") + message.ephemeralSettingTimestamp = object.ephemeralSettingTimestamp; + else if (typeof object.ephemeralSettingTimestamp === "object") + message.ephemeralSettingTimestamp = new $util.LongBits(object.ephemeralSettingTimestamp.low >>> 0, object.ephemeralSettingTimestamp.high >>> 0).toNumber(); + switch (object.endOfHistoryTransferType) { + case "COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY": + case 0: + message.endOfHistoryTransferType = 0; + break; + case "COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY": + case 1: + message.endOfHistoryTransferType = 1; + break; + } + if (object.conversationTimestamp != null) + if ($util.Long) + (message.conversationTimestamp = $util.Long.fromValue(object.conversationTimestamp)).unsigned = true; + else if (typeof object.conversationTimestamp === "string") + message.conversationTimestamp = parseInt(object.conversationTimestamp, 10); + else if (typeof object.conversationTimestamp === "number") + message.conversationTimestamp = object.conversationTimestamp; + else if (typeof object.conversationTimestamp === "object") + message.conversationTimestamp = new $util.LongBits(object.conversationTimestamp.low >>> 0, object.conversationTimestamp.high >>> 0).toNumber(true); + if (object.name != null) + message.name = String(object.name); + if (object.pHash != null) + message.pHash = String(object.pHash); + if (object.notSpam != null) + message.notSpam = Boolean(object.notSpam); + return message; + }; + + /** + * Creates a plain object from a Conversation message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Conversation + * @static + * @param {proto.Conversation} message Conversation + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Conversation.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.messages = []; + if (options.defaults) { + object.id = ""; + object.newJid = ""; + object.oldJid = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.lastMsgTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.lastMsgTimestamp = options.longs === String ? "0" : 0; + object.unreadCount = 0; + object.readOnly = false; + object.endOfHistoryTransfer = false; + object.ephemeralExpiration = 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.ephemeralSettingTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.ephemeralSettingTimestamp = options.longs === String ? "0" : 0; + object.endOfHistoryTransferType = options.enums === String ? "COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.conversationTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.conversationTimestamp = options.longs === String ? "0" : 0; + object.name = ""; + object.pHash = ""; + object.notSpam = false; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.messages && message.messages.length) { + object.messages = []; + for (var j = 0; j < message.messages.length; ++j) + object.messages[j] = $root.proto.HistorySyncMsg.toObject(message.messages[j], options); + } + if (message.newJid != null && message.hasOwnProperty("newJid")) + object.newJid = message.newJid; + if (message.oldJid != null && message.hasOwnProperty("oldJid")) + object.oldJid = message.oldJid; + if (message.lastMsgTimestamp != null && message.hasOwnProperty("lastMsgTimestamp")) + if (typeof message.lastMsgTimestamp === "number") + object.lastMsgTimestamp = options.longs === String ? String(message.lastMsgTimestamp) : message.lastMsgTimestamp; + else + object.lastMsgTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.lastMsgTimestamp) : options.longs === Number ? new $util.LongBits(message.lastMsgTimestamp.low >>> 0, message.lastMsgTimestamp.high >>> 0).toNumber(true) : message.lastMsgTimestamp; + if (message.unreadCount != null && message.hasOwnProperty("unreadCount")) + object.unreadCount = message.unreadCount; + if (message.readOnly != null && message.hasOwnProperty("readOnly")) + object.readOnly = message.readOnly; + if (message.endOfHistoryTransfer != null && message.hasOwnProperty("endOfHistoryTransfer")) + object.endOfHistoryTransfer = message.endOfHistoryTransfer; + if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration")) + object.ephemeralExpiration = message.ephemeralExpiration; + if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp")) + if (typeof message.ephemeralSettingTimestamp === "number") + object.ephemeralSettingTimestamp = options.longs === String ? String(message.ephemeralSettingTimestamp) : message.ephemeralSettingTimestamp; + else + object.ephemeralSettingTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.ephemeralSettingTimestamp) : options.longs === Number ? new $util.LongBits(message.ephemeralSettingTimestamp.low >>> 0, message.ephemeralSettingTimestamp.high >>> 0).toNumber() : message.ephemeralSettingTimestamp; + if (message.endOfHistoryTransferType != null && message.hasOwnProperty("endOfHistoryTransferType")) + object.endOfHistoryTransferType = options.enums === String ? $root.proto.Conversation.ConversationEndOfHistoryTransferType[message.endOfHistoryTransferType] : message.endOfHistoryTransferType; + if (message.conversationTimestamp != null && message.hasOwnProperty("conversationTimestamp")) + if (typeof message.conversationTimestamp === "number") + object.conversationTimestamp = options.longs === String ? String(message.conversationTimestamp) : message.conversationTimestamp; + else + object.conversationTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.conversationTimestamp) : options.longs === Number ? new $util.LongBits(message.conversationTimestamp.low >>> 0, message.conversationTimestamp.high >>> 0).toNumber(true) : message.conversationTimestamp; + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.pHash != null && message.hasOwnProperty("pHash")) + object.pHash = message.pHash; + if (message.notSpam != null && message.hasOwnProperty("notSpam")) + object.notSpam = message.notSpam; + return object; + }; + + /** + * Converts this Conversation to JSON. + * @function toJSON + * @memberof proto.Conversation + * @instance + * @returns {Object.} JSON object + */ + Conversation.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * ConversationEndOfHistoryTransferType enum. + * @name proto.Conversation.ConversationEndOfHistoryTransferType + * @enum {number} + * @property {number} COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY=0 COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY value + * @property {number} COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY=1 COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY value + */ + Conversation.ConversationEndOfHistoryTransferType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY"] = 0; + values[valuesById[1] = "COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY"] = 1; + return values; + })(); + + return Conversation; + })(); + + proto.HistorySync = (function() { + + /** + * Properties of a HistorySync. + * @memberof proto + * @interface IHistorySync + * @property {proto.HistorySync.HistorySyncHistorySyncType} syncType HistorySync syncType + * @property {Array.|null} [conversations] HistorySync conversations + * @property {Array.|null} [statusV3Messages] HistorySync statusV3Messages + * @property {number|null} [chunkOrder] HistorySync chunkOrder + * @property {number|null} [progress] HistorySync progress + * @property {Array.|null} [pushnames] HistorySync pushnames + */ + + /** + * Constructs a new HistorySync. + * @memberof proto + * @classdesc Represents a HistorySync. + * @implements IHistorySync + * @constructor + * @param {proto.IHistorySync=} [properties] Properties to set + */ + function HistorySync(properties) { + this.conversations = []; + this.statusV3Messages = []; + this.pushnames = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HistorySync syncType. + * @member {proto.HistorySync.HistorySyncHistorySyncType} syncType + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.syncType = 0; + + /** + * HistorySync conversations. + * @member {Array.} conversations + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.conversations = $util.emptyArray; + + /** + * HistorySync statusV3Messages. + * @member {Array.} statusV3Messages + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.statusV3Messages = $util.emptyArray; + + /** + * HistorySync chunkOrder. + * @member {number} chunkOrder + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.chunkOrder = 0; + + /** + * HistorySync progress. + * @member {number} progress + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.progress = 0; + + /** + * HistorySync pushnames. + * @member {Array.} pushnames + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.pushnames = $util.emptyArray; + + /** + * Creates a new HistorySync instance using the specified properties. + * @function create + * @memberof proto.HistorySync + * @static + * @param {proto.IHistorySync=} [properties] Properties to set + * @returns {proto.HistorySync} HistorySync instance + */ + HistorySync.create = function create(properties) { + return new HistorySync(properties); + }; + + /** + * Encodes the specified HistorySync message. Does not implicitly {@link proto.HistorySync.verify|verify} messages. + * @function encode + * @memberof proto.HistorySync + * @static + * @param {proto.IHistorySync} message HistorySync message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HistorySync.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.syncType); + if (message.conversations != null && message.conversations.length) + for (var i = 0; i < message.conversations.length; ++i) + $root.proto.Conversation.encode(message.conversations[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.statusV3Messages != null && message.statusV3Messages.length) + for (var i = 0; i < message.statusV3Messages.length; ++i) + $root.proto.WebMessageInfo.encode(message.statusV3Messages[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.chunkOrder != null && Object.hasOwnProperty.call(message, "chunkOrder")) + writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.chunkOrder); + if (message.progress != null && Object.hasOwnProperty.call(message, "progress")) + writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.progress); + if (message.pushnames != null && message.pushnames.length) + for (var i = 0; i < message.pushnames.length; ++i) + $root.proto.Pushname.encode(message.pushnames[i], writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified HistorySync message, length delimited. Does not implicitly {@link proto.HistorySync.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HistorySync + * @static + * @param {proto.IHistorySync} message HistorySync message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HistorySync.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HistorySync message from the specified reader or buffer. + * @function decode + * @memberof proto.HistorySync + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HistorySync} HistorySync + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HistorySync.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HistorySync(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.syncType = reader.int32(); + break; + case 2: + if (!(message.conversations && message.conversations.length)) + message.conversations = []; + message.conversations.push($root.proto.Conversation.decode(reader, reader.uint32())); + break; + case 3: + if (!(message.statusV3Messages && message.statusV3Messages.length)) + message.statusV3Messages = []; + message.statusV3Messages.push($root.proto.WebMessageInfo.decode(reader, reader.uint32())); + break; + case 5: + message.chunkOrder = reader.uint32(); + break; + case 6: + message.progress = reader.uint32(); + break; + case 7: + if (!(message.pushnames && message.pushnames.length)) + message.pushnames = []; + message.pushnames.push($root.proto.Pushname.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + if (!message.hasOwnProperty("syncType")) + throw $util.ProtocolError("missing required 'syncType'", { instance: message }); + return message; + }; + + /** + * Decodes a HistorySync message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HistorySync + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HistorySync} HistorySync + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HistorySync.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HistorySync message. + * @function verify + * @memberof proto.HistorySync + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HistorySync.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + switch (message.syncType) { + default: + return "syncType: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + break; + } + if (message.conversations != null && message.hasOwnProperty("conversations")) { + if (!Array.isArray(message.conversations)) + return "conversations: array expected"; + for (var i = 0; i < message.conversations.length; ++i) { + var error = $root.proto.Conversation.verify(message.conversations[i]); + if (error) + return "conversations." + error; + } + } + if (message.statusV3Messages != null && message.hasOwnProperty("statusV3Messages")) { + if (!Array.isArray(message.statusV3Messages)) + return "statusV3Messages: array expected"; + for (var i = 0; i < message.statusV3Messages.length; ++i) { + var error = $root.proto.WebMessageInfo.verify(message.statusV3Messages[i]); + if (error) + return "statusV3Messages." + error; + } + } + if (message.chunkOrder != null && message.hasOwnProperty("chunkOrder")) + if (!$util.isInteger(message.chunkOrder)) + return "chunkOrder: integer expected"; + if (message.progress != null && message.hasOwnProperty("progress")) + if (!$util.isInteger(message.progress)) + return "progress: integer expected"; + if (message.pushnames != null && message.hasOwnProperty("pushnames")) { + if (!Array.isArray(message.pushnames)) + return "pushnames: array expected"; + for (var i = 0; i < message.pushnames.length; ++i) { + var error = $root.proto.Pushname.verify(message.pushnames[i]); + if (error) + return "pushnames." + error; + } + } + return null; + }; + + /** + * Creates a HistorySync message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HistorySync + * @static + * @param {Object.} object Plain object + * @returns {proto.HistorySync} HistorySync + */ + HistorySync.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HistorySync) + return object; + var message = new $root.proto.HistorySync(); + switch (object.syncType) { + case "INITIAL_BOOTSTRAP": + case 0: + message.syncType = 0; + break; + case "INITIAL_STATUS_V3": + case 1: + message.syncType = 1; + break; + case "FULL": + case 2: + message.syncType = 2; + break; + case "RECENT": + case 3: + message.syncType = 3; + break; + case "PUSH_NAME": + case 4: + message.syncType = 4; + break; + } + if (object.conversations) { + if (!Array.isArray(object.conversations)) + throw TypeError(".proto.HistorySync.conversations: array expected"); + message.conversations = []; + for (var i = 0; i < object.conversations.length; ++i) { + if (typeof object.conversations[i] !== "object") + throw TypeError(".proto.HistorySync.conversations: object expected"); + message.conversations[i] = $root.proto.Conversation.fromObject(object.conversations[i]); + } + } + if (object.statusV3Messages) { + if (!Array.isArray(object.statusV3Messages)) + throw TypeError(".proto.HistorySync.statusV3Messages: array expected"); + message.statusV3Messages = []; + for (var i = 0; i < object.statusV3Messages.length; ++i) { + if (typeof object.statusV3Messages[i] !== "object") + throw TypeError(".proto.HistorySync.statusV3Messages: object expected"); + message.statusV3Messages[i] = $root.proto.WebMessageInfo.fromObject(object.statusV3Messages[i]); + } + } + if (object.chunkOrder != null) + message.chunkOrder = object.chunkOrder >>> 0; + if (object.progress != null) + message.progress = object.progress >>> 0; + if (object.pushnames) { + if (!Array.isArray(object.pushnames)) + throw TypeError(".proto.HistorySync.pushnames: array expected"); + message.pushnames = []; + for (var i = 0; i < object.pushnames.length; ++i) { + if (typeof object.pushnames[i] !== "object") + throw TypeError(".proto.HistorySync.pushnames: object expected"); + message.pushnames[i] = $root.proto.Pushname.fromObject(object.pushnames[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a HistorySync message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HistorySync + * @static + * @param {proto.HistorySync} message HistorySync + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HistorySync.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.conversations = []; + object.statusV3Messages = []; + object.pushnames = []; + } + if (options.defaults) { + object.syncType = options.enums === String ? "INITIAL_BOOTSTRAP" : 0; + object.chunkOrder = 0; + object.progress = 0; + } + if (message.syncType != null && message.hasOwnProperty("syncType")) + object.syncType = options.enums === String ? $root.proto.HistorySync.HistorySyncHistorySyncType[message.syncType] : message.syncType; + if (message.conversations && message.conversations.length) { + object.conversations = []; + for (var j = 0; j < message.conversations.length; ++j) + object.conversations[j] = $root.proto.Conversation.toObject(message.conversations[j], options); + } + if (message.statusV3Messages && message.statusV3Messages.length) { + object.statusV3Messages = []; + for (var j = 0; j < message.statusV3Messages.length; ++j) + object.statusV3Messages[j] = $root.proto.WebMessageInfo.toObject(message.statusV3Messages[j], options); + } + if (message.chunkOrder != null && message.hasOwnProperty("chunkOrder")) + object.chunkOrder = message.chunkOrder; + if (message.progress != null && message.hasOwnProperty("progress")) + object.progress = message.progress; + if (message.pushnames && message.pushnames.length) { + object.pushnames = []; + for (var j = 0; j < message.pushnames.length; ++j) + object.pushnames[j] = $root.proto.Pushname.toObject(message.pushnames[j], options); + } + return object; + }; + + /** + * Converts this HistorySync to JSON. + * @function toJSON + * @memberof proto.HistorySync + * @instance + * @returns {Object.} JSON object + */ + HistorySync.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * HistorySyncHistorySyncType enum. + * @name proto.HistorySync.HistorySyncHistorySyncType + * @enum {number} + * @property {number} INITIAL_BOOTSTRAP=0 INITIAL_BOOTSTRAP value + * @property {number} INITIAL_STATUS_V3=1 INITIAL_STATUS_V3 value + * @property {number} FULL=2 FULL value + * @property {number} RECENT=3 RECENT value + * @property {number} PUSH_NAME=4 PUSH_NAME value + */ + HistorySync.HistorySyncHistorySyncType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "INITIAL_BOOTSTRAP"] = 0; + values[valuesById[1] = "INITIAL_STATUS_V3"] = 1; + values[valuesById[2] = "FULL"] = 2; + values[valuesById[3] = "RECENT"] = 3; + values[valuesById[4] = "PUSH_NAME"] = 4; + return values; + })(); + + return HistorySync; + })(); + + proto.EphemeralSetting = (function() { + + /** + * Properties of an EphemeralSetting. + * @memberof proto + * @interface IEphemeralSetting + * @property {number|null} [duration] EphemeralSetting duration + * @property {number|Long|null} [timestamp] EphemeralSetting timestamp + */ + + /** + * Constructs a new EphemeralSetting. + * @memberof proto + * @classdesc Represents an EphemeralSetting. + * @implements IEphemeralSetting + * @constructor + * @param {proto.IEphemeralSetting=} [properties] Properties to set + */ + function EphemeralSetting(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * EphemeralSetting duration. + * @member {number} duration + * @memberof proto.EphemeralSetting + * @instance + */ + EphemeralSetting.prototype.duration = 0; + + /** + * EphemeralSetting timestamp. + * @member {number|Long} timestamp + * @memberof proto.EphemeralSetting + * @instance + */ + EphemeralSetting.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new EphemeralSetting instance using the specified properties. + * @function create + * @memberof proto.EphemeralSetting + * @static + * @param {proto.IEphemeralSetting=} [properties] Properties to set + * @returns {proto.EphemeralSetting} EphemeralSetting instance + */ + EphemeralSetting.create = function create(properties) { + return new EphemeralSetting(properties); + }; + + /** + * Encodes the specified EphemeralSetting message. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. + * @function encode + * @memberof proto.EphemeralSetting + * @static + * @param {proto.IEphemeralSetting} message EphemeralSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + EphemeralSetting.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.duration != null && Object.hasOwnProperty.call(message, "duration")) + writer.uint32(/* id 1, wireType 5 =*/13).sfixed32(message.duration); + if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) + writer.uint32(/* id 2, wireType 1 =*/17).sfixed64(message.timestamp); + return writer; + }; + + /** + * Encodes the specified EphemeralSetting message, length delimited. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.EphemeralSetting + * @static + * @param {proto.IEphemeralSetting} message EphemeralSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + EphemeralSetting.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an EphemeralSetting message from the specified reader or buffer. + * @function decode + * @memberof proto.EphemeralSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.EphemeralSetting} EphemeralSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + EphemeralSetting.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.EphemeralSetting(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.duration = reader.sfixed32(); + break; + case 2: + message.timestamp = reader.sfixed64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an EphemeralSetting message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.EphemeralSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.EphemeralSetting} EphemeralSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + EphemeralSetting.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an EphemeralSetting message. + * @function verify + * @memberof proto.EphemeralSetting + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + EphemeralSetting.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.duration != null && message.hasOwnProperty("duration")) + if (!$util.isInteger(message.duration)) + return "duration: integer expected"; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) + return "timestamp: integer|Long expected"; + return null; + }; + + /** + * Creates an EphemeralSetting message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.EphemeralSetting + * @static + * @param {Object.} object Plain object + * @returns {proto.EphemeralSetting} EphemeralSetting + */ + EphemeralSetting.fromObject = function fromObject(object) { + if (object instanceof $root.proto.EphemeralSetting) + return object; + var message = new $root.proto.EphemeralSetting(); + if (object.duration != null) + message.duration = object.duration | 0; + if (object.timestamp != null) + if ($util.Long) + (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false; + else if (typeof object.timestamp === "string") + message.timestamp = parseInt(object.timestamp, 10); + else if (typeof object.timestamp === "number") + message.timestamp = object.timestamp; + else if (typeof object.timestamp === "object") + message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from an EphemeralSetting message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.EphemeralSetting + * @static + * @param {proto.EphemeralSetting} message EphemeralSetting + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + EphemeralSetting.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.duration = 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.timestamp = options.longs === String ? "0" : 0; + } + if (message.duration != null && message.hasOwnProperty("duration")) + object.duration = message.duration; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (typeof message.timestamp === "number") + object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; + else + object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp; + return object; + }; + + /** + * Converts this EphemeralSetting to JSON. + * @function toJSON + * @memberof proto.EphemeralSetting + * @instance + * @returns {Object.} JSON object + */ + EphemeralSetting.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return EphemeralSetting; + })(); + + proto.PaymentBackground = (function() { + + /** + * Properties of a PaymentBackground. + * @memberof proto + * @interface IPaymentBackground + * @property {string|null} [id] PaymentBackground id + * @property {string|null} [fileLength] PaymentBackground fileLength + * @property {number|null} [width] PaymentBackground width + * @property {number|null} [height] PaymentBackground height + * @property {string|null} [mimetype] PaymentBackground mimetype + * @property {number|null} [placeholderArgb] PaymentBackground placeholderArgb + * @property {number|null} [textArgb] PaymentBackground textArgb + * @property {number|null} [subtextArgb] PaymentBackground subtextArgb + */ + + /** + * Constructs a new PaymentBackground. + * @memberof proto + * @classdesc Represents a PaymentBackground. + * @implements IPaymentBackground + * @constructor + * @param {proto.IPaymentBackground=} [properties] Properties to set + */ + function PaymentBackground(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * PaymentBackground id. + * @member {string} id + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.id = ""; + + /** + * PaymentBackground fileLength. + * @member {string} fileLength + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.fileLength = ""; + + /** + * PaymentBackground width. + * @member {number} width + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.width = 0; + + /** + * PaymentBackground height. + * @member {number} height + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.height = 0; + + /** + * PaymentBackground mimetype. + * @member {string} mimetype + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.mimetype = ""; + + /** + * PaymentBackground placeholderArgb. + * @member {number} placeholderArgb + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.placeholderArgb = 0; + + /** + * PaymentBackground textArgb. + * @member {number} textArgb + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.textArgb = 0; + + /** + * PaymentBackground subtextArgb. + * @member {number} subtextArgb + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.subtextArgb = 0; + + /** + * Creates a new PaymentBackground instance using the specified properties. + * @function create + * @memberof proto.PaymentBackground + * @static + * @param {proto.IPaymentBackground=} [properties] Properties to set + * @returns {proto.PaymentBackground} PaymentBackground instance + */ + PaymentBackground.create = function create(properties) { + return new PaymentBackground(properties); + }; + + /** + * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @function encode + * @memberof proto.PaymentBackground + * @static + * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PaymentBackground.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); + if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.fileLength); + if (message.width != null && Object.hasOwnProperty.call(message, "width")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.width); + if (message.height != null && Object.hasOwnProperty.call(message, "height")) + writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.height); + if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.mimetype); + if (message.placeholderArgb != null && Object.hasOwnProperty.call(message, "placeholderArgb")) + writer.uint32(/* id 6, wireType 5 =*/53).fixed32(message.placeholderArgb); + if (message.textArgb != null && Object.hasOwnProperty.call(message, "textArgb")) + writer.uint32(/* id 7, wireType 5 =*/61).fixed32(message.textArgb); + if (message.subtextArgb != null && Object.hasOwnProperty.call(message, "subtextArgb")) + writer.uint32(/* id 8, wireType 5 =*/69).fixed32(message.subtextArgb); + return writer; + }; + + /** + * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.PaymentBackground + * @static + * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PaymentBackground.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a PaymentBackground message from the specified reader or buffer. + * @function decode + * @memberof proto.PaymentBackground + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.PaymentBackground} PaymentBackground + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PaymentBackground.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentBackground(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.fileLength = reader.string(); + break; + case 3: + message.width = reader.uint32(); + break; + case 4: + message.height = reader.uint32(); + break; + case 5: + message.mimetype = reader.string(); + break; + case 6: + message.placeholderArgb = reader.fixed32(); + break; + case 7: + message.textArgb = reader.fixed32(); + break; + case 8: + message.subtextArgb = reader.fixed32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.PaymentBackground + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.PaymentBackground} PaymentBackground + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PaymentBackground.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a PaymentBackground message. + * @function verify + * @memberof proto.PaymentBackground + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + PaymentBackground.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.fileLength != null && message.hasOwnProperty("fileLength")) + if (!$util.isString(message.fileLength)) + return "fileLength: string expected"; + if (message.width != null && message.hasOwnProperty("width")) + if (!$util.isInteger(message.width)) + return "width: integer expected"; + if (message.height != null && message.hasOwnProperty("height")) + if (!$util.isInteger(message.height)) + return "height: integer expected"; + if (message.mimetype != null && message.hasOwnProperty("mimetype")) + if (!$util.isString(message.mimetype)) + return "mimetype: string expected"; + if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) + if (!$util.isInteger(message.placeholderArgb)) + return "placeholderArgb: integer expected"; + if (message.textArgb != null && message.hasOwnProperty("textArgb")) + if (!$util.isInteger(message.textArgb)) + return "textArgb: integer expected"; + if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) + if (!$util.isInteger(message.subtextArgb)) + return "subtextArgb: integer expected"; + return null; + }; + + /** + * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.PaymentBackground + * @static + * @param {Object.} object Plain object + * @returns {proto.PaymentBackground} PaymentBackground + */ + PaymentBackground.fromObject = function fromObject(object) { + if (object instanceof $root.proto.PaymentBackground) + return object; + var message = new $root.proto.PaymentBackground(); + if (object.id != null) + message.id = String(object.id); + if (object.fileLength != null) + message.fileLength = String(object.fileLength); + if (object.width != null) + message.width = object.width >>> 0; + if (object.height != null) + message.height = object.height >>> 0; + if (object.mimetype != null) + message.mimetype = String(object.mimetype); + if (object.placeholderArgb != null) + message.placeholderArgb = object.placeholderArgb >>> 0; + if (object.textArgb != null) + message.textArgb = object.textArgb >>> 0; + if (object.subtextArgb != null) + message.subtextArgb = object.subtextArgb >>> 0; + return message; + }; + + /** + * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.PaymentBackground + * @static + * @param {proto.PaymentBackground} message PaymentBackground + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + PaymentBackground.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.id = ""; + object.fileLength = ""; + object.width = 0; + object.height = 0; + object.mimetype = ""; + object.placeholderArgb = 0; + object.textArgb = 0; + object.subtextArgb = 0; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.fileLength != null && message.hasOwnProperty("fileLength")) + object.fileLength = message.fileLength; + if (message.width != null && message.hasOwnProperty("width")) + object.width = message.width; + if (message.height != null && message.hasOwnProperty("height")) + object.height = message.height; + if (message.mimetype != null && message.hasOwnProperty("mimetype")) + object.mimetype = message.mimetype; + if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) + object.placeholderArgb = message.placeholderArgb; + if (message.textArgb != null && message.hasOwnProperty("textArgb")) + object.textArgb = message.textArgb; + if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) + object.subtextArgb = message.subtextArgb; + return object; + }; + + /** + * Converts this PaymentBackground to JSON. + * @function toJSON + * @memberof proto.PaymentBackground + * @instance + * @returns {Object.} JSON object + */ + PaymentBackground.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return PaymentBackground; + })(); + + proto.Money = (function() { + + /** + * Properties of a Money. + * @memberof proto + * @interface IMoney + * @property {number|Long|null} [value] Money value + * @property {number|null} [offset] Money offset + * @property {string|null} [currencyCode] Money currencyCode + */ + + /** + * Constructs a new Money. + * @memberof proto + * @classdesc Represents a Money. + * @implements IMoney + * @constructor + * @param {proto.IMoney=} [properties] Properties to set + */ + function Money(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Money value. + * @member {number|Long} value + * @memberof proto.Money + * @instance + */ + Money.prototype.value = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Money offset. + * @member {number} offset + * @memberof proto.Money + * @instance + */ + Money.prototype.offset = 0; + + /** + * Money currencyCode. + * @member {string} currencyCode + * @memberof proto.Money + * @instance + */ + Money.prototype.currencyCode = ""; + + /** + * Creates a new Money instance using the specified properties. + * @function create + * @memberof proto.Money + * @static + * @param {proto.IMoney=} [properties] Properties to set + * @returns {proto.Money} Money instance + */ + Money.create = function create(properties) { + return new Money(properties); + }; + + /** + * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. + * @function encode + * @memberof proto.Money + * @static + * @param {proto.IMoney} message Money message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Money.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.value != null && Object.hasOwnProperty.call(message, "value")) + writer.uint32(/* id 1, wireType 0 =*/8).int64(message.value); + if (message.offset != null && Object.hasOwnProperty.call(message, "offset")) + writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.offset); + if (message.currencyCode != null && Object.hasOwnProperty.call(message, "currencyCode")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.currencyCode); + return writer; + }; + + /** + * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Money + * @static + * @param {proto.IMoney} message Money message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Money.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Money message from the specified reader or buffer. + * @function decode + * @memberof proto.Money + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Money} Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Money.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Money(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.value = reader.int64(); + break; + case 2: + message.offset = reader.uint32(); + break; + case 3: + message.currencyCode = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Money message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Money + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Money} Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Money.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Money message. + * @function verify + * @memberof proto.Money + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Money.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.value != null && message.hasOwnProperty("value")) + if (!$util.isInteger(message.value) && !(message.value && $util.isInteger(message.value.low) && $util.isInteger(message.value.high))) + return "value: integer|Long expected"; + if (message.offset != null && message.hasOwnProperty("offset")) + if (!$util.isInteger(message.offset)) + return "offset: integer expected"; + if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) + if (!$util.isString(message.currencyCode)) + return "currencyCode: string expected"; + return null; + }; + + /** + * Creates a Money message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Money + * @static + * @param {Object.} object Plain object + * @returns {proto.Money} Money + */ + Money.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Money) + return object; + var message = new $root.proto.Money(); + if (object.value != null) + if ($util.Long) + (message.value = $util.Long.fromValue(object.value)).unsigned = false; + else if (typeof object.value === "string") + message.value = parseInt(object.value, 10); + else if (typeof object.value === "number") + message.value = object.value; + else if (typeof object.value === "object") + message.value = new $util.LongBits(object.value.low >>> 0, object.value.high >>> 0).toNumber(); + if (object.offset != null) + message.offset = object.offset >>> 0; + if (object.currencyCode != null) + message.currencyCode = String(object.currencyCode); + return message; + }; + + /** + * Creates a plain object from a Money message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Money + * @static + * @param {proto.Money} message Money + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Money.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.value = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.value = options.longs === String ? "0" : 0; + object.offset = 0; + object.currencyCode = ""; + } + if (message.value != null && message.hasOwnProperty("value")) + if (typeof message.value === "number") + object.value = options.longs === String ? String(message.value) : message.value; + else + object.value = options.longs === String ? $util.Long.prototype.toString.call(message.value) : options.longs === Number ? new $util.LongBits(message.value.low >>> 0, message.value.high >>> 0).toNumber() : message.value; + if (message.offset != null && message.hasOwnProperty("offset")) + object.offset = message.offset; + if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) + object.currencyCode = message.currencyCode; + return object; + }; + + /** + * Converts this Money to JSON. + * @function toJSON + * @memberof proto.Money + * @instance + * @returns {Object.} JSON object + */ + Money.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Money; })(); proto.HydratedQuickReplyButton = (function() { @@ -7630,6 +20998,615 @@ $root.proto = (function() { return InteractiveAnnotation; })(); + proto.DeviceListMetadata = (function() { + + /** + * Properties of a DeviceListMetadata. + * @memberof proto + * @interface IDeviceListMetadata + * @property {Uint8Array|null} [senderKeyHash] DeviceListMetadata senderKeyHash + * @property {number|Long|null} [senderTimestamp] DeviceListMetadata senderTimestamp + * @property {Array.|null} [senderKeyIndexes] DeviceListMetadata senderKeyIndexes + * @property {Uint8Array|null} [recipientKeyHash] DeviceListMetadata recipientKeyHash + * @property {number|Long|null} [recipientTimestamp] DeviceListMetadata recipientTimestamp + * @property {Array.|null} [recipientKeyIndexes] DeviceListMetadata recipientKeyIndexes + */ + + /** + * Constructs a new DeviceListMetadata. + * @memberof proto + * @classdesc Represents a DeviceListMetadata. + * @implements IDeviceListMetadata + * @constructor + * @param {proto.IDeviceListMetadata=} [properties] Properties to set + */ + function DeviceListMetadata(properties) { + this.senderKeyIndexes = []; + this.recipientKeyIndexes = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * DeviceListMetadata senderKeyHash. + * @member {Uint8Array} senderKeyHash + * @memberof proto.DeviceListMetadata + * @instance + */ + DeviceListMetadata.prototype.senderKeyHash = $util.newBuffer([]); + + /** + * DeviceListMetadata senderTimestamp. + * @member {number|Long} senderTimestamp + * @memberof proto.DeviceListMetadata + * @instance + */ + DeviceListMetadata.prototype.senderTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * DeviceListMetadata senderKeyIndexes. + * @member {Array.} senderKeyIndexes + * @memberof proto.DeviceListMetadata + * @instance + */ + DeviceListMetadata.prototype.senderKeyIndexes = $util.emptyArray; + + /** + * DeviceListMetadata recipientKeyHash. + * @member {Uint8Array} recipientKeyHash + * @memberof proto.DeviceListMetadata + * @instance + */ + DeviceListMetadata.prototype.recipientKeyHash = $util.newBuffer([]); + + /** + * DeviceListMetadata recipientTimestamp. + * @member {number|Long} recipientTimestamp + * @memberof proto.DeviceListMetadata + * @instance + */ + DeviceListMetadata.prototype.recipientTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * DeviceListMetadata recipientKeyIndexes. + * @member {Array.} recipientKeyIndexes + * @memberof proto.DeviceListMetadata + * @instance + */ + DeviceListMetadata.prototype.recipientKeyIndexes = $util.emptyArray; + + /** + * Creates a new DeviceListMetadata instance using the specified properties. + * @function create + * @memberof proto.DeviceListMetadata + * @static + * @param {proto.IDeviceListMetadata=} [properties] Properties to set + * @returns {proto.DeviceListMetadata} DeviceListMetadata instance + */ + DeviceListMetadata.create = function create(properties) { + return new DeviceListMetadata(properties); + }; + + /** + * Encodes the specified DeviceListMetadata message. Does not implicitly {@link proto.DeviceListMetadata.verify|verify} messages. + * @function encode + * @memberof proto.DeviceListMetadata + * @static + * @param {proto.IDeviceListMetadata} message DeviceListMetadata message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DeviceListMetadata.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.senderKeyHash != null && Object.hasOwnProperty.call(message, "senderKeyHash")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.senderKeyHash); + if (message.senderTimestamp != null && Object.hasOwnProperty.call(message, "senderTimestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.senderTimestamp); + if (message.senderKeyIndexes != null && message.senderKeyIndexes.length) { + writer.uint32(/* id 3, wireType 2 =*/26).fork(); + for (var i = 0; i < message.senderKeyIndexes.length; ++i) + writer.uint32(message.senderKeyIndexes[i]); + writer.ldelim(); + } + if (message.recipientKeyHash != null && Object.hasOwnProperty.call(message, "recipientKeyHash")) + writer.uint32(/* id 8, wireType 2 =*/66).bytes(message.recipientKeyHash); + if (message.recipientTimestamp != null && Object.hasOwnProperty.call(message, "recipientTimestamp")) + writer.uint32(/* id 9, wireType 0 =*/72).uint64(message.recipientTimestamp); + if (message.recipientKeyIndexes != null && message.recipientKeyIndexes.length) { + writer.uint32(/* id 10, wireType 2 =*/82).fork(); + for (var i = 0; i < message.recipientKeyIndexes.length; ++i) + writer.uint32(message.recipientKeyIndexes[i]); + writer.ldelim(); + } + return writer; + }; + + /** + * Encodes the specified DeviceListMetadata message, length delimited. Does not implicitly {@link proto.DeviceListMetadata.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.DeviceListMetadata + * @static + * @param {proto.IDeviceListMetadata} message DeviceListMetadata message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DeviceListMetadata.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a DeviceListMetadata message from the specified reader or buffer. + * @function decode + * @memberof proto.DeviceListMetadata + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.DeviceListMetadata} DeviceListMetadata + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DeviceListMetadata.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DeviceListMetadata(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.senderKeyHash = reader.bytes(); + break; + case 2: + message.senderTimestamp = reader.uint64(); + break; + case 3: + if (!(message.senderKeyIndexes && message.senderKeyIndexes.length)) + message.senderKeyIndexes = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.senderKeyIndexes.push(reader.uint32()); + } else + message.senderKeyIndexes.push(reader.uint32()); + break; + case 8: + message.recipientKeyHash = reader.bytes(); + break; + case 9: + message.recipientTimestamp = reader.uint64(); + break; + case 10: + if (!(message.recipientKeyIndexes && message.recipientKeyIndexes.length)) + message.recipientKeyIndexes = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.recipientKeyIndexes.push(reader.uint32()); + } else + message.recipientKeyIndexes.push(reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a DeviceListMetadata message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.DeviceListMetadata + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.DeviceListMetadata} DeviceListMetadata + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DeviceListMetadata.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a DeviceListMetadata message. + * @function verify + * @memberof proto.DeviceListMetadata + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + DeviceListMetadata.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.senderKeyHash != null && message.hasOwnProperty("senderKeyHash")) + if (!(message.senderKeyHash && typeof message.senderKeyHash.length === "number" || $util.isString(message.senderKeyHash))) + return "senderKeyHash: buffer expected"; + if (message.senderTimestamp != null && message.hasOwnProperty("senderTimestamp")) + if (!$util.isInteger(message.senderTimestamp) && !(message.senderTimestamp && $util.isInteger(message.senderTimestamp.low) && $util.isInteger(message.senderTimestamp.high))) + return "senderTimestamp: integer|Long expected"; + if (message.senderKeyIndexes != null && message.hasOwnProperty("senderKeyIndexes")) { + if (!Array.isArray(message.senderKeyIndexes)) + return "senderKeyIndexes: array expected"; + for (var i = 0; i < message.senderKeyIndexes.length; ++i) + if (!$util.isInteger(message.senderKeyIndexes[i])) + return "senderKeyIndexes: integer[] expected"; + } + if (message.recipientKeyHash != null && message.hasOwnProperty("recipientKeyHash")) + if (!(message.recipientKeyHash && typeof message.recipientKeyHash.length === "number" || $util.isString(message.recipientKeyHash))) + return "recipientKeyHash: buffer expected"; + if (message.recipientTimestamp != null && message.hasOwnProperty("recipientTimestamp")) + if (!$util.isInteger(message.recipientTimestamp) && !(message.recipientTimestamp && $util.isInteger(message.recipientTimestamp.low) && $util.isInteger(message.recipientTimestamp.high))) + return "recipientTimestamp: integer|Long expected"; + if (message.recipientKeyIndexes != null && message.hasOwnProperty("recipientKeyIndexes")) { + if (!Array.isArray(message.recipientKeyIndexes)) + return "recipientKeyIndexes: array expected"; + for (var i = 0; i < message.recipientKeyIndexes.length; ++i) + if (!$util.isInteger(message.recipientKeyIndexes[i])) + return "recipientKeyIndexes: integer[] expected"; + } + return null; + }; + + /** + * Creates a DeviceListMetadata message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.DeviceListMetadata + * @static + * @param {Object.} object Plain object + * @returns {proto.DeviceListMetadata} DeviceListMetadata + */ + DeviceListMetadata.fromObject = function fromObject(object) { + if (object instanceof $root.proto.DeviceListMetadata) + return object; + var message = new $root.proto.DeviceListMetadata(); + if (object.senderKeyHash != null) + if (typeof object.senderKeyHash === "string") + $util.base64.decode(object.senderKeyHash, message.senderKeyHash = $util.newBuffer($util.base64.length(object.senderKeyHash)), 0); + else if (object.senderKeyHash.length) + message.senderKeyHash = object.senderKeyHash; + if (object.senderTimestamp != null) + if ($util.Long) + (message.senderTimestamp = $util.Long.fromValue(object.senderTimestamp)).unsigned = true; + else if (typeof object.senderTimestamp === "string") + message.senderTimestamp = parseInt(object.senderTimestamp, 10); + else if (typeof object.senderTimestamp === "number") + message.senderTimestamp = object.senderTimestamp; + else if (typeof object.senderTimestamp === "object") + message.senderTimestamp = new $util.LongBits(object.senderTimestamp.low >>> 0, object.senderTimestamp.high >>> 0).toNumber(true); + if (object.senderKeyIndexes) { + if (!Array.isArray(object.senderKeyIndexes)) + throw TypeError(".proto.DeviceListMetadata.senderKeyIndexes: array expected"); + message.senderKeyIndexes = []; + for (var i = 0; i < object.senderKeyIndexes.length; ++i) + message.senderKeyIndexes[i] = object.senderKeyIndexes[i] >>> 0; + } + if (object.recipientKeyHash != null) + if (typeof object.recipientKeyHash === "string") + $util.base64.decode(object.recipientKeyHash, message.recipientKeyHash = $util.newBuffer($util.base64.length(object.recipientKeyHash)), 0); + else if (object.recipientKeyHash.length) + message.recipientKeyHash = object.recipientKeyHash; + if (object.recipientTimestamp != null) + if ($util.Long) + (message.recipientTimestamp = $util.Long.fromValue(object.recipientTimestamp)).unsigned = true; + else if (typeof object.recipientTimestamp === "string") + message.recipientTimestamp = parseInt(object.recipientTimestamp, 10); + else if (typeof object.recipientTimestamp === "number") + message.recipientTimestamp = object.recipientTimestamp; + else if (typeof object.recipientTimestamp === "object") + message.recipientTimestamp = new $util.LongBits(object.recipientTimestamp.low >>> 0, object.recipientTimestamp.high >>> 0).toNumber(true); + if (object.recipientKeyIndexes) { + if (!Array.isArray(object.recipientKeyIndexes)) + throw TypeError(".proto.DeviceListMetadata.recipientKeyIndexes: array expected"); + message.recipientKeyIndexes = []; + for (var i = 0; i < object.recipientKeyIndexes.length; ++i) + message.recipientKeyIndexes[i] = object.recipientKeyIndexes[i] >>> 0; + } + return message; + }; + + /** + * Creates a plain object from a DeviceListMetadata message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.DeviceListMetadata + * @static + * @param {proto.DeviceListMetadata} message DeviceListMetadata + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + DeviceListMetadata.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.senderKeyIndexes = []; + object.recipientKeyIndexes = []; + } + if (options.defaults) { + if (options.bytes === String) + object.senderKeyHash = ""; + else { + object.senderKeyHash = []; + if (options.bytes !== Array) + object.senderKeyHash = $util.newBuffer(object.senderKeyHash); + } + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.senderTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.senderTimestamp = options.longs === String ? "0" : 0; + if (options.bytes === String) + object.recipientKeyHash = ""; + else { + object.recipientKeyHash = []; + if (options.bytes !== Array) + object.recipientKeyHash = $util.newBuffer(object.recipientKeyHash); + } + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.recipientTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.recipientTimestamp = options.longs === String ? "0" : 0; + } + if (message.senderKeyHash != null && message.hasOwnProperty("senderKeyHash")) + object.senderKeyHash = options.bytes === String ? $util.base64.encode(message.senderKeyHash, 0, message.senderKeyHash.length) : options.bytes === Array ? Array.prototype.slice.call(message.senderKeyHash) : message.senderKeyHash; + if (message.senderTimestamp != null && message.hasOwnProperty("senderTimestamp")) + if (typeof message.senderTimestamp === "number") + object.senderTimestamp = options.longs === String ? String(message.senderTimestamp) : message.senderTimestamp; + else + object.senderTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.senderTimestamp) : options.longs === Number ? new $util.LongBits(message.senderTimestamp.low >>> 0, message.senderTimestamp.high >>> 0).toNumber(true) : message.senderTimestamp; + if (message.senderKeyIndexes && message.senderKeyIndexes.length) { + object.senderKeyIndexes = []; + for (var j = 0; j < message.senderKeyIndexes.length; ++j) + object.senderKeyIndexes[j] = message.senderKeyIndexes[j]; + } + if (message.recipientKeyHash != null && message.hasOwnProperty("recipientKeyHash")) + object.recipientKeyHash = options.bytes === String ? $util.base64.encode(message.recipientKeyHash, 0, message.recipientKeyHash.length) : options.bytes === Array ? Array.prototype.slice.call(message.recipientKeyHash) : message.recipientKeyHash; + if (message.recipientTimestamp != null && message.hasOwnProperty("recipientTimestamp")) + if (typeof message.recipientTimestamp === "number") + object.recipientTimestamp = options.longs === String ? String(message.recipientTimestamp) : message.recipientTimestamp; + else + object.recipientTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.recipientTimestamp) : options.longs === Number ? new $util.LongBits(message.recipientTimestamp.low >>> 0, message.recipientTimestamp.high >>> 0).toNumber(true) : message.recipientTimestamp; + if (message.recipientKeyIndexes && message.recipientKeyIndexes.length) { + object.recipientKeyIndexes = []; + for (var j = 0; j < message.recipientKeyIndexes.length; ++j) + object.recipientKeyIndexes[j] = message.recipientKeyIndexes[j]; + } + return object; + }; + + /** + * Converts this DeviceListMetadata to JSON. + * @function toJSON + * @memberof proto.DeviceListMetadata + * @instance + * @returns {Object.} JSON object + */ + DeviceListMetadata.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return DeviceListMetadata; + })(); + + proto.MessageContextInfo = (function() { + + /** + * Properties of a MessageContextInfo. + * @memberof proto + * @interface IMessageContextInfo + * @property {proto.IDeviceListMetadata|null} [deviceListMetadata] MessageContextInfo deviceListMetadata + * @property {number|null} [deviceListMetadataVersion] MessageContextInfo deviceListMetadataVersion + */ + + /** + * Constructs a new MessageContextInfo. + * @memberof proto + * @classdesc Represents a MessageContextInfo. + * @implements IMessageContextInfo + * @constructor + * @param {proto.IMessageContextInfo=} [properties] Properties to set + */ + function MessageContextInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MessageContextInfo deviceListMetadata. + * @member {proto.IDeviceListMetadata|null|undefined} deviceListMetadata + * @memberof proto.MessageContextInfo + * @instance + */ + MessageContextInfo.prototype.deviceListMetadata = null; + + /** + * MessageContextInfo deviceListMetadataVersion. + * @member {number} deviceListMetadataVersion + * @memberof proto.MessageContextInfo + * @instance + */ + MessageContextInfo.prototype.deviceListMetadataVersion = 0; + + /** + * Creates a new MessageContextInfo instance using the specified properties. + * @function create + * @memberof proto.MessageContextInfo + * @static + * @param {proto.IMessageContextInfo=} [properties] Properties to set + * @returns {proto.MessageContextInfo} MessageContextInfo instance + */ + MessageContextInfo.create = function create(properties) { + return new MessageContextInfo(properties); + }; + + /** + * Encodes the specified MessageContextInfo message. Does not implicitly {@link proto.MessageContextInfo.verify|verify} messages. + * @function encode + * @memberof proto.MessageContextInfo + * @static + * @param {proto.IMessageContextInfo} message MessageContextInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MessageContextInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.deviceListMetadata != null && Object.hasOwnProperty.call(message, "deviceListMetadata")) + $root.proto.DeviceListMetadata.encode(message.deviceListMetadata, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.deviceListMetadataVersion != null && Object.hasOwnProperty.call(message, "deviceListMetadataVersion")) + writer.uint32(/* id 2, wireType 0 =*/16).int32(message.deviceListMetadataVersion); + return writer; + }; + + /** + * Encodes the specified MessageContextInfo message, length delimited. Does not implicitly {@link proto.MessageContextInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MessageContextInfo + * @static + * @param {proto.IMessageContextInfo} message MessageContextInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MessageContextInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MessageContextInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.MessageContextInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MessageContextInfo} MessageContextInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MessageContextInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MessageContextInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.deviceListMetadata = $root.proto.DeviceListMetadata.decode(reader, reader.uint32()); + break; + case 2: + message.deviceListMetadataVersion = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MessageContextInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MessageContextInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MessageContextInfo} MessageContextInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MessageContextInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MessageContextInfo message. + * @function verify + * @memberof proto.MessageContextInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MessageContextInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.deviceListMetadata != null && message.hasOwnProperty("deviceListMetadata")) { + var error = $root.proto.DeviceListMetadata.verify(message.deviceListMetadata); + if (error) + return "deviceListMetadata." + error; + } + if (message.deviceListMetadataVersion != null && message.hasOwnProperty("deviceListMetadataVersion")) + if (!$util.isInteger(message.deviceListMetadataVersion)) + return "deviceListMetadataVersion: integer expected"; + return null; + }; + + /** + * Creates a MessageContextInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MessageContextInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.MessageContextInfo} MessageContextInfo + */ + MessageContextInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MessageContextInfo) + return object; + var message = new $root.proto.MessageContextInfo(); + if (object.deviceListMetadata != null) { + if (typeof object.deviceListMetadata !== "object") + throw TypeError(".proto.MessageContextInfo.deviceListMetadata: object expected"); + message.deviceListMetadata = $root.proto.DeviceListMetadata.fromObject(object.deviceListMetadata); + } + if (object.deviceListMetadataVersion != null) + message.deviceListMetadataVersion = object.deviceListMetadataVersion | 0; + return message; + }; + + /** + * Creates a plain object from a MessageContextInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MessageContextInfo + * @static + * @param {proto.MessageContextInfo} message MessageContextInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MessageContextInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.deviceListMetadata = null; + object.deviceListMetadataVersion = 0; + } + if (message.deviceListMetadata != null && message.hasOwnProperty("deviceListMetadata")) + object.deviceListMetadata = $root.proto.DeviceListMetadata.toObject(message.deviceListMetadata, options); + if (message.deviceListMetadataVersion != null && message.hasOwnProperty("deviceListMetadataVersion")) + object.deviceListMetadataVersion = message.deviceListMetadataVersion; + return object; + }; + + /** + * Converts this MessageContextInfo to JSON. + * @function toJSON + * @memberof proto.MessageContextInfo + * @instance + * @returns {Object.} JSON object + */ + MessageContextInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MessageContextInfo; + })(); + proto.AdReplyInfo = (function() { /** @@ -8356,6 +22333,9 @@ $root.proto = (function() { * @property {number|Long|null} [ephemeralSettingTimestamp] ContextInfo ephemeralSettingTimestamp * @property {Uint8Array|null} [ephemeralSharedSecret] ContextInfo ephemeralSharedSecret * @property {proto.IExternalAdReplyInfo|null} [externalAdReply] ContextInfo externalAdReply + * @property {string|null} [entryPointConversionSource] ContextInfo entryPointConversionSource + * @property {string|null} [entryPointConversionApp] ContextInfo entryPointConversionApp + * @property {number|null} [entryPointConversionDelaySeconds] ContextInfo entryPointConversionDelaySeconds */ /** @@ -8502,6 +22482,30 @@ $root.proto = (function() { */ ContextInfo.prototype.externalAdReply = null; + /** + * ContextInfo entryPointConversionSource. + * @member {string} entryPointConversionSource + * @memberof proto.ContextInfo + * @instance + */ + ContextInfo.prototype.entryPointConversionSource = ""; + + /** + * ContextInfo entryPointConversionApp. + * @member {string} entryPointConversionApp + * @memberof proto.ContextInfo + * @instance + */ + ContextInfo.prototype.entryPointConversionApp = ""; + + /** + * ContextInfo entryPointConversionDelaySeconds. + * @member {number} entryPointConversionDelaySeconds + * @memberof proto.ContextInfo + * @instance + */ + ContextInfo.prototype.entryPointConversionDelaySeconds = 0; + /** * Creates a new ContextInfo instance using the specified properties. * @function create @@ -8559,6 +22563,12 @@ $root.proto = (function() { writer.uint32(/* id 27, wireType 2 =*/218).bytes(message.ephemeralSharedSecret); if (message.externalAdReply != null && Object.hasOwnProperty.call(message, "externalAdReply")) $root.proto.ExternalAdReplyInfo.encode(message.externalAdReply, writer.uint32(/* id 28, wireType 2 =*/226).fork()).ldelim(); + if (message.entryPointConversionSource != null && Object.hasOwnProperty.call(message, "entryPointConversionSource")) + writer.uint32(/* id 29, wireType 2 =*/234).string(message.entryPointConversionSource); + if (message.entryPointConversionApp != null && Object.hasOwnProperty.call(message, "entryPointConversionApp")) + writer.uint32(/* id 30, wireType 2 =*/242).string(message.entryPointConversionApp); + if (message.entryPointConversionDelaySeconds != null && Object.hasOwnProperty.call(message, "entryPointConversionDelaySeconds")) + writer.uint32(/* id 31, wireType 0 =*/248).uint32(message.entryPointConversionDelaySeconds); return writer; }; @@ -8643,6 +22653,15 @@ $root.proto = (function() { case 28: message.externalAdReply = $root.proto.ExternalAdReplyInfo.decode(reader, reader.uint32()); break; + case 29: + message.entryPointConversionSource = reader.string(); + break; + case 30: + message.entryPointConversionApp = reader.string(); + break; + case 31: + message.entryPointConversionDelaySeconds = reader.uint32(); + break; default: reader.skipType(tag & 7); break; @@ -8738,6 +22757,15 @@ $root.proto = (function() { if (error) return "externalAdReply." + error; } + if (message.entryPointConversionSource != null && message.hasOwnProperty("entryPointConversionSource")) + if (!$util.isString(message.entryPointConversionSource)) + return "entryPointConversionSource: string expected"; + if (message.entryPointConversionApp != null && message.hasOwnProperty("entryPointConversionApp")) + if (!$util.isString(message.entryPointConversionApp)) + return "entryPointConversionApp: string expected"; + if (message.entryPointConversionDelaySeconds != null && message.hasOwnProperty("entryPointConversionDelaySeconds")) + if (!$util.isInteger(message.entryPointConversionDelaySeconds)) + return "entryPointConversionDelaySeconds: integer expected"; return null; }; @@ -8815,6 +22843,12 @@ $root.proto = (function() { throw TypeError(".proto.ContextInfo.externalAdReply: object expected"); message.externalAdReply = $root.proto.ExternalAdReplyInfo.fromObject(object.externalAdReply); } + if (object.entryPointConversionSource != null) + message.entryPointConversionSource = String(object.entryPointConversionSource); + if (object.entryPointConversionApp != null) + message.entryPointConversionApp = String(object.entryPointConversionApp); + if (object.entryPointConversionDelaySeconds != null) + message.entryPointConversionDelaySeconds = object.entryPointConversionDelaySeconds >>> 0; return message; }; @@ -8865,6 +22899,9 @@ $root.proto = (function() { object.ephemeralSharedSecret = $util.newBuffer(object.ephemeralSharedSecret); } object.externalAdReply = null; + object.entryPointConversionSource = ""; + object.entryPointConversionApp = ""; + object.entryPointConversionDelaySeconds = 0; } if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) object.stanzaId = message.stanzaId; @@ -8904,6 +22941,12 @@ $root.proto = (function() { object.ephemeralSharedSecret = options.bytes === String ? $util.base64.encode(message.ephemeralSharedSecret, 0, message.ephemeralSharedSecret.length) : options.bytes === Array ? Array.prototype.slice.call(message.ephemeralSharedSecret) : message.ephemeralSharedSecret; if (message.externalAdReply != null && message.hasOwnProperty("externalAdReply")) object.externalAdReply = $root.proto.ExternalAdReplyInfo.toObject(message.externalAdReply, options); + if (message.entryPointConversionSource != null && message.hasOwnProperty("entryPointConversionSource")) + object.entryPointConversionSource = message.entryPointConversionSource; + if (message.entryPointConversionApp != null && message.hasOwnProperty("entryPointConversionApp")) + object.entryPointConversionApp = message.entryPointConversionApp; + if (message.entryPointConversionDelaySeconds != null && message.hasOwnProperty("entryPointConversionDelaySeconds")) + object.entryPointConversionDelaySeconds = message.entryPointConversionDelaySeconds; return object; }; @@ -9168,6 +23211,9 @@ $root.proto = (function() { * @property {Uint8Array|null} [midQualityFileSha256] ImageMessage midQualityFileSha256 * @property {Uint8Array|null} [midQualityFileEncSha256] ImageMessage midQualityFileEncSha256 * @property {boolean|null} [viewOnce] ImageMessage viewOnce + * @property {string|null} [thumbnailDirectPath] ImageMessage thumbnailDirectPath + * @property {Uint8Array|null} [thumbnailSha256] ImageMessage thumbnailSha256 + * @property {Uint8Array|null} [thumbnailEncSha256] ImageMessage thumbnailEncSha256 */ /** @@ -9363,6 +23409,30 @@ $root.proto = (function() { */ ImageMessage.prototype.viewOnce = false; + /** + * ImageMessage thumbnailDirectPath. + * @member {string} thumbnailDirectPath + * @memberof proto.ImageMessage + * @instance + */ + ImageMessage.prototype.thumbnailDirectPath = ""; + + /** + * ImageMessage thumbnailSha256. + * @member {Uint8Array} thumbnailSha256 + * @memberof proto.ImageMessage + * @instance + */ + ImageMessage.prototype.thumbnailSha256 = $util.newBuffer([]); + + /** + * ImageMessage thumbnailEncSha256. + * @member {Uint8Array} thumbnailEncSha256 + * @memberof proto.ImageMessage + * @instance + */ + ImageMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]); + /** * Creates a new ImageMessage instance using the specified properties. * @function create @@ -9433,6 +23503,12 @@ $root.proto = (function() { writer.uint32(/* id 24, wireType 2 =*/194).bytes(message.midQualityFileEncSha256); if (message.viewOnce != null && Object.hasOwnProperty.call(message, "viewOnce")) writer.uint32(/* id 25, wireType 0 =*/200).bool(message.viewOnce); + if (message.thumbnailDirectPath != null && Object.hasOwnProperty.call(message, "thumbnailDirectPath")) + writer.uint32(/* id 26, wireType 2 =*/210).string(message.thumbnailDirectPath); + if (message.thumbnailSha256 != null && Object.hasOwnProperty.call(message, "thumbnailSha256")) + writer.uint32(/* id 27, wireType 2 =*/218).bytes(message.thumbnailSha256); + if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256")) + writer.uint32(/* id 28, wireType 2 =*/226).bytes(message.thumbnailEncSha256); return writer; }; @@ -9542,6 +23618,15 @@ $root.proto = (function() { case 25: message.viewOnce = reader.bool(); break; + case 26: + message.thumbnailDirectPath = reader.string(); + break; + case 27: + message.thumbnailSha256 = reader.bytes(); + break; + case 28: + message.thumbnailEncSha256 = reader.bytes(); + break; default: reader.skipType(tag & 7); break; @@ -9655,6 +23740,15 @@ $root.proto = (function() { if (message.viewOnce != null && message.hasOwnProperty("viewOnce")) if (typeof message.viewOnce !== "boolean") return "viewOnce: boolean expected"; + if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath")) + if (!$util.isString(message.thumbnailDirectPath)) + return "thumbnailDirectPath: string expected"; + if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256")) + if (!(message.thumbnailSha256 && typeof message.thumbnailSha256.length === "number" || $util.isString(message.thumbnailSha256))) + return "thumbnailSha256: buffer expected"; + if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) + if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256))) + return "thumbnailEncSha256: buffer expected"; return null; }; @@ -9768,6 +23862,18 @@ $root.proto = (function() { message.midQualityFileEncSha256 = object.midQualityFileEncSha256; if (object.viewOnce != null) message.viewOnce = Boolean(object.viewOnce); + if (object.thumbnailDirectPath != null) + message.thumbnailDirectPath = String(object.thumbnailDirectPath); + if (object.thumbnailSha256 != null) + if (typeof object.thumbnailSha256 === "string") + $util.base64.decode(object.thumbnailSha256, message.thumbnailSha256 = $util.newBuffer($util.base64.length(object.thumbnailSha256)), 0); + else if (object.thumbnailSha256.length) + message.thumbnailSha256 = object.thumbnailSha256; + if (object.thumbnailEncSha256 != null) + if (typeof object.thumbnailEncSha256 === "string") + $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0); + else if (object.thumbnailEncSha256.length) + message.thumbnailEncSha256 = object.thumbnailEncSha256; return message; }; @@ -9865,6 +23971,21 @@ $root.proto = (function() { object.midQualityFileEncSha256 = $util.newBuffer(object.midQualityFileEncSha256); } object.viewOnce = false; + object.thumbnailDirectPath = ""; + if (options.bytes === String) + object.thumbnailSha256 = ""; + else { + object.thumbnailSha256 = []; + if (options.bytes !== Array) + object.thumbnailSha256 = $util.newBuffer(object.thumbnailSha256); + } + if (options.bytes === String) + object.thumbnailEncSha256 = ""; + else { + object.thumbnailEncSha256 = []; + if (options.bytes !== Array) + object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256); + } } if (message.url != null && message.hasOwnProperty("url")) object.url = message.url; @@ -9922,6 +24043,12 @@ $root.proto = (function() { object.midQualityFileEncSha256 = options.bytes === String ? $util.base64.encode(message.midQualityFileEncSha256, 0, message.midQualityFileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.midQualityFileEncSha256) : message.midQualityFileEncSha256; if (message.viewOnce != null && message.hasOwnProperty("viewOnce")) object.viewOnce = message.viewOnce; + if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath")) + object.thumbnailDirectPath = message.thumbnailDirectPath; + if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256")) + object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256; + if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) + object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256; return object; }; @@ -9939,6 +24066,469 @@ $root.proto = (function() { return ImageMessage; })(); + proto.InvoiceMessage = (function() { + + /** + * Properties of an InvoiceMessage. + * @memberof proto + * @interface IInvoiceMessage + * @property {string|null} [note] InvoiceMessage note + * @property {string|null} [token] InvoiceMessage token + * @property {proto.InvoiceMessage.InvoiceMessageAttachmentType|null} [attachmentType] InvoiceMessage attachmentType + * @property {string|null} [attachmentMimetype] InvoiceMessage attachmentMimetype + * @property {Uint8Array|null} [attachmentMediaKey] InvoiceMessage attachmentMediaKey + * @property {number|Long|null} [attachmentMediaKeyTimestamp] InvoiceMessage attachmentMediaKeyTimestamp + * @property {Uint8Array|null} [attachmentFileSha256] InvoiceMessage attachmentFileSha256 + * @property {Uint8Array|null} [attachmentFileEncSha256] InvoiceMessage attachmentFileEncSha256 + * @property {string|null} [attachmentDirectPath] InvoiceMessage attachmentDirectPath + * @property {Uint8Array|null} [attachmentJpegThumbnail] InvoiceMessage attachmentJpegThumbnail + */ + + /** + * Constructs a new InvoiceMessage. + * @memberof proto + * @classdesc Represents an InvoiceMessage. + * @implements IInvoiceMessage + * @constructor + * @param {proto.IInvoiceMessage=} [properties] Properties to set + */ + function InvoiceMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * InvoiceMessage note. + * @member {string} note + * @memberof proto.InvoiceMessage + * @instance + */ + InvoiceMessage.prototype.note = ""; + + /** + * InvoiceMessage token. + * @member {string} token + * @memberof proto.InvoiceMessage + * @instance + */ + InvoiceMessage.prototype.token = ""; + + /** + * InvoiceMessage attachmentType. + * @member {proto.InvoiceMessage.InvoiceMessageAttachmentType} attachmentType + * @memberof proto.InvoiceMessage + * @instance + */ + InvoiceMessage.prototype.attachmentType = 0; + + /** + * InvoiceMessage attachmentMimetype. + * @member {string} attachmentMimetype + * @memberof proto.InvoiceMessage + * @instance + */ + InvoiceMessage.prototype.attachmentMimetype = ""; + + /** + * InvoiceMessage attachmentMediaKey. + * @member {Uint8Array} attachmentMediaKey + * @memberof proto.InvoiceMessage + * @instance + */ + InvoiceMessage.prototype.attachmentMediaKey = $util.newBuffer([]); + + /** + * InvoiceMessage attachmentMediaKeyTimestamp. + * @member {number|Long} attachmentMediaKeyTimestamp + * @memberof proto.InvoiceMessage + * @instance + */ + InvoiceMessage.prototype.attachmentMediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * InvoiceMessage attachmentFileSha256. + * @member {Uint8Array} attachmentFileSha256 + * @memberof proto.InvoiceMessage + * @instance + */ + InvoiceMessage.prototype.attachmentFileSha256 = $util.newBuffer([]); + + /** + * InvoiceMessage attachmentFileEncSha256. + * @member {Uint8Array} attachmentFileEncSha256 + * @memberof proto.InvoiceMessage + * @instance + */ + InvoiceMessage.prototype.attachmentFileEncSha256 = $util.newBuffer([]); + + /** + * InvoiceMessage attachmentDirectPath. + * @member {string} attachmentDirectPath + * @memberof proto.InvoiceMessage + * @instance + */ + InvoiceMessage.prototype.attachmentDirectPath = ""; + + /** + * InvoiceMessage attachmentJpegThumbnail. + * @member {Uint8Array} attachmentJpegThumbnail + * @memberof proto.InvoiceMessage + * @instance + */ + InvoiceMessage.prototype.attachmentJpegThumbnail = $util.newBuffer([]); + + /** + * Creates a new InvoiceMessage instance using the specified properties. + * @function create + * @memberof proto.InvoiceMessage + * @static + * @param {proto.IInvoiceMessage=} [properties] Properties to set + * @returns {proto.InvoiceMessage} InvoiceMessage instance + */ + InvoiceMessage.create = function create(properties) { + return new InvoiceMessage(properties); + }; + + /** + * Encodes the specified InvoiceMessage message. Does not implicitly {@link proto.InvoiceMessage.verify|verify} messages. + * @function encode + * @memberof proto.InvoiceMessage + * @static + * @param {proto.IInvoiceMessage} message InvoiceMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + InvoiceMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.note != null && Object.hasOwnProperty.call(message, "note")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.note); + if (message.token != null && Object.hasOwnProperty.call(message, "token")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.token); + if (message.attachmentType != null && Object.hasOwnProperty.call(message, "attachmentType")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.attachmentType); + if (message.attachmentMimetype != null && Object.hasOwnProperty.call(message, "attachmentMimetype")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.attachmentMimetype); + if (message.attachmentMediaKey != null && Object.hasOwnProperty.call(message, "attachmentMediaKey")) + writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.attachmentMediaKey); + if (message.attachmentMediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "attachmentMediaKeyTimestamp")) + writer.uint32(/* id 6, wireType 0 =*/48).int64(message.attachmentMediaKeyTimestamp); + if (message.attachmentFileSha256 != null && Object.hasOwnProperty.call(message, "attachmentFileSha256")) + writer.uint32(/* id 7, wireType 2 =*/58).bytes(message.attachmentFileSha256); + if (message.attachmentFileEncSha256 != null && Object.hasOwnProperty.call(message, "attachmentFileEncSha256")) + writer.uint32(/* id 8, wireType 2 =*/66).bytes(message.attachmentFileEncSha256); + if (message.attachmentDirectPath != null && Object.hasOwnProperty.call(message, "attachmentDirectPath")) + writer.uint32(/* id 9, wireType 2 =*/74).string(message.attachmentDirectPath); + if (message.attachmentJpegThumbnail != null && Object.hasOwnProperty.call(message, "attachmentJpegThumbnail")) + writer.uint32(/* id 10, wireType 2 =*/82).bytes(message.attachmentJpegThumbnail); + return writer; + }; + + /** + * Encodes the specified InvoiceMessage message, length delimited. Does not implicitly {@link proto.InvoiceMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.InvoiceMessage + * @static + * @param {proto.IInvoiceMessage} message InvoiceMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + InvoiceMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an InvoiceMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.InvoiceMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.InvoiceMessage} InvoiceMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + InvoiceMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.InvoiceMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.note = reader.string(); + break; + case 2: + message.token = reader.string(); + break; + case 3: + message.attachmentType = reader.int32(); + break; + case 4: + message.attachmentMimetype = reader.string(); + break; + case 5: + message.attachmentMediaKey = reader.bytes(); + break; + case 6: + message.attachmentMediaKeyTimestamp = reader.int64(); + break; + case 7: + message.attachmentFileSha256 = reader.bytes(); + break; + case 8: + message.attachmentFileEncSha256 = reader.bytes(); + break; + case 9: + message.attachmentDirectPath = reader.string(); + break; + case 10: + message.attachmentJpegThumbnail = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an InvoiceMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.InvoiceMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.InvoiceMessage} InvoiceMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + InvoiceMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an InvoiceMessage message. + * @function verify + * @memberof proto.InvoiceMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + InvoiceMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.note != null && message.hasOwnProperty("note")) + if (!$util.isString(message.note)) + return "note: string expected"; + if (message.token != null && message.hasOwnProperty("token")) + if (!$util.isString(message.token)) + return "token: string expected"; + if (message.attachmentType != null && message.hasOwnProperty("attachmentType")) + switch (message.attachmentType) { + default: + return "attachmentType: enum value expected"; + case 0: + case 1: + break; + } + if (message.attachmentMimetype != null && message.hasOwnProperty("attachmentMimetype")) + if (!$util.isString(message.attachmentMimetype)) + return "attachmentMimetype: string expected"; + if (message.attachmentMediaKey != null && message.hasOwnProperty("attachmentMediaKey")) + if (!(message.attachmentMediaKey && typeof message.attachmentMediaKey.length === "number" || $util.isString(message.attachmentMediaKey))) + return "attachmentMediaKey: buffer expected"; + if (message.attachmentMediaKeyTimestamp != null && message.hasOwnProperty("attachmentMediaKeyTimestamp")) + if (!$util.isInteger(message.attachmentMediaKeyTimestamp) && !(message.attachmentMediaKeyTimestamp && $util.isInteger(message.attachmentMediaKeyTimestamp.low) && $util.isInteger(message.attachmentMediaKeyTimestamp.high))) + return "attachmentMediaKeyTimestamp: integer|Long expected"; + if (message.attachmentFileSha256 != null && message.hasOwnProperty("attachmentFileSha256")) + if (!(message.attachmentFileSha256 && typeof message.attachmentFileSha256.length === "number" || $util.isString(message.attachmentFileSha256))) + return "attachmentFileSha256: buffer expected"; + if (message.attachmentFileEncSha256 != null && message.hasOwnProperty("attachmentFileEncSha256")) + if (!(message.attachmentFileEncSha256 && typeof message.attachmentFileEncSha256.length === "number" || $util.isString(message.attachmentFileEncSha256))) + return "attachmentFileEncSha256: buffer expected"; + if (message.attachmentDirectPath != null && message.hasOwnProperty("attachmentDirectPath")) + if (!$util.isString(message.attachmentDirectPath)) + return "attachmentDirectPath: string expected"; + if (message.attachmentJpegThumbnail != null && message.hasOwnProperty("attachmentJpegThumbnail")) + if (!(message.attachmentJpegThumbnail && typeof message.attachmentJpegThumbnail.length === "number" || $util.isString(message.attachmentJpegThumbnail))) + return "attachmentJpegThumbnail: buffer expected"; + return null; + }; + + /** + * Creates an InvoiceMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.InvoiceMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.InvoiceMessage} InvoiceMessage + */ + InvoiceMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.InvoiceMessage) + return object; + var message = new $root.proto.InvoiceMessage(); + if (object.note != null) + message.note = String(object.note); + if (object.token != null) + message.token = String(object.token); + switch (object.attachmentType) { + case "IMAGE": + case 0: + message.attachmentType = 0; + break; + case "PDF": + case 1: + message.attachmentType = 1; + break; + } + if (object.attachmentMimetype != null) + message.attachmentMimetype = String(object.attachmentMimetype); + if (object.attachmentMediaKey != null) + if (typeof object.attachmentMediaKey === "string") + $util.base64.decode(object.attachmentMediaKey, message.attachmentMediaKey = $util.newBuffer($util.base64.length(object.attachmentMediaKey)), 0); + else if (object.attachmentMediaKey.length) + message.attachmentMediaKey = object.attachmentMediaKey; + if (object.attachmentMediaKeyTimestamp != null) + if ($util.Long) + (message.attachmentMediaKeyTimestamp = $util.Long.fromValue(object.attachmentMediaKeyTimestamp)).unsigned = false; + else if (typeof object.attachmentMediaKeyTimestamp === "string") + message.attachmentMediaKeyTimestamp = parseInt(object.attachmentMediaKeyTimestamp, 10); + else if (typeof object.attachmentMediaKeyTimestamp === "number") + message.attachmentMediaKeyTimestamp = object.attachmentMediaKeyTimestamp; + else if (typeof object.attachmentMediaKeyTimestamp === "object") + message.attachmentMediaKeyTimestamp = new $util.LongBits(object.attachmentMediaKeyTimestamp.low >>> 0, object.attachmentMediaKeyTimestamp.high >>> 0).toNumber(); + if (object.attachmentFileSha256 != null) + if (typeof object.attachmentFileSha256 === "string") + $util.base64.decode(object.attachmentFileSha256, message.attachmentFileSha256 = $util.newBuffer($util.base64.length(object.attachmentFileSha256)), 0); + else if (object.attachmentFileSha256.length) + message.attachmentFileSha256 = object.attachmentFileSha256; + if (object.attachmentFileEncSha256 != null) + if (typeof object.attachmentFileEncSha256 === "string") + $util.base64.decode(object.attachmentFileEncSha256, message.attachmentFileEncSha256 = $util.newBuffer($util.base64.length(object.attachmentFileEncSha256)), 0); + else if (object.attachmentFileEncSha256.length) + message.attachmentFileEncSha256 = object.attachmentFileEncSha256; + if (object.attachmentDirectPath != null) + message.attachmentDirectPath = String(object.attachmentDirectPath); + if (object.attachmentJpegThumbnail != null) + if (typeof object.attachmentJpegThumbnail === "string") + $util.base64.decode(object.attachmentJpegThumbnail, message.attachmentJpegThumbnail = $util.newBuffer($util.base64.length(object.attachmentJpegThumbnail)), 0); + else if (object.attachmentJpegThumbnail.length) + message.attachmentJpegThumbnail = object.attachmentJpegThumbnail; + return message; + }; + + /** + * Creates a plain object from an InvoiceMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.InvoiceMessage + * @static + * @param {proto.InvoiceMessage} message InvoiceMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + InvoiceMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.note = ""; + object.token = ""; + object.attachmentType = options.enums === String ? "IMAGE" : 0; + object.attachmentMimetype = ""; + if (options.bytes === String) + object.attachmentMediaKey = ""; + else { + object.attachmentMediaKey = []; + if (options.bytes !== Array) + object.attachmentMediaKey = $util.newBuffer(object.attachmentMediaKey); + } + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.attachmentMediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.attachmentMediaKeyTimestamp = options.longs === String ? "0" : 0; + if (options.bytes === String) + object.attachmentFileSha256 = ""; + else { + object.attachmentFileSha256 = []; + if (options.bytes !== Array) + object.attachmentFileSha256 = $util.newBuffer(object.attachmentFileSha256); + } + if (options.bytes === String) + object.attachmentFileEncSha256 = ""; + else { + object.attachmentFileEncSha256 = []; + if (options.bytes !== Array) + object.attachmentFileEncSha256 = $util.newBuffer(object.attachmentFileEncSha256); + } + object.attachmentDirectPath = ""; + if (options.bytes === String) + object.attachmentJpegThumbnail = ""; + else { + object.attachmentJpegThumbnail = []; + if (options.bytes !== Array) + object.attachmentJpegThumbnail = $util.newBuffer(object.attachmentJpegThumbnail); + } + } + if (message.note != null && message.hasOwnProperty("note")) + object.note = message.note; + if (message.token != null && message.hasOwnProperty("token")) + object.token = message.token; + if (message.attachmentType != null && message.hasOwnProperty("attachmentType")) + object.attachmentType = options.enums === String ? $root.proto.InvoiceMessage.InvoiceMessageAttachmentType[message.attachmentType] : message.attachmentType; + if (message.attachmentMimetype != null && message.hasOwnProperty("attachmentMimetype")) + object.attachmentMimetype = message.attachmentMimetype; + if (message.attachmentMediaKey != null && message.hasOwnProperty("attachmentMediaKey")) + object.attachmentMediaKey = options.bytes === String ? $util.base64.encode(message.attachmentMediaKey, 0, message.attachmentMediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.attachmentMediaKey) : message.attachmentMediaKey; + if (message.attachmentMediaKeyTimestamp != null && message.hasOwnProperty("attachmentMediaKeyTimestamp")) + if (typeof message.attachmentMediaKeyTimestamp === "number") + object.attachmentMediaKeyTimestamp = options.longs === String ? String(message.attachmentMediaKeyTimestamp) : message.attachmentMediaKeyTimestamp; + else + object.attachmentMediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.attachmentMediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.attachmentMediaKeyTimestamp.low >>> 0, message.attachmentMediaKeyTimestamp.high >>> 0).toNumber() : message.attachmentMediaKeyTimestamp; + if (message.attachmentFileSha256 != null && message.hasOwnProperty("attachmentFileSha256")) + object.attachmentFileSha256 = options.bytes === String ? $util.base64.encode(message.attachmentFileSha256, 0, message.attachmentFileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.attachmentFileSha256) : message.attachmentFileSha256; + if (message.attachmentFileEncSha256 != null && message.hasOwnProperty("attachmentFileEncSha256")) + object.attachmentFileEncSha256 = options.bytes === String ? $util.base64.encode(message.attachmentFileEncSha256, 0, message.attachmentFileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.attachmentFileEncSha256) : message.attachmentFileEncSha256; + if (message.attachmentDirectPath != null && message.hasOwnProperty("attachmentDirectPath")) + object.attachmentDirectPath = message.attachmentDirectPath; + if (message.attachmentJpegThumbnail != null && message.hasOwnProperty("attachmentJpegThumbnail")) + object.attachmentJpegThumbnail = options.bytes === String ? $util.base64.encode(message.attachmentJpegThumbnail, 0, message.attachmentJpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.attachmentJpegThumbnail) : message.attachmentJpegThumbnail; + return object; + }; + + /** + * Converts this InvoiceMessage to JSON. + * @function toJSON + * @memberof proto.InvoiceMessage + * @instance + * @returns {Object.} JSON object + */ + InvoiceMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * InvoiceMessageAttachmentType enum. + * @name proto.InvoiceMessage.InvoiceMessageAttachmentType + * @enum {number} + * @property {number} IMAGE=0 IMAGE value + * @property {number} PDF=1 PDF value + */ + InvoiceMessage.InvoiceMessageAttachmentType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "IMAGE"] = 0; + values[valuesById[1] = "PDF"] = 1; + return values; + })(); + + return InvoiceMessage; + })(); + proto.ContactMessage = (function() { /** @@ -10638,6 +25228,13 @@ $root.proto = (function() { * @property {Uint8Array|null} [jpegThumbnail] ExtendedTextMessage jpegThumbnail * @property {proto.IContextInfo|null} [contextInfo] ExtendedTextMessage contextInfo * @property {boolean|null} [doNotPlayInline] ExtendedTextMessage doNotPlayInline + * @property {string|null} [thumbnailDirectPath] ExtendedTextMessage thumbnailDirectPath + * @property {Uint8Array|null} [thumbnailSha256] ExtendedTextMessage thumbnailSha256 + * @property {Uint8Array|null} [thumbnailEncSha256] ExtendedTextMessage thumbnailEncSha256 + * @property {Uint8Array|null} [mediaKey] ExtendedTextMessage mediaKey + * @property {number|Long|null} [mediaKeyTimestamp] ExtendedTextMessage mediaKeyTimestamp + * @property {number|null} [thumbnailHeight] ExtendedTextMessage thumbnailHeight + * @property {number|null} [thumbnailWidth] ExtendedTextMessage thumbnailWidth */ /** @@ -10751,6 +25348,62 @@ $root.proto = (function() { */ ExtendedTextMessage.prototype.doNotPlayInline = false; + /** + * ExtendedTextMessage thumbnailDirectPath. + * @member {string} thumbnailDirectPath + * @memberof proto.ExtendedTextMessage + * @instance + */ + ExtendedTextMessage.prototype.thumbnailDirectPath = ""; + + /** + * ExtendedTextMessage thumbnailSha256. + * @member {Uint8Array} thumbnailSha256 + * @memberof proto.ExtendedTextMessage + * @instance + */ + ExtendedTextMessage.prototype.thumbnailSha256 = $util.newBuffer([]); + + /** + * ExtendedTextMessage thumbnailEncSha256. + * @member {Uint8Array} thumbnailEncSha256 + * @memberof proto.ExtendedTextMessage + * @instance + */ + ExtendedTextMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]); + + /** + * ExtendedTextMessage mediaKey. + * @member {Uint8Array} mediaKey + * @memberof proto.ExtendedTextMessage + * @instance + */ + ExtendedTextMessage.prototype.mediaKey = $util.newBuffer([]); + + /** + * ExtendedTextMessage mediaKeyTimestamp. + * @member {number|Long} mediaKeyTimestamp + * @memberof proto.ExtendedTextMessage + * @instance + */ + ExtendedTextMessage.prototype.mediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * ExtendedTextMessage thumbnailHeight. + * @member {number} thumbnailHeight + * @memberof proto.ExtendedTextMessage + * @instance + */ + ExtendedTextMessage.prototype.thumbnailHeight = 0; + + /** + * ExtendedTextMessage thumbnailWidth. + * @member {number} thumbnailWidth + * @memberof proto.ExtendedTextMessage + * @instance + */ + ExtendedTextMessage.prototype.thumbnailWidth = 0; + /** * Creates a new ExtendedTextMessage instance using the specified properties. * @function create @@ -10799,6 +25452,20 @@ $root.proto = (function() { $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim(); if (message.doNotPlayInline != null && Object.hasOwnProperty.call(message, "doNotPlayInline")) writer.uint32(/* id 18, wireType 0 =*/144).bool(message.doNotPlayInline); + if (message.thumbnailDirectPath != null && Object.hasOwnProperty.call(message, "thumbnailDirectPath")) + writer.uint32(/* id 19, wireType 2 =*/154).string(message.thumbnailDirectPath); + if (message.thumbnailSha256 != null && Object.hasOwnProperty.call(message, "thumbnailSha256")) + writer.uint32(/* id 20, wireType 2 =*/162).bytes(message.thumbnailSha256); + if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256")) + writer.uint32(/* id 21, wireType 2 =*/170).bytes(message.thumbnailEncSha256); + if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey")) + writer.uint32(/* id 22, wireType 2 =*/178).bytes(message.mediaKey); + if (message.mediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "mediaKeyTimestamp")) + writer.uint32(/* id 23, wireType 0 =*/184).int64(message.mediaKeyTimestamp); + if (message.thumbnailHeight != null && Object.hasOwnProperty.call(message, "thumbnailHeight")) + writer.uint32(/* id 24, wireType 0 =*/192).uint32(message.thumbnailHeight); + if (message.thumbnailWidth != null && Object.hasOwnProperty.call(message, "thumbnailWidth")) + writer.uint32(/* id 25, wireType 0 =*/200).uint32(message.thumbnailWidth); return writer; }; @@ -10869,6 +25536,27 @@ $root.proto = (function() { case 18: message.doNotPlayInline = reader.bool(); break; + case 19: + message.thumbnailDirectPath = reader.string(); + break; + case 20: + message.thumbnailSha256 = reader.bytes(); + break; + case 21: + message.thumbnailEncSha256 = reader.bytes(); + break; + case 22: + message.mediaKey = reader.bytes(); + break; + case 23: + message.mediaKeyTimestamp = reader.int64(); + break; + case 24: + message.thumbnailHeight = reader.uint32(); + break; + case 25: + message.thumbnailWidth = reader.uint32(); + break; default: reader.skipType(tag & 7); break; @@ -10956,6 +25644,27 @@ $root.proto = (function() { if (message.doNotPlayInline != null && message.hasOwnProperty("doNotPlayInline")) if (typeof message.doNotPlayInline !== "boolean") return "doNotPlayInline: boolean expected"; + if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath")) + if (!$util.isString(message.thumbnailDirectPath)) + return "thumbnailDirectPath: string expected"; + if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256")) + if (!(message.thumbnailSha256 && typeof message.thumbnailSha256.length === "number" || $util.isString(message.thumbnailSha256))) + return "thumbnailSha256: buffer expected"; + if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) + if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256))) + return "thumbnailEncSha256: buffer expected"; + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey))) + return "mediaKey: buffer expected"; + if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp")) + if (!$util.isInteger(message.mediaKeyTimestamp) && !(message.mediaKeyTimestamp && $util.isInteger(message.mediaKeyTimestamp.low) && $util.isInteger(message.mediaKeyTimestamp.high))) + return "mediaKeyTimestamp: integer|Long expected"; + if (message.thumbnailHeight != null && message.hasOwnProperty("thumbnailHeight")) + if (!$util.isInteger(message.thumbnailHeight)) + return "thumbnailHeight: integer expected"; + if (message.thumbnailWidth != null && message.hasOwnProperty("thumbnailWidth")) + if (!$util.isInteger(message.thumbnailWidth)) + return "thumbnailWidth: integer expected"; return null; }; @@ -11033,6 +25742,36 @@ $root.proto = (function() { } if (object.doNotPlayInline != null) message.doNotPlayInline = Boolean(object.doNotPlayInline); + if (object.thumbnailDirectPath != null) + message.thumbnailDirectPath = String(object.thumbnailDirectPath); + if (object.thumbnailSha256 != null) + if (typeof object.thumbnailSha256 === "string") + $util.base64.decode(object.thumbnailSha256, message.thumbnailSha256 = $util.newBuffer($util.base64.length(object.thumbnailSha256)), 0); + else if (object.thumbnailSha256.length) + message.thumbnailSha256 = object.thumbnailSha256; + if (object.thumbnailEncSha256 != null) + if (typeof object.thumbnailEncSha256 === "string") + $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0); + else if (object.thumbnailEncSha256.length) + message.thumbnailEncSha256 = object.thumbnailEncSha256; + if (object.mediaKey != null) + if (typeof object.mediaKey === "string") + $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0); + else if (object.mediaKey.length) + message.mediaKey = object.mediaKey; + if (object.mediaKeyTimestamp != null) + if ($util.Long) + (message.mediaKeyTimestamp = $util.Long.fromValue(object.mediaKeyTimestamp)).unsigned = false; + else if (typeof object.mediaKeyTimestamp === "string") + message.mediaKeyTimestamp = parseInt(object.mediaKeyTimestamp, 10); + else if (typeof object.mediaKeyTimestamp === "number") + message.mediaKeyTimestamp = object.mediaKeyTimestamp; + else if (typeof object.mediaKeyTimestamp === "object") + message.mediaKeyTimestamp = new $util.LongBits(object.mediaKeyTimestamp.low >>> 0, object.mediaKeyTimestamp.high >>> 0).toNumber(); + if (object.thumbnailHeight != null) + message.thumbnailHeight = object.thumbnailHeight >>> 0; + if (object.thumbnailWidth != null) + message.thumbnailWidth = object.thumbnailWidth >>> 0; return message; }; @@ -11068,6 +25807,35 @@ $root.proto = (function() { } object.contextInfo = null; object.doNotPlayInline = false; + object.thumbnailDirectPath = ""; + if (options.bytes === String) + object.thumbnailSha256 = ""; + else { + object.thumbnailSha256 = []; + if (options.bytes !== Array) + object.thumbnailSha256 = $util.newBuffer(object.thumbnailSha256); + } + if (options.bytes === String) + object.thumbnailEncSha256 = ""; + else { + object.thumbnailEncSha256 = []; + if (options.bytes !== Array) + object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256); + } + if (options.bytes === String) + object.mediaKey = ""; + else { + object.mediaKey = []; + if (options.bytes !== Array) + object.mediaKey = $util.newBuffer(object.mediaKey); + } + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.mediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.mediaKeyTimestamp = options.longs === String ? "0" : 0; + object.thumbnailHeight = 0; + object.thumbnailWidth = 0; } if (message.text != null && message.hasOwnProperty("text")) object.text = message.text; @@ -11093,6 +25861,23 @@ $root.proto = (function() { object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options); if (message.doNotPlayInline != null && message.hasOwnProperty("doNotPlayInline")) object.doNotPlayInline = message.doNotPlayInline; + if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath")) + object.thumbnailDirectPath = message.thumbnailDirectPath; + if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256")) + object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256; + if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) + object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256; + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey; + if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp")) + if (typeof message.mediaKeyTimestamp === "number") + object.mediaKeyTimestamp = options.longs === String ? String(message.mediaKeyTimestamp) : message.mediaKeyTimestamp; + else + object.mediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.mediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.mediaKeyTimestamp.low >>> 0, message.mediaKeyTimestamp.high >>> 0).toNumber() : message.mediaKeyTimestamp; + if (message.thumbnailHeight != null && message.hasOwnProperty("thumbnailHeight")) + object.thumbnailHeight = message.thumbnailHeight; + if (message.thumbnailWidth != null && message.hasOwnProperty("thumbnailWidth")) + object.thumbnailWidth = message.thumbnailWidth; return object; }; @@ -12341,6 +27126,9 @@ $root.proto = (function() { * @property {Uint8Array|null} [streamingSidecar] VideoMessage streamingSidecar * @property {proto.VideoMessage.VideoMessageAttribution|null} [gifAttribution] VideoMessage gifAttribution * @property {boolean|null} [viewOnce] VideoMessage viewOnce + * @property {string|null} [thumbnailDirectPath] VideoMessage thumbnailDirectPath + * @property {Uint8Array|null} [thumbnailSha256] VideoMessage thumbnailSha256 + * @property {Uint8Array|null} [thumbnailEncSha256] VideoMessage thumbnailEncSha256 */ /** @@ -12511,6 +27299,30 @@ $root.proto = (function() { */ VideoMessage.prototype.viewOnce = false; + /** + * VideoMessage thumbnailDirectPath. + * @member {string} thumbnailDirectPath + * @memberof proto.VideoMessage + * @instance + */ + VideoMessage.prototype.thumbnailDirectPath = ""; + + /** + * VideoMessage thumbnailSha256. + * @member {Uint8Array} thumbnailSha256 + * @memberof proto.VideoMessage + * @instance + */ + VideoMessage.prototype.thumbnailSha256 = $util.newBuffer([]); + + /** + * VideoMessage thumbnailEncSha256. + * @member {Uint8Array} thumbnailEncSha256 + * @memberof proto.VideoMessage + * @instance + */ + VideoMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]); + /** * Creates a new VideoMessage instance using the specified properties. * @function create @@ -12574,6 +27386,12 @@ $root.proto = (function() { writer.uint32(/* id 19, wireType 0 =*/152).int32(message.gifAttribution); if (message.viewOnce != null && Object.hasOwnProperty.call(message, "viewOnce")) writer.uint32(/* id 20, wireType 0 =*/160).bool(message.viewOnce); + if (message.thumbnailDirectPath != null && Object.hasOwnProperty.call(message, "thumbnailDirectPath")) + writer.uint32(/* id 21, wireType 2 =*/170).string(message.thumbnailDirectPath); + if (message.thumbnailSha256 != null && Object.hasOwnProperty.call(message, "thumbnailSha256")) + writer.uint32(/* id 22, wireType 2 =*/178).bytes(message.thumbnailSha256); + if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256")) + writer.uint32(/* id 23, wireType 2 =*/186).bytes(message.thumbnailEncSha256); return writer; }; @@ -12667,6 +27485,15 @@ $root.proto = (function() { case 20: message.viewOnce = reader.bool(); break; + case 21: + message.thumbnailDirectPath = reader.string(); + break; + case 22: + message.thumbnailSha256 = reader.bytes(); + break; + case 23: + message.thumbnailEncSha256 = reader.bytes(); + break; default: reader.skipType(tag & 7); break; @@ -12773,6 +27600,15 @@ $root.proto = (function() { if (message.viewOnce != null && message.hasOwnProperty("viewOnce")) if (typeof message.viewOnce !== "boolean") return "viewOnce: boolean expected"; + if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath")) + if (!$util.isString(message.thumbnailDirectPath)) + return "thumbnailDirectPath: string expected"; + if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256")) + if (!(message.thumbnailSha256 && typeof message.thumbnailSha256.length === "number" || $util.isString(message.thumbnailSha256))) + return "thumbnailSha256: buffer expected"; + if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) + if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256))) + return "thumbnailEncSha256: buffer expected"; return null; }; @@ -12878,6 +27714,18 @@ $root.proto = (function() { } if (object.viewOnce != null) message.viewOnce = Boolean(object.viewOnce); + if (object.thumbnailDirectPath != null) + message.thumbnailDirectPath = String(object.thumbnailDirectPath); + if (object.thumbnailSha256 != null) + if (typeof object.thumbnailSha256 === "string") + $util.base64.decode(object.thumbnailSha256, message.thumbnailSha256 = $util.newBuffer($util.base64.length(object.thumbnailSha256)), 0); + else if (object.thumbnailSha256.length) + message.thumbnailSha256 = object.thumbnailSha256; + if (object.thumbnailEncSha256 != null) + if (typeof object.thumbnailEncSha256 === "string") + $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0); + else if (object.thumbnailEncSha256.length) + message.thumbnailEncSha256 = object.thumbnailEncSha256; return message; }; @@ -12953,6 +27801,21 @@ $root.proto = (function() { } object.gifAttribution = options.enums === String ? "NONE" : 0; object.viewOnce = false; + object.thumbnailDirectPath = ""; + if (options.bytes === String) + object.thumbnailSha256 = ""; + else { + object.thumbnailSha256 = []; + if (options.bytes !== Array) + object.thumbnailSha256 = $util.newBuffer(object.thumbnailSha256); + } + if (options.bytes === String) + object.thumbnailEncSha256 = ""; + else { + object.thumbnailEncSha256 = []; + if (options.bytes !== Array) + object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256); + } } if (message.url != null && message.hasOwnProperty("url")) object.url = message.url; @@ -13001,6 +27864,12 @@ $root.proto = (function() { object.gifAttribution = options.enums === String ? $root.proto.VideoMessage.VideoMessageAttribution[message.gifAttribution] : message.gifAttribution; if (message.viewOnce != null && message.hasOwnProperty("viewOnce")) object.viewOnce = message.viewOnce; + if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath")) + object.thumbnailDirectPath = message.thumbnailDirectPath; + if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256")) + object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256; + if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) + object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256; return object; }; @@ -13041,6 +27910,9 @@ $root.proto = (function() { * @memberof proto * @interface ICall * @property {Uint8Array|null} [callKey] Call callKey + * @property {string|null} [conversionSource] Call conversionSource + * @property {Uint8Array|null} [conversionData] Call conversionData + * @property {number|null} [conversionDelaySeconds] Call conversionDelaySeconds */ /** @@ -13066,6 +27938,30 @@ $root.proto = (function() { */ Call.prototype.callKey = $util.newBuffer([]); + /** + * Call conversionSource. + * @member {string} conversionSource + * @memberof proto.Call + * @instance + */ + Call.prototype.conversionSource = ""; + + /** + * Call conversionData. + * @member {Uint8Array} conversionData + * @memberof proto.Call + * @instance + */ + Call.prototype.conversionData = $util.newBuffer([]); + + /** + * Call conversionDelaySeconds. + * @member {number} conversionDelaySeconds + * @memberof proto.Call + * @instance + */ + Call.prototype.conversionDelaySeconds = 0; + /** * Creates a new Call instance using the specified properties. * @function create @@ -13092,6 +27988,12 @@ $root.proto = (function() { writer = $Writer.create(); if (message.callKey != null && Object.hasOwnProperty.call(message, "callKey")) writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.callKey); + if (message.conversionSource != null && Object.hasOwnProperty.call(message, "conversionSource")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.conversionSource); + if (message.conversionData != null && Object.hasOwnProperty.call(message, "conversionData")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.conversionData); + if (message.conversionDelaySeconds != null && Object.hasOwnProperty.call(message, "conversionDelaySeconds")) + writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.conversionDelaySeconds); return writer; }; @@ -13129,6 +28031,15 @@ $root.proto = (function() { case 1: message.callKey = reader.bytes(); break; + case 2: + message.conversionSource = reader.string(); + break; + case 3: + message.conversionData = reader.bytes(); + break; + case 4: + message.conversionDelaySeconds = reader.uint32(); + break; default: reader.skipType(tag & 7); break; @@ -13167,6 +28078,15 @@ $root.proto = (function() { if (message.callKey != null && message.hasOwnProperty("callKey")) if (!(message.callKey && typeof message.callKey.length === "number" || $util.isString(message.callKey))) return "callKey: buffer expected"; + if (message.conversionSource != null && message.hasOwnProperty("conversionSource")) + if (!$util.isString(message.conversionSource)) + return "conversionSource: string expected"; + if (message.conversionData != null && message.hasOwnProperty("conversionData")) + if (!(message.conversionData && typeof message.conversionData.length === "number" || $util.isString(message.conversionData))) + return "conversionData: buffer expected"; + if (message.conversionDelaySeconds != null && message.hasOwnProperty("conversionDelaySeconds")) + if (!$util.isInteger(message.conversionDelaySeconds)) + return "conversionDelaySeconds: integer expected"; return null; }; @@ -13187,6 +28107,15 @@ $root.proto = (function() { $util.base64.decode(object.callKey, message.callKey = $util.newBuffer($util.base64.length(object.callKey)), 0); else if (object.callKey.length) message.callKey = object.callKey; + if (object.conversionSource != null) + message.conversionSource = String(object.conversionSource); + if (object.conversionData != null) + if (typeof object.conversionData === "string") + $util.base64.decode(object.conversionData, message.conversionData = $util.newBuffer($util.base64.length(object.conversionData)), 0); + else if (object.conversionData.length) + message.conversionData = object.conversionData; + if (object.conversionDelaySeconds != null) + message.conversionDelaySeconds = object.conversionDelaySeconds >>> 0; return message; }; @@ -13203,7 +28132,7 @@ $root.proto = (function() { if (!options) options = {}; var object = {}; - if (options.defaults) + if (options.defaults) { if (options.bytes === String) object.callKey = ""; else { @@ -13211,8 +28140,24 @@ $root.proto = (function() { if (options.bytes !== Array) object.callKey = $util.newBuffer(object.callKey); } + object.conversionSource = ""; + if (options.bytes === String) + object.conversionData = ""; + else { + object.conversionData = []; + if (options.bytes !== Array) + object.conversionData = $util.newBuffer(object.conversionData); + } + object.conversionDelaySeconds = 0; + } if (message.callKey != null && message.hasOwnProperty("callKey")) object.callKey = options.bytes === String ? $util.base64.encode(message.callKey, 0, message.callKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.callKey) : message.callKey; + if (message.conversionSource != null && message.hasOwnProperty("conversionSource")) + object.conversionSource = message.conversionSource; + if (message.conversionData != null && message.hasOwnProperty("conversionData")) + object.conversionData = options.bytes === String ? $util.base64.encode(message.conversionData, 0, message.conversionData.length) : options.bytes === Array ? Array.prototype.slice.call(message.conversionData) : message.conversionData; + if (message.conversionDelaySeconds != null && message.hasOwnProperty("conversionDelaySeconds")) + object.conversionDelaySeconds = message.conversionDelaySeconds; return object; }; @@ -13454,6 +28399,7 @@ $root.proto = (function() { * @property {proto.IAppStateSyncKeyShare|null} [appStateSyncKeyShare] ProtocolMessage appStateSyncKeyShare * @property {proto.IAppStateSyncKeyRequest|null} [appStateSyncKeyRequest] ProtocolMessage appStateSyncKeyRequest * @property {proto.IInitialSecurityNotificationSettingSync|null} [initialSecurityNotificationSettingSync] ProtocolMessage initialSecurityNotificationSettingSync + * @property {proto.IAppStateFatalExceptionNotification|null} [appStateFatalExceptionNotification] ProtocolMessage appStateFatalExceptionNotification */ /** @@ -13535,6 +28481,14 @@ $root.proto = (function() { */ ProtocolMessage.prototype.initialSecurityNotificationSettingSync = null; + /** + * ProtocolMessage appStateFatalExceptionNotification. + * @member {proto.IAppStateFatalExceptionNotification|null|undefined} appStateFatalExceptionNotification + * @memberof proto.ProtocolMessage + * @instance + */ + ProtocolMessage.prototype.appStateFatalExceptionNotification = null; + /** * Creates a new ProtocolMessage instance using the specified properties. * @function create @@ -13575,6 +28529,8 @@ $root.proto = (function() { $root.proto.AppStateSyncKeyRequest.encode(message.appStateSyncKeyRequest, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim(); if (message.initialSecurityNotificationSettingSync != null && Object.hasOwnProperty.call(message, "initialSecurityNotificationSettingSync")) $root.proto.InitialSecurityNotificationSettingSync.encode(message.initialSecurityNotificationSettingSync, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim(); + if (message.appStateFatalExceptionNotification != null && Object.hasOwnProperty.call(message, "appStateFatalExceptionNotification")) + $root.proto.AppStateFatalExceptionNotification.encode(message.appStateFatalExceptionNotification, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim(); return writer; }; @@ -13633,6 +28589,9 @@ $root.proto = (function() { case 9: message.initialSecurityNotificationSettingSync = $root.proto.InitialSecurityNotificationSettingSync.decode(reader, reader.uint32()); break; + case 10: + message.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.decode(reader, reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -13685,6 +28644,7 @@ $root.proto = (function() { case 7: case 8: case 9: + case 10: break; } if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration")) @@ -13713,6 +28673,11 @@ $root.proto = (function() { if (error) return "initialSecurityNotificationSettingSync." + error; } + if (message.appStateFatalExceptionNotification != null && message.hasOwnProperty("appStateFatalExceptionNotification")) { + var error = $root.proto.AppStateFatalExceptionNotification.verify(message.appStateFatalExceptionNotification); + if (error) + return "appStateFatalExceptionNotification." + error; + } return null; }; @@ -13766,6 +28731,10 @@ $root.proto = (function() { case 9: message.type = 9; break; + case "APP_STATE_FATAL_EXCEPTION_NOTIFICATION": + case 10: + message.type = 10; + break; } if (object.ephemeralExpiration != null) message.ephemeralExpiration = object.ephemeralExpiration >>> 0; @@ -13798,6 +28767,11 @@ $root.proto = (function() { throw TypeError(".proto.ProtocolMessage.initialSecurityNotificationSettingSync: object expected"); message.initialSecurityNotificationSettingSync = $root.proto.InitialSecurityNotificationSettingSync.fromObject(object.initialSecurityNotificationSettingSync); } + if (object.appStateFatalExceptionNotification != null) { + if (typeof object.appStateFatalExceptionNotification !== "object") + throw TypeError(".proto.ProtocolMessage.appStateFatalExceptionNotification: object expected"); + message.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.fromObject(object.appStateFatalExceptionNotification); + } return message; }; @@ -13827,6 +28801,7 @@ $root.proto = (function() { object.appStateSyncKeyShare = null; object.appStateSyncKeyRequest = null; object.initialSecurityNotificationSettingSync = null; + object.appStateFatalExceptionNotification = null; } if (message.key != null && message.hasOwnProperty("key")) object.key = $root.proto.MessageKey.toObject(message.key, options); @@ -13847,6 +28822,8 @@ $root.proto = (function() { object.appStateSyncKeyRequest = $root.proto.AppStateSyncKeyRequest.toObject(message.appStateSyncKeyRequest, options); if (message.initialSecurityNotificationSettingSync != null && message.hasOwnProperty("initialSecurityNotificationSettingSync")) object.initialSecurityNotificationSettingSync = $root.proto.InitialSecurityNotificationSettingSync.toObject(message.initialSecurityNotificationSettingSync, options); + if (message.appStateFatalExceptionNotification != null && message.hasOwnProperty("appStateFatalExceptionNotification")) + object.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.toObject(message.appStateFatalExceptionNotification, options); return object; }; @@ -13873,6 +28850,7 @@ $root.proto = (function() { * @property {number} APP_STATE_SYNC_KEY_REQUEST=7 APP_STATE_SYNC_KEY_REQUEST value * @property {number} MSG_FANOUT_BACKFILL_REQUEST=8 MSG_FANOUT_BACKFILL_REQUEST value * @property {number} INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC=9 INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC value + * @property {number} APP_STATE_FATAL_EXCEPTION_NOTIFICATION=10 APP_STATE_FATAL_EXCEPTION_NOTIFICATION value */ ProtocolMessage.ProtocolMessageType = (function() { var valuesById = {}, values = Object.create(valuesById); @@ -13884,6 +28862,7 @@ $root.proto = (function() { values[valuesById[7] = "APP_STATE_SYNC_KEY_REQUEST"] = 7; values[valuesById[8] = "MSG_FANOUT_BACKFILL_REQUEST"] = 8; values[valuesById[9] = "INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC"] = 9; + values[valuesById[10] = "APP_STATE_FATAL_EXCEPTION_NOTIFICATION"] = 10; return values; })(); @@ -14141,6 +29120,7 @@ $root.proto = (function() { case 1: case 2: case 3: + case 4: break; } if (message.chunkOrder != null && message.hasOwnProperty("chunkOrder")) @@ -14207,6 +29187,10 @@ $root.proto = (function() { case 3: message.syncType = 3; break; + case "PUSH_NAME": + case 4: + message.syncType = 4; + break; } if (object.chunkOrder != null) message.chunkOrder = object.chunkOrder >>> 0; @@ -14301,6 +29285,7 @@ $root.proto = (function() { * @property {number} INITIAL_STATUS_V3=1 INITIAL_STATUS_V3 value * @property {number} FULL=2 FULL value * @property {number} RECENT=3 RECENT value + * @property {number} PUSH_NAME=4 PUSH_NAME value */ HistorySyncNotification.HistorySyncNotificationHistorySyncType = (function() { var valuesById = {}, values = Object.create(valuesById); @@ -14308,6 +29293,7 @@ $root.proto = (function() { values[valuesById[1] = "INITIAL_STATUS_V3"] = 1; values[valuesById[2] = "FULL"] = 2; values[valuesById[3] = "RECENT"] = 3; + values[valuesById[4] = "PUSH_NAME"] = 4; return values; })(); @@ -14738,6 +29724,7 @@ $root.proto = (function() { * @interface IAppStateSyncKeyFingerprint * @property {number|null} [rawId] AppStateSyncKeyFingerprint rawId * @property {number|null} [currentIndex] AppStateSyncKeyFingerprint currentIndex + * @property {Array.|null} [deviceIndexes] AppStateSyncKeyFingerprint deviceIndexes */ /** @@ -14749,6 +29736,7 @@ $root.proto = (function() { * @param {proto.IAppStateSyncKeyFingerprint=} [properties] Properties to set */ function AppStateSyncKeyFingerprint(properties) { + this.deviceIndexes = []; if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -14771,6 +29759,14 @@ $root.proto = (function() { */ AppStateSyncKeyFingerprint.prototype.currentIndex = 0; + /** + * AppStateSyncKeyFingerprint deviceIndexes. + * @member {Array.} deviceIndexes + * @memberof proto.AppStateSyncKeyFingerprint + * @instance + */ + AppStateSyncKeyFingerprint.prototype.deviceIndexes = $util.emptyArray; + /** * Creates a new AppStateSyncKeyFingerprint instance using the specified properties. * @function create @@ -14799,6 +29795,12 @@ $root.proto = (function() { writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.rawId); if (message.currentIndex != null && Object.hasOwnProperty.call(message, "currentIndex")) writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.currentIndex); + if (message.deviceIndexes != null && message.deviceIndexes.length) { + writer.uint32(/* id 3, wireType 2 =*/26).fork(); + for (var i = 0; i < message.deviceIndexes.length; ++i) + writer.uint32(message.deviceIndexes[i]); + writer.ldelim(); + } return writer; }; @@ -14839,6 +29841,16 @@ $root.proto = (function() { case 2: message.currentIndex = reader.uint32(); break; + case 3: + if (!(message.deviceIndexes && message.deviceIndexes.length)) + message.deviceIndexes = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.deviceIndexes.push(reader.uint32()); + } else + message.deviceIndexes.push(reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -14880,6 +29892,13 @@ $root.proto = (function() { if (message.currentIndex != null && message.hasOwnProperty("currentIndex")) if (!$util.isInteger(message.currentIndex)) return "currentIndex: integer expected"; + if (message.deviceIndexes != null && message.hasOwnProperty("deviceIndexes")) { + if (!Array.isArray(message.deviceIndexes)) + return "deviceIndexes: array expected"; + for (var i = 0; i < message.deviceIndexes.length; ++i) + if (!$util.isInteger(message.deviceIndexes[i])) + return "deviceIndexes: integer[] expected"; + } return null; }; @@ -14899,6 +29918,13 @@ $root.proto = (function() { message.rawId = object.rawId >>> 0; if (object.currentIndex != null) message.currentIndex = object.currentIndex >>> 0; + if (object.deviceIndexes) { + if (!Array.isArray(object.deviceIndexes)) + throw TypeError(".proto.AppStateSyncKeyFingerprint.deviceIndexes: array expected"); + message.deviceIndexes = []; + for (var i = 0; i < object.deviceIndexes.length; ++i) + message.deviceIndexes[i] = object.deviceIndexes[i] >>> 0; + } return message; }; @@ -14915,6 +29941,8 @@ $root.proto = (function() { if (!options) options = {}; var object = {}; + if (options.arrays || options.defaults) + object.deviceIndexes = []; if (options.defaults) { object.rawId = 0; object.currentIndex = 0; @@ -14923,6 +29951,11 @@ $root.proto = (function() { object.rawId = message.rawId; if (message.currentIndex != null && message.hasOwnProperty("currentIndex")) object.currentIndex = message.currentIndex; + if (message.deviceIndexes && message.deviceIndexes.length) { + object.deviceIndexes = []; + for (var j = 0; j < message.deviceIndexes.length; ++j) + object.deviceIndexes[j] = message.deviceIndexes[j]; + } return object; }; @@ -15616,6 +30649,246 @@ $root.proto = (function() { return AppStateSyncKeyRequest; })(); + proto.AppStateFatalExceptionNotification = (function() { + + /** + * Properties of an AppStateFatalExceptionNotification. + * @memberof proto + * @interface IAppStateFatalExceptionNotification + * @property {Array.|null} [collectionNames] AppStateFatalExceptionNotification collectionNames + * @property {number|Long|null} [timestamp] AppStateFatalExceptionNotification timestamp + */ + + /** + * Constructs a new AppStateFatalExceptionNotification. + * @memberof proto + * @classdesc Represents an AppStateFatalExceptionNotification. + * @implements IAppStateFatalExceptionNotification + * @constructor + * @param {proto.IAppStateFatalExceptionNotification=} [properties] Properties to set + */ + function AppStateFatalExceptionNotification(properties) { + this.collectionNames = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * AppStateFatalExceptionNotification collectionNames. + * @member {Array.} collectionNames + * @memberof proto.AppStateFatalExceptionNotification + * @instance + */ + AppStateFatalExceptionNotification.prototype.collectionNames = $util.emptyArray; + + /** + * AppStateFatalExceptionNotification timestamp. + * @member {number|Long} timestamp + * @memberof proto.AppStateFatalExceptionNotification + * @instance + */ + AppStateFatalExceptionNotification.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new AppStateFatalExceptionNotification instance using the specified properties. + * @function create + * @memberof proto.AppStateFatalExceptionNotification + * @static + * @param {proto.IAppStateFatalExceptionNotification=} [properties] Properties to set + * @returns {proto.AppStateFatalExceptionNotification} AppStateFatalExceptionNotification instance + */ + AppStateFatalExceptionNotification.create = function create(properties) { + return new AppStateFatalExceptionNotification(properties); + }; + + /** + * Encodes the specified AppStateFatalExceptionNotification message. Does not implicitly {@link proto.AppStateFatalExceptionNotification.verify|verify} messages. + * @function encode + * @memberof proto.AppStateFatalExceptionNotification + * @static + * @param {proto.IAppStateFatalExceptionNotification} message AppStateFatalExceptionNotification message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + AppStateFatalExceptionNotification.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.collectionNames != null && message.collectionNames.length) + for (var i = 0; i < message.collectionNames.length; ++i) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.collectionNames[i]); + if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.timestamp); + return writer; + }; + + /** + * Encodes the specified AppStateFatalExceptionNotification message, length delimited. Does not implicitly {@link proto.AppStateFatalExceptionNotification.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.AppStateFatalExceptionNotification + * @static + * @param {proto.IAppStateFatalExceptionNotification} message AppStateFatalExceptionNotification message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + AppStateFatalExceptionNotification.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an AppStateFatalExceptionNotification message from the specified reader or buffer. + * @function decode + * @memberof proto.AppStateFatalExceptionNotification + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.AppStateFatalExceptionNotification} AppStateFatalExceptionNotification + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + AppStateFatalExceptionNotification.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AppStateFatalExceptionNotification(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.collectionNames && message.collectionNames.length)) + message.collectionNames = []; + message.collectionNames.push(reader.string()); + break; + case 2: + message.timestamp = reader.int64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an AppStateFatalExceptionNotification message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.AppStateFatalExceptionNotification + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.AppStateFatalExceptionNotification} AppStateFatalExceptionNotification + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + AppStateFatalExceptionNotification.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an AppStateFatalExceptionNotification message. + * @function verify + * @memberof proto.AppStateFatalExceptionNotification + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + AppStateFatalExceptionNotification.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.collectionNames != null && message.hasOwnProperty("collectionNames")) { + if (!Array.isArray(message.collectionNames)) + return "collectionNames: array expected"; + for (var i = 0; i < message.collectionNames.length; ++i) + if (!$util.isString(message.collectionNames[i])) + return "collectionNames: string[] expected"; + } + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) + return "timestamp: integer|Long expected"; + return null; + }; + + /** + * Creates an AppStateFatalExceptionNotification message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.AppStateFatalExceptionNotification + * @static + * @param {Object.} object Plain object + * @returns {proto.AppStateFatalExceptionNotification} AppStateFatalExceptionNotification + */ + AppStateFatalExceptionNotification.fromObject = function fromObject(object) { + if (object instanceof $root.proto.AppStateFatalExceptionNotification) + return object; + var message = new $root.proto.AppStateFatalExceptionNotification(); + if (object.collectionNames) { + if (!Array.isArray(object.collectionNames)) + throw TypeError(".proto.AppStateFatalExceptionNotification.collectionNames: array expected"); + message.collectionNames = []; + for (var i = 0; i < object.collectionNames.length; ++i) + message.collectionNames[i] = String(object.collectionNames[i]); + } + if (object.timestamp != null) + if ($util.Long) + (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false; + else if (typeof object.timestamp === "string") + message.timestamp = parseInt(object.timestamp, 10); + else if (typeof object.timestamp === "number") + message.timestamp = object.timestamp; + else if (typeof object.timestamp === "object") + message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from an AppStateFatalExceptionNotification message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.AppStateFatalExceptionNotification + * @static + * @param {proto.AppStateFatalExceptionNotification} message AppStateFatalExceptionNotification + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + AppStateFatalExceptionNotification.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.collectionNames = []; + if (options.defaults) + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.timestamp = options.longs === String ? "0" : 0; + if (message.collectionNames && message.collectionNames.length) { + object.collectionNames = []; + for (var j = 0; j < message.collectionNames.length; ++j) + object.collectionNames[j] = message.collectionNames[j]; + } + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (typeof message.timestamp === "number") + object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; + else + object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp; + return object; + }; + + /** + * Converts this AppStateFatalExceptionNotification to JSON. + * @function toJSON + * @memberof proto.AppStateFatalExceptionNotification + * @instance + * @returns {Object.} JSON object + */ + AppStateFatalExceptionNotification.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return AppStateFatalExceptionNotification; + })(); + proto.InitialSecurityNotificationSettingSync = (function() { /** @@ -17825,6 +33098,7 @@ $root.proto = (function() { * @interface ISendPaymentMessage * @property {proto.IMessage|null} [noteMessage] SendPaymentMessage noteMessage * @property {proto.IMessageKey|null} [requestMessageKey] SendPaymentMessage requestMessageKey + * @property {proto.IPaymentBackground|null} [background] SendPaymentMessage background */ /** @@ -17858,6 +33132,14 @@ $root.proto = (function() { */ SendPaymentMessage.prototype.requestMessageKey = null; + /** + * SendPaymentMessage background. + * @member {proto.IPaymentBackground|null|undefined} background + * @memberof proto.SendPaymentMessage + * @instance + */ + SendPaymentMessage.prototype.background = null; + /** * Creates a new SendPaymentMessage instance using the specified properties. * @function create @@ -17886,6 +33168,8 @@ $root.proto = (function() { $root.proto.Message.encode(message.noteMessage, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); if (message.requestMessageKey != null && Object.hasOwnProperty.call(message, "requestMessageKey")) $root.proto.MessageKey.encode(message.requestMessageKey, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.background != null && Object.hasOwnProperty.call(message, "background")) + $root.proto.PaymentBackground.encode(message.background, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); return writer; }; @@ -17926,6 +33210,9 @@ $root.proto = (function() { case 3: message.requestMessageKey = $root.proto.MessageKey.decode(reader, reader.uint32()); break; + case 4: + message.background = $root.proto.PaymentBackground.decode(reader, reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -17971,6 +33258,11 @@ $root.proto = (function() { if (error) return "requestMessageKey." + error; } + if (message.background != null && message.hasOwnProperty("background")) { + var error = $root.proto.PaymentBackground.verify(message.background); + if (error) + return "background." + error; + } return null; }; @@ -17996,6 +33288,11 @@ $root.proto = (function() { throw TypeError(".proto.SendPaymentMessage.requestMessageKey: object expected"); message.requestMessageKey = $root.proto.MessageKey.fromObject(object.requestMessageKey); } + if (object.background != null) { + if (typeof object.background !== "object") + throw TypeError(".proto.SendPaymentMessage.background: object expected"); + message.background = $root.proto.PaymentBackground.fromObject(object.background); + } return message; }; @@ -18015,11 +33312,14 @@ $root.proto = (function() { if (options.defaults) { object.noteMessage = null; object.requestMessageKey = null; + object.background = null; } if (message.noteMessage != null && message.hasOwnProperty("noteMessage")) object.noteMessage = $root.proto.Message.toObject(message.noteMessage, options); if (message.requestMessageKey != null && message.hasOwnProperty("requestMessageKey")) object.requestMessageKey = $root.proto.MessageKey.toObject(message.requestMessageKey, options); + if (message.background != null && message.hasOwnProperty("background")) + object.background = $root.proto.PaymentBackground.toObject(message.background, options); return object; }; @@ -18048,6 +33348,8 @@ $root.proto = (function() { * @property {number|Long|null} [amount1000] RequestPaymentMessage amount1000 * @property {string|null} [requestFrom] RequestPaymentMessage requestFrom * @property {number|Long|null} [expiryTimestamp] RequestPaymentMessage expiryTimestamp + * @property {proto.IMoney|null} [amount] RequestPaymentMessage amount + * @property {proto.IPaymentBackground|null} [background] RequestPaymentMessage background */ /** @@ -18105,6 +33407,22 @@ $root.proto = (function() { */ RequestPaymentMessage.prototype.expiryTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + /** + * RequestPaymentMessage amount. + * @member {proto.IMoney|null|undefined} amount + * @memberof proto.RequestPaymentMessage + * @instance + */ + RequestPaymentMessage.prototype.amount = null; + + /** + * RequestPaymentMessage background. + * @member {proto.IPaymentBackground|null|undefined} background + * @memberof proto.RequestPaymentMessage + * @instance + */ + RequestPaymentMessage.prototype.background = null; + /** * Creates a new RequestPaymentMessage instance using the specified properties. * @function create @@ -18139,6 +33457,10 @@ $root.proto = (function() { $root.proto.Message.encode(message.noteMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); if (message.expiryTimestamp != null && Object.hasOwnProperty.call(message, "expiryTimestamp")) writer.uint32(/* id 5, wireType 0 =*/40).int64(message.expiryTimestamp); + if (message.amount != null && Object.hasOwnProperty.call(message, "amount")) + $root.proto.Money.encode(message.amount, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.background != null && Object.hasOwnProperty.call(message, "background")) + $root.proto.PaymentBackground.encode(message.background, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); return writer; }; @@ -18188,6 +33510,12 @@ $root.proto = (function() { case 5: message.expiryTimestamp = reader.int64(); break; + case 6: + message.amount = $root.proto.Money.decode(reader, reader.uint32()); + break; + case 7: + message.background = $root.proto.PaymentBackground.decode(reader, reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -18240,6 +33568,16 @@ $root.proto = (function() { if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp")) if (!$util.isInteger(message.expiryTimestamp) && !(message.expiryTimestamp && $util.isInteger(message.expiryTimestamp.low) && $util.isInteger(message.expiryTimestamp.high))) return "expiryTimestamp: integer|Long expected"; + if (message.amount != null && message.hasOwnProperty("amount")) { + var error = $root.proto.Money.verify(message.amount); + if (error) + return "amount." + error; + } + if (message.background != null && message.hasOwnProperty("background")) { + var error = $root.proto.PaymentBackground.verify(message.background); + if (error) + return "background." + error; + } return null; }; @@ -18282,6 +33620,16 @@ $root.proto = (function() { message.expiryTimestamp = object.expiryTimestamp; else if (typeof object.expiryTimestamp === "object") message.expiryTimestamp = new $util.LongBits(object.expiryTimestamp.low >>> 0, object.expiryTimestamp.high >>> 0).toNumber(); + if (object.amount != null) { + if (typeof object.amount !== "object") + throw TypeError(".proto.RequestPaymentMessage.amount: object expected"); + message.amount = $root.proto.Money.fromObject(object.amount); + } + if (object.background != null) { + if (typeof object.background !== "object") + throw TypeError(".proto.RequestPaymentMessage.background: object expected"); + message.background = $root.proto.PaymentBackground.fromObject(object.background); + } return message; }; @@ -18312,6 +33660,8 @@ $root.proto = (function() { object.expiryTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; } else object.expiryTimestamp = options.longs === String ? "0" : 0; + object.amount = null; + object.background = null; } if (message.currencyCodeIso4217 != null && message.hasOwnProperty("currencyCodeIso4217")) object.currencyCodeIso4217 = message.currencyCodeIso4217; @@ -18329,6 +33679,10 @@ $root.proto = (function() { object.expiryTimestamp = options.longs === String ? String(message.expiryTimestamp) : message.expiryTimestamp; else object.expiryTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.expiryTimestamp) : options.longs === Number ? new $util.LongBits(message.expiryTimestamp.low >>> 0, message.expiryTimestamp.high >>> 0).toNumber() : message.expiryTimestamp; + if (message.amount != null && message.hasOwnProperty("amount")) + object.amount = $root.proto.Money.toObject(message.amount, options); + if (message.background != null && message.hasOwnProperty("background")) + object.background = $root.proto.PaymentBackground.toObject(message.background, options); return object; }; @@ -18730,6 +34084,271 @@ $root.proto = (function() { return CancelPaymentRequestMessage; })(); + proto.PaymentInviteMessage = (function() { + + /** + * Properties of a PaymentInviteMessage. + * @memberof proto + * @interface IPaymentInviteMessage + * @property {proto.PaymentInviteMessage.PaymentInviteMessageServiceType|null} [serviceType] PaymentInviteMessage serviceType + * @property {number|Long|null} [expiryTimestamp] PaymentInviteMessage expiryTimestamp + */ + + /** + * Constructs a new PaymentInviteMessage. + * @memberof proto + * @classdesc Represents a PaymentInviteMessage. + * @implements IPaymentInviteMessage + * @constructor + * @param {proto.IPaymentInviteMessage=} [properties] Properties to set + */ + function PaymentInviteMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * PaymentInviteMessage serviceType. + * @member {proto.PaymentInviteMessage.PaymentInviteMessageServiceType} serviceType + * @memberof proto.PaymentInviteMessage + * @instance + */ + PaymentInviteMessage.prototype.serviceType = 0; + + /** + * PaymentInviteMessage expiryTimestamp. + * @member {number|Long} expiryTimestamp + * @memberof proto.PaymentInviteMessage + * @instance + */ + PaymentInviteMessage.prototype.expiryTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new PaymentInviteMessage instance using the specified properties. + * @function create + * @memberof proto.PaymentInviteMessage + * @static + * @param {proto.IPaymentInviteMessage=} [properties] Properties to set + * @returns {proto.PaymentInviteMessage} PaymentInviteMessage instance + */ + PaymentInviteMessage.create = function create(properties) { + return new PaymentInviteMessage(properties); + }; + + /** + * Encodes the specified PaymentInviteMessage message. Does not implicitly {@link proto.PaymentInviteMessage.verify|verify} messages. + * @function encode + * @memberof proto.PaymentInviteMessage + * @static + * @param {proto.IPaymentInviteMessage} message PaymentInviteMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PaymentInviteMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.serviceType != null && Object.hasOwnProperty.call(message, "serviceType")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.serviceType); + if (message.expiryTimestamp != null && Object.hasOwnProperty.call(message, "expiryTimestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.expiryTimestamp); + return writer; + }; + + /** + * Encodes the specified PaymentInviteMessage message, length delimited. Does not implicitly {@link proto.PaymentInviteMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.PaymentInviteMessage + * @static + * @param {proto.IPaymentInviteMessage} message PaymentInviteMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PaymentInviteMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a PaymentInviteMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.PaymentInviteMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.PaymentInviteMessage} PaymentInviteMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PaymentInviteMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentInviteMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.serviceType = reader.int32(); + break; + case 2: + message.expiryTimestamp = reader.int64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a PaymentInviteMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.PaymentInviteMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.PaymentInviteMessage} PaymentInviteMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PaymentInviteMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a PaymentInviteMessage message. + * @function verify + * @memberof proto.PaymentInviteMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + PaymentInviteMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.serviceType != null && message.hasOwnProperty("serviceType")) + switch (message.serviceType) { + default: + return "serviceType: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp")) + if (!$util.isInteger(message.expiryTimestamp) && !(message.expiryTimestamp && $util.isInteger(message.expiryTimestamp.low) && $util.isInteger(message.expiryTimestamp.high))) + return "expiryTimestamp: integer|Long expected"; + return null; + }; + + /** + * Creates a PaymentInviteMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.PaymentInviteMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.PaymentInviteMessage} PaymentInviteMessage + */ + PaymentInviteMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.PaymentInviteMessage) + return object; + var message = new $root.proto.PaymentInviteMessage(); + switch (object.serviceType) { + case "UNKNOWN": + case 0: + message.serviceType = 0; + break; + case "FBPAY": + case 1: + message.serviceType = 1; + break; + case "NOVI": + case 2: + message.serviceType = 2; + break; + case "UPI": + case 3: + message.serviceType = 3; + break; + } + if (object.expiryTimestamp != null) + if ($util.Long) + (message.expiryTimestamp = $util.Long.fromValue(object.expiryTimestamp)).unsigned = false; + else if (typeof object.expiryTimestamp === "string") + message.expiryTimestamp = parseInt(object.expiryTimestamp, 10); + else if (typeof object.expiryTimestamp === "number") + message.expiryTimestamp = object.expiryTimestamp; + else if (typeof object.expiryTimestamp === "object") + message.expiryTimestamp = new $util.LongBits(object.expiryTimestamp.low >>> 0, object.expiryTimestamp.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from a PaymentInviteMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.PaymentInviteMessage + * @static + * @param {proto.PaymentInviteMessage} message PaymentInviteMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + PaymentInviteMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.serviceType = options.enums === String ? "UNKNOWN" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.expiryTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.expiryTimestamp = options.longs === String ? "0" : 0; + } + if (message.serviceType != null && message.hasOwnProperty("serviceType")) + object.serviceType = options.enums === String ? $root.proto.PaymentInviteMessage.PaymentInviteMessageServiceType[message.serviceType] : message.serviceType; + if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp")) + if (typeof message.expiryTimestamp === "number") + object.expiryTimestamp = options.longs === String ? String(message.expiryTimestamp) : message.expiryTimestamp; + else + object.expiryTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.expiryTimestamp) : options.longs === Number ? new $util.LongBits(message.expiryTimestamp.low >>> 0, message.expiryTimestamp.high >>> 0).toNumber() : message.expiryTimestamp; + return object; + }; + + /** + * Converts this PaymentInviteMessage to JSON. + * @function toJSON + * @memberof proto.PaymentInviteMessage + * @instance + * @returns {Object.} JSON object + */ + PaymentInviteMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * PaymentInviteMessageServiceType enum. + * @name proto.PaymentInviteMessage.PaymentInviteMessageServiceType + * @enum {number} + * @property {number} UNKNOWN=0 UNKNOWN value + * @property {number} FBPAY=1 FBPAY value + * @property {number} NOVI=2 NOVI value + * @property {number} UPI=3 UPI value + */ + PaymentInviteMessage.PaymentInviteMessageServiceType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN"] = 0; + values[valuesById[1] = "FBPAY"] = 1; + values[valuesById[2] = "NOVI"] = 2; + values[valuesById[3] = "UPI"] = 3; + return values; + })(); + + return PaymentInviteMessage; + })(); + proto.LiveLocationMessage = (function() { /** @@ -20240,11 +35859,11 @@ $root.proto = (function() { /** * HydratedFourRowTemplate hydratedTitleText. - * @member {string} hydratedTitleText + * @member {string|null|undefined} hydratedTitleText * @memberof proto.HydratedFourRowTemplate * @instance */ - HydratedFourRowTemplate.prototype.hydratedTitleText = ""; + HydratedFourRowTemplate.prototype.hydratedTitleText = null; /** * HydratedFourRowTemplate imageMessage. @@ -21431,6 +37050,7 @@ $root.proto = (function() { * @property {string|null} [url] ProductSnapshot url * @property {number|null} [productImageCount] ProductSnapshot productImageCount * @property {string|null} [firstImageId] ProductSnapshot firstImageId + * @property {number|Long|null} [salePriceAmount1000] ProductSnapshot salePriceAmount1000 */ /** @@ -21528,6 +37148,14 @@ $root.proto = (function() { */ ProductSnapshot.prototype.firstImageId = ""; + /** + * ProductSnapshot salePriceAmount1000. + * @member {number|Long} salePriceAmount1000 + * @memberof proto.ProductSnapshot + * @instance + */ + ProductSnapshot.prototype.salePriceAmount1000 = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + /** * Creates a new ProductSnapshot instance using the specified properties. * @function create @@ -21572,6 +37200,8 @@ $root.proto = (function() { writer.uint32(/* id 9, wireType 0 =*/72).uint32(message.productImageCount); if (message.firstImageId != null && Object.hasOwnProperty.call(message, "firstImageId")) writer.uint32(/* id 11, wireType 2 =*/90).string(message.firstImageId); + if (message.salePriceAmount1000 != null && Object.hasOwnProperty.call(message, "salePriceAmount1000")) + writer.uint32(/* id 12, wireType 0 =*/96).int64(message.salePriceAmount1000); return writer; }; @@ -21636,6 +37266,9 @@ $root.proto = (function() { case 11: message.firstImageId = reader.string(); break; + case 12: + message.salePriceAmount1000 = reader.int64(); + break; default: reader.skipType(tag & 7); break; @@ -21703,6 +37336,9 @@ $root.proto = (function() { if (message.firstImageId != null && message.hasOwnProperty("firstImageId")) if (!$util.isString(message.firstImageId)) return "firstImageId: string expected"; + if (message.salePriceAmount1000 != null && message.hasOwnProperty("salePriceAmount1000")) + if (!$util.isInteger(message.salePriceAmount1000) && !(message.salePriceAmount1000 && $util.isInteger(message.salePriceAmount1000.low) && $util.isInteger(message.salePriceAmount1000.high))) + return "salePriceAmount1000: integer|Long expected"; return null; }; @@ -21748,6 +37384,15 @@ $root.proto = (function() { message.productImageCount = object.productImageCount >>> 0; if (object.firstImageId != null) message.firstImageId = String(object.firstImageId); + if (object.salePriceAmount1000 != null) + if ($util.Long) + (message.salePriceAmount1000 = $util.Long.fromValue(object.salePriceAmount1000)).unsigned = false; + else if (typeof object.salePriceAmount1000 === "string") + message.salePriceAmount1000 = parseInt(object.salePriceAmount1000, 10); + else if (typeof object.salePriceAmount1000 === "number") + message.salePriceAmount1000 = object.salePriceAmount1000; + else if (typeof object.salePriceAmount1000 === "object") + message.salePriceAmount1000 = new $util.LongBits(object.salePriceAmount1000.low >>> 0, object.salePriceAmount1000.high >>> 0).toNumber(); return message; }; @@ -21779,6 +37424,11 @@ $root.proto = (function() { object.url = ""; object.productImageCount = 0; object.firstImageId = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.salePriceAmount1000 = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.salePriceAmount1000 = options.longs === String ? "0" : 0; } if (message.productImage != null && message.hasOwnProperty("productImage")) object.productImage = $root.proto.ImageMessage.toObject(message.productImage, options); @@ -21803,6 +37453,11 @@ $root.proto = (function() { object.productImageCount = message.productImageCount; if (message.firstImageId != null && message.hasOwnProperty("firstImageId")) object.firstImageId = message.firstImageId; + if (message.salePriceAmount1000 != null && message.hasOwnProperty("salePriceAmount1000")) + if (typeof message.salePriceAmount1000 === "number") + object.salePriceAmount1000 = options.longs === String ? String(message.salePriceAmount1000) : message.salePriceAmount1000; + else + object.salePriceAmount1000 = options.longs === String ? $util.Long.prototype.toString.call(message.salePriceAmount1000) : options.longs === Number ? new $util.LongBits(message.salePriceAmount1000.low >>> 0, message.salePriceAmount1000.high >>> 0).toNumber() : message.salePriceAmount1000; return object; }; @@ -22104,6 +37759,8 @@ $root.proto = (function() { * @property {string|null} [orderTitle] OrderMessage orderTitle * @property {string|null} [sellerJid] OrderMessage sellerJid * @property {string|null} [token] OrderMessage token + * @property {number|Long|null} [totalAmount1000] OrderMessage totalAmount1000 + * @property {string|null} [totalCurrencyCode] OrderMessage totalCurrencyCode * @property {proto.IContextInfo|null} [contextInfo] OrderMessage contextInfo */ @@ -22194,6 +37851,22 @@ $root.proto = (function() { */ OrderMessage.prototype.token = ""; + /** + * OrderMessage totalAmount1000. + * @member {number|Long} totalAmount1000 + * @memberof proto.OrderMessage + * @instance + */ + OrderMessage.prototype.totalAmount1000 = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * OrderMessage totalCurrencyCode. + * @member {string} totalCurrencyCode + * @memberof proto.OrderMessage + * @instance + */ + OrderMessage.prototype.totalCurrencyCode = ""; + /** * OrderMessage contextInfo. * @member {proto.IContextInfo|null|undefined} contextInfo @@ -22244,6 +37917,10 @@ $root.proto = (function() { writer.uint32(/* id 8, wireType 2 =*/66).string(message.sellerJid); if (message.token != null && Object.hasOwnProperty.call(message, "token")) writer.uint32(/* id 9, wireType 2 =*/74).string(message.token); + if (message.totalAmount1000 != null && Object.hasOwnProperty.call(message, "totalAmount1000")) + writer.uint32(/* id 10, wireType 0 =*/80).int64(message.totalAmount1000); + if (message.totalCurrencyCode != null && Object.hasOwnProperty.call(message, "totalCurrencyCode")) + writer.uint32(/* id 11, wireType 2 =*/90).string(message.totalCurrencyCode); if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo")) $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim(); return writer; @@ -22307,6 +37984,12 @@ $root.proto = (function() { case 9: message.token = reader.string(); break; + case 10: + message.totalAmount1000 = reader.int64(); + break; + case 11: + message.totalCurrencyCode = reader.string(); + break; case 17: message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32()); break; @@ -22380,6 +38063,12 @@ $root.proto = (function() { if (message.token != null && message.hasOwnProperty("token")) if (!$util.isString(message.token)) return "token: string expected"; + if (message.totalAmount1000 != null && message.hasOwnProperty("totalAmount1000")) + if (!$util.isInteger(message.totalAmount1000) && !(message.totalAmount1000 && $util.isInteger(message.totalAmount1000.low) && $util.isInteger(message.totalAmount1000.high))) + return "totalAmount1000: integer|Long expected"; + if (message.totalCurrencyCode != null && message.hasOwnProperty("totalCurrencyCode")) + if (!$util.isString(message.totalCurrencyCode)) + return "totalCurrencyCode: string expected"; if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) { var error = $root.proto.ContextInfo.verify(message.contextInfo); if (error) @@ -22429,6 +38118,17 @@ $root.proto = (function() { message.sellerJid = String(object.sellerJid); if (object.token != null) message.token = String(object.token); + if (object.totalAmount1000 != null) + if ($util.Long) + (message.totalAmount1000 = $util.Long.fromValue(object.totalAmount1000)).unsigned = false; + else if (typeof object.totalAmount1000 === "string") + message.totalAmount1000 = parseInt(object.totalAmount1000, 10); + else if (typeof object.totalAmount1000 === "number") + message.totalAmount1000 = object.totalAmount1000; + else if (typeof object.totalAmount1000 === "object") + message.totalAmount1000 = new $util.LongBits(object.totalAmount1000.low >>> 0, object.totalAmount1000.high >>> 0).toNumber(); + if (object.totalCurrencyCode != null) + message.totalCurrencyCode = String(object.totalCurrencyCode); if (object.contextInfo != null) { if (typeof object.contextInfo !== "object") throw TypeError(".proto.OrderMessage.contextInfo: object expected"); @@ -22466,6 +38166,12 @@ $root.proto = (function() { object.orderTitle = ""; object.sellerJid = ""; object.token = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.totalAmount1000 = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.totalAmount1000 = options.longs === String ? "0" : 0; + object.totalCurrencyCode = ""; object.contextInfo = null; } if (message.orderId != null && message.hasOwnProperty("orderId")) @@ -22486,6 +38192,13 @@ $root.proto = (function() { object.sellerJid = message.sellerJid; if (message.token != null && message.hasOwnProperty("token")) object.token = message.token; + if (message.totalAmount1000 != null && message.hasOwnProperty("totalAmount1000")) + if (typeof message.totalAmount1000 === "number") + object.totalAmount1000 = options.longs === String ? String(message.totalAmount1000) : message.totalAmount1000; + else + object.totalAmount1000 = options.longs === String ? $util.Long.prototype.toString.call(message.totalAmount1000) : options.longs === Number ? new $util.LongBits(message.totalAmount1000.low >>> 0, message.totalAmount1000.high >>> 0).toNumber() : message.totalAmount1000; + if (message.totalCurrencyCode != null && message.hasOwnProperty("totalCurrencyCode")) + object.totalCurrencyCode = message.totalCurrencyCode; if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options); return object; @@ -22992,6 +38705,902 @@ $root.proto = (function() { return Section; })(); + proto.Product = (function() { + + /** + * Properties of a Product. + * @memberof proto + * @interface IProduct + * @property {string|null} [productId] Product productId + */ + + /** + * Constructs a new Product. + * @memberof proto + * @classdesc Represents a Product. + * @implements IProduct + * @constructor + * @param {proto.IProduct=} [properties] Properties to set + */ + function Product(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Product productId. + * @member {string} productId + * @memberof proto.Product + * @instance + */ + Product.prototype.productId = ""; + + /** + * Creates a new Product instance using the specified properties. + * @function create + * @memberof proto.Product + * @static + * @param {proto.IProduct=} [properties] Properties to set + * @returns {proto.Product} Product instance + */ + Product.create = function create(properties) { + return new Product(properties); + }; + + /** + * Encodes the specified Product message. Does not implicitly {@link proto.Product.verify|verify} messages. + * @function encode + * @memberof proto.Product + * @static + * @param {proto.IProduct} message Product message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Product.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.productId != null && Object.hasOwnProperty.call(message, "productId")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.productId); + return writer; + }; + + /** + * Encodes the specified Product message, length delimited. Does not implicitly {@link proto.Product.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Product + * @static + * @param {proto.IProduct} message Product message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Product.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Product message from the specified reader or buffer. + * @function decode + * @memberof proto.Product + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Product} Product + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Product.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Product(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.productId = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Product message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Product + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Product} Product + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Product.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Product message. + * @function verify + * @memberof proto.Product + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Product.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.productId != null && message.hasOwnProperty("productId")) + if (!$util.isString(message.productId)) + return "productId: string expected"; + return null; + }; + + /** + * Creates a Product message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Product + * @static + * @param {Object.} object Plain object + * @returns {proto.Product} Product + */ + Product.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Product) + return object; + var message = new $root.proto.Product(); + if (object.productId != null) + message.productId = String(object.productId); + return message; + }; + + /** + * Creates a plain object from a Product message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Product + * @static + * @param {proto.Product} message Product + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Product.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.productId = ""; + if (message.productId != null && message.hasOwnProperty("productId")) + object.productId = message.productId; + return object; + }; + + /** + * Converts this Product to JSON. + * @function toJSON + * @memberof proto.Product + * @instance + * @returns {Object.} JSON object + */ + Product.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Product; + })(); + + proto.ProductSection = (function() { + + /** + * Properties of a ProductSection. + * @memberof proto + * @interface IProductSection + * @property {string|null} [title] ProductSection title + * @property {Array.|null} [products] ProductSection products + */ + + /** + * Constructs a new ProductSection. + * @memberof proto + * @classdesc Represents a ProductSection. + * @implements IProductSection + * @constructor + * @param {proto.IProductSection=} [properties] Properties to set + */ + function ProductSection(properties) { + this.products = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ProductSection title. + * @member {string} title + * @memberof proto.ProductSection + * @instance + */ + ProductSection.prototype.title = ""; + + /** + * ProductSection products. + * @member {Array.} products + * @memberof proto.ProductSection + * @instance + */ + ProductSection.prototype.products = $util.emptyArray; + + /** + * Creates a new ProductSection instance using the specified properties. + * @function create + * @memberof proto.ProductSection + * @static + * @param {proto.IProductSection=} [properties] Properties to set + * @returns {proto.ProductSection} ProductSection instance + */ + ProductSection.create = function create(properties) { + return new ProductSection(properties); + }; + + /** + * Encodes the specified ProductSection message. Does not implicitly {@link proto.ProductSection.verify|verify} messages. + * @function encode + * @memberof proto.ProductSection + * @static + * @param {proto.IProductSection} message ProductSection message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ProductSection.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.title != null && Object.hasOwnProperty.call(message, "title")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.title); + if (message.products != null && message.products.length) + for (var i = 0; i < message.products.length; ++i) + $root.proto.Product.encode(message.products[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified ProductSection message, length delimited. Does not implicitly {@link proto.ProductSection.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ProductSection + * @static + * @param {proto.IProductSection} message ProductSection message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ProductSection.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ProductSection message from the specified reader or buffer. + * @function decode + * @memberof proto.ProductSection + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ProductSection} ProductSection + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ProductSection.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ProductSection(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.title = reader.string(); + break; + case 2: + if (!(message.products && message.products.length)) + message.products = []; + message.products.push($root.proto.Product.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ProductSection message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ProductSection + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ProductSection} ProductSection + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ProductSection.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ProductSection message. + * @function verify + * @memberof proto.ProductSection + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ProductSection.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.title != null && message.hasOwnProperty("title")) + if (!$util.isString(message.title)) + return "title: string expected"; + if (message.products != null && message.hasOwnProperty("products")) { + if (!Array.isArray(message.products)) + return "products: array expected"; + for (var i = 0; i < message.products.length; ++i) { + var error = $root.proto.Product.verify(message.products[i]); + if (error) + return "products." + error; + } + } + return null; + }; + + /** + * Creates a ProductSection message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ProductSection + * @static + * @param {Object.} object Plain object + * @returns {proto.ProductSection} ProductSection + */ + ProductSection.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ProductSection) + return object; + var message = new $root.proto.ProductSection(); + if (object.title != null) + message.title = String(object.title); + if (object.products) { + if (!Array.isArray(object.products)) + throw TypeError(".proto.ProductSection.products: array expected"); + message.products = []; + for (var i = 0; i < object.products.length; ++i) { + if (typeof object.products[i] !== "object") + throw TypeError(".proto.ProductSection.products: object expected"); + message.products[i] = $root.proto.Product.fromObject(object.products[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a ProductSection message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ProductSection + * @static + * @param {proto.ProductSection} message ProductSection + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ProductSection.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.products = []; + if (options.defaults) + object.title = ""; + if (message.title != null && message.hasOwnProperty("title")) + object.title = message.title; + if (message.products && message.products.length) { + object.products = []; + for (var j = 0; j < message.products.length; ++j) + object.products[j] = $root.proto.Product.toObject(message.products[j], options); + } + return object; + }; + + /** + * Converts this ProductSection to JSON. + * @function toJSON + * @memberof proto.ProductSection + * @instance + * @returns {Object.} JSON object + */ + ProductSection.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ProductSection; + })(); + + proto.ProductListHeaderImage = (function() { + + /** + * Properties of a ProductListHeaderImage. + * @memberof proto + * @interface IProductListHeaderImage + * @property {string|null} [productId] ProductListHeaderImage productId + * @property {Uint8Array|null} [jpegThumbnail] ProductListHeaderImage jpegThumbnail + */ + + /** + * Constructs a new ProductListHeaderImage. + * @memberof proto + * @classdesc Represents a ProductListHeaderImage. + * @implements IProductListHeaderImage + * @constructor + * @param {proto.IProductListHeaderImage=} [properties] Properties to set + */ + function ProductListHeaderImage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ProductListHeaderImage productId. + * @member {string} productId + * @memberof proto.ProductListHeaderImage + * @instance + */ + ProductListHeaderImage.prototype.productId = ""; + + /** + * ProductListHeaderImage jpegThumbnail. + * @member {Uint8Array} jpegThumbnail + * @memberof proto.ProductListHeaderImage + * @instance + */ + ProductListHeaderImage.prototype.jpegThumbnail = $util.newBuffer([]); + + /** + * Creates a new ProductListHeaderImage instance using the specified properties. + * @function create + * @memberof proto.ProductListHeaderImage + * @static + * @param {proto.IProductListHeaderImage=} [properties] Properties to set + * @returns {proto.ProductListHeaderImage} ProductListHeaderImage instance + */ + ProductListHeaderImage.create = function create(properties) { + return new ProductListHeaderImage(properties); + }; + + /** + * Encodes the specified ProductListHeaderImage message. Does not implicitly {@link proto.ProductListHeaderImage.verify|verify} messages. + * @function encode + * @memberof proto.ProductListHeaderImage + * @static + * @param {proto.IProductListHeaderImage} message ProductListHeaderImage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ProductListHeaderImage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.productId != null && Object.hasOwnProperty.call(message, "productId")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.productId); + if (message.jpegThumbnail != null && Object.hasOwnProperty.call(message, "jpegThumbnail")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.jpegThumbnail); + return writer; + }; + + /** + * Encodes the specified ProductListHeaderImage message, length delimited. Does not implicitly {@link proto.ProductListHeaderImage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ProductListHeaderImage + * @static + * @param {proto.IProductListHeaderImage} message ProductListHeaderImage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ProductListHeaderImage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ProductListHeaderImage message from the specified reader or buffer. + * @function decode + * @memberof proto.ProductListHeaderImage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ProductListHeaderImage} ProductListHeaderImage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ProductListHeaderImage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ProductListHeaderImage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.productId = reader.string(); + break; + case 2: + message.jpegThumbnail = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ProductListHeaderImage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ProductListHeaderImage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ProductListHeaderImage} ProductListHeaderImage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ProductListHeaderImage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ProductListHeaderImage message. + * @function verify + * @memberof proto.ProductListHeaderImage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ProductListHeaderImage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.productId != null && message.hasOwnProperty("productId")) + if (!$util.isString(message.productId)) + return "productId: string expected"; + if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail")) + if (!(message.jpegThumbnail && typeof message.jpegThumbnail.length === "number" || $util.isString(message.jpegThumbnail))) + return "jpegThumbnail: buffer expected"; + return null; + }; + + /** + * Creates a ProductListHeaderImage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ProductListHeaderImage + * @static + * @param {Object.} object Plain object + * @returns {proto.ProductListHeaderImage} ProductListHeaderImage + */ + ProductListHeaderImage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ProductListHeaderImage) + return object; + var message = new $root.proto.ProductListHeaderImage(); + if (object.productId != null) + message.productId = String(object.productId); + if (object.jpegThumbnail != null) + if (typeof object.jpegThumbnail === "string") + $util.base64.decode(object.jpegThumbnail, message.jpegThumbnail = $util.newBuffer($util.base64.length(object.jpegThumbnail)), 0); + else if (object.jpegThumbnail.length) + message.jpegThumbnail = object.jpegThumbnail; + return message; + }; + + /** + * Creates a plain object from a ProductListHeaderImage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ProductListHeaderImage + * @static + * @param {proto.ProductListHeaderImage} message ProductListHeaderImage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ProductListHeaderImage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.productId = ""; + if (options.bytes === String) + object.jpegThumbnail = ""; + else { + object.jpegThumbnail = []; + if (options.bytes !== Array) + object.jpegThumbnail = $util.newBuffer(object.jpegThumbnail); + } + } + if (message.productId != null && message.hasOwnProperty("productId")) + object.productId = message.productId; + if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail")) + object.jpegThumbnail = options.bytes === String ? $util.base64.encode(message.jpegThumbnail, 0, message.jpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.jpegThumbnail) : message.jpegThumbnail; + return object; + }; + + /** + * Converts this ProductListHeaderImage to JSON. + * @function toJSON + * @memberof proto.ProductListHeaderImage + * @instance + * @returns {Object.} JSON object + */ + ProductListHeaderImage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ProductListHeaderImage; + })(); + + proto.ProductListInfo = (function() { + + /** + * Properties of a ProductListInfo. + * @memberof proto + * @interface IProductListInfo + * @property {Array.|null} [productSections] ProductListInfo productSections + * @property {proto.IProductListHeaderImage|null} [headerImage] ProductListInfo headerImage + * @property {string|null} [businessOwnerJid] ProductListInfo businessOwnerJid + */ + + /** + * Constructs a new ProductListInfo. + * @memberof proto + * @classdesc Represents a ProductListInfo. + * @implements IProductListInfo + * @constructor + * @param {proto.IProductListInfo=} [properties] Properties to set + */ + function ProductListInfo(properties) { + this.productSections = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ProductListInfo productSections. + * @member {Array.} productSections + * @memberof proto.ProductListInfo + * @instance + */ + ProductListInfo.prototype.productSections = $util.emptyArray; + + /** + * ProductListInfo headerImage. + * @member {proto.IProductListHeaderImage|null|undefined} headerImage + * @memberof proto.ProductListInfo + * @instance + */ + ProductListInfo.prototype.headerImage = null; + + /** + * ProductListInfo businessOwnerJid. + * @member {string} businessOwnerJid + * @memberof proto.ProductListInfo + * @instance + */ + ProductListInfo.prototype.businessOwnerJid = ""; + + /** + * Creates a new ProductListInfo instance using the specified properties. + * @function create + * @memberof proto.ProductListInfo + * @static + * @param {proto.IProductListInfo=} [properties] Properties to set + * @returns {proto.ProductListInfo} ProductListInfo instance + */ + ProductListInfo.create = function create(properties) { + return new ProductListInfo(properties); + }; + + /** + * Encodes the specified ProductListInfo message. Does not implicitly {@link proto.ProductListInfo.verify|verify} messages. + * @function encode + * @memberof proto.ProductListInfo + * @static + * @param {proto.IProductListInfo} message ProductListInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ProductListInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.productSections != null && message.productSections.length) + for (var i = 0; i < message.productSections.length; ++i) + $root.proto.ProductSection.encode(message.productSections[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.headerImage != null && Object.hasOwnProperty.call(message, "headerImage")) + $root.proto.ProductListHeaderImage.encode(message.headerImage, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.businessOwnerJid != null && Object.hasOwnProperty.call(message, "businessOwnerJid")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.businessOwnerJid); + return writer; + }; + + /** + * Encodes the specified ProductListInfo message, length delimited. Does not implicitly {@link proto.ProductListInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ProductListInfo + * @static + * @param {proto.IProductListInfo} message ProductListInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ProductListInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ProductListInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.ProductListInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ProductListInfo} ProductListInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ProductListInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ProductListInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.productSections && message.productSections.length)) + message.productSections = []; + message.productSections.push($root.proto.ProductSection.decode(reader, reader.uint32())); + break; + case 2: + message.headerImage = $root.proto.ProductListHeaderImage.decode(reader, reader.uint32()); + break; + case 3: + message.businessOwnerJid = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ProductListInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ProductListInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ProductListInfo} ProductListInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ProductListInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ProductListInfo message. + * @function verify + * @memberof proto.ProductListInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ProductListInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.productSections != null && message.hasOwnProperty("productSections")) { + if (!Array.isArray(message.productSections)) + return "productSections: array expected"; + for (var i = 0; i < message.productSections.length; ++i) { + var error = $root.proto.ProductSection.verify(message.productSections[i]); + if (error) + return "productSections." + error; + } + } + if (message.headerImage != null && message.hasOwnProperty("headerImage")) { + var error = $root.proto.ProductListHeaderImage.verify(message.headerImage); + if (error) + return "headerImage." + error; + } + if (message.businessOwnerJid != null && message.hasOwnProperty("businessOwnerJid")) + if (!$util.isString(message.businessOwnerJid)) + return "businessOwnerJid: string expected"; + return null; + }; + + /** + * Creates a ProductListInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ProductListInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.ProductListInfo} ProductListInfo + */ + ProductListInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ProductListInfo) + return object; + var message = new $root.proto.ProductListInfo(); + if (object.productSections) { + if (!Array.isArray(object.productSections)) + throw TypeError(".proto.ProductListInfo.productSections: array expected"); + message.productSections = []; + for (var i = 0; i < object.productSections.length; ++i) { + if (typeof object.productSections[i] !== "object") + throw TypeError(".proto.ProductListInfo.productSections: object expected"); + message.productSections[i] = $root.proto.ProductSection.fromObject(object.productSections[i]); + } + } + if (object.headerImage != null) { + if (typeof object.headerImage !== "object") + throw TypeError(".proto.ProductListInfo.headerImage: object expected"); + message.headerImage = $root.proto.ProductListHeaderImage.fromObject(object.headerImage); + } + if (object.businessOwnerJid != null) + message.businessOwnerJid = String(object.businessOwnerJid); + return message; + }; + + /** + * Creates a plain object from a ProductListInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ProductListInfo + * @static + * @param {proto.ProductListInfo} message ProductListInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ProductListInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.productSections = []; + if (options.defaults) { + object.headerImage = null; + object.businessOwnerJid = ""; + } + if (message.productSections && message.productSections.length) { + object.productSections = []; + for (var j = 0; j < message.productSections.length; ++j) + object.productSections[j] = $root.proto.ProductSection.toObject(message.productSections[j], options); + } + if (message.headerImage != null && message.hasOwnProperty("headerImage")) + object.headerImage = $root.proto.ProductListHeaderImage.toObject(message.headerImage, options); + if (message.businessOwnerJid != null && message.hasOwnProperty("businessOwnerJid")) + object.businessOwnerJid = message.businessOwnerJid; + return object; + }; + + /** + * Converts this ProductListInfo to JSON. + * @function toJSON + * @memberof proto.ProductListInfo + * @instance + * @returns {Object.} JSON object + */ + ProductListInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ProductListInfo; + })(); + proto.ListMessage = (function() { /** @@ -23003,6 +39612,9 @@ $root.proto = (function() { * @property {string|null} [buttonText] ListMessage buttonText * @property {proto.ListMessage.ListMessageListType|null} [listType] ListMessage listType * @property {Array.|null} [sections] ListMessage sections + * @property {proto.IProductListInfo|null} [productListInfo] ListMessage productListInfo + * @property {string|null} [footerText] ListMessage footerText + * @property {proto.IContextInfo|null} [contextInfo] ListMessage contextInfo */ /** @@ -23061,6 +39673,30 @@ $root.proto = (function() { */ ListMessage.prototype.sections = $util.emptyArray; + /** + * ListMessage productListInfo. + * @member {proto.IProductListInfo|null|undefined} productListInfo + * @memberof proto.ListMessage + * @instance + */ + ListMessage.prototype.productListInfo = null; + + /** + * ListMessage footerText. + * @member {string} footerText + * @memberof proto.ListMessage + * @instance + */ + ListMessage.prototype.footerText = ""; + + /** + * ListMessage contextInfo. + * @member {proto.IContextInfo|null|undefined} contextInfo + * @memberof proto.ListMessage + * @instance + */ + ListMessage.prototype.contextInfo = null; + /** * Creates a new ListMessage instance using the specified properties. * @function create @@ -23096,6 +39732,12 @@ $root.proto = (function() { if (message.sections != null && message.sections.length) for (var i = 0; i < message.sections.length; ++i) $root.proto.Section.encode(message.sections[i], writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + if (message.productListInfo != null && Object.hasOwnProperty.call(message, "productListInfo")) + $root.proto.ProductListInfo.encode(message.productListInfo, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.footerText != null && Object.hasOwnProperty.call(message, "footerText")) + writer.uint32(/* id 7, wireType 2 =*/58).string(message.footerText); + if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo")) + $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim(); return writer; }; @@ -23147,6 +39789,15 @@ $root.proto = (function() { message.sections = []; message.sections.push($root.proto.Section.decode(reader, reader.uint32())); break; + case 6: + message.productListInfo = $root.proto.ProductListInfo.decode(reader, reader.uint32()); + break; + case 7: + message.footerText = reader.string(); + break; + case 8: + message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -23197,6 +39848,7 @@ $root.proto = (function() { return "listType: enum value expected"; case 0: case 1: + case 2: break; } if (message.sections != null && message.hasOwnProperty("sections")) { @@ -23208,6 +39860,19 @@ $root.proto = (function() { return "sections." + error; } } + if (message.productListInfo != null && message.hasOwnProperty("productListInfo")) { + var error = $root.proto.ProductListInfo.verify(message.productListInfo); + if (error) + return "productListInfo." + error; + } + if (message.footerText != null && message.hasOwnProperty("footerText")) + if (!$util.isString(message.footerText)) + return "footerText: string expected"; + if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) { + var error = $root.proto.ContextInfo.verify(message.contextInfo); + if (error) + return "contextInfo." + error; + } return null; }; @@ -23238,6 +39903,10 @@ $root.proto = (function() { case 1: message.listType = 1; break; + case "PRODUCT_LIST": + case 2: + message.listType = 2; + break; } if (object.sections) { if (!Array.isArray(object.sections)) @@ -23249,6 +39918,18 @@ $root.proto = (function() { message.sections[i] = $root.proto.Section.fromObject(object.sections[i]); } } + if (object.productListInfo != null) { + if (typeof object.productListInfo !== "object") + throw TypeError(".proto.ListMessage.productListInfo: object expected"); + message.productListInfo = $root.proto.ProductListInfo.fromObject(object.productListInfo); + } + if (object.footerText != null) + message.footerText = String(object.footerText); + if (object.contextInfo != null) { + if (typeof object.contextInfo !== "object") + throw TypeError(".proto.ListMessage.contextInfo: object expected"); + message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo); + } return message; }; @@ -23272,6 +39953,9 @@ $root.proto = (function() { object.description = ""; object.buttonText = ""; object.listType = options.enums === String ? "UNKNOWN" : 0; + object.productListInfo = null; + object.footerText = ""; + object.contextInfo = null; } if (message.title != null && message.hasOwnProperty("title")) object.title = message.title; @@ -23286,6 +39970,12 @@ $root.proto = (function() { for (var j = 0; j < message.sections.length; ++j) object.sections[j] = $root.proto.Section.toObject(message.sections[j], options); } + if (message.productListInfo != null && message.hasOwnProperty("productListInfo")) + object.productListInfo = $root.proto.ProductListInfo.toObject(message.productListInfo, options); + if (message.footerText != null && message.hasOwnProperty("footerText")) + object.footerText = message.footerText; + if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) + object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options); return object; }; @@ -23306,11 +39996,13 @@ $root.proto = (function() { * @enum {number} * @property {number} UNKNOWN=0 UNKNOWN value * @property {number} SINGLE_SELECT=1 SINGLE_SELECT value + * @property {number} PRODUCT_LIST=2 PRODUCT_LIST value */ ListMessage.ListMessageListType = (function() { var valuesById = {}, values = Object.create(valuesById); values[valuesById[0] = "UNKNOWN"] = 0; values[valuesById[1] = "SINGLE_SELECT"] = 1; + values[valuesById[2] = "PRODUCT_LIST"] = 2; return values; })(); @@ -23510,10 +40202,11 @@ $root.proto = (function() { * Properties of a ListResponseMessage. * @memberof proto * @interface IListResponseMessage - * @property {string|null} [selectedDisplayText] ListResponseMessage selectedDisplayText + * @property {string|null} [title] ListResponseMessage title * @property {proto.ListResponseMessage.ListResponseMessageListType|null} [listType] ListResponseMessage listType * @property {proto.ISingleSelectReply|null} [singleSelectReply] ListResponseMessage singleSelectReply * @property {proto.IContextInfo|null} [contextInfo] ListResponseMessage contextInfo + * @property {string|null} [description] ListResponseMessage description */ /** @@ -23532,12 +40225,12 @@ $root.proto = (function() { } /** - * ListResponseMessage selectedDisplayText. - * @member {string} selectedDisplayText + * ListResponseMessage title. + * @member {string} title * @memberof proto.ListResponseMessage * @instance */ - ListResponseMessage.prototype.selectedDisplayText = ""; + ListResponseMessage.prototype.title = ""; /** * ListResponseMessage listType. @@ -23563,6 +40256,14 @@ $root.proto = (function() { */ ListResponseMessage.prototype.contextInfo = null; + /** + * ListResponseMessage description. + * @member {string} description + * @memberof proto.ListResponseMessage + * @instance + */ + ListResponseMessage.prototype.description = ""; + /** * Creates a new ListResponseMessage instance using the specified properties. * @function create @@ -23587,14 +40288,16 @@ $root.proto = (function() { ListResponseMessage.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.selectedDisplayText != null && Object.hasOwnProperty.call(message, "selectedDisplayText")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.selectedDisplayText); + if (message.title != null && Object.hasOwnProperty.call(message, "title")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.title); if (message.listType != null && Object.hasOwnProperty.call(message, "listType")) writer.uint32(/* id 2, wireType 0 =*/16).int32(message.listType); if (message.singleSelectReply != null && Object.hasOwnProperty.call(message, "singleSelectReply")) $root.proto.SingleSelectReply.encode(message.singleSelectReply, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo")) $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + if (message.description != null && Object.hasOwnProperty.call(message, "description")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.description); return writer; }; @@ -23630,7 +40333,7 @@ $root.proto = (function() { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.selectedDisplayText = reader.string(); + message.title = reader.string(); break; case 2: message.listType = reader.int32(); @@ -23641,6 +40344,9 @@ $root.proto = (function() { case 4: message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32()); break; + case 5: + message.description = reader.string(); + break; default: reader.skipType(tag & 7); break; @@ -23676,9 +40382,9 @@ $root.proto = (function() { ListResponseMessage.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.selectedDisplayText != null && message.hasOwnProperty("selectedDisplayText")) - if (!$util.isString(message.selectedDisplayText)) - return "selectedDisplayText: string expected"; + if (message.title != null && message.hasOwnProperty("title")) + if (!$util.isString(message.title)) + return "title: string expected"; if (message.listType != null && message.hasOwnProperty("listType")) switch (message.listType) { default: @@ -23697,6 +40403,9 @@ $root.proto = (function() { if (error) return "contextInfo." + error; } + if (message.description != null && message.hasOwnProperty("description")) + if (!$util.isString(message.description)) + return "description: string expected"; return null; }; @@ -23712,8 +40421,8 @@ $root.proto = (function() { if (object instanceof $root.proto.ListResponseMessage) return object; var message = new $root.proto.ListResponseMessage(); - if (object.selectedDisplayText != null) - message.selectedDisplayText = String(object.selectedDisplayText); + if (object.title != null) + message.title = String(object.title); switch (object.listType) { case "UNKNOWN": case 0: @@ -23734,6 +40443,8 @@ $root.proto = (function() { throw TypeError(".proto.ListResponseMessage.contextInfo: object expected"); message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo); } + if (object.description != null) + message.description = String(object.description); return message; }; @@ -23751,19 +40462,22 @@ $root.proto = (function() { options = {}; var object = {}; if (options.defaults) { - object.selectedDisplayText = ""; + object.title = ""; object.listType = options.enums === String ? "UNKNOWN" : 0; object.singleSelectReply = null; object.contextInfo = null; + object.description = ""; } - if (message.selectedDisplayText != null && message.hasOwnProperty("selectedDisplayText")) - object.selectedDisplayText = message.selectedDisplayText; + if (message.title != null && message.hasOwnProperty("title")) + object.title = message.title; if (message.listType != null && message.hasOwnProperty("listType")) object.listType = options.enums === String ? $root.proto.ListResponseMessage.ListResponseMessageListType[message.listType] : message.listType; if (message.singleSelectReply != null && message.hasOwnProperty("singleSelectReply")) object.singleSelectReply = $root.proto.SingleSelectReply.toObject(message.singleSelectReply, options); if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options); + if (message.description != null && message.hasOwnProperty("description")) + object.description = message.description; return object; }; @@ -24143,252 +40857,6 @@ $root.proto = (function() { return GroupInviteMessage; })(); - proto.EphemeralSetting = (function() { - - /** - * Properties of an EphemeralSetting. - * @memberof proto - * @interface IEphemeralSetting - * @property {string|null} [chatJid] EphemeralSetting chatJid - * @property {number|null} [ephemeralExpiration] EphemeralSetting ephemeralExpiration - * @property {number|Long|null} [ephemeralSettingTimestamp] EphemeralSetting ephemeralSettingTimestamp - */ - - /** - * Constructs a new EphemeralSetting. - * @memberof proto - * @classdesc Represents an EphemeralSetting. - * @implements IEphemeralSetting - * @constructor - * @param {proto.IEphemeralSetting=} [properties] Properties to set - */ - function EphemeralSetting(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * EphemeralSetting chatJid. - * @member {string} chatJid - * @memberof proto.EphemeralSetting - * @instance - */ - EphemeralSetting.prototype.chatJid = ""; - - /** - * EphemeralSetting ephemeralExpiration. - * @member {number} ephemeralExpiration - * @memberof proto.EphemeralSetting - * @instance - */ - EphemeralSetting.prototype.ephemeralExpiration = 0; - - /** - * EphemeralSetting ephemeralSettingTimestamp. - * @member {number|Long} ephemeralSettingTimestamp - * @memberof proto.EphemeralSetting - * @instance - */ - EphemeralSetting.prototype.ephemeralSettingTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * Creates a new EphemeralSetting instance using the specified properties. - * @function create - * @memberof proto.EphemeralSetting - * @static - * @param {proto.IEphemeralSetting=} [properties] Properties to set - * @returns {proto.EphemeralSetting} EphemeralSetting instance - */ - EphemeralSetting.create = function create(properties) { - return new EphemeralSetting(properties); - }; - - /** - * Encodes the specified EphemeralSetting message. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. - * @function encode - * @memberof proto.EphemeralSetting - * @static - * @param {proto.IEphemeralSetting} message EphemeralSetting message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - EphemeralSetting.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.chatJid != null && Object.hasOwnProperty.call(message, "chatJid")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.chatJid); - if (message.ephemeralExpiration != null && Object.hasOwnProperty.call(message, "ephemeralExpiration")) - writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.ephemeralExpiration); - if (message.ephemeralSettingTimestamp != null && Object.hasOwnProperty.call(message, "ephemeralSettingTimestamp")) - writer.uint32(/* id 3, wireType 0 =*/24).int64(message.ephemeralSettingTimestamp); - return writer; - }; - - /** - * Encodes the specified EphemeralSetting message, length delimited. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.EphemeralSetting - * @static - * @param {proto.IEphemeralSetting} message EphemeralSetting message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - EphemeralSetting.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes an EphemeralSetting message from the specified reader or buffer. - * @function decode - * @memberof proto.EphemeralSetting - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.EphemeralSetting} EphemeralSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - EphemeralSetting.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.EphemeralSetting(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.chatJid = reader.string(); - break; - case 2: - message.ephemeralExpiration = reader.uint32(); - break; - case 3: - message.ephemeralSettingTimestamp = reader.int64(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes an EphemeralSetting message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.EphemeralSetting - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.EphemeralSetting} EphemeralSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - EphemeralSetting.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies an EphemeralSetting message. - * @function verify - * @memberof proto.EphemeralSetting - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - EphemeralSetting.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.chatJid != null && message.hasOwnProperty("chatJid")) - if (!$util.isString(message.chatJid)) - return "chatJid: string expected"; - if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration")) - if (!$util.isInteger(message.ephemeralExpiration)) - return "ephemeralExpiration: integer expected"; - if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp")) - if (!$util.isInteger(message.ephemeralSettingTimestamp) && !(message.ephemeralSettingTimestamp && $util.isInteger(message.ephemeralSettingTimestamp.low) && $util.isInteger(message.ephemeralSettingTimestamp.high))) - return "ephemeralSettingTimestamp: integer|Long expected"; - return null; - }; - - /** - * Creates an EphemeralSetting message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.EphemeralSetting - * @static - * @param {Object.} object Plain object - * @returns {proto.EphemeralSetting} EphemeralSetting - */ - EphemeralSetting.fromObject = function fromObject(object) { - if (object instanceof $root.proto.EphemeralSetting) - return object; - var message = new $root.proto.EphemeralSetting(); - if (object.chatJid != null) - message.chatJid = String(object.chatJid); - if (object.ephemeralExpiration != null) - message.ephemeralExpiration = object.ephemeralExpiration >>> 0; - if (object.ephemeralSettingTimestamp != null) - if ($util.Long) - (message.ephemeralSettingTimestamp = $util.Long.fromValue(object.ephemeralSettingTimestamp)).unsigned = false; - else if (typeof object.ephemeralSettingTimestamp === "string") - message.ephemeralSettingTimestamp = parseInt(object.ephemeralSettingTimestamp, 10); - else if (typeof object.ephemeralSettingTimestamp === "number") - message.ephemeralSettingTimestamp = object.ephemeralSettingTimestamp; - else if (typeof object.ephemeralSettingTimestamp === "object") - message.ephemeralSettingTimestamp = new $util.LongBits(object.ephemeralSettingTimestamp.low >>> 0, object.ephemeralSettingTimestamp.high >>> 0).toNumber(); - return message; - }; - - /** - * Creates a plain object from an EphemeralSetting message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.EphemeralSetting - * @static - * @param {proto.EphemeralSetting} message EphemeralSetting - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - EphemeralSetting.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.chatJid = ""; - object.ephemeralExpiration = 0; - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.ephemeralSettingTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.ephemeralSettingTimestamp = options.longs === String ? "0" : 0; - } - if (message.chatJid != null && message.hasOwnProperty("chatJid")) - object.chatJid = message.chatJid; - if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration")) - object.ephemeralExpiration = message.ephemeralExpiration; - if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp")) - if (typeof message.ephemeralSettingTimestamp === "number") - object.ephemeralSettingTimestamp = options.longs === String ? String(message.ephemeralSettingTimestamp) : message.ephemeralSettingTimestamp; - else - object.ephemeralSettingTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.ephemeralSettingTimestamp) : options.longs === Number ? new $util.LongBits(message.ephemeralSettingTimestamp.low >>> 0, message.ephemeralSettingTimestamp.high >>> 0).toNumber() : message.ephemeralSettingTimestamp; - return object; - }; - - /** - * Converts this EphemeralSetting to JSON. - * @function toJSON - * @memberof proto.EphemeralSetting - * @instance - * @returns {Object.} JSON object - */ - EphemeralSetting.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return EphemeralSetting; - })(); - proto.DeviceSentMessage = (function() { /** @@ -24398,7 +40866,6 @@ $root.proto = (function() { * @property {string|null} [destinationJid] DeviceSentMessage destinationJid * @property {proto.IMessage|null} [message] DeviceSentMessage message * @property {string|null} [phash] DeviceSentMessage phash - * @property {Array.|null} [broadcastEphemeralSettings] DeviceSentMessage broadcastEphemeralSettings */ /** @@ -24410,7 +40877,6 @@ $root.proto = (function() { * @param {proto.IDeviceSentMessage=} [properties] Properties to set */ function DeviceSentMessage(properties) { - this.broadcastEphemeralSettings = []; if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -24441,14 +40907,6 @@ $root.proto = (function() { */ DeviceSentMessage.prototype.phash = ""; - /** - * DeviceSentMessage broadcastEphemeralSettings. - * @member {Array.} broadcastEphemeralSettings - * @memberof proto.DeviceSentMessage - * @instance - */ - DeviceSentMessage.prototype.broadcastEphemeralSettings = $util.emptyArray; - /** * Creates a new DeviceSentMessage instance using the specified properties. * @function create @@ -24479,9 +40937,6 @@ $root.proto = (function() { $root.proto.Message.encode(message.message, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); if (message.phash != null && Object.hasOwnProperty.call(message, "phash")) writer.uint32(/* id 3, wireType 2 =*/26).string(message.phash); - if (message.broadcastEphemeralSettings != null && message.broadcastEphemeralSettings.length) - for (var i = 0; i < message.broadcastEphemeralSettings.length; ++i) - $root.proto.EphemeralSetting.encode(message.broadcastEphemeralSettings[i], writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); return writer; }; @@ -24525,11 +40980,6 @@ $root.proto = (function() { case 3: message.phash = reader.string(); break; - case 4: - if (!(message.broadcastEphemeralSettings && message.broadcastEphemeralSettings.length)) - message.broadcastEphemeralSettings = []; - message.broadcastEphemeralSettings.push($root.proto.EphemeralSetting.decode(reader, reader.uint32())); - break; default: reader.skipType(tag & 7); break; @@ -24576,15 +41026,6 @@ $root.proto = (function() { if (message.phash != null && message.hasOwnProperty("phash")) if (!$util.isString(message.phash)) return "phash: string expected"; - if (message.broadcastEphemeralSettings != null && message.hasOwnProperty("broadcastEphemeralSettings")) { - if (!Array.isArray(message.broadcastEphemeralSettings)) - return "broadcastEphemeralSettings: array expected"; - for (var i = 0; i < message.broadcastEphemeralSettings.length; ++i) { - var error = $root.proto.EphemeralSetting.verify(message.broadcastEphemeralSettings[i]); - if (error) - return "broadcastEphemeralSettings." + error; - } - } return null; }; @@ -24609,16 +41050,6 @@ $root.proto = (function() { } if (object.phash != null) message.phash = String(object.phash); - if (object.broadcastEphemeralSettings) { - if (!Array.isArray(object.broadcastEphemeralSettings)) - throw TypeError(".proto.DeviceSentMessage.broadcastEphemeralSettings: array expected"); - message.broadcastEphemeralSettings = []; - for (var i = 0; i < object.broadcastEphemeralSettings.length; ++i) { - if (typeof object.broadcastEphemeralSettings[i] !== "object") - throw TypeError(".proto.DeviceSentMessage.broadcastEphemeralSettings: object expected"); - message.broadcastEphemeralSettings[i] = $root.proto.EphemeralSetting.fromObject(object.broadcastEphemeralSettings[i]); - } - } return message; }; @@ -24635,8 +41066,6 @@ $root.proto = (function() { if (!options) options = {}; var object = {}; - if (options.arrays || options.defaults) - object.broadcastEphemeralSettings = []; if (options.defaults) { object.destinationJid = ""; object.message = null; @@ -24648,11 +41077,6 @@ $root.proto = (function() { object.message = $root.proto.Message.toObject(message.message, options); if (message.phash != null && message.hasOwnProperty("phash")) object.phash = message.phash; - if (message.broadcastEphemeralSettings && message.broadcastEphemeralSettings.length) { - object.broadcastEphemeralSettings = []; - for (var j = 0; j < message.broadcastEphemeralSettings.length; ++j) - object.broadcastEphemeralSettings[j] = $root.proto.EphemeralSetting.toObject(message.broadcastEphemeralSettings[j], options); - } return object; }; @@ -24862,6 +41286,1548 @@ $root.proto = (function() { return FutureProofMessage; })(); + proto.ButtonText = (function() { + + /** + * Properties of a ButtonText. + * @memberof proto + * @interface IButtonText + * @property {string|null} [displayText] ButtonText displayText + */ + + /** + * Constructs a new ButtonText. + * @memberof proto + * @classdesc Represents a ButtonText. + * @implements IButtonText + * @constructor + * @param {proto.IButtonText=} [properties] Properties to set + */ + function ButtonText(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ButtonText displayText. + * @member {string} displayText + * @memberof proto.ButtonText + * @instance + */ + ButtonText.prototype.displayText = ""; + + /** + * Creates a new ButtonText instance using the specified properties. + * @function create + * @memberof proto.ButtonText + * @static + * @param {proto.IButtonText=} [properties] Properties to set + * @returns {proto.ButtonText} ButtonText instance + */ + ButtonText.create = function create(properties) { + return new ButtonText(properties); + }; + + /** + * Encodes the specified ButtonText message. Does not implicitly {@link proto.ButtonText.verify|verify} messages. + * @function encode + * @memberof proto.ButtonText + * @static + * @param {proto.IButtonText} message ButtonText message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ButtonText.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); + return writer; + }; + + /** + * Encodes the specified ButtonText message, length delimited. Does not implicitly {@link proto.ButtonText.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ButtonText + * @static + * @param {proto.IButtonText} message ButtonText message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ButtonText.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ButtonText message from the specified reader or buffer. + * @function decode + * @memberof proto.ButtonText + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ButtonText} ButtonText + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ButtonText.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ButtonText(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ButtonText message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ButtonText + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ButtonText} ButtonText + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ButtonText.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ButtonText message. + * @function verify + * @memberof proto.ButtonText + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ButtonText.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) + if (!$util.isString(message.displayText)) + return "displayText: string expected"; + return null; + }; + + /** + * Creates a ButtonText message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ButtonText + * @static + * @param {Object.} object Plain object + * @returns {proto.ButtonText} ButtonText + */ + ButtonText.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ButtonText) + return object; + var message = new $root.proto.ButtonText(); + if (object.displayText != null) + message.displayText = String(object.displayText); + return message; + }; + + /** + * Creates a plain object from a ButtonText message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ButtonText + * @static + * @param {proto.ButtonText} message ButtonText + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ButtonText.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.displayText = ""; + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = message.displayText; + return object; + }; + + /** + * Converts this ButtonText to JSON. + * @function toJSON + * @memberof proto.ButtonText + * @instance + * @returns {Object.} JSON object + */ + ButtonText.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ButtonText; + })(); + + proto.NativeFlowInfo = (function() { + + /** + * Properties of a NativeFlowInfo. + * @memberof proto + * @interface INativeFlowInfo + * @property {string|null} [name] NativeFlowInfo name + * @property {string|null} [paramsJson] NativeFlowInfo paramsJson + */ + + /** + * Constructs a new NativeFlowInfo. + * @memberof proto + * @classdesc Represents a NativeFlowInfo. + * @implements INativeFlowInfo + * @constructor + * @param {proto.INativeFlowInfo=} [properties] Properties to set + */ + function NativeFlowInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * NativeFlowInfo name. + * @member {string} name + * @memberof proto.NativeFlowInfo + * @instance + */ + NativeFlowInfo.prototype.name = ""; + + /** + * NativeFlowInfo paramsJson. + * @member {string} paramsJson + * @memberof proto.NativeFlowInfo + * @instance + */ + NativeFlowInfo.prototype.paramsJson = ""; + + /** + * Creates a new NativeFlowInfo instance using the specified properties. + * @function create + * @memberof proto.NativeFlowInfo + * @static + * @param {proto.INativeFlowInfo=} [properties] Properties to set + * @returns {proto.NativeFlowInfo} NativeFlowInfo instance + */ + NativeFlowInfo.create = function create(properties) { + return new NativeFlowInfo(properties); + }; + + /** + * Encodes the specified NativeFlowInfo message. Does not implicitly {@link proto.NativeFlowInfo.verify|verify} messages. + * @function encode + * @memberof proto.NativeFlowInfo + * @static + * @param {proto.INativeFlowInfo} message NativeFlowInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + NativeFlowInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.name); + if (message.paramsJson != null && Object.hasOwnProperty.call(message, "paramsJson")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.paramsJson); + return writer; + }; + + /** + * Encodes the specified NativeFlowInfo message, length delimited. Does not implicitly {@link proto.NativeFlowInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.NativeFlowInfo + * @static + * @param {proto.INativeFlowInfo} message NativeFlowInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + NativeFlowInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a NativeFlowInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.NativeFlowInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.NativeFlowInfo} NativeFlowInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + NativeFlowInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NativeFlowInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.name = reader.string(); + break; + case 2: + message.paramsJson = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a NativeFlowInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.NativeFlowInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.NativeFlowInfo} NativeFlowInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + NativeFlowInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a NativeFlowInfo message. + * @function verify + * @memberof proto.NativeFlowInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + NativeFlowInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + if (message.paramsJson != null && message.hasOwnProperty("paramsJson")) + if (!$util.isString(message.paramsJson)) + return "paramsJson: string expected"; + return null; + }; + + /** + * Creates a NativeFlowInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.NativeFlowInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.NativeFlowInfo} NativeFlowInfo + */ + NativeFlowInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.NativeFlowInfo) + return object; + var message = new $root.proto.NativeFlowInfo(); + if (object.name != null) + message.name = String(object.name); + if (object.paramsJson != null) + message.paramsJson = String(object.paramsJson); + return message; + }; + + /** + * Creates a plain object from a NativeFlowInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.NativeFlowInfo + * @static + * @param {proto.NativeFlowInfo} message NativeFlowInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + NativeFlowInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.name = ""; + object.paramsJson = ""; + } + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.paramsJson != null && message.hasOwnProperty("paramsJson")) + object.paramsJson = message.paramsJson; + return object; + }; + + /** + * Converts this NativeFlowInfo to JSON. + * @function toJSON + * @memberof proto.NativeFlowInfo + * @instance + * @returns {Object.} JSON object + */ + NativeFlowInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return NativeFlowInfo; + })(); + + proto.Button = (function() { + + /** + * Properties of a Button. + * @memberof proto + * @interface IButton + * @property {string|null} [buttonId] Button buttonId + * @property {proto.IButtonText|null} [buttonText] Button buttonText + * @property {proto.Button.ButtonType|null} [type] Button type + * @property {proto.INativeFlowInfo|null} [nativeFlowInfo] Button nativeFlowInfo + */ + + /** + * Constructs a new Button. + * @memberof proto + * @classdesc Represents a Button. + * @implements IButton + * @constructor + * @param {proto.IButton=} [properties] Properties to set + */ + function Button(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Button buttonId. + * @member {string} buttonId + * @memberof proto.Button + * @instance + */ + Button.prototype.buttonId = ""; + + /** + * Button buttonText. + * @member {proto.IButtonText|null|undefined} buttonText + * @memberof proto.Button + * @instance + */ + Button.prototype.buttonText = null; + + /** + * Button type. + * @member {proto.Button.ButtonType} type + * @memberof proto.Button + * @instance + */ + Button.prototype.type = 0; + + /** + * Button nativeFlowInfo. + * @member {proto.INativeFlowInfo|null|undefined} nativeFlowInfo + * @memberof proto.Button + * @instance + */ + Button.prototype.nativeFlowInfo = null; + + /** + * Creates a new Button instance using the specified properties. + * @function create + * @memberof proto.Button + * @static + * @param {proto.IButton=} [properties] Properties to set + * @returns {proto.Button} Button instance + */ + Button.create = function create(properties) { + return new Button(properties); + }; + + /** + * Encodes the specified Button message. Does not implicitly {@link proto.Button.verify|verify} messages. + * @function encode + * @memberof proto.Button + * @static + * @param {proto.IButton} message Button message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Button.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.buttonId != null && Object.hasOwnProperty.call(message, "buttonId")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.buttonId); + if (message.buttonText != null && Object.hasOwnProperty.call(message, "buttonText")) + $root.proto.ButtonText.encode(message.buttonText, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.type != null && Object.hasOwnProperty.call(message, "type")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.type); + if (message.nativeFlowInfo != null && Object.hasOwnProperty.call(message, "nativeFlowInfo")) + $root.proto.NativeFlowInfo.encode(message.nativeFlowInfo, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified Button message, length delimited. Does not implicitly {@link proto.Button.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Button + * @static + * @param {proto.IButton} message Button message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Button.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Button message from the specified reader or buffer. + * @function decode + * @memberof proto.Button + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Button} Button + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Button.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Button(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.buttonId = reader.string(); + break; + case 2: + message.buttonText = $root.proto.ButtonText.decode(reader, reader.uint32()); + break; + case 3: + message.type = reader.int32(); + break; + case 4: + message.nativeFlowInfo = $root.proto.NativeFlowInfo.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Button message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Button + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Button} Button + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Button.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Button message. + * @function verify + * @memberof proto.Button + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Button.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.buttonId != null && message.hasOwnProperty("buttonId")) + if (!$util.isString(message.buttonId)) + return "buttonId: string expected"; + if (message.buttonText != null && message.hasOwnProperty("buttonText")) { + var error = $root.proto.ButtonText.verify(message.buttonText); + if (error) + return "buttonText." + error; + } + if (message.type != null && message.hasOwnProperty("type")) + switch (message.type) { + default: + return "type: enum value expected"; + case 0: + case 1: + case 2: + break; + } + if (message.nativeFlowInfo != null && message.hasOwnProperty("nativeFlowInfo")) { + var error = $root.proto.NativeFlowInfo.verify(message.nativeFlowInfo); + if (error) + return "nativeFlowInfo." + error; + } + return null; + }; + + /** + * Creates a Button message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Button + * @static + * @param {Object.} object Plain object + * @returns {proto.Button} Button + */ + Button.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Button) + return object; + var message = new $root.proto.Button(); + if (object.buttonId != null) + message.buttonId = String(object.buttonId); + if (object.buttonText != null) { + if (typeof object.buttonText !== "object") + throw TypeError(".proto.Button.buttonText: object expected"); + message.buttonText = $root.proto.ButtonText.fromObject(object.buttonText); + } + switch (object.type) { + case "UNKNOWN": + case 0: + message.type = 0; + break; + case "RESPONSE": + case 1: + message.type = 1; + break; + case "NATIVE_FLOW": + case 2: + message.type = 2; + break; + } + if (object.nativeFlowInfo != null) { + if (typeof object.nativeFlowInfo !== "object") + throw TypeError(".proto.Button.nativeFlowInfo: object expected"); + message.nativeFlowInfo = $root.proto.NativeFlowInfo.fromObject(object.nativeFlowInfo); + } + return message; + }; + + /** + * Creates a plain object from a Button message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Button + * @static + * @param {proto.Button} message Button + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Button.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.buttonId = ""; + object.buttonText = null; + object.type = options.enums === String ? "UNKNOWN" : 0; + object.nativeFlowInfo = null; + } + if (message.buttonId != null && message.hasOwnProperty("buttonId")) + object.buttonId = message.buttonId; + if (message.buttonText != null && message.hasOwnProperty("buttonText")) + object.buttonText = $root.proto.ButtonText.toObject(message.buttonText, options); + if (message.type != null && message.hasOwnProperty("type")) + object.type = options.enums === String ? $root.proto.Button.ButtonType[message.type] : message.type; + if (message.nativeFlowInfo != null && message.hasOwnProperty("nativeFlowInfo")) + object.nativeFlowInfo = $root.proto.NativeFlowInfo.toObject(message.nativeFlowInfo, options); + return object; + }; + + /** + * Converts this Button to JSON. + * @function toJSON + * @memberof proto.Button + * @instance + * @returns {Object.} JSON object + */ + Button.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * ButtonType enum. + * @name proto.Button.ButtonType + * @enum {number} + * @property {number} UNKNOWN=0 UNKNOWN value + * @property {number} RESPONSE=1 RESPONSE value + * @property {number} NATIVE_FLOW=2 NATIVE_FLOW value + */ + Button.ButtonType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN"] = 0; + values[valuesById[1] = "RESPONSE"] = 1; + values[valuesById[2] = "NATIVE_FLOW"] = 2; + return values; + })(); + + return Button; + })(); + + proto.ButtonsMessage = (function() { + + /** + * Properties of a ButtonsMessage. + * @memberof proto + * @interface IButtonsMessage + * @property {string|null} [contentText] ButtonsMessage contentText + * @property {string|null} [footerText] ButtonsMessage footerText + * @property {proto.IContextInfo|null} [contextInfo] ButtonsMessage contextInfo + * @property {Array.|null} [buttons] ButtonsMessage buttons + * @property {proto.ButtonsMessage.ButtonsMessageHeaderType|null} [headerType] ButtonsMessage headerType + * @property {string|null} [text] ButtonsMessage text + * @property {proto.IDocumentMessage|null} [documentMessage] ButtonsMessage documentMessage + * @property {proto.IImageMessage|null} [imageMessage] ButtonsMessage imageMessage + * @property {proto.IVideoMessage|null} [videoMessage] ButtonsMessage videoMessage + * @property {proto.ILocationMessage|null} [locationMessage] ButtonsMessage locationMessage + */ + + /** + * Constructs a new ButtonsMessage. + * @memberof proto + * @classdesc Represents a ButtonsMessage. + * @implements IButtonsMessage + * @constructor + * @param {proto.IButtonsMessage=} [properties] Properties to set + */ + function ButtonsMessage(properties) { + this.buttons = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ButtonsMessage contentText. + * @member {string} contentText + * @memberof proto.ButtonsMessage + * @instance + */ + ButtonsMessage.prototype.contentText = ""; + + /** + * ButtonsMessage footerText. + * @member {string} footerText + * @memberof proto.ButtonsMessage + * @instance + */ + ButtonsMessage.prototype.footerText = ""; + + /** + * ButtonsMessage contextInfo. + * @member {proto.IContextInfo|null|undefined} contextInfo + * @memberof proto.ButtonsMessage + * @instance + */ + ButtonsMessage.prototype.contextInfo = null; + + /** + * ButtonsMessage buttons. + * @member {Array.} buttons + * @memberof proto.ButtonsMessage + * @instance + */ + ButtonsMessage.prototype.buttons = $util.emptyArray; + + /** + * ButtonsMessage headerType. + * @member {proto.ButtonsMessage.ButtonsMessageHeaderType} headerType + * @memberof proto.ButtonsMessage + * @instance + */ + ButtonsMessage.prototype.headerType = 0; + + /** + * ButtonsMessage text. + * @member {string|null|undefined} text + * @memberof proto.ButtonsMessage + * @instance + */ + ButtonsMessage.prototype.text = null; + + /** + * ButtonsMessage documentMessage. + * @member {proto.IDocumentMessage|null|undefined} documentMessage + * @memberof proto.ButtonsMessage + * @instance + */ + ButtonsMessage.prototype.documentMessage = null; + + /** + * ButtonsMessage imageMessage. + * @member {proto.IImageMessage|null|undefined} imageMessage + * @memberof proto.ButtonsMessage + * @instance + */ + ButtonsMessage.prototype.imageMessage = null; + + /** + * ButtonsMessage videoMessage. + * @member {proto.IVideoMessage|null|undefined} videoMessage + * @memberof proto.ButtonsMessage + * @instance + */ + ButtonsMessage.prototype.videoMessage = null; + + /** + * ButtonsMessage locationMessage. + * @member {proto.ILocationMessage|null|undefined} locationMessage + * @memberof proto.ButtonsMessage + * @instance + */ + ButtonsMessage.prototype.locationMessage = null; + + // OneOf field names bound to virtual getters and setters + var $oneOfFields; + + /** + * ButtonsMessage header. + * @member {"text"|"documentMessage"|"imageMessage"|"videoMessage"|"locationMessage"|undefined} header + * @memberof proto.ButtonsMessage + * @instance + */ + Object.defineProperty(ButtonsMessage.prototype, "header", { + get: $util.oneOfGetter($oneOfFields = ["text", "documentMessage", "imageMessage", "videoMessage", "locationMessage"]), + set: $util.oneOfSetter($oneOfFields) + }); + + /** + * Creates a new ButtonsMessage instance using the specified properties. + * @function create + * @memberof proto.ButtonsMessage + * @static + * @param {proto.IButtonsMessage=} [properties] Properties to set + * @returns {proto.ButtonsMessage} ButtonsMessage instance + */ + ButtonsMessage.create = function create(properties) { + return new ButtonsMessage(properties); + }; + + /** + * Encodes the specified ButtonsMessage message. Does not implicitly {@link proto.ButtonsMessage.verify|verify} messages. + * @function encode + * @memberof proto.ButtonsMessage + * @static + * @param {proto.IButtonsMessage} message ButtonsMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ButtonsMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.text != null && Object.hasOwnProperty.call(message, "text")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.text); + if (message.documentMessage != null && Object.hasOwnProperty.call(message, "documentMessage")) + $root.proto.DocumentMessage.encode(message.documentMessage, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.imageMessage != null && Object.hasOwnProperty.call(message, "imageMessage")) + $root.proto.ImageMessage.encode(message.imageMessage, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.videoMessage != null && Object.hasOwnProperty.call(message, "videoMessage")) + $root.proto.VideoMessage.encode(message.videoMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + if (message.locationMessage != null && Object.hasOwnProperty.call(message, "locationMessage")) + $root.proto.LocationMessage.encode(message.locationMessage, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + if (message.contentText != null && Object.hasOwnProperty.call(message, "contentText")) + writer.uint32(/* id 6, wireType 2 =*/50).string(message.contentText); + if (message.footerText != null && Object.hasOwnProperty.call(message, "footerText")) + writer.uint32(/* id 7, wireType 2 =*/58).string(message.footerText); + if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo")) + $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim(); + if (message.buttons != null && message.buttons.length) + for (var i = 0; i < message.buttons.length; ++i) + $root.proto.Button.encode(message.buttons[i], writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim(); + if (message.headerType != null && Object.hasOwnProperty.call(message, "headerType")) + writer.uint32(/* id 10, wireType 0 =*/80).int32(message.headerType); + return writer; + }; + + /** + * Encodes the specified ButtonsMessage message, length delimited. Does not implicitly {@link proto.ButtonsMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ButtonsMessage + * @static + * @param {proto.IButtonsMessage} message ButtonsMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ButtonsMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ButtonsMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.ButtonsMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ButtonsMessage} ButtonsMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ButtonsMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ButtonsMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 6: + message.contentText = reader.string(); + break; + case 7: + message.footerText = reader.string(); + break; + case 8: + message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32()); + break; + case 9: + if (!(message.buttons && message.buttons.length)) + message.buttons = []; + message.buttons.push($root.proto.Button.decode(reader, reader.uint32())); + break; + case 10: + message.headerType = reader.int32(); + break; + case 1: + message.text = reader.string(); + break; + case 2: + message.documentMessage = $root.proto.DocumentMessage.decode(reader, reader.uint32()); + break; + case 3: + message.imageMessage = $root.proto.ImageMessage.decode(reader, reader.uint32()); + break; + case 4: + message.videoMessage = $root.proto.VideoMessage.decode(reader, reader.uint32()); + break; + case 5: + message.locationMessage = $root.proto.LocationMessage.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ButtonsMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ButtonsMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ButtonsMessage} ButtonsMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ButtonsMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ButtonsMessage message. + * @function verify + * @memberof proto.ButtonsMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ButtonsMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var properties = {}; + if (message.contentText != null && message.hasOwnProperty("contentText")) + if (!$util.isString(message.contentText)) + return "contentText: string expected"; + if (message.footerText != null && message.hasOwnProperty("footerText")) + if (!$util.isString(message.footerText)) + return "footerText: string expected"; + if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) { + var error = $root.proto.ContextInfo.verify(message.contextInfo); + if (error) + return "contextInfo." + error; + } + if (message.buttons != null && message.hasOwnProperty("buttons")) { + if (!Array.isArray(message.buttons)) + return "buttons: array expected"; + for (var i = 0; i < message.buttons.length; ++i) { + var error = $root.proto.Button.verify(message.buttons[i]); + if (error) + return "buttons." + error; + } + } + if (message.headerType != null && message.hasOwnProperty("headerType")) + switch (message.headerType) { + default: + return "headerType: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + break; + } + if (message.text != null && message.hasOwnProperty("text")) { + properties.header = 1; + if (!$util.isString(message.text)) + return "text: string expected"; + } + if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) { + if (properties.header === 1) + return "header: multiple values"; + properties.header = 1; + { + var error = $root.proto.DocumentMessage.verify(message.documentMessage); + if (error) + return "documentMessage." + error; + } + } + if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) { + if (properties.header === 1) + return "header: multiple values"; + properties.header = 1; + { + var error = $root.proto.ImageMessage.verify(message.imageMessage); + if (error) + return "imageMessage." + error; + } + } + if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) { + if (properties.header === 1) + return "header: multiple values"; + properties.header = 1; + { + var error = $root.proto.VideoMessage.verify(message.videoMessage); + if (error) + return "videoMessage." + error; + } + } + if (message.locationMessage != null && message.hasOwnProperty("locationMessage")) { + if (properties.header === 1) + return "header: multiple values"; + properties.header = 1; + { + var error = $root.proto.LocationMessage.verify(message.locationMessage); + if (error) + return "locationMessage." + error; + } + } + return null; + }; + + /** + * Creates a ButtonsMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ButtonsMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.ButtonsMessage} ButtonsMessage + */ + ButtonsMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ButtonsMessage) + return object; + var message = new $root.proto.ButtonsMessage(); + if (object.contentText != null) + message.contentText = String(object.contentText); + if (object.footerText != null) + message.footerText = String(object.footerText); + if (object.contextInfo != null) { + if (typeof object.contextInfo !== "object") + throw TypeError(".proto.ButtonsMessage.contextInfo: object expected"); + message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo); + } + if (object.buttons) { + if (!Array.isArray(object.buttons)) + throw TypeError(".proto.ButtonsMessage.buttons: array expected"); + message.buttons = []; + for (var i = 0; i < object.buttons.length; ++i) { + if (typeof object.buttons[i] !== "object") + throw TypeError(".proto.ButtonsMessage.buttons: object expected"); + message.buttons[i] = $root.proto.Button.fromObject(object.buttons[i]); + } + } + switch (object.headerType) { + case "UNKNOWN": + case 0: + message.headerType = 0; + break; + case "EMPTY": + case 1: + message.headerType = 1; + break; + case "TEXT": + case 2: + message.headerType = 2; + break; + case "DOCUMENT": + case 3: + message.headerType = 3; + break; + case "IMAGE": + case 4: + message.headerType = 4; + break; + case "VIDEO": + case 5: + message.headerType = 5; + break; + case "LOCATION": + case 6: + message.headerType = 6; + break; + } + if (object.text != null) + message.text = String(object.text); + if (object.documentMessage != null) { + if (typeof object.documentMessage !== "object") + throw TypeError(".proto.ButtonsMessage.documentMessage: object expected"); + message.documentMessage = $root.proto.DocumentMessage.fromObject(object.documentMessage); + } + if (object.imageMessage != null) { + if (typeof object.imageMessage !== "object") + throw TypeError(".proto.ButtonsMessage.imageMessage: object expected"); + message.imageMessage = $root.proto.ImageMessage.fromObject(object.imageMessage); + } + if (object.videoMessage != null) { + if (typeof object.videoMessage !== "object") + throw TypeError(".proto.ButtonsMessage.videoMessage: object expected"); + message.videoMessage = $root.proto.VideoMessage.fromObject(object.videoMessage); + } + if (object.locationMessage != null) { + if (typeof object.locationMessage !== "object") + throw TypeError(".proto.ButtonsMessage.locationMessage: object expected"); + message.locationMessage = $root.proto.LocationMessage.fromObject(object.locationMessage); + } + return message; + }; + + /** + * Creates a plain object from a ButtonsMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ButtonsMessage + * @static + * @param {proto.ButtonsMessage} message ButtonsMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ButtonsMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.buttons = []; + if (options.defaults) { + object.contentText = ""; + object.footerText = ""; + object.contextInfo = null; + object.headerType = options.enums === String ? "UNKNOWN" : 0; + } + if (message.text != null && message.hasOwnProperty("text")) { + object.text = message.text; + if (options.oneofs) + object.header = "text"; + } + if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) { + object.documentMessage = $root.proto.DocumentMessage.toObject(message.documentMessage, options); + if (options.oneofs) + object.header = "documentMessage"; + } + if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) { + object.imageMessage = $root.proto.ImageMessage.toObject(message.imageMessage, options); + if (options.oneofs) + object.header = "imageMessage"; + } + if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) { + object.videoMessage = $root.proto.VideoMessage.toObject(message.videoMessage, options); + if (options.oneofs) + object.header = "videoMessage"; + } + if (message.locationMessage != null && message.hasOwnProperty("locationMessage")) { + object.locationMessage = $root.proto.LocationMessage.toObject(message.locationMessage, options); + if (options.oneofs) + object.header = "locationMessage"; + } + if (message.contentText != null && message.hasOwnProperty("contentText")) + object.contentText = message.contentText; + if (message.footerText != null && message.hasOwnProperty("footerText")) + object.footerText = message.footerText; + if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) + object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options); + if (message.buttons && message.buttons.length) { + object.buttons = []; + for (var j = 0; j < message.buttons.length; ++j) + object.buttons[j] = $root.proto.Button.toObject(message.buttons[j], options); + } + if (message.headerType != null && message.hasOwnProperty("headerType")) + object.headerType = options.enums === String ? $root.proto.ButtonsMessage.ButtonsMessageHeaderType[message.headerType] : message.headerType; + return object; + }; + + /** + * Converts this ButtonsMessage to JSON. + * @function toJSON + * @memberof proto.ButtonsMessage + * @instance + * @returns {Object.} JSON object + */ + ButtonsMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * ButtonsMessageHeaderType enum. + * @name proto.ButtonsMessage.ButtonsMessageHeaderType + * @enum {number} + * @property {number} UNKNOWN=0 UNKNOWN value + * @property {number} EMPTY=1 EMPTY value + * @property {number} TEXT=2 TEXT value + * @property {number} DOCUMENT=3 DOCUMENT value + * @property {number} IMAGE=4 IMAGE value + * @property {number} VIDEO=5 VIDEO value + * @property {number} LOCATION=6 LOCATION value + */ + ButtonsMessage.ButtonsMessageHeaderType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN"] = 0; + values[valuesById[1] = "EMPTY"] = 1; + values[valuesById[2] = "TEXT"] = 2; + values[valuesById[3] = "DOCUMENT"] = 3; + values[valuesById[4] = "IMAGE"] = 4; + values[valuesById[5] = "VIDEO"] = 5; + values[valuesById[6] = "LOCATION"] = 6; + return values; + })(); + + return ButtonsMessage; + })(); + + proto.ButtonsResponseMessage = (function() { + + /** + * Properties of a ButtonsResponseMessage. + * @memberof proto + * @interface IButtonsResponseMessage + * @property {string|null} [selectedButtonId] ButtonsResponseMessage selectedButtonId + * @property {proto.IContextInfo|null} [contextInfo] ButtonsResponseMessage contextInfo + * @property {proto.ButtonsResponseMessage.ButtonsResponseMessageType|null} [type] ButtonsResponseMessage type + * @property {string|null} [selectedDisplayText] ButtonsResponseMessage selectedDisplayText + */ + + /** + * Constructs a new ButtonsResponseMessage. + * @memberof proto + * @classdesc Represents a ButtonsResponseMessage. + * @implements IButtonsResponseMessage + * @constructor + * @param {proto.IButtonsResponseMessage=} [properties] Properties to set + */ + function ButtonsResponseMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ButtonsResponseMessage selectedButtonId. + * @member {string} selectedButtonId + * @memberof proto.ButtonsResponseMessage + * @instance + */ + ButtonsResponseMessage.prototype.selectedButtonId = ""; + + /** + * ButtonsResponseMessage contextInfo. + * @member {proto.IContextInfo|null|undefined} contextInfo + * @memberof proto.ButtonsResponseMessage + * @instance + */ + ButtonsResponseMessage.prototype.contextInfo = null; + + /** + * ButtonsResponseMessage type. + * @member {proto.ButtonsResponseMessage.ButtonsResponseMessageType} type + * @memberof proto.ButtonsResponseMessage + * @instance + */ + ButtonsResponseMessage.prototype.type = 0; + + /** + * ButtonsResponseMessage selectedDisplayText. + * @member {string|null|undefined} selectedDisplayText + * @memberof proto.ButtonsResponseMessage + * @instance + */ + ButtonsResponseMessage.prototype.selectedDisplayText = null; + + // OneOf field names bound to virtual getters and setters + var $oneOfFields; + + /** + * ButtonsResponseMessage response. + * @member {"selectedDisplayText"|undefined} response + * @memberof proto.ButtonsResponseMessage + * @instance + */ + Object.defineProperty(ButtonsResponseMessage.prototype, "response", { + get: $util.oneOfGetter($oneOfFields = ["selectedDisplayText"]), + set: $util.oneOfSetter($oneOfFields) + }); + + /** + * Creates a new ButtonsResponseMessage instance using the specified properties. + * @function create + * @memberof proto.ButtonsResponseMessage + * @static + * @param {proto.IButtonsResponseMessage=} [properties] Properties to set + * @returns {proto.ButtonsResponseMessage} ButtonsResponseMessage instance + */ + ButtonsResponseMessage.create = function create(properties) { + return new ButtonsResponseMessage(properties); + }; + + /** + * Encodes the specified ButtonsResponseMessage message. Does not implicitly {@link proto.ButtonsResponseMessage.verify|verify} messages. + * @function encode + * @memberof proto.ButtonsResponseMessage + * @static + * @param {proto.IButtonsResponseMessage} message ButtonsResponseMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ButtonsResponseMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.selectedButtonId != null && Object.hasOwnProperty.call(message, "selectedButtonId")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.selectedButtonId); + if (message.selectedDisplayText != null && Object.hasOwnProperty.call(message, "selectedDisplayText")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.selectedDisplayText); + if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo")) + $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.type != null && Object.hasOwnProperty.call(message, "type")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.type); + return writer; + }; + + /** + * Encodes the specified ButtonsResponseMessage message, length delimited. Does not implicitly {@link proto.ButtonsResponseMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ButtonsResponseMessage + * @static + * @param {proto.IButtonsResponseMessage} message ButtonsResponseMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ButtonsResponseMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ButtonsResponseMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.ButtonsResponseMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ButtonsResponseMessage} ButtonsResponseMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ButtonsResponseMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ButtonsResponseMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.selectedButtonId = reader.string(); + break; + case 3: + message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32()); + break; + case 4: + message.type = reader.int32(); + break; + case 2: + message.selectedDisplayText = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ButtonsResponseMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ButtonsResponseMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ButtonsResponseMessage} ButtonsResponseMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ButtonsResponseMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ButtonsResponseMessage message. + * @function verify + * @memberof proto.ButtonsResponseMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ButtonsResponseMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var properties = {}; + if (message.selectedButtonId != null && message.hasOwnProperty("selectedButtonId")) + if (!$util.isString(message.selectedButtonId)) + return "selectedButtonId: string expected"; + if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) { + var error = $root.proto.ContextInfo.verify(message.contextInfo); + if (error) + return "contextInfo." + error; + } + if (message.type != null && message.hasOwnProperty("type")) + switch (message.type) { + default: + return "type: enum value expected"; + case 0: + case 1: + break; + } + if (message.selectedDisplayText != null && message.hasOwnProperty("selectedDisplayText")) { + properties.response = 1; + if (!$util.isString(message.selectedDisplayText)) + return "selectedDisplayText: string expected"; + } + return null; + }; + + /** + * Creates a ButtonsResponseMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ButtonsResponseMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.ButtonsResponseMessage} ButtonsResponseMessage + */ + ButtonsResponseMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ButtonsResponseMessage) + return object; + var message = new $root.proto.ButtonsResponseMessage(); + if (object.selectedButtonId != null) + message.selectedButtonId = String(object.selectedButtonId); + if (object.contextInfo != null) { + if (typeof object.contextInfo !== "object") + throw TypeError(".proto.ButtonsResponseMessage.contextInfo: object expected"); + message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo); + } + switch (object.type) { + case "UNKNOWN": + case 0: + message.type = 0; + break; + case "DISPLAY_TEXT": + case 1: + message.type = 1; + break; + } + if (object.selectedDisplayText != null) + message.selectedDisplayText = String(object.selectedDisplayText); + return message; + }; + + /** + * Creates a plain object from a ButtonsResponseMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ButtonsResponseMessage + * @static + * @param {proto.ButtonsResponseMessage} message ButtonsResponseMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ButtonsResponseMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.selectedButtonId = ""; + object.contextInfo = null; + object.type = options.enums === String ? "UNKNOWN" : 0; + } + if (message.selectedButtonId != null && message.hasOwnProperty("selectedButtonId")) + object.selectedButtonId = message.selectedButtonId; + if (message.selectedDisplayText != null && message.hasOwnProperty("selectedDisplayText")) { + object.selectedDisplayText = message.selectedDisplayText; + if (options.oneofs) + object.response = "selectedDisplayText"; + } + if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) + object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options); + if (message.type != null && message.hasOwnProperty("type")) + object.type = options.enums === String ? $root.proto.ButtonsResponseMessage.ButtonsResponseMessageType[message.type] : message.type; + return object; + }; + + /** + * Converts this ButtonsResponseMessage to JSON. + * @function toJSON + * @memberof proto.ButtonsResponseMessage + * @instance + * @returns {Object.} JSON object + */ + ButtonsResponseMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * ButtonsResponseMessageType enum. + * @name proto.ButtonsResponseMessage.ButtonsResponseMessageType + * @enum {number} + * @property {number} UNKNOWN=0 UNKNOWN value + * @property {number} DISPLAY_TEXT=1 DISPLAY_TEXT value + */ + ButtonsResponseMessage.ButtonsResponseMessageType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN"] = 0; + values[valuesById[1] = "DISPLAY_TEXT"] = 1; + return values; + })(); + + return ButtonsResponseMessage; + })(); + proto.Message = (function() { /** @@ -24894,11 +42860,16 @@ $root.proto = (function() { * @property {proto.ITemplateButtonReplyMessage|null} [templateButtonReplyMessage] Message templateButtonReplyMessage * @property {proto.IProductMessage|null} [productMessage] Message productMessage * @property {proto.IDeviceSentMessage|null} [deviceSentMessage] Message deviceSentMessage + * @property {proto.IMessageContextInfo|null} [messageContextInfo] Message messageContextInfo * @property {proto.IListMessage|null} [listMessage] Message listMessage * @property {proto.IFutureProofMessage|null} [viewOnceMessage] Message viewOnceMessage * @property {proto.IOrderMessage|null} [orderMessage] Message orderMessage * @property {proto.IListResponseMessage|null} [listResponseMessage] Message listResponseMessage * @property {proto.IFutureProofMessage|null} [ephemeralMessage] Message ephemeralMessage + * @property {proto.IInvoiceMessage|null} [invoiceMessage] Message invoiceMessage + * @property {proto.IButtonsMessage|null} [buttonsMessage] Message buttonsMessage + * @property {proto.IButtonsResponseMessage|null} [buttonsResponseMessage] Message buttonsResponseMessage + * @property {proto.IPaymentInviteMessage|null} [paymentInviteMessage] Message paymentInviteMessage */ /** @@ -25124,6 +43095,14 @@ $root.proto = (function() { */ Message.prototype.deviceSentMessage = null; + /** + * Message messageContextInfo. + * @member {proto.IMessageContextInfo|null|undefined} messageContextInfo + * @memberof proto.Message + * @instance + */ + Message.prototype.messageContextInfo = null; + /** * Message listMessage. * @member {proto.IListMessage|null|undefined} listMessage @@ -25164,6 +43143,38 @@ $root.proto = (function() { */ Message.prototype.ephemeralMessage = null; + /** + * Message invoiceMessage. + * @member {proto.IInvoiceMessage|null|undefined} invoiceMessage + * @memberof proto.Message + * @instance + */ + Message.prototype.invoiceMessage = null; + + /** + * Message buttonsMessage. + * @member {proto.IButtonsMessage|null|undefined} buttonsMessage + * @memberof proto.Message + * @instance + */ + Message.prototype.buttonsMessage = null; + + /** + * Message buttonsResponseMessage. + * @member {proto.IButtonsResponseMessage|null|undefined} buttonsResponseMessage + * @memberof proto.Message + * @instance + */ + Message.prototype.buttonsResponseMessage = null; + + /** + * Message paymentInviteMessage. + * @member {proto.IPaymentInviteMessage|null|undefined} paymentInviteMessage + * @memberof proto.Message + * @instance + */ + Message.prototype.paymentInviteMessage = null; + /** * Creates a new Message instance using the specified properties. * @function create @@ -25240,6 +43251,8 @@ $root.proto = (function() { $root.proto.ProductMessage.encode(message.productMessage, writer.uint32(/* id 30, wireType 2 =*/242).fork()).ldelim(); if (message.deviceSentMessage != null && Object.hasOwnProperty.call(message, "deviceSentMessage")) $root.proto.DeviceSentMessage.encode(message.deviceSentMessage, writer.uint32(/* id 31, wireType 2 =*/250).fork()).ldelim(); + if (message.messageContextInfo != null && Object.hasOwnProperty.call(message, "messageContextInfo")) + $root.proto.MessageContextInfo.encode(message.messageContextInfo, writer.uint32(/* id 35, wireType 2 =*/282).fork()).ldelim(); if (message.listMessage != null && Object.hasOwnProperty.call(message, "listMessage")) $root.proto.ListMessage.encode(message.listMessage, writer.uint32(/* id 36, wireType 2 =*/290).fork()).ldelim(); if (message.viewOnceMessage != null && Object.hasOwnProperty.call(message, "viewOnceMessage")) @@ -25250,6 +43263,14 @@ $root.proto = (function() { $root.proto.ListResponseMessage.encode(message.listResponseMessage, writer.uint32(/* id 39, wireType 2 =*/314).fork()).ldelim(); if (message.ephemeralMessage != null && Object.hasOwnProperty.call(message, "ephemeralMessage")) $root.proto.FutureProofMessage.encode(message.ephemeralMessage, writer.uint32(/* id 40, wireType 2 =*/322).fork()).ldelim(); + if (message.invoiceMessage != null && Object.hasOwnProperty.call(message, "invoiceMessage")) + $root.proto.InvoiceMessage.encode(message.invoiceMessage, writer.uint32(/* id 41, wireType 2 =*/330).fork()).ldelim(); + if (message.buttonsMessage != null && Object.hasOwnProperty.call(message, "buttonsMessage")) + $root.proto.ButtonsMessage.encode(message.buttonsMessage, writer.uint32(/* id 42, wireType 2 =*/338).fork()).ldelim(); + if (message.buttonsResponseMessage != null && Object.hasOwnProperty.call(message, "buttonsResponseMessage")) + $root.proto.ButtonsResponseMessage.encode(message.buttonsResponseMessage, writer.uint32(/* id 43, wireType 2 =*/346).fork()).ldelim(); + if (message.paymentInviteMessage != null && Object.hasOwnProperty.call(message, "paymentInviteMessage")) + $root.proto.PaymentInviteMessage.encode(message.paymentInviteMessage, writer.uint32(/* id 44, wireType 2 =*/354).fork()).ldelim(); return writer; }; @@ -25362,6 +43383,9 @@ $root.proto = (function() { case 31: message.deviceSentMessage = $root.proto.DeviceSentMessage.decode(reader, reader.uint32()); break; + case 35: + message.messageContextInfo = $root.proto.MessageContextInfo.decode(reader, reader.uint32()); + break; case 36: message.listMessage = $root.proto.ListMessage.decode(reader, reader.uint32()); break; @@ -25377,6 +43401,18 @@ $root.proto = (function() { case 40: message.ephemeralMessage = $root.proto.FutureProofMessage.decode(reader, reader.uint32()); break; + case 41: + message.invoiceMessage = $root.proto.InvoiceMessage.decode(reader, reader.uint32()); + break; + case 42: + message.buttonsMessage = $root.proto.ButtonsMessage.decode(reader, reader.uint32()); + break; + case 43: + message.buttonsResponseMessage = $root.proto.ButtonsResponseMessage.decode(reader, reader.uint32()); + break; + case 44: + message.paymentInviteMessage = $root.proto.PaymentInviteMessage.decode(reader, reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -25540,6 +43576,11 @@ $root.proto = (function() { if (error) return "deviceSentMessage." + error; } + if (message.messageContextInfo != null && message.hasOwnProperty("messageContextInfo")) { + var error = $root.proto.MessageContextInfo.verify(message.messageContextInfo); + if (error) + return "messageContextInfo." + error; + } if (message.listMessage != null && message.hasOwnProperty("listMessage")) { var error = $root.proto.ListMessage.verify(message.listMessage); if (error) @@ -25565,6 +43606,26 @@ $root.proto = (function() { if (error) return "ephemeralMessage." + error; } + if (message.invoiceMessage != null && message.hasOwnProperty("invoiceMessage")) { + var error = $root.proto.InvoiceMessage.verify(message.invoiceMessage); + if (error) + return "invoiceMessage." + error; + } + if (message.buttonsMessage != null && message.hasOwnProperty("buttonsMessage")) { + var error = $root.proto.ButtonsMessage.verify(message.buttonsMessage); + if (error) + return "buttonsMessage." + error; + } + if (message.buttonsResponseMessage != null && message.hasOwnProperty("buttonsResponseMessage")) { + var error = $root.proto.ButtonsResponseMessage.verify(message.buttonsResponseMessage); + if (error) + return "buttonsResponseMessage." + error; + } + if (message.paymentInviteMessage != null && message.hasOwnProperty("paymentInviteMessage")) { + var error = $root.proto.PaymentInviteMessage.verify(message.paymentInviteMessage); + if (error) + return "paymentInviteMessage." + error; + } return null; }; @@ -25707,6 +43768,11 @@ $root.proto = (function() { throw TypeError(".proto.Message.deviceSentMessage: object expected"); message.deviceSentMessage = $root.proto.DeviceSentMessage.fromObject(object.deviceSentMessage); } + if (object.messageContextInfo != null) { + if (typeof object.messageContextInfo !== "object") + throw TypeError(".proto.Message.messageContextInfo: object expected"); + message.messageContextInfo = $root.proto.MessageContextInfo.fromObject(object.messageContextInfo); + } if (object.listMessage != null) { if (typeof object.listMessage !== "object") throw TypeError(".proto.Message.listMessage: object expected"); @@ -25732,6 +43798,26 @@ $root.proto = (function() { throw TypeError(".proto.Message.ephemeralMessage: object expected"); message.ephemeralMessage = $root.proto.FutureProofMessage.fromObject(object.ephemeralMessage); } + if (object.invoiceMessage != null) { + if (typeof object.invoiceMessage !== "object") + throw TypeError(".proto.Message.invoiceMessage: object expected"); + message.invoiceMessage = $root.proto.InvoiceMessage.fromObject(object.invoiceMessage); + } + if (object.buttonsMessage != null) { + if (typeof object.buttonsMessage !== "object") + throw TypeError(".proto.Message.buttonsMessage: object expected"); + message.buttonsMessage = $root.proto.ButtonsMessage.fromObject(object.buttonsMessage); + } + if (object.buttonsResponseMessage != null) { + if (typeof object.buttonsResponseMessage !== "object") + throw TypeError(".proto.Message.buttonsResponseMessage: object expected"); + message.buttonsResponseMessage = $root.proto.ButtonsResponseMessage.fromObject(object.buttonsResponseMessage); + } + if (object.paymentInviteMessage != null) { + if (typeof object.paymentInviteMessage !== "object") + throw TypeError(".proto.Message.paymentInviteMessage: object expected"); + message.paymentInviteMessage = $root.proto.PaymentInviteMessage.fromObject(object.paymentInviteMessage); + } return message; }; @@ -25775,11 +43861,16 @@ $root.proto = (function() { object.templateButtonReplyMessage = null; object.productMessage = null; object.deviceSentMessage = null; + object.messageContextInfo = null; object.listMessage = null; object.viewOnceMessage = null; object.orderMessage = null; object.listResponseMessage = null; object.ephemeralMessage = null; + object.invoiceMessage = null; + object.buttonsMessage = null; + object.buttonsResponseMessage = null; + object.paymentInviteMessage = null; } if (message.conversation != null && message.hasOwnProperty("conversation")) object.conversation = message.conversation; @@ -25833,6 +43924,8 @@ $root.proto = (function() { object.productMessage = $root.proto.ProductMessage.toObject(message.productMessage, options); if (message.deviceSentMessage != null && message.hasOwnProperty("deviceSentMessage")) object.deviceSentMessage = $root.proto.DeviceSentMessage.toObject(message.deviceSentMessage, options); + if (message.messageContextInfo != null && message.hasOwnProperty("messageContextInfo")) + object.messageContextInfo = $root.proto.MessageContextInfo.toObject(message.messageContextInfo, options); if (message.listMessage != null && message.hasOwnProperty("listMessage")) object.listMessage = $root.proto.ListMessage.toObject(message.listMessage, options); if (message.viewOnceMessage != null && message.hasOwnProperty("viewOnceMessage")) @@ -25843,6 +43936,14 @@ $root.proto = (function() { object.listResponseMessage = $root.proto.ListResponseMessage.toObject(message.listResponseMessage, options); if (message.ephemeralMessage != null && message.hasOwnProperty("ephemeralMessage")) object.ephemeralMessage = $root.proto.FutureProofMessage.toObject(message.ephemeralMessage, options); + if (message.invoiceMessage != null && message.hasOwnProperty("invoiceMessage")) + object.invoiceMessage = $root.proto.InvoiceMessage.toObject(message.invoiceMessage, options); + if (message.buttonsMessage != null && message.hasOwnProperty("buttonsMessage")) + object.buttonsMessage = $root.proto.ButtonsMessage.toObject(message.buttonsMessage, options); + if (message.buttonsResponseMessage != null && message.hasOwnProperty("buttonsResponseMessage")) + object.buttonsResponseMessage = $root.proto.ButtonsResponseMessage.toObject(message.buttonsResponseMessage, options); + if (message.paymentInviteMessage != null && message.hasOwnProperty("paymentInviteMessage")) + object.paymentInviteMessage = $root.proto.PaymentInviteMessage.toObject(message.paymentInviteMessage, options); return object; }; @@ -25860,6 +43961,1654 @@ $root.proto = (function() { return Message; })(); + proto.CompanionProps = (function() { + + /** + * Properties of a CompanionProps. + * @memberof proto + * @interface ICompanionProps + * @property {string|null} [os] CompanionProps os + * @property {proto.IAppVersion|null} [version] CompanionProps version + * @property {proto.CompanionProps.CompanionPropsPlatformType|null} [platformType] CompanionProps platformType + * @property {boolean|null} [requireFullSync] CompanionProps requireFullSync + */ + + /** + * Constructs a new CompanionProps. + * @memberof proto + * @classdesc Represents a CompanionProps. + * @implements ICompanionProps + * @constructor + * @param {proto.ICompanionProps=} [properties] Properties to set + */ + function CompanionProps(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * CompanionProps os. + * @member {string} os + * @memberof proto.CompanionProps + * @instance + */ + CompanionProps.prototype.os = ""; + + /** + * CompanionProps version. + * @member {proto.IAppVersion|null|undefined} version + * @memberof proto.CompanionProps + * @instance + */ + CompanionProps.prototype.version = null; + + /** + * CompanionProps platformType. + * @member {proto.CompanionProps.CompanionPropsPlatformType} platformType + * @memberof proto.CompanionProps + * @instance + */ + CompanionProps.prototype.platformType = 0; + + /** + * CompanionProps requireFullSync. + * @member {boolean} requireFullSync + * @memberof proto.CompanionProps + * @instance + */ + CompanionProps.prototype.requireFullSync = false; + + /** + * Creates a new CompanionProps instance using the specified properties. + * @function create + * @memberof proto.CompanionProps + * @static + * @param {proto.ICompanionProps=} [properties] Properties to set + * @returns {proto.CompanionProps} CompanionProps instance + */ + CompanionProps.create = function create(properties) { + return new CompanionProps(properties); + }; + + /** + * Encodes the specified CompanionProps message. Does not implicitly {@link proto.CompanionProps.verify|verify} messages. + * @function encode + * @memberof proto.CompanionProps + * @static + * @param {proto.ICompanionProps} message CompanionProps message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CompanionProps.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.os != null && Object.hasOwnProperty.call(message, "os")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.os); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + $root.proto.AppVersion.encode(message.version, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.platformType != null && Object.hasOwnProperty.call(message, "platformType")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.platformType); + if (message.requireFullSync != null && Object.hasOwnProperty.call(message, "requireFullSync")) + writer.uint32(/* id 4, wireType 0 =*/32).bool(message.requireFullSync); + return writer; + }; + + /** + * Encodes the specified CompanionProps message, length delimited. Does not implicitly {@link proto.CompanionProps.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.CompanionProps + * @static + * @param {proto.ICompanionProps} message CompanionProps message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CompanionProps.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a CompanionProps message from the specified reader or buffer. + * @function decode + * @memberof proto.CompanionProps + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.CompanionProps} CompanionProps + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CompanionProps.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CompanionProps(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.os = reader.string(); + break; + case 2: + message.version = $root.proto.AppVersion.decode(reader, reader.uint32()); + break; + case 3: + message.platformType = reader.int32(); + break; + case 4: + message.requireFullSync = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a CompanionProps message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.CompanionProps + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.CompanionProps} CompanionProps + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CompanionProps.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a CompanionProps message. + * @function verify + * @memberof proto.CompanionProps + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + CompanionProps.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.os != null && message.hasOwnProperty("os")) + if (!$util.isString(message.os)) + return "os: string expected"; + if (message.version != null && message.hasOwnProperty("version")) { + var error = $root.proto.AppVersion.verify(message.version); + if (error) + return "version." + error; + } + if (message.platformType != null && message.hasOwnProperty("platformType")) + switch (message.platformType) { + default: + return "platformType: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + break; + } + if (message.requireFullSync != null && message.hasOwnProperty("requireFullSync")) + if (typeof message.requireFullSync !== "boolean") + return "requireFullSync: boolean expected"; + return null; + }; + + /** + * Creates a CompanionProps message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.CompanionProps + * @static + * @param {Object.} object Plain object + * @returns {proto.CompanionProps} CompanionProps + */ + CompanionProps.fromObject = function fromObject(object) { + if (object instanceof $root.proto.CompanionProps) + return object; + var message = new $root.proto.CompanionProps(); + if (object.os != null) + message.os = String(object.os); + if (object.version != null) { + if (typeof object.version !== "object") + throw TypeError(".proto.CompanionProps.version: object expected"); + message.version = $root.proto.AppVersion.fromObject(object.version); + } + switch (object.platformType) { + case "UNKNOWN": + case 0: + message.platformType = 0; + break; + case "CHROME": + case 1: + message.platformType = 1; + break; + case "FIREFOX": + case 2: + message.platformType = 2; + break; + case "IE": + case 3: + message.platformType = 3; + break; + case "OPERA": + case 4: + message.platformType = 4; + break; + case "SAFARI": + case 5: + message.platformType = 5; + break; + case "EDGE": + case 6: + message.platformType = 6; + break; + case "DESKTOP": + case 7: + message.platformType = 7; + break; + case "IPAD": + case 8: + message.platformType = 8; + break; + case "ANDROID_TABLET": + case 9: + message.platformType = 9; + break; + case "OHANA": + case 10: + message.platformType = 10; + break; + case "ALOHA": + case 11: + message.platformType = 11; + break; + case "CATALINA": + case 12: + message.platformType = 12; + break; + } + if (object.requireFullSync != null) + message.requireFullSync = Boolean(object.requireFullSync); + return message; + }; + + /** + * Creates a plain object from a CompanionProps message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.CompanionProps + * @static + * @param {proto.CompanionProps} message CompanionProps + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + CompanionProps.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.os = ""; + object.version = null; + object.platformType = options.enums === String ? "UNKNOWN" : 0; + object.requireFullSync = false; + } + if (message.os != null && message.hasOwnProperty("os")) + object.os = message.os; + if (message.version != null && message.hasOwnProperty("version")) + object.version = $root.proto.AppVersion.toObject(message.version, options); + if (message.platformType != null && message.hasOwnProperty("platformType")) + object.platformType = options.enums === String ? $root.proto.CompanionProps.CompanionPropsPlatformType[message.platformType] : message.platformType; + if (message.requireFullSync != null && message.hasOwnProperty("requireFullSync")) + object.requireFullSync = message.requireFullSync; + return object; + }; + + /** + * Converts this CompanionProps to JSON. + * @function toJSON + * @memberof proto.CompanionProps + * @instance + * @returns {Object.} JSON object + */ + CompanionProps.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * CompanionPropsPlatformType enum. + * @name proto.CompanionProps.CompanionPropsPlatformType + * @enum {number} + * @property {number} UNKNOWN=0 UNKNOWN value + * @property {number} CHROME=1 CHROME value + * @property {number} FIREFOX=2 FIREFOX value + * @property {number} IE=3 IE value + * @property {number} OPERA=4 OPERA value + * @property {number} SAFARI=5 SAFARI value + * @property {number} EDGE=6 EDGE value + * @property {number} DESKTOP=7 DESKTOP value + * @property {number} IPAD=8 IPAD value + * @property {number} ANDROID_TABLET=9 ANDROID_TABLET value + * @property {number} OHANA=10 OHANA value + * @property {number} ALOHA=11 ALOHA value + * @property {number} CATALINA=12 CATALINA value + */ + CompanionProps.CompanionPropsPlatformType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN"] = 0; + values[valuesById[1] = "CHROME"] = 1; + values[valuesById[2] = "FIREFOX"] = 2; + values[valuesById[3] = "IE"] = 3; + values[valuesById[4] = "OPERA"] = 4; + values[valuesById[5] = "SAFARI"] = 5; + values[valuesById[6] = "EDGE"] = 6; + values[valuesById[7] = "DESKTOP"] = 7; + values[valuesById[8] = "IPAD"] = 8; + values[valuesById[9] = "ANDROID_TABLET"] = 9; + values[valuesById[10] = "OHANA"] = 10; + values[valuesById[11] = "ALOHA"] = 11; + values[valuesById[12] = "CATALINA"] = 12; + return values; + })(); + + return CompanionProps; + })(); + + proto.ADVSignedDeviceIdentityHMAC = (function() { + + /** + * Properties of a ADVSignedDeviceIdentityHMAC. + * @memberof proto + * @interface IADVSignedDeviceIdentityHMAC + * @property {Uint8Array|null} [details] ADVSignedDeviceIdentityHMAC details + * @property {Uint8Array|null} [hmac] ADVSignedDeviceIdentityHMAC hmac + */ + + /** + * Constructs a new ADVSignedDeviceIdentityHMAC. + * @memberof proto + * @classdesc Represents a ADVSignedDeviceIdentityHMAC. + * @implements IADVSignedDeviceIdentityHMAC + * @constructor + * @param {proto.IADVSignedDeviceIdentityHMAC=} [properties] Properties to set + */ + function ADVSignedDeviceIdentityHMAC(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ADVSignedDeviceIdentityHMAC details. + * @member {Uint8Array} details + * @memberof proto.ADVSignedDeviceIdentityHMAC + * @instance + */ + ADVSignedDeviceIdentityHMAC.prototype.details = $util.newBuffer([]); + + /** + * ADVSignedDeviceIdentityHMAC hmac. + * @member {Uint8Array} hmac + * @memberof proto.ADVSignedDeviceIdentityHMAC + * @instance + */ + ADVSignedDeviceIdentityHMAC.prototype.hmac = $util.newBuffer([]); + + /** + * Creates a new ADVSignedDeviceIdentityHMAC instance using the specified properties. + * @function create + * @memberof proto.ADVSignedDeviceIdentityHMAC + * @static + * @param {proto.IADVSignedDeviceIdentityHMAC=} [properties] Properties to set + * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC instance + */ + ADVSignedDeviceIdentityHMAC.create = function create(properties) { + return new ADVSignedDeviceIdentityHMAC(properties); + }; + + /** + * Encodes the specified ADVSignedDeviceIdentityHMAC message. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages. + * @function encode + * @memberof proto.ADVSignedDeviceIdentityHMAC + * @static + * @param {proto.IADVSignedDeviceIdentityHMAC} message ADVSignedDeviceIdentityHMAC message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVSignedDeviceIdentityHMAC.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.details != null && Object.hasOwnProperty.call(message, "details")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); + if (message.hmac != null && Object.hasOwnProperty.call(message, "hmac")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.hmac); + return writer; + }; + + /** + * Encodes the specified ADVSignedDeviceIdentityHMAC message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ADVSignedDeviceIdentityHMAC + * @static + * @param {proto.IADVSignedDeviceIdentityHMAC} message ADVSignedDeviceIdentityHMAC message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVSignedDeviceIdentityHMAC.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer. + * @function decode + * @memberof proto.ADVSignedDeviceIdentityHMAC + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVSignedDeviceIdentityHMAC.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVSignedDeviceIdentityHMAC(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.details = reader.bytes(); + break; + case 2: + message.hmac = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ADVSignedDeviceIdentityHMAC + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVSignedDeviceIdentityHMAC.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ADVSignedDeviceIdentityHMAC message. + * @function verify + * @memberof proto.ADVSignedDeviceIdentityHMAC + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ADVSignedDeviceIdentityHMAC.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.details != null && message.hasOwnProperty("details")) + if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) + return "details: buffer expected"; + if (message.hmac != null && message.hasOwnProperty("hmac")) + if (!(message.hmac && typeof message.hmac.length === "number" || $util.isString(message.hmac))) + return "hmac: buffer expected"; + return null; + }; + + /** + * Creates a ADVSignedDeviceIdentityHMAC message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ADVSignedDeviceIdentityHMAC + * @static + * @param {Object.} object Plain object + * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC + */ + ADVSignedDeviceIdentityHMAC.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ADVSignedDeviceIdentityHMAC) + return object; + var message = new $root.proto.ADVSignedDeviceIdentityHMAC(); + if (object.details != null) + if (typeof object.details === "string") + $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); + else if (object.details.length) + message.details = object.details; + if (object.hmac != null) + if (typeof object.hmac === "string") + $util.base64.decode(object.hmac, message.hmac = $util.newBuffer($util.base64.length(object.hmac)), 0); + else if (object.hmac.length) + message.hmac = object.hmac; + return message; + }; + + /** + * Creates a plain object from a ADVSignedDeviceIdentityHMAC message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ADVSignedDeviceIdentityHMAC + * @static + * @param {proto.ADVSignedDeviceIdentityHMAC} message ADVSignedDeviceIdentityHMAC + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ADVSignedDeviceIdentityHMAC.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.details = ""; + else { + object.details = []; + if (options.bytes !== Array) + object.details = $util.newBuffer(object.details); + } + if (options.bytes === String) + object.hmac = ""; + else { + object.hmac = []; + if (options.bytes !== Array) + object.hmac = $util.newBuffer(object.hmac); + } + } + if (message.details != null && message.hasOwnProperty("details")) + object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; + if (message.hmac != null && message.hasOwnProperty("hmac")) + object.hmac = options.bytes === String ? $util.base64.encode(message.hmac, 0, message.hmac.length) : options.bytes === Array ? Array.prototype.slice.call(message.hmac) : message.hmac; + return object; + }; + + /** + * Converts this ADVSignedDeviceIdentityHMAC to JSON. + * @function toJSON + * @memberof proto.ADVSignedDeviceIdentityHMAC + * @instance + * @returns {Object.} JSON object + */ + ADVSignedDeviceIdentityHMAC.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ADVSignedDeviceIdentityHMAC; + })(); + + proto.ADVSignedDeviceIdentity = (function() { + + /** + * Properties of a ADVSignedDeviceIdentity. + * @memberof proto + * @interface IADVSignedDeviceIdentity + * @property {Uint8Array|null} [details] ADVSignedDeviceIdentity details + * @property {Uint8Array|null} [accountSignatureKey] ADVSignedDeviceIdentity accountSignatureKey + * @property {Uint8Array|null} [accountSignature] ADVSignedDeviceIdentity accountSignature + * @property {Uint8Array|null} [deviceSignature] ADVSignedDeviceIdentity deviceSignature + */ + + /** + * Constructs a new ADVSignedDeviceIdentity. + * @memberof proto + * @classdesc Represents a ADVSignedDeviceIdentity. + * @implements IADVSignedDeviceIdentity + * @constructor + * @param {proto.IADVSignedDeviceIdentity=} [properties] Properties to set + */ + function ADVSignedDeviceIdentity(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ADVSignedDeviceIdentity details. + * @member {Uint8Array} details + * @memberof proto.ADVSignedDeviceIdentity + * @instance + */ + ADVSignedDeviceIdentity.prototype.details = $util.newBuffer([]); + + /** + * ADVSignedDeviceIdentity accountSignatureKey. + * @member {Uint8Array} accountSignatureKey + * @memberof proto.ADVSignedDeviceIdentity + * @instance + */ + ADVSignedDeviceIdentity.prototype.accountSignatureKey = $util.newBuffer([]); + + /** + * ADVSignedDeviceIdentity accountSignature. + * @member {Uint8Array} accountSignature + * @memberof proto.ADVSignedDeviceIdentity + * @instance + */ + ADVSignedDeviceIdentity.prototype.accountSignature = $util.newBuffer([]); + + /** + * ADVSignedDeviceIdentity deviceSignature. + * @member {Uint8Array} deviceSignature + * @memberof proto.ADVSignedDeviceIdentity + * @instance + */ + ADVSignedDeviceIdentity.prototype.deviceSignature = $util.newBuffer([]); + + /** + * Creates a new ADVSignedDeviceIdentity instance using the specified properties. + * @function create + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {proto.IADVSignedDeviceIdentity=} [properties] Properties to set + * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity instance + */ + ADVSignedDeviceIdentity.create = function create(properties) { + return new ADVSignedDeviceIdentity(properties); + }; + + /** + * Encodes the specified ADVSignedDeviceIdentity message. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages. + * @function encode + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {proto.IADVSignedDeviceIdentity} message ADVSignedDeviceIdentity message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVSignedDeviceIdentity.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.details != null && Object.hasOwnProperty.call(message, "details")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); + if (message.accountSignatureKey != null && Object.hasOwnProperty.call(message, "accountSignatureKey")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.accountSignatureKey); + if (message.accountSignature != null && Object.hasOwnProperty.call(message, "accountSignature")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.accountSignature); + if (message.deviceSignature != null && Object.hasOwnProperty.call(message, "deviceSignature")) + writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.deviceSignature); + return writer; + }; + + /** + * Encodes the specified ADVSignedDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {proto.IADVSignedDeviceIdentity} message ADVSignedDeviceIdentity message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVSignedDeviceIdentity.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer. + * @function decode + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVSignedDeviceIdentity.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVSignedDeviceIdentity(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.details = reader.bytes(); + break; + case 2: + message.accountSignatureKey = reader.bytes(); + break; + case 3: + message.accountSignature = reader.bytes(); + break; + case 4: + message.deviceSignature = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVSignedDeviceIdentity.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ADVSignedDeviceIdentity message. + * @function verify + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ADVSignedDeviceIdentity.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.details != null && message.hasOwnProperty("details")) + if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) + return "details: buffer expected"; + if (message.accountSignatureKey != null && message.hasOwnProperty("accountSignatureKey")) + if (!(message.accountSignatureKey && typeof message.accountSignatureKey.length === "number" || $util.isString(message.accountSignatureKey))) + return "accountSignatureKey: buffer expected"; + if (message.accountSignature != null && message.hasOwnProperty("accountSignature")) + if (!(message.accountSignature && typeof message.accountSignature.length === "number" || $util.isString(message.accountSignature))) + return "accountSignature: buffer expected"; + if (message.deviceSignature != null && message.hasOwnProperty("deviceSignature")) + if (!(message.deviceSignature && typeof message.deviceSignature.length === "number" || $util.isString(message.deviceSignature))) + return "deviceSignature: buffer expected"; + return null; + }; + + /** + * Creates a ADVSignedDeviceIdentity message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {Object.} object Plain object + * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity + */ + ADVSignedDeviceIdentity.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ADVSignedDeviceIdentity) + return object; + var message = new $root.proto.ADVSignedDeviceIdentity(); + if (object.details != null) + if (typeof object.details === "string") + $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); + else if (object.details.length) + message.details = object.details; + if (object.accountSignatureKey != null) + if (typeof object.accountSignatureKey === "string") + $util.base64.decode(object.accountSignatureKey, message.accountSignatureKey = $util.newBuffer($util.base64.length(object.accountSignatureKey)), 0); + else if (object.accountSignatureKey.length) + message.accountSignatureKey = object.accountSignatureKey; + if (object.accountSignature != null) + if (typeof object.accountSignature === "string") + $util.base64.decode(object.accountSignature, message.accountSignature = $util.newBuffer($util.base64.length(object.accountSignature)), 0); + else if (object.accountSignature.length) + message.accountSignature = object.accountSignature; + if (object.deviceSignature != null) + if (typeof object.deviceSignature === "string") + $util.base64.decode(object.deviceSignature, message.deviceSignature = $util.newBuffer($util.base64.length(object.deviceSignature)), 0); + else if (object.deviceSignature.length) + message.deviceSignature = object.deviceSignature; + return message; + }; + + /** + * Creates a plain object from a ADVSignedDeviceIdentity message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {proto.ADVSignedDeviceIdentity} message ADVSignedDeviceIdentity + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ADVSignedDeviceIdentity.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.details = ""; + else { + object.details = []; + if (options.bytes !== Array) + object.details = $util.newBuffer(object.details); + } + if (options.bytes === String) + object.accountSignatureKey = ""; + else { + object.accountSignatureKey = []; + if (options.bytes !== Array) + object.accountSignatureKey = $util.newBuffer(object.accountSignatureKey); + } + if (options.bytes === String) + object.accountSignature = ""; + else { + object.accountSignature = []; + if (options.bytes !== Array) + object.accountSignature = $util.newBuffer(object.accountSignature); + } + if (options.bytes === String) + object.deviceSignature = ""; + else { + object.deviceSignature = []; + if (options.bytes !== Array) + object.deviceSignature = $util.newBuffer(object.deviceSignature); + } + } + if (message.details != null && message.hasOwnProperty("details")) + object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; + if (message.accountSignatureKey != null && message.hasOwnProperty("accountSignatureKey")) + object.accountSignatureKey = options.bytes === String ? $util.base64.encode(message.accountSignatureKey, 0, message.accountSignatureKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.accountSignatureKey) : message.accountSignatureKey; + if (message.accountSignature != null && message.hasOwnProperty("accountSignature")) + object.accountSignature = options.bytes === String ? $util.base64.encode(message.accountSignature, 0, message.accountSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.accountSignature) : message.accountSignature; + if (message.deviceSignature != null && message.hasOwnProperty("deviceSignature")) + object.deviceSignature = options.bytes === String ? $util.base64.encode(message.deviceSignature, 0, message.deviceSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.deviceSignature) : message.deviceSignature; + return object; + }; + + /** + * Converts this ADVSignedDeviceIdentity to JSON. + * @function toJSON + * @memberof proto.ADVSignedDeviceIdentity + * @instance + * @returns {Object.} JSON object + */ + ADVSignedDeviceIdentity.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ADVSignedDeviceIdentity; + })(); + + proto.ADVDeviceIdentity = (function() { + + /** + * Properties of a ADVDeviceIdentity. + * @memberof proto + * @interface IADVDeviceIdentity + * @property {number|null} [rawId] ADVDeviceIdentity rawId + * @property {number|Long|null} [timestamp] ADVDeviceIdentity timestamp + * @property {number|null} [keyIndex] ADVDeviceIdentity keyIndex + */ + + /** + * Constructs a new ADVDeviceIdentity. + * @memberof proto + * @classdesc Represents a ADVDeviceIdentity. + * @implements IADVDeviceIdentity + * @constructor + * @param {proto.IADVDeviceIdentity=} [properties] Properties to set + */ + function ADVDeviceIdentity(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ADVDeviceIdentity rawId. + * @member {number} rawId + * @memberof proto.ADVDeviceIdentity + * @instance + */ + ADVDeviceIdentity.prototype.rawId = 0; + + /** + * ADVDeviceIdentity timestamp. + * @member {number|Long} timestamp + * @memberof proto.ADVDeviceIdentity + * @instance + */ + ADVDeviceIdentity.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * ADVDeviceIdentity keyIndex. + * @member {number} keyIndex + * @memberof proto.ADVDeviceIdentity + * @instance + */ + ADVDeviceIdentity.prototype.keyIndex = 0; + + /** + * Creates a new ADVDeviceIdentity instance using the specified properties. + * @function create + * @memberof proto.ADVDeviceIdentity + * @static + * @param {proto.IADVDeviceIdentity=} [properties] Properties to set + * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity instance + */ + ADVDeviceIdentity.create = function create(properties) { + return new ADVDeviceIdentity(properties); + }; + + /** + * Encodes the specified ADVDeviceIdentity message. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages. + * @function encode + * @memberof proto.ADVDeviceIdentity + * @static + * @param {proto.IADVDeviceIdentity} message ADVDeviceIdentity message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVDeviceIdentity.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.rawId != null && Object.hasOwnProperty.call(message, "rawId")) + writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.rawId); + if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.timestamp); + if (message.keyIndex != null && Object.hasOwnProperty.call(message, "keyIndex")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.keyIndex); + return writer; + }; + + /** + * Encodes the specified ADVDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ADVDeviceIdentity + * @static + * @param {proto.IADVDeviceIdentity} message ADVDeviceIdentity message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVDeviceIdentity.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ADVDeviceIdentity message from the specified reader or buffer. + * @function decode + * @memberof proto.ADVDeviceIdentity + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVDeviceIdentity.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVDeviceIdentity(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.rawId = reader.uint32(); + break; + case 2: + message.timestamp = reader.uint64(); + break; + case 3: + message.keyIndex = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ADVDeviceIdentity message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ADVDeviceIdentity + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVDeviceIdentity.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ADVDeviceIdentity message. + * @function verify + * @memberof proto.ADVDeviceIdentity + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ADVDeviceIdentity.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.rawId != null && message.hasOwnProperty("rawId")) + if (!$util.isInteger(message.rawId)) + return "rawId: integer expected"; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) + return "timestamp: integer|Long expected"; + if (message.keyIndex != null && message.hasOwnProperty("keyIndex")) + if (!$util.isInteger(message.keyIndex)) + return "keyIndex: integer expected"; + return null; + }; + + /** + * Creates a ADVDeviceIdentity message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ADVDeviceIdentity + * @static + * @param {Object.} object Plain object + * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity + */ + ADVDeviceIdentity.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ADVDeviceIdentity) + return object; + var message = new $root.proto.ADVDeviceIdentity(); + if (object.rawId != null) + message.rawId = object.rawId >>> 0; + if (object.timestamp != null) + if ($util.Long) + (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = true; + else if (typeof object.timestamp === "string") + message.timestamp = parseInt(object.timestamp, 10); + else if (typeof object.timestamp === "number") + message.timestamp = object.timestamp; + else if (typeof object.timestamp === "object") + message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(true); + if (object.keyIndex != null) + message.keyIndex = object.keyIndex >>> 0; + return message; + }; + + /** + * Creates a plain object from a ADVDeviceIdentity message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ADVDeviceIdentity + * @static + * @param {proto.ADVDeviceIdentity} message ADVDeviceIdentity + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ADVDeviceIdentity.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.rawId = 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.timestamp = options.longs === String ? "0" : 0; + object.keyIndex = 0; + } + if (message.rawId != null && message.hasOwnProperty("rawId")) + object.rawId = message.rawId; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (typeof message.timestamp === "number") + object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; + else + object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber(true) : message.timestamp; + if (message.keyIndex != null && message.hasOwnProperty("keyIndex")) + object.keyIndex = message.keyIndex; + return object; + }; + + /** + * Converts this ADVDeviceIdentity to JSON. + * @function toJSON + * @memberof proto.ADVDeviceIdentity + * @instance + * @returns {Object.} JSON object + */ + ADVDeviceIdentity.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ADVDeviceIdentity; + })(); + + proto.ADVSignedKeyIndexList = (function() { + + /** + * Properties of a ADVSignedKeyIndexList. + * @memberof proto + * @interface IADVSignedKeyIndexList + * @property {Uint8Array|null} [details] ADVSignedKeyIndexList details + * @property {Uint8Array|null} [accountSignature] ADVSignedKeyIndexList accountSignature + */ + + /** + * Constructs a new ADVSignedKeyIndexList. + * @memberof proto + * @classdesc Represents a ADVSignedKeyIndexList. + * @implements IADVSignedKeyIndexList + * @constructor + * @param {proto.IADVSignedKeyIndexList=} [properties] Properties to set + */ + function ADVSignedKeyIndexList(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ADVSignedKeyIndexList details. + * @member {Uint8Array} details + * @memberof proto.ADVSignedKeyIndexList + * @instance + */ + ADVSignedKeyIndexList.prototype.details = $util.newBuffer([]); + + /** + * ADVSignedKeyIndexList accountSignature. + * @member {Uint8Array} accountSignature + * @memberof proto.ADVSignedKeyIndexList + * @instance + */ + ADVSignedKeyIndexList.prototype.accountSignature = $util.newBuffer([]); + + /** + * Creates a new ADVSignedKeyIndexList instance using the specified properties. + * @function create + * @memberof proto.ADVSignedKeyIndexList + * @static + * @param {proto.IADVSignedKeyIndexList=} [properties] Properties to set + * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList instance + */ + ADVSignedKeyIndexList.create = function create(properties) { + return new ADVSignedKeyIndexList(properties); + }; + + /** + * Encodes the specified ADVSignedKeyIndexList message. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages. + * @function encode + * @memberof proto.ADVSignedKeyIndexList + * @static + * @param {proto.IADVSignedKeyIndexList} message ADVSignedKeyIndexList message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVSignedKeyIndexList.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.details != null && Object.hasOwnProperty.call(message, "details")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); + if (message.accountSignature != null && Object.hasOwnProperty.call(message, "accountSignature")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.accountSignature); + return writer; + }; + + /** + * Encodes the specified ADVSignedKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ADVSignedKeyIndexList + * @static + * @param {proto.IADVSignedKeyIndexList} message ADVSignedKeyIndexList message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVSignedKeyIndexList.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer. + * @function decode + * @memberof proto.ADVSignedKeyIndexList + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVSignedKeyIndexList.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVSignedKeyIndexList(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.details = reader.bytes(); + break; + case 2: + message.accountSignature = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ADVSignedKeyIndexList + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVSignedKeyIndexList.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ADVSignedKeyIndexList message. + * @function verify + * @memberof proto.ADVSignedKeyIndexList + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ADVSignedKeyIndexList.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.details != null && message.hasOwnProperty("details")) + if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) + return "details: buffer expected"; + if (message.accountSignature != null && message.hasOwnProperty("accountSignature")) + if (!(message.accountSignature && typeof message.accountSignature.length === "number" || $util.isString(message.accountSignature))) + return "accountSignature: buffer expected"; + return null; + }; + + /** + * Creates a ADVSignedKeyIndexList message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ADVSignedKeyIndexList + * @static + * @param {Object.} object Plain object + * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList + */ + ADVSignedKeyIndexList.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ADVSignedKeyIndexList) + return object; + var message = new $root.proto.ADVSignedKeyIndexList(); + if (object.details != null) + if (typeof object.details === "string") + $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); + else if (object.details.length) + message.details = object.details; + if (object.accountSignature != null) + if (typeof object.accountSignature === "string") + $util.base64.decode(object.accountSignature, message.accountSignature = $util.newBuffer($util.base64.length(object.accountSignature)), 0); + else if (object.accountSignature.length) + message.accountSignature = object.accountSignature; + return message; + }; + + /** + * Creates a plain object from a ADVSignedKeyIndexList message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ADVSignedKeyIndexList + * @static + * @param {proto.ADVSignedKeyIndexList} message ADVSignedKeyIndexList + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ADVSignedKeyIndexList.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.details = ""; + else { + object.details = []; + if (options.bytes !== Array) + object.details = $util.newBuffer(object.details); + } + if (options.bytes === String) + object.accountSignature = ""; + else { + object.accountSignature = []; + if (options.bytes !== Array) + object.accountSignature = $util.newBuffer(object.accountSignature); + } + } + if (message.details != null && message.hasOwnProperty("details")) + object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; + if (message.accountSignature != null && message.hasOwnProperty("accountSignature")) + object.accountSignature = options.bytes === String ? $util.base64.encode(message.accountSignature, 0, message.accountSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.accountSignature) : message.accountSignature; + return object; + }; + + /** + * Converts this ADVSignedKeyIndexList to JSON. + * @function toJSON + * @memberof proto.ADVSignedKeyIndexList + * @instance + * @returns {Object.} JSON object + */ + ADVSignedKeyIndexList.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ADVSignedKeyIndexList; + })(); + + proto.ADVKeyIndexList = (function() { + + /** + * Properties of a ADVKeyIndexList. + * @memberof proto + * @interface IADVKeyIndexList + * @property {number|null} [rawId] ADVKeyIndexList rawId + * @property {number|Long|null} [timestamp] ADVKeyIndexList timestamp + * @property {number|null} [currentIndex] ADVKeyIndexList currentIndex + * @property {Array.|null} [validIndexes] ADVKeyIndexList validIndexes + */ + + /** + * Constructs a new ADVKeyIndexList. + * @memberof proto + * @classdesc Represents a ADVKeyIndexList. + * @implements IADVKeyIndexList + * @constructor + * @param {proto.IADVKeyIndexList=} [properties] Properties to set + */ + function ADVKeyIndexList(properties) { + this.validIndexes = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ADVKeyIndexList rawId. + * @member {number} rawId + * @memberof proto.ADVKeyIndexList + * @instance + */ + ADVKeyIndexList.prototype.rawId = 0; + + /** + * ADVKeyIndexList timestamp. + * @member {number|Long} timestamp + * @memberof proto.ADVKeyIndexList + * @instance + */ + ADVKeyIndexList.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * ADVKeyIndexList currentIndex. + * @member {number} currentIndex + * @memberof proto.ADVKeyIndexList + * @instance + */ + ADVKeyIndexList.prototype.currentIndex = 0; + + /** + * ADVKeyIndexList validIndexes. + * @member {Array.} validIndexes + * @memberof proto.ADVKeyIndexList + * @instance + */ + ADVKeyIndexList.prototype.validIndexes = $util.emptyArray; + + /** + * Creates a new ADVKeyIndexList instance using the specified properties. + * @function create + * @memberof proto.ADVKeyIndexList + * @static + * @param {proto.IADVKeyIndexList=} [properties] Properties to set + * @returns {proto.ADVKeyIndexList} ADVKeyIndexList instance + */ + ADVKeyIndexList.create = function create(properties) { + return new ADVKeyIndexList(properties); + }; + + /** + * Encodes the specified ADVKeyIndexList message. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages. + * @function encode + * @memberof proto.ADVKeyIndexList + * @static + * @param {proto.IADVKeyIndexList} message ADVKeyIndexList message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVKeyIndexList.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.rawId != null && Object.hasOwnProperty.call(message, "rawId")) + writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.rawId); + if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.timestamp); + if (message.currentIndex != null && Object.hasOwnProperty.call(message, "currentIndex")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.currentIndex); + if (message.validIndexes != null && message.validIndexes.length) { + writer.uint32(/* id 4, wireType 2 =*/34).fork(); + for (var i = 0; i < message.validIndexes.length; ++i) + writer.uint32(message.validIndexes[i]); + writer.ldelim(); + } + return writer; + }; + + /** + * Encodes the specified ADVKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ADVKeyIndexList + * @static + * @param {proto.IADVKeyIndexList} message ADVKeyIndexList message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVKeyIndexList.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ADVKeyIndexList message from the specified reader or buffer. + * @function decode + * @memberof proto.ADVKeyIndexList + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ADVKeyIndexList} ADVKeyIndexList + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVKeyIndexList.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVKeyIndexList(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.rawId = reader.uint32(); + break; + case 2: + message.timestamp = reader.uint64(); + break; + case 3: + message.currentIndex = reader.uint32(); + break; + case 4: + if (!(message.validIndexes && message.validIndexes.length)) + message.validIndexes = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.validIndexes.push(reader.uint32()); + } else + message.validIndexes.push(reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ADVKeyIndexList message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ADVKeyIndexList + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ADVKeyIndexList} ADVKeyIndexList + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVKeyIndexList.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ADVKeyIndexList message. + * @function verify + * @memberof proto.ADVKeyIndexList + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ADVKeyIndexList.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.rawId != null && message.hasOwnProperty("rawId")) + if (!$util.isInteger(message.rawId)) + return "rawId: integer expected"; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) + return "timestamp: integer|Long expected"; + if (message.currentIndex != null && message.hasOwnProperty("currentIndex")) + if (!$util.isInteger(message.currentIndex)) + return "currentIndex: integer expected"; + if (message.validIndexes != null && message.hasOwnProperty("validIndexes")) { + if (!Array.isArray(message.validIndexes)) + return "validIndexes: array expected"; + for (var i = 0; i < message.validIndexes.length; ++i) + if (!$util.isInteger(message.validIndexes[i])) + return "validIndexes: integer[] expected"; + } + return null; + }; + + /** + * Creates a ADVKeyIndexList message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ADVKeyIndexList + * @static + * @param {Object.} object Plain object + * @returns {proto.ADVKeyIndexList} ADVKeyIndexList + */ + ADVKeyIndexList.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ADVKeyIndexList) + return object; + var message = new $root.proto.ADVKeyIndexList(); + if (object.rawId != null) + message.rawId = object.rawId >>> 0; + if (object.timestamp != null) + if ($util.Long) + (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = true; + else if (typeof object.timestamp === "string") + message.timestamp = parseInt(object.timestamp, 10); + else if (typeof object.timestamp === "number") + message.timestamp = object.timestamp; + else if (typeof object.timestamp === "object") + message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(true); + if (object.currentIndex != null) + message.currentIndex = object.currentIndex >>> 0; + if (object.validIndexes) { + if (!Array.isArray(object.validIndexes)) + throw TypeError(".proto.ADVKeyIndexList.validIndexes: array expected"); + message.validIndexes = []; + for (var i = 0; i < object.validIndexes.length; ++i) + message.validIndexes[i] = object.validIndexes[i] >>> 0; + } + return message; + }; + + /** + * Creates a plain object from a ADVKeyIndexList message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ADVKeyIndexList + * @static + * @param {proto.ADVKeyIndexList} message ADVKeyIndexList + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ADVKeyIndexList.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.validIndexes = []; + if (options.defaults) { + object.rawId = 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.timestamp = options.longs === String ? "0" : 0; + object.currentIndex = 0; + } + if (message.rawId != null && message.hasOwnProperty("rawId")) + object.rawId = message.rawId; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (typeof message.timestamp === "number") + object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; + else + object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber(true) : message.timestamp; + if (message.currentIndex != null && message.hasOwnProperty("currentIndex")) + object.currentIndex = message.currentIndex; + if (message.validIndexes && message.validIndexes.length) { + object.validIndexes = []; + for (var j = 0; j < message.validIndexes.length; ++j) + object.validIndexes[j] = message.validIndexes[j]; + } + return object; + }; + + /** + * Converts this ADVKeyIndexList to JSON. + * @function toJSON + * @memberof proto.ADVKeyIndexList + * @instance + * @returns {Object.} JSON object + */ + ADVKeyIndexList.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ADVKeyIndexList; + })(); + proto.MessageKey = (function() { /** @@ -26114,7 +45863,5901 @@ $root.proto = (function() { return MessageKey; })(); + proto.PhotoChange = (function() { + + /** + * Properties of a PhotoChange. + * @memberof proto + * @interface IPhotoChange + * @property {Uint8Array|null} [oldPhoto] PhotoChange oldPhoto + * @property {Uint8Array|null} [newPhoto] PhotoChange newPhoto + * @property {number|null} [newPhotoId] PhotoChange newPhotoId + */ + + /** + * Constructs a new PhotoChange. + * @memberof proto + * @classdesc Represents a PhotoChange. + * @implements IPhotoChange + * @constructor + * @param {proto.IPhotoChange=} [properties] Properties to set + */ + function PhotoChange(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * PhotoChange oldPhoto. + * @member {Uint8Array} oldPhoto + * @memberof proto.PhotoChange + * @instance + */ + PhotoChange.prototype.oldPhoto = $util.newBuffer([]); + + /** + * PhotoChange newPhoto. + * @member {Uint8Array} newPhoto + * @memberof proto.PhotoChange + * @instance + */ + PhotoChange.prototype.newPhoto = $util.newBuffer([]); + + /** + * PhotoChange newPhotoId. + * @member {number} newPhotoId + * @memberof proto.PhotoChange + * @instance + */ + PhotoChange.prototype.newPhotoId = 0; + + /** + * Creates a new PhotoChange instance using the specified properties. + * @function create + * @memberof proto.PhotoChange + * @static + * @param {proto.IPhotoChange=} [properties] Properties to set + * @returns {proto.PhotoChange} PhotoChange instance + */ + PhotoChange.create = function create(properties) { + return new PhotoChange(properties); + }; + + /** + * Encodes the specified PhotoChange message. Does not implicitly {@link proto.PhotoChange.verify|verify} messages. + * @function encode + * @memberof proto.PhotoChange + * @static + * @param {proto.IPhotoChange} message PhotoChange message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PhotoChange.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.oldPhoto != null && Object.hasOwnProperty.call(message, "oldPhoto")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.oldPhoto); + if (message.newPhoto != null && Object.hasOwnProperty.call(message, "newPhoto")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.newPhoto); + if (message.newPhotoId != null && Object.hasOwnProperty.call(message, "newPhotoId")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.newPhotoId); + return writer; + }; + + /** + * Encodes the specified PhotoChange message, length delimited. Does not implicitly {@link proto.PhotoChange.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.PhotoChange + * @static + * @param {proto.IPhotoChange} message PhotoChange message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PhotoChange.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a PhotoChange message from the specified reader or buffer. + * @function decode + * @memberof proto.PhotoChange + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.PhotoChange} PhotoChange + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PhotoChange.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PhotoChange(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.oldPhoto = reader.bytes(); + break; + case 2: + message.newPhoto = reader.bytes(); + break; + case 3: + message.newPhotoId = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a PhotoChange message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.PhotoChange + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.PhotoChange} PhotoChange + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PhotoChange.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a PhotoChange message. + * @function verify + * @memberof proto.PhotoChange + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + PhotoChange.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.oldPhoto != null && message.hasOwnProperty("oldPhoto")) + if (!(message.oldPhoto && typeof message.oldPhoto.length === "number" || $util.isString(message.oldPhoto))) + return "oldPhoto: buffer expected"; + if (message.newPhoto != null && message.hasOwnProperty("newPhoto")) + if (!(message.newPhoto && typeof message.newPhoto.length === "number" || $util.isString(message.newPhoto))) + return "newPhoto: buffer expected"; + if (message.newPhotoId != null && message.hasOwnProperty("newPhotoId")) + if (!$util.isInteger(message.newPhotoId)) + return "newPhotoId: integer expected"; + return null; + }; + + /** + * Creates a PhotoChange message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.PhotoChange + * @static + * @param {Object.} object Plain object + * @returns {proto.PhotoChange} PhotoChange + */ + PhotoChange.fromObject = function fromObject(object) { + if (object instanceof $root.proto.PhotoChange) + return object; + var message = new $root.proto.PhotoChange(); + if (object.oldPhoto != null) + if (typeof object.oldPhoto === "string") + $util.base64.decode(object.oldPhoto, message.oldPhoto = $util.newBuffer($util.base64.length(object.oldPhoto)), 0); + else if (object.oldPhoto.length) + message.oldPhoto = object.oldPhoto; + if (object.newPhoto != null) + if (typeof object.newPhoto === "string") + $util.base64.decode(object.newPhoto, message.newPhoto = $util.newBuffer($util.base64.length(object.newPhoto)), 0); + else if (object.newPhoto.length) + message.newPhoto = object.newPhoto; + if (object.newPhotoId != null) + message.newPhotoId = object.newPhotoId >>> 0; + return message; + }; + + /** + * Creates a plain object from a PhotoChange message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.PhotoChange + * @static + * @param {proto.PhotoChange} message PhotoChange + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + PhotoChange.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.oldPhoto = ""; + else { + object.oldPhoto = []; + if (options.bytes !== Array) + object.oldPhoto = $util.newBuffer(object.oldPhoto); + } + if (options.bytes === String) + object.newPhoto = ""; + else { + object.newPhoto = []; + if (options.bytes !== Array) + object.newPhoto = $util.newBuffer(object.newPhoto); + } + object.newPhotoId = 0; + } + if (message.oldPhoto != null && message.hasOwnProperty("oldPhoto")) + object.oldPhoto = options.bytes === String ? $util.base64.encode(message.oldPhoto, 0, message.oldPhoto.length) : options.bytes === Array ? Array.prototype.slice.call(message.oldPhoto) : message.oldPhoto; + if (message.newPhoto != null && message.hasOwnProperty("newPhoto")) + object.newPhoto = options.bytes === String ? $util.base64.encode(message.newPhoto, 0, message.newPhoto.length) : options.bytes === Array ? Array.prototype.slice.call(message.newPhoto) : message.newPhoto; + if (message.newPhotoId != null && message.hasOwnProperty("newPhotoId")) + object.newPhotoId = message.newPhotoId; + return object; + }; + + /** + * Converts this PhotoChange to JSON. + * @function toJSON + * @memberof proto.PhotoChange + * @instance + * @returns {Object.} JSON object + */ + PhotoChange.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return PhotoChange; + })(); + + proto.MediaData = (function() { + + /** + * Properties of a MediaData. + * @memberof proto + * @interface IMediaData + * @property {string|null} [localPath] MediaData localPath + */ + + /** + * Constructs a new MediaData. + * @memberof proto + * @classdesc Represents a MediaData. + * @implements IMediaData + * @constructor + * @param {proto.IMediaData=} [properties] Properties to set + */ + function MediaData(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MediaData localPath. + * @member {string} localPath + * @memberof proto.MediaData + * @instance + */ + MediaData.prototype.localPath = ""; + + /** + * Creates a new MediaData instance using the specified properties. + * @function create + * @memberof proto.MediaData + * @static + * @param {proto.IMediaData=} [properties] Properties to set + * @returns {proto.MediaData} MediaData instance + */ + MediaData.create = function create(properties) { + return new MediaData(properties); + }; + + /** + * Encodes the specified MediaData message. Does not implicitly {@link proto.MediaData.verify|verify} messages. + * @function encode + * @memberof proto.MediaData + * @static + * @param {proto.IMediaData} message MediaData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MediaData.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.localPath != null && Object.hasOwnProperty.call(message, "localPath")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.localPath); + return writer; + }; + + /** + * Encodes the specified MediaData message, length delimited. Does not implicitly {@link proto.MediaData.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MediaData + * @static + * @param {proto.IMediaData} message MediaData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MediaData.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MediaData message from the specified reader or buffer. + * @function decode + * @memberof proto.MediaData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MediaData} MediaData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MediaData.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MediaData(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.localPath = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MediaData message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MediaData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MediaData} MediaData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MediaData.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MediaData message. + * @function verify + * @memberof proto.MediaData + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MediaData.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.localPath != null && message.hasOwnProperty("localPath")) + if (!$util.isString(message.localPath)) + return "localPath: string expected"; + return null; + }; + + /** + * Creates a MediaData message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MediaData + * @static + * @param {Object.} object Plain object + * @returns {proto.MediaData} MediaData + */ + MediaData.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MediaData) + return object; + var message = new $root.proto.MediaData(); + if (object.localPath != null) + message.localPath = String(object.localPath); + return message; + }; + + /** + * Creates a plain object from a MediaData message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MediaData + * @static + * @param {proto.MediaData} message MediaData + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MediaData.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.localPath = ""; + if (message.localPath != null && message.hasOwnProperty("localPath")) + object.localPath = message.localPath; + return object; + }; + + /** + * Converts this MediaData to JSON. + * @function toJSON + * @memberof proto.MediaData + * @instance + * @returns {Object.} JSON object + */ + MediaData.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MediaData; + })(); + + proto.WebFeatures = (function() { + + /** + * Properties of a WebFeatures. + * @memberof proto + * @interface IWebFeatures + * @property {proto.WebFeatures.WebFeaturesFlag|null} [labelsDisplay] WebFeatures labelsDisplay + * @property {proto.WebFeatures.WebFeaturesFlag|null} [voipIndividualOutgoing] WebFeatures voipIndividualOutgoing + * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupsV3] WebFeatures groupsV3 + * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupsV3Create] WebFeatures groupsV3Create + * @property {proto.WebFeatures.WebFeaturesFlag|null} [changeNumberV2] WebFeatures changeNumberV2 + * @property {proto.WebFeatures.WebFeaturesFlag|null} [queryStatusV3Thumbnail] WebFeatures queryStatusV3Thumbnail + * @property {proto.WebFeatures.WebFeaturesFlag|null} [liveLocations] WebFeatures liveLocations + * @property {proto.WebFeatures.WebFeaturesFlag|null} [queryVname] WebFeatures queryVname + * @property {proto.WebFeatures.WebFeaturesFlag|null} [voipIndividualIncoming] WebFeatures voipIndividualIncoming + * @property {proto.WebFeatures.WebFeaturesFlag|null} [quickRepliesQuery] WebFeatures quickRepliesQuery + * @property {proto.WebFeatures.WebFeaturesFlag|null} [payments] WebFeatures payments + * @property {proto.WebFeatures.WebFeaturesFlag|null} [stickerPackQuery] WebFeatures stickerPackQuery + * @property {proto.WebFeatures.WebFeaturesFlag|null} [liveLocationsFinal] WebFeatures liveLocationsFinal + * @property {proto.WebFeatures.WebFeaturesFlag|null} [labelsEdit] WebFeatures labelsEdit + * @property {proto.WebFeatures.WebFeaturesFlag|null} [mediaUpload] WebFeatures mediaUpload + * @property {proto.WebFeatures.WebFeaturesFlag|null} [mediaUploadRichQuickReplies] WebFeatures mediaUploadRichQuickReplies + * @property {proto.WebFeatures.WebFeaturesFlag|null} [vnameV2] WebFeatures vnameV2 + * @property {proto.WebFeatures.WebFeaturesFlag|null} [videoPlaybackUrl] WebFeatures videoPlaybackUrl + * @property {proto.WebFeatures.WebFeaturesFlag|null} [statusRanking] WebFeatures statusRanking + * @property {proto.WebFeatures.WebFeaturesFlag|null} [voipIndividualVideo] WebFeatures voipIndividualVideo + * @property {proto.WebFeatures.WebFeaturesFlag|null} [thirdPartyStickers] WebFeatures thirdPartyStickers + * @property {proto.WebFeatures.WebFeaturesFlag|null} [frequentlyForwardedSetting] WebFeatures frequentlyForwardedSetting + * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupsV4JoinPermission] WebFeatures groupsV4JoinPermission + * @property {proto.WebFeatures.WebFeaturesFlag|null} [recentStickers] WebFeatures recentStickers + * @property {proto.WebFeatures.WebFeaturesFlag|null} [catalog] WebFeatures catalog + * @property {proto.WebFeatures.WebFeaturesFlag|null} [starredStickers] WebFeatures starredStickers + * @property {proto.WebFeatures.WebFeaturesFlag|null} [voipGroupCall] WebFeatures voipGroupCall + * @property {proto.WebFeatures.WebFeaturesFlag|null} [templateMessage] WebFeatures templateMessage + * @property {proto.WebFeatures.WebFeaturesFlag|null} [templateMessageInteractivity] WebFeatures templateMessageInteractivity + * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeralMessages] WebFeatures ephemeralMessages + * @property {proto.WebFeatures.WebFeaturesFlag|null} [e2ENotificationSync] WebFeatures e2ENotificationSync + * @property {proto.WebFeatures.WebFeaturesFlag|null} [recentStickersV2] WebFeatures recentStickersV2 + * @property {proto.WebFeatures.WebFeaturesFlag|null} [recentStickersV3] WebFeatures recentStickersV3 + * @property {proto.WebFeatures.WebFeaturesFlag|null} [userNotice] WebFeatures userNotice + * @property {proto.WebFeatures.WebFeaturesFlag|null} [support] WebFeatures support + * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupUiiCleanup] WebFeatures groupUiiCleanup + * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupDogfoodingInternalOnly] WebFeatures groupDogfoodingInternalOnly + * @property {proto.WebFeatures.WebFeaturesFlag|null} [settingsSync] WebFeatures settingsSync + * @property {proto.WebFeatures.WebFeaturesFlag|null} [archiveV2] WebFeatures archiveV2 + * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeralAllowGroupMembers] WebFeatures ephemeralAllowGroupMembers + * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeral24HDuration] WebFeatures ephemeral24HDuration + * @property {proto.WebFeatures.WebFeaturesFlag|null} [mdForceUpgrade] WebFeatures mdForceUpgrade + */ + + /** + * Constructs a new WebFeatures. + * @memberof proto + * @classdesc Represents a WebFeatures. + * @implements IWebFeatures + * @constructor + * @param {proto.IWebFeatures=} [properties] Properties to set + */ + function WebFeatures(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * WebFeatures labelsDisplay. + * @member {proto.WebFeatures.WebFeaturesFlag} labelsDisplay + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.labelsDisplay = 0; + + /** + * WebFeatures voipIndividualOutgoing. + * @member {proto.WebFeatures.WebFeaturesFlag} voipIndividualOutgoing + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.voipIndividualOutgoing = 0; + + /** + * WebFeatures groupsV3. + * @member {proto.WebFeatures.WebFeaturesFlag} groupsV3 + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.groupsV3 = 0; + + /** + * WebFeatures groupsV3Create. + * @member {proto.WebFeatures.WebFeaturesFlag} groupsV3Create + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.groupsV3Create = 0; + + /** + * WebFeatures changeNumberV2. + * @member {proto.WebFeatures.WebFeaturesFlag} changeNumberV2 + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.changeNumberV2 = 0; + + /** + * WebFeatures queryStatusV3Thumbnail. + * @member {proto.WebFeatures.WebFeaturesFlag} queryStatusV3Thumbnail + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.queryStatusV3Thumbnail = 0; + + /** + * WebFeatures liveLocations. + * @member {proto.WebFeatures.WebFeaturesFlag} liveLocations + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.liveLocations = 0; + + /** + * WebFeatures queryVname. + * @member {proto.WebFeatures.WebFeaturesFlag} queryVname + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.queryVname = 0; + + /** + * WebFeatures voipIndividualIncoming. + * @member {proto.WebFeatures.WebFeaturesFlag} voipIndividualIncoming + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.voipIndividualIncoming = 0; + + /** + * WebFeatures quickRepliesQuery. + * @member {proto.WebFeatures.WebFeaturesFlag} quickRepliesQuery + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.quickRepliesQuery = 0; + + /** + * WebFeatures payments. + * @member {proto.WebFeatures.WebFeaturesFlag} payments + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.payments = 0; + + /** + * WebFeatures stickerPackQuery. + * @member {proto.WebFeatures.WebFeaturesFlag} stickerPackQuery + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.stickerPackQuery = 0; + + /** + * WebFeatures liveLocationsFinal. + * @member {proto.WebFeatures.WebFeaturesFlag} liveLocationsFinal + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.liveLocationsFinal = 0; + + /** + * WebFeatures labelsEdit. + * @member {proto.WebFeatures.WebFeaturesFlag} labelsEdit + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.labelsEdit = 0; + + /** + * WebFeatures mediaUpload. + * @member {proto.WebFeatures.WebFeaturesFlag} mediaUpload + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.mediaUpload = 0; + + /** + * WebFeatures mediaUploadRichQuickReplies. + * @member {proto.WebFeatures.WebFeaturesFlag} mediaUploadRichQuickReplies + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.mediaUploadRichQuickReplies = 0; + + /** + * WebFeatures vnameV2. + * @member {proto.WebFeatures.WebFeaturesFlag} vnameV2 + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.vnameV2 = 0; + + /** + * WebFeatures videoPlaybackUrl. + * @member {proto.WebFeatures.WebFeaturesFlag} videoPlaybackUrl + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.videoPlaybackUrl = 0; + + /** + * WebFeatures statusRanking. + * @member {proto.WebFeatures.WebFeaturesFlag} statusRanking + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.statusRanking = 0; + + /** + * WebFeatures voipIndividualVideo. + * @member {proto.WebFeatures.WebFeaturesFlag} voipIndividualVideo + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.voipIndividualVideo = 0; + + /** + * WebFeatures thirdPartyStickers. + * @member {proto.WebFeatures.WebFeaturesFlag} thirdPartyStickers + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.thirdPartyStickers = 0; + + /** + * WebFeatures frequentlyForwardedSetting. + * @member {proto.WebFeatures.WebFeaturesFlag} frequentlyForwardedSetting + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.frequentlyForwardedSetting = 0; + + /** + * WebFeatures groupsV4JoinPermission. + * @member {proto.WebFeatures.WebFeaturesFlag} groupsV4JoinPermission + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.groupsV4JoinPermission = 0; + + /** + * WebFeatures recentStickers. + * @member {proto.WebFeatures.WebFeaturesFlag} recentStickers + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.recentStickers = 0; + + /** + * WebFeatures catalog. + * @member {proto.WebFeatures.WebFeaturesFlag} catalog + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.catalog = 0; + + /** + * WebFeatures starredStickers. + * @member {proto.WebFeatures.WebFeaturesFlag} starredStickers + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.starredStickers = 0; + + /** + * WebFeatures voipGroupCall. + * @member {proto.WebFeatures.WebFeaturesFlag} voipGroupCall + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.voipGroupCall = 0; + + /** + * WebFeatures templateMessage. + * @member {proto.WebFeatures.WebFeaturesFlag} templateMessage + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.templateMessage = 0; + + /** + * WebFeatures templateMessageInteractivity. + * @member {proto.WebFeatures.WebFeaturesFlag} templateMessageInteractivity + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.templateMessageInteractivity = 0; + + /** + * WebFeatures ephemeralMessages. + * @member {proto.WebFeatures.WebFeaturesFlag} ephemeralMessages + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.ephemeralMessages = 0; + + /** + * WebFeatures e2ENotificationSync. + * @member {proto.WebFeatures.WebFeaturesFlag} e2ENotificationSync + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.e2ENotificationSync = 0; + + /** + * WebFeatures recentStickersV2. + * @member {proto.WebFeatures.WebFeaturesFlag} recentStickersV2 + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.recentStickersV2 = 0; + + /** + * WebFeatures recentStickersV3. + * @member {proto.WebFeatures.WebFeaturesFlag} recentStickersV3 + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.recentStickersV3 = 0; + + /** + * WebFeatures userNotice. + * @member {proto.WebFeatures.WebFeaturesFlag} userNotice + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.userNotice = 0; + + /** + * WebFeatures support. + * @member {proto.WebFeatures.WebFeaturesFlag} support + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.support = 0; + + /** + * WebFeatures groupUiiCleanup. + * @member {proto.WebFeatures.WebFeaturesFlag} groupUiiCleanup + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.groupUiiCleanup = 0; + + /** + * WebFeatures groupDogfoodingInternalOnly. + * @member {proto.WebFeatures.WebFeaturesFlag} groupDogfoodingInternalOnly + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.groupDogfoodingInternalOnly = 0; + + /** + * WebFeatures settingsSync. + * @member {proto.WebFeatures.WebFeaturesFlag} settingsSync + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.settingsSync = 0; + + /** + * WebFeatures archiveV2. + * @member {proto.WebFeatures.WebFeaturesFlag} archiveV2 + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.archiveV2 = 0; + + /** + * WebFeatures ephemeralAllowGroupMembers. + * @member {proto.WebFeatures.WebFeaturesFlag} ephemeralAllowGroupMembers + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.ephemeralAllowGroupMembers = 0; + + /** + * WebFeatures ephemeral24HDuration. + * @member {proto.WebFeatures.WebFeaturesFlag} ephemeral24HDuration + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.ephemeral24HDuration = 0; + + /** + * WebFeatures mdForceUpgrade. + * @member {proto.WebFeatures.WebFeaturesFlag} mdForceUpgrade + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.mdForceUpgrade = 0; + + /** + * Creates a new WebFeatures instance using the specified properties. + * @function create + * @memberof proto.WebFeatures + * @static + * @param {proto.IWebFeatures=} [properties] Properties to set + * @returns {proto.WebFeatures} WebFeatures instance + */ + WebFeatures.create = function create(properties) { + return new WebFeatures(properties); + }; + + /** + * Encodes the specified WebFeatures message. Does not implicitly {@link proto.WebFeatures.verify|verify} messages. + * @function encode + * @memberof proto.WebFeatures + * @static + * @param {proto.IWebFeatures} message WebFeatures message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WebFeatures.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.labelsDisplay != null && Object.hasOwnProperty.call(message, "labelsDisplay")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.labelsDisplay); + if (message.voipIndividualOutgoing != null && Object.hasOwnProperty.call(message, "voipIndividualOutgoing")) + writer.uint32(/* id 2, wireType 0 =*/16).int32(message.voipIndividualOutgoing); + if (message.groupsV3 != null && Object.hasOwnProperty.call(message, "groupsV3")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.groupsV3); + if (message.groupsV3Create != null && Object.hasOwnProperty.call(message, "groupsV3Create")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.groupsV3Create); + if (message.changeNumberV2 != null && Object.hasOwnProperty.call(message, "changeNumberV2")) + writer.uint32(/* id 5, wireType 0 =*/40).int32(message.changeNumberV2); + if (message.queryStatusV3Thumbnail != null && Object.hasOwnProperty.call(message, "queryStatusV3Thumbnail")) + writer.uint32(/* id 6, wireType 0 =*/48).int32(message.queryStatusV3Thumbnail); + if (message.liveLocations != null && Object.hasOwnProperty.call(message, "liveLocations")) + writer.uint32(/* id 7, wireType 0 =*/56).int32(message.liveLocations); + if (message.queryVname != null && Object.hasOwnProperty.call(message, "queryVname")) + writer.uint32(/* id 8, wireType 0 =*/64).int32(message.queryVname); + if (message.voipIndividualIncoming != null && Object.hasOwnProperty.call(message, "voipIndividualIncoming")) + writer.uint32(/* id 9, wireType 0 =*/72).int32(message.voipIndividualIncoming); + if (message.quickRepliesQuery != null && Object.hasOwnProperty.call(message, "quickRepliesQuery")) + writer.uint32(/* id 10, wireType 0 =*/80).int32(message.quickRepliesQuery); + if (message.payments != null && Object.hasOwnProperty.call(message, "payments")) + writer.uint32(/* id 11, wireType 0 =*/88).int32(message.payments); + if (message.stickerPackQuery != null && Object.hasOwnProperty.call(message, "stickerPackQuery")) + writer.uint32(/* id 12, wireType 0 =*/96).int32(message.stickerPackQuery); + if (message.liveLocationsFinal != null && Object.hasOwnProperty.call(message, "liveLocationsFinal")) + writer.uint32(/* id 13, wireType 0 =*/104).int32(message.liveLocationsFinal); + if (message.labelsEdit != null && Object.hasOwnProperty.call(message, "labelsEdit")) + writer.uint32(/* id 14, wireType 0 =*/112).int32(message.labelsEdit); + if (message.mediaUpload != null && Object.hasOwnProperty.call(message, "mediaUpload")) + writer.uint32(/* id 15, wireType 0 =*/120).int32(message.mediaUpload); + if (message.mediaUploadRichQuickReplies != null && Object.hasOwnProperty.call(message, "mediaUploadRichQuickReplies")) + writer.uint32(/* id 18, wireType 0 =*/144).int32(message.mediaUploadRichQuickReplies); + if (message.vnameV2 != null && Object.hasOwnProperty.call(message, "vnameV2")) + writer.uint32(/* id 19, wireType 0 =*/152).int32(message.vnameV2); + if (message.videoPlaybackUrl != null && Object.hasOwnProperty.call(message, "videoPlaybackUrl")) + writer.uint32(/* id 20, wireType 0 =*/160).int32(message.videoPlaybackUrl); + if (message.statusRanking != null && Object.hasOwnProperty.call(message, "statusRanking")) + writer.uint32(/* id 21, wireType 0 =*/168).int32(message.statusRanking); + if (message.voipIndividualVideo != null && Object.hasOwnProperty.call(message, "voipIndividualVideo")) + writer.uint32(/* id 22, wireType 0 =*/176).int32(message.voipIndividualVideo); + if (message.thirdPartyStickers != null && Object.hasOwnProperty.call(message, "thirdPartyStickers")) + writer.uint32(/* id 23, wireType 0 =*/184).int32(message.thirdPartyStickers); + if (message.frequentlyForwardedSetting != null && Object.hasOwnProperty.call(message, "frequentlyForwardedSetting")) + writer.uint32(/* id 24, wireType 0 =*/192).int32(message.frequentlyForwardedSetting); + if (message.groupsV4JoinPermission != null && Object.hasOwnProperty.call(message, "groupsV4JoinPermission")) + writer.uint32(/* id 25, wireType 0 =*/200).int32(message.groupsV4JoinPermission); + if (message.recentStickers != null && Object.hasOwnProperty.call(message, "recentStickers")) + writer.uint32(/* id 26, wireType 0 =*/208).int32(message.recentStickers); + if (message.catalog != null && Object.hasOwnProperty.call(message, "catalog")) + writer.uint32(/* id 27, wireType 0 =*/216).int32(message.catalog); + if (message.starredStickers != null && Object.hasOwnProperty.call(message, "starredStickers")) + writer.uint32(/* id 28, wireType 0 =*/224).int32(message.starredStickers); + if (message.voipGroupCall != null && Object.hasOwnProperty.call(message, "voipGroupCall")) + writer.uint32(/* id 29, wireType 0 =*/232).int32(message.voipGroupCall); + if (message.templateMessage != null && Object.hasOwnProperty.call(message, "templateMessage")) + writer.uint32(/* id 30, wireType 0 =*/240).int32(message.templateMessage); + if (message.templateMessageInteractivity != null && Object.hasOwnProperty.call(message, "templateMessageInteractivity")) + writer.uint32(/* id 31, wireType 0 =*/248).int32(message.templateMessageInteractivity); + if (message.ephemeralMessages != null && Object.hasOwnProperty.call(message, "ephemeralMessages")) + writer.uint32(/* id 32, wireType 0 =*/256).int32(message.ephemeralMessages); + if (message.e2ENotificationSync != null && Object.hasOwnProperty.call(message, "e2ENotificationSync")) + writer.uint32(/* id 33, wireType 0 =*/264).int32(message.e2ENotificationSync); + if (message.recentStickersV2 != null && Object.hasOwnProperty.call(message, "recentStickersV2")) + writer.uint32(/* id 34, wireType 0 =*/272).int32(message.recentStickersV2); + if (message.recentStickersV3 != null && Object.hasOwnProperty.call(message, "recentStickersV3")) + writer.uint32(/* id 36, wireType 0 =*/288).int32(message.recentStickersV3); + if (message.userNotice != null && Object.hasOwnProperty.call(message, "userNotice")) + writer.uint32(/* id 37, wireType 0 =*/296).int32(message.userNotice); + if (message.support != null && Object.hasOwnProperty.call(message, "support")) + writer.uint32(/* id 39, wireType 0 =*/312).int32(message.support); + if (message.groupUiiCleanup != null && Object.hasOwnProperty.call(message, "groupUiiCleanup")) + writer.uint32(/* id 40, wireType 0 =*/320).int32(message.groupUiiCleanup); + if (message.groupDogfoodingInternalOnly != null && Object.hasOwnProperty.call(message, "groupDogfoodingInternalOnly")) + writer.uint32(/* id 41, wireType 0 =*/328).int32(message.groupDogfoodingInternalOnly); + if (message.settingsSync != null && Object.hasOwnProperty.call(message, "settingsSync")) + writer.uint32(/* id 42, wireType 0 =*/336).int32(message.settingsSync); + if (message.archiveV2 != null && Object.hasOwnProperty.call(message, "archiveV2")) + writer.uint32(/* id 43, wireType 0 =*/344).int32(message.archiveV2); + if (message.ephemeralAllowGroupMembers != null && Object.hasOwnProperty.call(message, "ephemeralAllowGroupMembers")) + writer.uint32(/* id 44, wireType 0 =*/352).int32(message.ephemeralAllowGroupMembers); + if (message.ephemeral24HDuration != null && Object.hasOwnProperty.call(message, "ephemeral24HDuration")) + writer.uint32(/* id 45, wireType 0 =*/360).int32(message.ephemeral24HDuration); + if (message.mdForceUpgrade != null && Object.hasOwnProperty.call(message, "mdForceUpgrade")) + writer.uint32(/* id 46, wireType 0 =*/368).int32(message.mdForceUpgrade); + return writer; + }; + + /** + * Encodes the specified WebFeatures message, length delimited. Does not implicitly {@link proto.WebFeatures.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.WebFeatures + * @static + * @param {proto.IWebFeatures} message WebFeatures message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WebFeatures.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a WebFeatures message from the specified reader or buffer. + * @function decode + * @memberof proto.WebFeatures + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.WebFeatures} WebFeatures + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebFeatures.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebFeatures(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.labelsDisplay = reader.int32(); + break; + case 2: + message.voipIndividualOutgoing = reader.int32(); + break; + case 3: + message.groupsV3 = reader.int32(); + break; + case 4: + message.groupsV3Create = reader.int32(); + break; + case 5: + message.changeNumberV2 = reader.int32(); + break; + case 6: + message.queryStatusV3Thumbnail = reader.int32(); + break; + case 7: + message.liveLocations = reader.int32(); + break; + case 8: + message.queryVname = reader.int32(); + break; + case 9: + message.voipIndividualIncoming = reader.int32(); + break; + case 10: + message.quickRepliesQuery = reader.int32(); + break; + case 11: + message.payments = reader.int32(); + break; + case 12: + message.stickerPackQuery = reader.int32(); + break; + case 13: + message.liveLocationsFinal = reader.int32(); + break; + case 14: + message.labelsEdit = reader.int32(); + break; + case 15: + message.mediaUpload = reader.int32(); + break; + case 18: + message.mediaUploadRichQuickReplies = reader.int32(); + break; + case 19: + message.vnameV2 = reader.int32(); + break; + case 20: + message.videoPlaybackUrl = reader.int32(); + break; + case 21: + message.statusRanking = reader.int32(); + break; + case 22: + message.voipIndividualVideo = reader.int32(); + break; + case 23: + message.thirdPartyStickers = reader.int32(); + break; + case 24: + message.frequentlyForwardedSetting = reader.int32(); + break; + case 25: + message.groupsV4JoinPermission = reader.int32(); + break; + case 26: + message.recentStickers = reader.int32(); + break; + case 27: + message.catalog = reader.int32(); + break; + case 28: + message.starredStickers = reader.int32(); + break; + case 29: + message.voipGroupCall = reader.int32(); + break; + case 30: + message.templateMessage = reader.int32(); + break; + case 31: + message.templateMessageInteractivity = reader.int32(); + break; + case 32: + message.ephemeralMessages = reader.int32(); + break; + case 33: + message.e2ENotificationSync = reader.int32(); + break; + case 34: + message.recentStickersV2 = reader.int32(); + break; + case 36: + message.recentStickersV3 = reader.int32(); + break; + case 37: + message.userNotice = reader.int32(); + break; + case 39: + message.support = reader.int32(); + break; + case 40: + message.groupUiiCleanup = reader.int32(); + break; + case 41: + message.groupDogfoodingInternalOnly = reader.int32(); + break; + case 42: + message.settingsSync = reader.int32(); + break; + case 43: + message.archiveV2 = reader.int32(); + break; + case 44: + message.ephemeralAllowGroupMembers = reader.int32(); + break; + case 45: + message.ephemeral24HDuration = reader.int32(); + break; + case 46: + message.mdForceUpgrade = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a WebFeatures message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.WebFeatures + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.WebFeatures} WebFeatures + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebFeatures.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a WebFeatures message. + * @function verify + * @memberof proto.WebFeatures + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + WebFeatures.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.labelsDisplay != null && message.hasOwnProperty("labelsDisplay")) + switch (message.labelsDisplay) { + default: + return "labelsDisplay: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.voipIndividualOutgoing != null && message.hasOwnProperty("voipIndividualOutgoing")) + switch (message.voipIndividualOutgoing) { + default: + return "voipIndividualOutgoing: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.groupsV3 != null && message.hasOwnProperty("groupsV3")) + switch (message.groupsV3) { + default: + return "groupsV3: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.groupsV3Create != null && message.hasOwnProperty("groupsV3Create")) + switch (message.groupsV3Create) { + default: + return "groupsV3Create: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.changeNumberV2 != null && message.hasOwnProperty("changeNumberV2")) + switch (message.changeNumberV2) { + default: + return "changeNumberV2: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.queryStatusV3Thumbnail != null && message.hasOwnProperty("queryStatusV3Thumbnail")) + switch (message.queryStatusV3Thumbnail) { + default: + return "queryStatusV3Thumbnail: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.liveLocations != null && message.hasOwnProperty("liveLocations")) + switch (message.liveLocations) { + default: + return "liveLocations: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.queryVname != null && message.hasOwnProperty("queryVname")) + switch (message.queryVname) { + default: + return "queryVname: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.voipIndividualIncoming != null && message.hasOwnProperty("voipIndividualIncoming")) + switch (message.voipIndividualIncoming) { + default: + return "voipIndividualIncoming: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.quickRepliesQuery != null && message.hasOwnProperty("quickRepliesQuery")) + switch (message.quickRepliesQuery) { + default: + return "quickRepliesQuery: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.payments != null && message.hasOwnProperty("payments")) + switch (message.payments) { + default: + return "payments: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.stickerPackQuery != null && message.hasOwnProperty("stickerPackQuery")) + switch (message.stickerPackQuery) { + default: + return "stickerPackQuery: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.liveLocationsFinal != null && message.hasOwnProperty("liveLocationsFinal")) + switch (message.liveLocationsFinal) { + default: + return "liveLocationsFinal: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.labelsEdit != null && message.hasOwnProperty("labelsEdit")) + switch (message.labelsEdit) { + default: + return "labelsEdit: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.mediaUpload != null && message.hasOwnProperty("mediaUpload")) + switch (message.mediaUpload) { + default: + return "mediaUpload: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.mediaUploadRichQuickReplies != null && message.hasOwnProperty("mediaUploadRichQuickReplies")) + switch (message.mediaUploadRichQuickReplies) { + default: + return "mediaUploadRichQuickReplies: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.vnameV2 != null && message.hasOwnProperty("vnameV2")) + switch (message.vnameV2) { + default: + return "vnameV2: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.videoPlaybackUrl != null && message.hasOwnProperty("videoPlaybackUrl")) + switch (message.videoPlaybackUrl) { + default: + return "videoPlaybackUrl: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.statusRanking != null && message.hasOwnProperty("statusRanking")) + switch (message.statusRanking) { + default: + return "statusRanking: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.voipIndividualVideo != null && message.hasOwnProperty("voipIndividualVideo")) + switch (message.voipIndividualVideo) { + default: + return "voipIndividualVideo: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.thirdPartyStickers != null && message.hasOwnProperty("thirdPartyStickers")) + switch (message.thirdPartyStickers) { + default: + return "thirdPartyStickers: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.frequentlyForwardedSetting != null && message.hasOwnProperty("frequentlyForwardedSetting")) + switch (message.frequentlyForwardedSetting) { + default: + return "frequentlyForwardedSetting: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.groupsV4JoinPermission != null && message.hasOwnProperty("groupsV4JoinPermission")) + switch (message.groupsV4JoinPermission) { + default: + return "groupsV4JoinPermission: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.recentStickers != null && message.hasOwnProperty("recentStickers")) + switch (message.recentStickers) { + default: + return "recentStickers: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.catalog != null && message.hasOwnProperty("catalog")) + switch (message.catalog) { + default: + return "catalog: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.starredStickers != null && message.hasOwnProperty("starredStickers")) + switch (message.starredStickers) { + default: + return "starredStickers: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.voipGroupCall != null && message.hasOwnProperty("voipGroupCall")) + switch (message.voipGroupCall) { + default: + return "voipGroupCall: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.templateMessage != null && message.hasOwnProperty("templateMessage")) + switch (message.templateMessage) { + default: + return "templateMessage: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.templateMessageInteractivity != null && message.hasOwnProperty("templateMessageInteractivity")) + switch (message.templateMessageInteractivity) { + default: + return "templateMessageInteractivity: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.ephemeralMessages != null && message.hasOwnProperty("ephemeralMessages")) + switch (message.ephemeralMessages) { + default: + return "ephemeralMessages: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.e2ENotificationSync != null && message.hasOwnProperty("e2ENotificationSync")) + switch (message.e2ENotificationSync) { + default: + return "e2ENotificationSync: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.recentStickersV2 != null && message.hasOwnProperty("recentStickersV2")) + switch (message.recentStickersV2) { + default: + return "recentStickersV2: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.recentStickersV3 != null && message.hasOwnProperty("recentStickersV3")) + switch (message.recentStickersV3) { + default: + return "recentStickersV3: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.userNotice != null && message.hasOwnProperty("userNotice")) + switch (message.userNotice) { + default: + return "userNotice: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.support != null && message.hasOwnProperty("support")) + switch (message.support) { + default: + return "support: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.groupUiiCleanup != null && message.hasOwnProperty("groupUiiCleanup")) + switch (message.groupUiiCleanup) { + default: + return "groupUiiCleanup: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.groupDogfoodingInternalOnly != null && message.hasOwnProperty("groupDogfoodingInternalOnly")) + switch (message.groupDogfoodingInternalOnly) { + default: + return "groupDogfoodingInternalOnly: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.settingsSync != null && message.hasOwnProperty("settingsSync")) + switch (message.settingsSync) { + default: + return "settingsSync: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.archiveV2 != null && message.hasOwnProperty("archiveV2")) + switch (message.archiveV2) { + default: + return "archiveV2: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.ephemeralAllowGroupMembers != null && message.hasOwnProperty("ephemeralAllowGroupMembers")) + switch (message.ephemeralAllowGroupMembers) { + default: + return "ephemeralAllowGroupMembers: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.ephemeral24HDuration != null && message.hasOwnProperty("ephemeral24HDuration")) + switch (message.ephemeral24HDuration) { + default: + return "ephemeral24HDuration: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.mdForceUpgrade != null && message.hasOwnProperty("mdForceUpgrade")) + switch (message.mdForceUpgrade) { + default: + return "mdForceUpgrade: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + return null; + }; + + /** + * Creates a WebFeatures message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.WebFeatures + * @static + * @param {Object.} object Plain object + * @returns {proto.WebFeatures} WebFeatures + */ + WebFeatures.fromObject = function fromObject(object) { + if (object instanceof $root.proto.WebFeatures) + return object; + var message = new $root.proto.WebFeatures(); + switch (object.labelsDisplay) { + case "NOT_STARTED": + case 0: + message.labelsDisplay = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.labelsDisplay = 1; + break; + case "DEVELOPMENT": + case 2: + message.labelsDisplay = 2; + break; + case "PRODUCTION": + case 3: + message.labelsDisplay = 3; + break; + } + switch (object.voipIndividualOutgoing) { + case "NOT_STARTED": + case 0: + message.voipIndividualOutgoing = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.voipIndividualOutgoing = 1; + break; + case "DEVELOPMENT": + case 2: + message.voipIndividualOutgoing = 2; + break; + case "PRODUCTION": + case 3: + message.voipIndividualOutgoing = 3; + break; + } + switch (object.groupsV3) { + case "NOT_STARTED": + case 0: + message.groupsV3 = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.groupsV3 = 1; + break; + case "DEVELOPMENT": + case 2: + message.groupsV3 = 2; + break; + case "PRODUCTION": + case 3: + message.groupsV3 = 3; + break; + } + switch (object.groupsV3Create) { + case "NOT_STARTED": + case 0: + message.groupsV3Create = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.groupsV3Create = 1; + break; + case "DEVELOPMENT": + case 2: + message.groupsV3Create = 2; + break; + case "PRODUCTION": + case 3: + message.groupsV3Create = 3; + break; + } + switch (object.changeNumberV2) { + case "NOT_STARTED": + case 0: + message.changeNumberV2 = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.changeNumberV2 = 1; + break; + case "DEVELOPMENT": + case 2: + message.changeNumberV2 = 2; + break; + case "PRODUCTION": + case 3: + message.changeNumberV2 = 3; + break; + } + switch (object.queryStatusV3Thumbnail) { + case "NOT_STARTED": + case 0: + message.queryStatusV3Thumbnail = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.queryStatusV3Thumbnail = 1; + break; + case "DEVELOPMENT": + case 2: + message.queryStatusV3Thumbnail = 2; + break; + case "PRODUCTION": + case 3: + message.queryStatusV3Thumbnail = 3; + break; + } + switch (object.liveLocations) { + case "NOT_STARTED": + case 0: + message.liveLocations = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.liveLocations = 1; + break; + case "DEVELOPMENT": + case 2: + message.liveLocations = 2; + break; + case "PRODUCTION": + case 3: + message.liveLocations = 3; + break; + } + switch (object.queryVname) { + case "NOT_STARTED": + case 0: + message.queryVname = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.queryVname = 1; + break; + case "DEVELOPMENT": + case 2: + message.queryVname = 2; + break; + case "PRODUCTION": + case 3: + message.queryVname = 3; + break; + } + switch (object.voipIndividualIncoming) { + case "NOT_STARTED": + case 0: + message.voipIndividualIncoming = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.voipIndividualIncoming = 1; + break; + case "DEVELOPMENT": + case 2: + message.voipIndividualIncoming = 2; + break; + case "PRODUCTION": + case 3: + message.voipIndividualIncoming = 3; + break; + } + switch (object.quickRepliesQuery) { + case "NOT_STARTED": + case 0: + message.quickRepliesQuery = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.quickRepliesQuery = 1; + break; + case "DEVELOPMENT": + case 2: + message.quickRepliesQuery = 2; + break; + case "PRODUCTION": + case 3: + message.quickRepliesQuery = 3; + break; + } + switch (object.payments) { + case "NOT_STARTED": + case 0: + message.payments = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.payments = 1; + break; + case "DEVELOPMENT": + case 2: + message.payments = 2; + break; + case "PRODUCTION": + case 3: + message.payments = 3; + break; + } + switch (object.stickerPackQuery) { + case "NOT_STARTED": + case 0: + message.stickerPackQuery = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.stickerPackQuery = 1; + break; + case "DEVELOPMENT": + case 2: + message.stickerPackQuery = 2; + break; + case "PRODUCTION": + case 3: + message.stickerPackQuery = 3; + break; + } + switch (object.liveLocationsFinal) { + case "NOT_STARTED": + case 0: + message.liveLocationsFinal = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.liveLocationsFinal = 1; + break; + case "DEVELOPMENT": + case 2: + message.liveLocationsFinal = 2; + break; + case "PRODUCTION": + case 3: + message.liveLocationsFinal = 3; + break; + } + switch (object.labelsEdit) { + case "NOT_STARTED": + case 0: + message.labelsEdit = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.labelsEdit = 1; + break; + case "DEVELOPMENT": + case 2: + message.labelsEdit = 2; + break; + case "PRODUCTION": + case 3: + message.labelsEdit = 3; + break; + } + switch (object.mediaUpload) { + case "NOT_STARTED": + case 0: + message.mediaUpload = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.mediaUpload = 1; + break; + case "DEVELOPMENT": + case 2: + message.mediaUpload = 2; + break; + case "PRODUCTION": + case 3: + message.mediaUpload = 3; + break; + } + switch (object.mediaUploadRichQuickReplies) { + case "NOT_STARTED": + case 0: + message.mediaUploadRichQuickReplies = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.mediaUploadRichQuickReplies = 1; + break; + case "DEVELOPMENT": + case 2: + message.mediaUploadRichQuickReplies = 2; + break; + case "PRODUCTION": + case 3: + message.mediaUploadRichQuickReplies = 3; + break; + } + switch (object.vnameV2) { + case "NOT_STARTED": + case 0: + message.vnameV2 = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.vnameV2 = 1; + break; + case "DEVELOPMENT": + case 2: + message.vnameV2 = 2; + break; + case "PRODUCTION": + case 3: + message.vnameV2 = 3; + break; + } + switch (object.videoPlaybackUrl) { + case "NOT_STARTED": + case 0: + message.videoPlaybackUrl = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.videoPlaybackUrl = 1; + break; + case "DEVELOPMENT": + case 2: + message.videoPlaybackUrl = 2; + break; + case "PRODUCTION": + case 3: + message.videoPlaybackUrl = 3; + break; + } + switch (object.statusRanking) { + case "NOT_STARTED": + case 0: + message.statusRanking = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.statusRanking = 1; + break; + case "DEVELOPMENT": + case 2: + message.statusRanking = 2; + break; + case "PRODUCTION": + case 3: + message.statusRanking = 3; + break; + } + switch (object.voipIndividualVideo) { + case "NOT_STARTED": + case 0: + message.voipIndividualVideo = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.voipIndividualVideo = 1; + break; + case "DEVELOPMENT": + case 2: + message.voipIndividualVideo = 2; + break; + case "PRODUCTION": + case 3: + message.voipIndividualVideo = 3; + break; + } + switch (object.thirdPartyStickers) { + case "NOT_STARTED": + case 0: + message.thirdPartyStickers = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.thirdPartyStickers = 1; + break; + case "DEVELOPMENT": + case 2: + message.thirdPartyStickers = 2; + break; + case "PRODUCTION": + case 3: + message.thirdPartyStickers = 3; + break; + } + switch (object.frequentlyForwardedSetting) { + case "NOT_STARTED": + case 0: + message.frequentlyForwardedSetting = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.frequentlyForwardedSetting = 1; + break; + case "DEVELOPMENT": + case 2: + message.frequentlyForwardedSetting = 2; + break; + case "PRODUCTION": + case 3: + message.frequentlyForwardedSetting = 3; + break; + } + switch (object.groupsV4JoinPermission) { + case "NOT_STARTED": + case 0: + message.groupsV4JoinPermission = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.groupsV4JoinPermission = 1; + break; + case "DEVELOPMENT": + case 2: + message.groupsV4JoinPermission = 2; + break; + case "PRODUCTION": + case 3: + message.groupsV4JoinPermission = 3; + break; + } + switch (object.recentStickers) { + case "NOT_STARTED": + case 0: + message.recentStickers = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.recentStickers = 1; + break; + case "DEVELOPMENT": + case 2: + message.recentStickers = 2; + break; + case "PRODUCTION": + case 3: + message.recentStickers = 3; + break; + } + switch (object.catalog) { + case "NOT_STARTED": + case 0: + message.catalog = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.catalog = 1; + break; + case "DEVELOPMENT": + case 2: + message.catalog = 2; + break; + case "PRODUCTION": + case 3: + message.catalog = 3; + break; + } + switch (object.starredStickers) { + case "NOT_STARTED": + case 0: + message.starredStickers = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.starredStickers = 1; + break; + case "DEVELOPMENT": + case 2: + message.starredStickers = 2; + break; + case "PRODUCTION": + case 3: + message.starredStickers = 3; + break; + } + switch (object.voipGroupCall) { + case "NOT_STARTED": + case 0: + message.voipGroupCall = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.voipGroupCall = 1; + break; + case "DEVELOPMENT": + case 2: + message.voipGroupCall = 2; + break; + case "PRODUCTION": + case 3: + message.voipGroupCall = 3; + break; + } + switch (object.templateMessage) { + case "NOT_STARTED": + case 0: + message.templateMessage = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.templateMessage = 1; + break; + case "DEVELOPMENT": + case 2: + message.templateMessage = 2; + break; + case "PRODUCTION": + case 3: + message.templateMessage = 3; + break; + } + switch (object.templateMessageInteractivity) { + case "NOT_STARTED": + case 0: + message.templateMessageInteractivity = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.templateMessageInteractivity = 1; + break; + case "DEVELOPMENT": + case 2: + message.templateMessageInteractivity = 2; + break; + case "PRODUCTION": + case 3: + message.templateMessageInteractivity = 3; + break; + } + switch (object.ephemeralMessages) { + case "NOT_STARTED": + case 0: + message.ephemeralMessages = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.ephemeralMessages = 1; + break; + case "DEVELOPMENT": + case 2: + message.ephemeralMessages = 2; + break; + case "PRODUCTION": + case 3: + message.ephemeralMessages = 3; + break; + } + switch (object.e2ENotificationSync) { + case "NOT_STARTED": + case 0: + message.e2ENotificationSync = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.e2ENotificationSync = 1; + break; + case "DEVELOPMENT": + case 2: + message.e2ENotificationSync = 2; + break; + case "PRODUCTION": + case 3: + message.e2ENotificationSync = 3; + break; + } + switch (object.recentStickersV2) { + case "NOT_STARTED": + case 0: + message.recentStickersV2 = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.recentStickersV2 = 1; + break; + case "DEVELOPMENT": + case 2: + message.recentStickersV2 = 2; + break; + case "PRODUCTION": + case 3: + message.recentStickersV2 = 3; + break; + } + switch (object.recentStickersV3) { + case "NOT_STARTED": + case 0: + message.recentStickersV3 = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.recentStickersV3 = 1; + break; + case "DEVELOPMENT": + case 2: + message.recentStickersV3 = 2; + break; + case "PRODUCTION": + case 3: + message.recentStickersV3 = 3; + break; + } + switch (object.userNotice) { + case "NOT_STARTED": + case 0: + message.userNotice = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.userNotice = 1; + break; + case "DEVELOPMENT": + case 2: + message.userNotice = 2; + break; + case "PRODUCTION": + case 3: + message.userNotice = 3; + break; + } + switch (object.support) { + case "NOT_STARTED": + case 0: + message.support = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.support = 1; + break; + case "DEVELOPMENT": + case 2: + message.support = 2; + break; + case "PRODUCTION": + case 3: + message.support = 3; + break; + } + switch (object.groupUiiCleanup) { + case "NOT_STARTED": + case 0: + message.groupUiiCleanup = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.groupUiiCleanup = 1; + break; + case "DEVELOPMENT": + case 2: + message.groupUiiCleanup = 2; + break; + case "PRODUCTION": + case 3: + message.groupUiiCleanup = 3; + break; + } + switch (object.groupDogfoodingInternalOnly) { + case "NOT_STARTED": + case 0: + message.groupDogfoodingInternalOnly = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.groupDogfoodingInternalOnly = 1; + break; + case "DEVELOPMENT": + case 2: + message.groupDogfoodingInternalOnly = 2; + break; + case "PRODUCTION": + case 3: + message.groupDogfoodingInternalOnly = 3; + break; + } + switch (object.settingsSync) { + case "NOT_STARTED": + case 0: + message.settingsSync = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.settingsSync = 1; + break; + case "DEVELOPMENT": + case 2: + message.settingsSync = 2; + break; + case "PRODUCTION": + case 3: + message.settingsSync = 3; + break; + } + switch (object.archiveV2) { + case "NOT_STARTED": + case 0: + message.archiveV2 = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.archiveV2 = 1; + break; + case "DEVELOPMENT": + case 2: + message.archiveV2 = 2; + break; + case "PRODUCTION": + case 3: + message.archiveV2 = 3; + break; + } + switch (object.ephemeralAllowGroupMembers) { + case "NOT_STARTED": + case 0: + message.ephemeralAllowGroupMembers = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.ephemeralAllowGroupMembers = 1; + break; + case "DEVELOPMENT": + case 2: + message.ephemeralAllowGroupMembers = 2; + break; + case "PRODUCTION": + case 3: + message.ephemeralAllowGroupMembers = 3; + break; + } + switch (object.ephemeral24HDuration) { + case "NOT_STARTED": + case 0: + message.ephemeral24HDuration = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.ephemeral24HDuration = 1; + break; + case "DEVELOPMENT": + case 2: + message.ephemeral24HDuration = 2; + break; + case "PRODUCTION": + case 3: + message.ephemeral24HDuration = 3; + break; + } + switch (object.mdForceUpgrade) { + case "NOT_STARTED": + case 0: + message.mdForceUpgrade = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.mdForceUpgrade = 1; + break; + case "DEVELOPMENT": + case 2: + message.mdForceUpgrade = 2; + break; + case "PRODUCTION": + case 3: + message.mdForceUpgrade = 3; + break; + } + return message; + }; + + /** + * Creates a plain object from a WebFeatures message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.WebFeatures + * @static + * @param {proto.WebFeatures} message WebFeatures + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + WebFeatures.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.labelsDisplay = options.enums === String ? "NOT_STARTED" : 0; + object.voipIndividualOutgoing = options.enums === String ? "NOT_STARTED" : 0; + object.groupsV3 = options.enums === String ? "NOT_STARTED" : 0; + object.groupsV3Create = options.enums === String ? "NOT_STARTED" : 0; + object.changeNumberV2 = options.enums === String ? "NOT_STARTED" : 0; + object.queryStatusV3Thumbnail = options.enums === String ? "NOT_STARTED" : 0; + object.liveLocations = options.enums === String ? "NOT_STARTED" : 0; + object.queryVname = options.enums === String ? "NOT_STARTED" : 0; + object.voipIndividualIncoming = options.enums === String ? "NOT_STARTED" : 0; + object.quickRepliesQuery = options.enums === String ? "NOT_STARTED" : 0; + object.payments = options.enums === String ? "NOT_STARTED" : 0; + object.stickerPackQuery = options.enums === String ? "NOT_STARTED" : 0; + object.liveLocationsFinal = options.enums === String ? "NOT_STARTED" : 0; + object.labelsEdit = options.enums === String ? "NOT_STARTED" : 0; + object.mediaUpload = options.enums === String ? "NOT_STARTED" : 0; + object.mediaUploadRichQuickReplies = options.enums === String ? "NOT_STARTED" : 0; + object.vnameV2 = options.enums === String ? "NOT_STARTED" : 0; + object.videoPlaybackUrl = options.enums === String ? "NOT_STARTED" : 0; + object.statusRanking = options.enums === String ? "NOT_STARTED" : 0; + object.voipIndividualVideo = options.enums === String ? "NOT_STARTED" : 0; + object.thirdPartyStickers = options.enums === String ? "NOT_STARTED" : 0; + object.frequentlyForwardedSetting = options.enums === String ? "NOT_STARTED" : 0; + object.groupsV4JoinPermission = options.enums === String ? "NOT_STARTED" : 0; + object.recentStickers = options.enums === String ? "NOT_STARTED" : 0; + object.catalog = options.enums === String ? "NOT_STARTED" : 0; + object.starredStickers = options.enums === String ? "NOT_STARTED" : 0; + object.voipGroupCall = options.enums === String ? "NOT_STARTED" : 0; + object.templateMessage = options.enums === String ? "NOT_STARTED" : 0; + object.templateMessageInteractivity = options.enums === String ? "NOT_STARTED" : 0; + object.ephemeralMessages = options.enums === String ? "NOT_STARTED" : 0; + object.e2ENotificationSync = options.enums === String ? "NOT_STARTED" : 0; + object.recentStickersV2 = options.enums === String ? "NOT_STARTED" : 0; + object.recentStickersV3 = options.enums === String ? "NOT_STARTED" : 0; + object.userNotice = options.enums === String ? "NOT_STARTED" : 0; + object.support = options.enums === String ? "NOT_STARTED" : 0; + object.groupUiiCleanup = options.enums === String ? "NOT_STARTED" : 0; + object.groupDogfoodingInternalOnly = options.enums === String ? "NOT_STARTED" : 0; + object.settingsSync = options.enums === String ? "NOT_STARTED" : 0; + object.archiveV2 = options.enums === String ? "NOT_STARTED" : 0; + object.ephemeralAllowGroupMembers = options.enums === String ? "NOT_STARTED" : 0; + object.ephemeral24HDuration = options.enums === String ? "NOT_STARTED" : 0; + object.mdForceUpgrade = options.enums === String ? "NOT_STARTED" : 0; + } + if (message.labelsDisplay != null && message.hasOwnProperty("labelsDisplay")) + object.labelsDisplay = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.labelsDisplay] : message.labelsDisplay; + if (message.voipIndividualOutgoing != null && message.hasOwnProperty("voipIndividualOutgoing")) + object.voipIndividualOutgoing = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.voipIndividualOutgoing] : message.voipIndividualOutgoing; + if (message.groupsV3 != null && message.hasOwnProperty("groupsV3")) + object.groupsV3 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupsV3] : message.groupsV3; + if (message.groupsV3Create != null && message.hasOwnProperty("groupsV3Create")) + object.groupsV3Create = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupsV3Create] : message.groupsV3Create; + if (message.changeNumberV2 != null && message.hasOwnProperty("changeNumberV2")) + object.changeNumberV2 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.changeNumberV2] : message.changeNumberV2; + if (message.queryStatusV3Thumbnail != null && message.hasOwnProperty("queryStatusV3Thumbnail")) + object.queryStatusV3Thumbnail = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.queryStatusV3Thumbnail] : message.queryStatusV3Thumbnail; + if (message.liveLocations != null && message.hasOwnProperty("liveLocations")) + object.liveLocations = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.liveLocations] : message.liveLocations; + if (message.queryVname != null && message.hasOwnProperty("queryVname")) + object.queryVname = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.queryVname] : message.queryVname; + if (message.voipIndividualIncoming != null && message.hasOwnProperty("voipIndividualIncoming")) + object.voipIndividualIncoming = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.voipIndividualIncoming] : message.voipIndividualIncoming; + if (message.quickRepliesQuery != null && message.hasOwnProperty("quickRepliesQuery")) + object.quickRepliesQuery = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.quickRepliesQuery] : message.quickRepliesQuery; + if (message.payments != null && message.hasOwnProperty("payments")) + object.payments = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.payments] : message.payments; + if (message.stickerPackQuery != null && message.hasOwnProperty("stickerPackQuery")) + object.stickerPackQuery = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.stickerPackQuery] : message.stickerPackQuery; + if (message.liveLocationsFinal != null && message.hasOwnProperty("liveLocationsFinal")) + object.liveLocationsFinal = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.liveLocationsFinal] : message.liveLocationsFinal; + if (message.labelsEdit != null && message.hasOwnProperty("labelsEdit")) + object.labelsEdit = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.labelsEdit] : message.labelsEdit; + if (message.mediaUpload != null && message.hasOwnProperty("mediaUpload")) + object.mediaUpload = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.mediaUpload] : message.mediaUpload; + if (message.mediaUploadRichQuickReplies != null && message.hasOwnProperty("mediaUploadRichQuickReplies")) + object.mediaUploadRichQuickReplies = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.mediaUploadRichQuickReplies] : message.mediaUploadRichQuickReplies; + if (message.vnameV2 != null && message.hasOwnProperty("vnameV2")) + object.vnameV2 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.vnameV2] : message.vnameV2; + if (message.videoPlaybackUrl != null && message.hasOwnProperty("videoPlaybackUrl")) + object.videoPlaybackUrl = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.videoPlaybackUrl] : message.videoPlaybackUrl; + if (message.statusRanking != null && message.hasOwnProperty("statusRanking")) + object.statusRanking = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.statusRanking] : message.statusRanking; + if (message.voipIndividualVideo != null && message.hasOwnProperty("voipIndividualVideo")) + object.voipIndividualVideo = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.voipIndividualVideo] : message.voipIndividualVideo; + if (message.thirdPartyStickers != null && message.hasOwnProperty("thirdPartyStickers")) + object.thirdPartyStickers = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.thirdPartyStickers] : message.thirdPartyStickers; + if (message.frequentlyForwardedSetting != null && message.hasOwnProperty("frequentlyForwardedSetting")) + object.frequentlyForwardedSetting = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.frequentlyForwardedSetting] : message.frequentlyForwardedSetting; + if (message.groupsV4JoinPermission != null && message.hasOwnProperty("groupsV4JoinPermission")) + object.groupsV4JoinPermission = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupsV4JoinPermission] : message.groupsV4JoinPermission; + if (message.recentStickers != null && message.hasOwnProperty("recentStickers")) + object.recentStickers = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.recentStickers] : message.recentStickers; + if (message.catalog != null && message.hasOwnProperty("catalog")) + object.catalog = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.catalog] : message.catalog; + if (message.starredStickers != null && message.hasOwnProperty("starredStickers")) + object.starredStickers = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.starredStickers] : message.starredStickers; + if (message.voipGroupCall != null && message.hasOwnProperty("voipGroupCall")) + object.voipGroupCall = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.voipGroupCall] : message.voipGroupCall; + if (message.templateMessage != null && message.hasOwnProperty("templateMessage")) + object.templateMessage = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.templateMessage] : message.templateMessage; + if (message.templateMessageInteractivity != null && message.hasOwnProperty("templateMessageInteractivity")) + object.templateMessageInteractivity = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.templateMessageInteractivity] : message.templateMessageInteractivity; + if (message.ephemeralMessages != null && message.hasOwnProperty("ephemeralMessages")) + object.ephemeralMessages = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.ephemeralMessages] : message.ephemeralMessages; + if (message.e2ENotificationSync != null && message.hasOwnProperty("e2ENotificationSync")) + object.e2ENotificationSync = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.e2ENotificationSync] : message.e2ENotificationSync; + if (message.recentStickersV2 != null && message.hasOwnProperty("recentStickersV2")) + object.recentStickersV2 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.recentStickersV2] : message.recentStickersV2; + if (message.recentStickersV3 != null && message.hasOwnProperty("recentStickersV3")) + object.recentStickersV3 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.recentStickersV3] : message.recentStickersV3; + if (message.userNotice != null && message.hasOwnProperty("userNotice")) + object.userNotice = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.userNotice] : message.userNotice; + if (message.support != null && message.hasOwnProperty("support")) + object.support = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.support] : message.support; + if (message.groupUiiCleanup != null && message.hasOwnProperty("groupUiiCleanup")) + object.groupUiiCleanup = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupUiiCleanup] : message.groupUiiCleanup; + if (message.groupDogfoodingInternalOnly != null && message.hasOwnProperty("groupDogfoodingInternalOnly")) + object.groupDogfoodingInternalOnly = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupDogfoodingInternalOnly] : message.groupDogfoodingInternalOnly; + if (message.settingsSync != null && message.hasOwnProperty("settingsSync")) + object.settingsSync = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.settingsSync] : message.settingsSync; + if (message.archiveV2 != null && message.hasOwnProperty("archiveV2")) + object.archiveV2 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.archiveV2] : message.archiveV2; + if (message.ephemeralAllowGroupMembers != null && message.hasOwnProperty("ephemeralAllowGroupMembers")) + object.ephemeralAllowGroupMembers = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.ephemeralAllowGroupMembers] : message.ephemeralAllowGroupMembers; + if (message.ephemeral24HDuration != null && message.hasOwnProperty("ephemeral24HDuration")) + object.ephemeral24HDuration = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.ephemeral24HDuration] : message.ephemeral24HDuration; + if (message.mdForceUpgrade != null && message.hasOwnProperty("mdForceUpgrade")) + object.mdForceUpgrade = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.mdForceUpgrade] : message.mdForceUpgrade; + return object; + }; + + /** + * Converts this WebFeatures to JSON. + * @function toJSON + * @memberof proto.WebFeatures + * @instance + * @returns {Object.} JSON object + */ + WebFeatures.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * WebFeaturesFlag enum. + * @name proto.WebFeatures.WebFeaturesFlag + * @enum {number} + * @property {number} NOT_STARTED=0 NOT_STARTED value + * @property {number} FORCE_UPGRADE=1 FORCE_UPGRADE value + * @property {number} DEVELOPMENT=2 DEVELOPMENT value + * @property {number} PRODUCTION=3 PRODUCTION value + */ + WebFeatures.WebFeaturesFlag = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "NOT_STARTED"] = 0; + values[valuesById[1] = "FORCE_UPGRADE"] = 1; + values[valuesById[2] = "DEVELOPMENT"] = 2; + values[valuesById[3] = "PRODUCTION"] = 3; + return values; + })(); + + return WebFeatures; + })(); + + proto.NotificationMessageInfo = (function() { + + /** + * Properties of a NotificationMessageInfo. + * @memberof proto + * @interface INotificationMessageInfo + * @property {proto.IMessageKey|null} [key] NotificationMessageInfo key + * @property {proto.IMessage|null} [message] NotificationMessageInfo message + * @property {number|Long|null} [messageTimestamp] NotificationMessageInfo messageTimestamp + * @property {string|null} [participant] NotificationMessageInfo participant + */ + + /** + * Constructs a new NotificationMessageInfo. + * @memberof proto + * @classdesc Represents a NotificationMessageInfo. + * @implements INotificationMessageInfo + * @constructor + * @param {proto.INotificationMessageInfo=} [properties] Properties to set + */ + function NotificationMessageInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * NotificationMessageInfo key. + * @member {proto.IMessageKey|null|undefined} key + * @memberof proto.NotificationMessageInfo + * @instance + */ + NotificationMessageInfo.prototype.key = null; + + /** + * NotificationMessageInfo message. + * @member {proto.IMessage|null|undefined} message + * @memberof proto.NotificationMessageInfo + * @instance + */ + NotificationMessageInfo.prototype.message = null; + + /** + * NotificationMessageInfo messageTimestamp. + * @member {number|Long} messageTimestamp + * @memberof proto.NotificationMessageInfo + * @instance + */ + NotificationMessageInfo.prototype.messageTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * NotificationMessageInfo participant. + * @member {string} participant + * @memberof proto.NotificationMessageInfo + * @instance + */ + NotificationMessageInfo.prototype.participant = ""; + + /** + * Creates a new NotificationMessageInfo instance using the specified properties. + * @function create + * @memberof proto.NotificationMessageInfo + * @static + * @param {proto.INotificationMessageInfo=} [properties] Properties to set + * @returns {proto.NotificationMessageInfo} NotificationMessageInfo instance + */ + NotificationMessageInfo.create = function create(properties) { + return new NotificationMessageInfo(properties); + }; + + /** + * Encodes the specified NotificationMessageInfo message. Does not implicitly {@link proto.NotificationMessageInfo.verify|verify} messages. + * @function encode + * @memberof proto.NotificationMessageInfo + * @static + * @param {proto.INotificationMessageInfo} message NotificationMessageInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + NotificationMessageInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.key != null && Object.hasOwnProperty.call(message, "key")) + $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.message != null && Object.hasOwnProperty.call(message, "message")) + $root.proto.Message.encode(message.message, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.messageTimestamp != null && Object.hasOwnProperty.call(message, "messageTimestamp")) + writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.messageTimestamp); + if (message.participant != null && Object.hasOwnProperty.call(message, "participant")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.participant); + return writer; + }; + + /** + * Encodes the specified NotificationMessageInfo message, length delimited. Does not implicitly {@link proto.NotificationMessageInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.NotificationMessageInfo + * @static + * @param {proto.INotificationMessageInfo} message NotificationMessageInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + NotificationMessageInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a NotificationMessageInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.NotificationMessageInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.NotificationMessageInfo} NotificationMessageInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + NotificationMessageInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NotificationMessageInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.key = $root.proto.MessageKey.decode(reader, reader.uint32()); + break; + case 2: + message.message = $root.proto.Message.decode(reader, reader.uint32()); + break; + case 3: + message.messageTimestamp = reader.uint64(); + break; + case 4: + message.participant = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a NotificationMessageInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.NotificationMessageInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.NotificationMessageInfo} NotificationMessageInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + NotificationMessageInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a NotificationMessageInfo message. + * @function verify + * @memberof proto.NotificationMessageInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + NotificationMessageInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.key != null && message.hasOwnProperty("key")) { + var error = $root.proto.MessageKey.verify(message.key); + if (error) + return "key." + error; + } + if (message.message != null && message.hasOwnProperty("message")) { + var error = $root.proto.Message.verify(message.message); + if (error) + return "message." + error; + } + if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) + if (!$util.isInteger(message.messageTimestamp) && !(message.messageTimestamp && $util.isInteger(message.messageTimestamp.low) && $util.isInteger(message.messageTimestamp.high))) + return "messageTimestamp: integer|Long expected"; + if (message.participant != null && message.hasOwnProperty("participant")) + if (!$util.isString(message.participant)) + return "participant: string expected"; + return null; + }; + + /** + * Creates a NotificationMessageInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.NotificationMessageInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.NotificationMessageInfo} NotificationMessageInfo + */ + NotificationMessageInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.NotificationMessageInfo) + return object; + var message = new $root.proto.NotificationMessageInfo(); + if (object.key != null) { + if (typeof object.key !== "object") + throw TypeError(".proto.NotificationMessageInfo.key: object expected"); + message.key = $root.proto.MessageKey.fromObject(object.key); + } + if (object.message != null) { + if (typeof object.message !== "object") + throw TypeError(".proto.NotificationMessageInfo.message: object expected"); + message.message = $root.proto.Message.fromObject(object.message); + } + if (object.messageTimestamp != null) + if ($util.Long) + (message.messageTimestamp = $util.Long.fromValue(object.messageTimestamp)).unsigned = true; + else if (typeof object.messageTimestamp === "string") + message.messageTimestamp = parseInt(object.messageTimestamp, 10); + else if (typeof object.messageTimestamp === "number") + message.messageTimestamp = object.messageTimestamp; + else if (typeof object.messageTimestamp === "object") + message.messageTimestamp = new $util.LongBits(object.messageTimestamp.low >>> 0, object.messageTimestamp.high >>> 0).toNumber(true); + if (object.participant != null) + message.participant = String(object.participant); + return message; + }; + + /** + * Creates a plain object from a NotificationMessageInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.NotificationMessageInfo + * @static + * @param {proto.NotificationMessageInfo} message NotificationMessageInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + NotificationMessageInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.key = null; + object.message = null; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.messageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.messageTimestamp = options.longs === String ? "0" : 0; + object.participant = ""; + } + if (message.key != null && message.hasOwnProperty("key")) + object.key = $root.proto.MessageKey.toObject(message.key, options); + if (message.message != null && message.hasOwnProperty("message")) + object.message = $root.proto.Message.toObject(message.message, options); + if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) + if (typeof message.messageTimestamp === "number") + object.messageTimestamp = options.longs === String ? String(message.messageTimestamp) : message.messageTimestamp; + else + object.messageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.messageTimestamp) : options.longs === Number ? new $util.LongBits(message.messageTimestamp.low >>> 0, message.messageTimestamp.high >>> 0).toNumber(true) : message.messageTimestamp; + if (message.participant != null && message.hasOwnProperty("participant")) + object.participant = message.participant; + return object; + }; + + /** + * Converts this NotificationMessageInfo to JSON. + * @function toJSON + * @memberof proto.NotificationMessageInfo + * @instance + * @returns {Object.} JSON object + */ + NotificationMessageInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return NotificationMessageInfo; + })(); + + proto.WebNotificationsInfo = (function() { + + /** + * Properties of a WebNotificationsInfo. + * @memberof proto + * @interface IWebNotificationsInfo + * @property {number|Long|null} [timestamp] WebNotificationsInfo timestamp + * @property {number|null} [unreadChats] WebNotificationsInfo unreadChats + * @property {number|null} [notifyMessageCount] WebNotificationsInfo notifyMessageCount + * @property {Array.|null} [notifyMessages] WebNotificationsInfo notifyMessages + */ + + /** + * Constructs a new WebNotificationsInfo. + * @memberof proto + * @classdesc Represents a WebNotificationsInfo. + * @implements IWebNotificationsInfo + * @constructor + * @param {proto.IWebNotificationsInfo=} [properties] Properties to set + */ + function WebNotificationsInfo(properties) { + this.notifyMessages = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * WebNotificationsInfo timestamp. + * @member {number|Long} timestamp + * @memberof proto.WebNotificationsInfo + * @instance + */ + WebNotificationsInfo.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * WebNotificationsInfo unreadChats. + * @member {number} unreadChats + * @memberof proto.WebNotificationsInfo + * @instance + */ + WebNotificationsInfo.prototype.unreadChats = 0; + + /** + * WebNotificationsInfo notifyMessageCount. + * @member {number} notifyMessageCount + * @memberof proto.WebNotificationsInfo + * @instance + */ + WebNotificationsInfo.prototype.notifyMessageCount = 0; + + /** + * WebNotificationsInfo notifyMessages. + * @member {Array.} notifyMessages + * @memberof proto.WebNotificationsInfo + * @instance + */ + WebNotificationsInfo.prototype.notifyMessages = $util.emptyArray; + + /** + * Creates a new WebNotificationsInfo instance using the specified properties. + * @function create + * @memberof proto.WebNotificationsInfo + * @static + * @param {proto.IWebNotificationsInfo=} [properties] Properties to set + * @returns {proto.WebNotificationsInfo} WebNotificationsInfo instance + */ + WebNotificationsInfo.create = function create(properties) { + return new WebNotificationsInfo(properties); + }; + + /** + * Encodes the specified WebNotificationsInfo message. Does not implicitly {@link proto.WebNotificationsInfo.verify|verify} messages. + * @function encode + * @memberof proto.WebNotificationsInfo + * @static + * @param {proto.IWebNotificationsInfo} message WebNotificationsInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WebNotificationsInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.timestamp); + if (message.unreadChats != null && Object.hasOwnProperty.call(message, "unreadChats")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.unreadChats); + if (message.notifyMessageCount != null && Object.hasOwnProperty.call(message, "notifyMessageCount")) + writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.notifyMessageCount); + if (message.notifyMessages != null && message.notifyMessages.length) + for (var i = 0; i < message.notifyMessages.length; ++i) + $root.proto.WebMessageInfo.encode(message.notifyMessages[i], writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified WebNotificationsInfo message, length delimited. Does not implicitly {@link proto.WebNotificationsInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.WebNotificationsInfo + * @static + * @param {proto.IWebNotificationsInfo} message WebNotificationsInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WebNotificationsInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a WebNotificationsInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.WebNotificationsInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.WebNotificationsInfo} WebNotificationsInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebNotificationsInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebNotificationsInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + message.timestamp = reader.uint64(); + break; + case 3: + message.unreadChats = reader.uint32(); + break; + case 4: + message.notifyMessageCount = reader.uint32(); + break; + case 5: + if (!(message.notifyMessages && message.notifyMessages.length)) + message.notifyMessages = []; + message.notifyMessages.push($root.proto.WebMessageInfo.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a WebNotificationsInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.WebNotificationsInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.WebNotificationsInfo} WebNotificationsInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebNotificationsInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a WebNotificationsInfo message. + * @function verify + * @memberof proto.WebNotificationsInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + WebNotificationsInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) + return "timestamp: integer|Long expected"; + if (message.unreadChats != null && message.hasOwnProperty("unreadChats")) + if (!$util.isInteger(message.unreadChats)) + return "unreadChats: integer expected"; + if (message.notifyMessageCount != null && message.hasOwnProperty("notifyMessageCount")) + if (!$util.isInteger(message.notifyMessageCount)) + return "notifyMessageCount: integer expected"; + if (message.notifyMessages != null && message.hasOwnProperty("notifyMessages")) { + if (!Array.isArray(message.notifyMessages)) + return "notifyMessages: array expected"; + for (var i = 0; i < message.notifyMessages.length; ++i) { + var error = $root.proto.WebMessageInfo.verify(message.notifyMessages[i]); + if (error) + return "notifyMessages." + error; + } + } + return null; + }; + + /** + * Creates a WebNotificationsInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.WebNotificationsInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.WebNotificationsInfo} WebNotificationsInfo + */ + WebNotificationsInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.WebNotificationsInfo) + return object; + var message = new $root.proto.WebNotificationsInfo(); + if (object.timestamp != null) + if ($util.Long) + (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = true; + else if (typeof object.timestamp === "string") + message.timestamp = parseInt(object.timestamp, 10); + else if (typeof object.timestamp === "number") + message.timestamp = object.timestamp; + else if (typeof object.timestamp === "object") + message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(true); + if (object.unreadChats != null) + message.unreadChats = object.unreadChats >>> 0; + if (object.notifyMessageCount != null) + message.notifyMessageCount = object.notifyMessageCount >>> 0; + if (object.notifyMessages) { + if (!Array.isArray(object.notifyMessages)) + throw TypeError(".proto.WebNotificationsInfo.notifyMessages: array expected"); + message.notifyMessages = []; + for (var i = 0; i < object.notifyMessages.length; ++i) { + if (typeof object.notifyMessages[i] !== "object") + throw TypeError(".proto.WebNotificationsInfo.notifyMessages: object expected"); + message.notifyMessages[i] = $root.proto.WebMessageInfo.fromObject(object.notifyMessages[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a WebNotificationsInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.WebNotificationsInfo + * @static + * @param {proto.WebNotificationsInfo} message WebNotificationsInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + WebNotificationsInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.notifyMessages = []; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.timestamp = options.longs === String ? "0" : 0; + object.unreadChats = 0; + object.notifyMessageCount = 0; + } + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (typeof message.timestamp === "number") + object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; + else + object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber(true) : message.timestamp; + if (message.unreadChats != null && message.hasOwnProperty("unreadChats")) + object.unreadChats = message.unreadChats; + if (message.notifyMessageCount != null && message.hasOwnProperty("notifyMessageCount")) + object.notifyMessageCount = message.notifyMessageCount; + if (message.notifyMessages && message.notifyMessages.length) { + object.notifyMessages = []; + for (var j = 0; j < message.notifyMessages.length; ++j) + object.notifyMessages[j] = $root.proto.WebMessageInfo.toObject(message.notifyMessages[j], options); + } + return object; + }; + + /** + * Converts this WebNotificationsInfo to JSON. + * @function toJSON + * @memberof proto.WebNotificationsInfo + * @instance + * @returns {Object.} JSON object + */ + WebNotificationsInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return WebNotificationsInfo; + })(); + + proto.PaymentInfo = (function() { + + /** + * Properties of a PaymentInfo. + * @memberof proto + * @interface IPaymentInfo + * @property {proto.PaymentInfo.PaymentInfoCurrency|null} [currencyDeprecated] PaymentInfo currencyDeprecated + * @property {number|Long|null} [amount1000] PaymentInfo amount1000 + * @property {string|null} [receiverJid] PaymentInfo receiverJid + * @property {proto.PaymentInfo.PaymentInfoStatus|null} [status] PaymentInfo status + * @property {number|Long|null} [transactionTimestamp] PaymentInfo transactionTimestamp + * @property {proto.IMessageKey|null} [requestMessageKey] PaymentInfo requestMessageKey + * @property {number|Long|null} [expiryTimestamp] PaymentInfo expiryTimestamp + * @property {boolean|null} [futureproofed] PaymentInfo futureproofed + * @property {string|null} [currency] PaymentInfo currency + * @property {proto.PaymentInfo.PaymentInfoTxnStatus|null} [txnStatus] PaymentInfo txnStatus + * @property {boolean|null} [useNoviFiatFormat] PaymentInfo useNoviFiatFormat + * @property {proto.IMoney|null} [primaryAmount] PaymentInfo primaryAmount + * @property {proto.IMoney|null} [exchangeAmount] PaymentInfo exchangeAmount + */ + + /** + * Constructs a new PaymentInfo. + * @memberof proto + * @classdesc Represents a PaymentInfo. + * @implements IPaymentInfo + * @constructor + * @param {proto.IPaymentInfo=} [properties] Properties to set + */ + function PaymentInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * PaymentInfo currencyDeprecated. + * @member {proto.PaymentInfo.PaymentInfoCurrency} currencyDeprecated + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.currencyDeprecated = 0; + + /** + * PaymentInfo amount1000. + * @member {number|Long} amount1000 + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.amount1000 = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * PaymentInfo receiverJid. + * @member {string} receiverJid + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.receiverJid = ""; + + /** + * PaymentInfo status. + * @member {proto.PaymentInfo.PaymentInfoStatus} status + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.status = 0; + + /** + * PaymentInfo transactionTimestamp. + * @member {number|Long} transactionTimestamp + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.transactionTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * PaymentInfo requestMessageKey. + * @member {proto.IMessageKey|null|undefined} requestMessageKey + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.requestMessageKey = null; + + /** + * PaymentInfo expiryTimestamp. + * @member {number|Long} expiryTimestamp + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.expiryTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * PaymentInfo futureproofed. + * @member {boolean} futureproofed + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.futureproofed = false; + + /** + * PaymentInfo currency. + * @member {string} currency + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.currency = ""; + + /** + * PaymentInfo txnStatus. + * @member {proto.PaymentInfo.PaymentInfoTxnStatus} txnStatus + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.txnStatus = 0; + + /** + * PaymentInfo useNoviFiatFormat. + * @member {boolean} useNoviFiatFormat + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.useNoviFiatFormat = false; + + /** + * PaymentInfo primaryAmount. + * @member {proto.IMoney|null|undefined} primaryAmount + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.primaryAmount = null; + + /** + * PaymentInfo exchangeAmount. + * @member {proto.IMoney|null|undefined} exchangeAmount + * @memberof proto.PaymentInfo + * @instance + */ + PaymentInfo.prototype.exchangeAmount = null; + + /** + * Creates a new PaymentInfo instance using the specified properties. + * @function create + * @memberof proto.PaymentInfo + * @static + * @param {proto.IPaymentInfo=} [properties] Properties to set + * @returns {proto.PaymentInfo} PaymentInfo instance + */ + PaymentInfo.create = function create(properties) { + return new PaymentInfo(properties); + }; + + /** + * Encodes the specified PaymentInfo message. Does not implicitly {@link proto.PaymentInfo.verify|verify} messages. + * @function encode + * @memberof proto.PaymentInfo + * @static + * @param {proto.IPaymentInfo} message PaymentInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PaymentInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.currencyDeprecated != null && Object.hasOwnProperty.call(message, "currencyDeprecated")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.currencyDeprecated); + if (message.amount1000 != null && Object.hasOwnProperty.call(message, "amount1000")) + writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.amount1000); + if (message.receiverJid != null && Object.hasOwnProperty.call(message, "receiverJid")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.receiverJid); + if (message.status != null && Object.hasOwnProperty.call(message, "status")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.status); + if (message.transactionTimestamp != null && Object.hasOwnProperty.call(message, "transactionTimestamp")) + writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.transactionTimestamp); + if (message.requestMessageKey != null && Object.hasOwnProperty.call(message, "requestMessageKey")) + $root.proto.MessageKey.encode(message.requestMessageKey, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.expiryTimestamp != null && Object.hasOwnProperty.call(message, "expiryTimestamp")) + writer.uint32(/* id 7, wireType 0 =*/56).uint64(message.expiryTimestamp); + if (message.futureproofed != null && Object.hasOwnProperty.call(message, "futureproofed")) + writer.uint32(/* id 8, wireType 0 =*/64).bool(message.futureproofed); + if (message.currency != null && Object.hasOwnProperty.call(message, "currency")) + writer.uint32(/* id 9, wireType 2 =*/74).string(message.currency); + if (message.txnStatus != null && Object.hasOwnProperty.call(message, "txnStatus")) + writer.uint32(/* id 10, wireType 0 =*/80).int32(message.txnStatus); + if (message.useNoviFiatFormat != null && Object.hasOwnProperty.call(message, "useNoviFiatFormat")) + writer.uint32(/* id 11, wireType 0 =*/88).bool(message.useNoviFiatFormat); + if (message.primaryAmount != null && Object.hasOwnProperty.call(message, "primaryAmount")) + $root.proto.Money.encode(message.primaryAmount, writer.uint32(/* id 12, wireType 2 =*/98).fork()).ldelim(); + if (message.exchangeAmount != null && Object.hasOwnProperty.call(message, "exchangeAmount")) + $root.proto.Money.encode(message.exchangeAmount, writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified PaymentInfo message, length delimited. Does not implicitly {@link proto.PaymentInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.PaymentInfo + * @static + * @param {proto.IPaymentInfo} message PaymentInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PaymentInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a PaymentInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.PaymentInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.PaymentInfo} PaymentInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PaymentInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.currencyDeprecated = reader.int32(); + break; + case 2: + message.amount1000 = reader.uint64(); + break; + case 3: + message.receiverJid = reader.string(); + break; + case 4: + message.status = reader.int32(); + break; + case 5: + message.transactionTimestamp = reader.uint64(); + break; + case 6: + message.requestMessageKey = $root.proto.MessageKey.decode(reader, reader.uint32()); + break; + case 7: + message.expiryTimestamp = reader.uint64(); + break; + case 8: + message.futureproofed = reader.bool(); + break; + case 9: + message.currency = reader.string(); + break; + case 10: + message.txnStatus = reader.int32(); + break; + case 11: + message.useNoviFiatFormat = reader.bool(); + break; + case 12: + message.primaryAmount = $root.proto.Money.decode(reader, reader.uint32()); + break; + case 13: + message.exchangeAmount = $root.proto.Money.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a PaymentInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.PaymentInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.PaymentInfo} PaymentInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PaymentInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a PaymentInfo message. + * @function verify + * @memberof proto.PaymentInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + PaymentInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.currencyDeprecated != null && message.hasOwnProperty("currencyDeprecated")) + switch (message.currencyDeprecated) { + default: + return "currencyDeprecated: enum value expected"; + case 0: + case 1: + break; + } + if (message.amount1000 != null && message.hasOwnProperty("amount1000")) + if (!$util.isInteger(message.amount1000) && !(message.amount1000 && $util.isInteger(message.amount1000.low) && $util.isInteger(message.amount1000.high))) + return "amount1000: integer|Long expected"; + if (message.receiverJid != null && message.hasOwnProperty("receiverJid")) + if (!$util.isString(message.receiverJid)) + return "receiverJid: string expected"; + if (message.status != null && message.hasOwnProperty("status")) + switch (message.status) { + default: + return "status: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + break; + } + if (message.transactionTimestamp != null && message.hasOwnProperty("transactionTimestamp")) + if (!$util.isInteger(message.transactionTimestamp) && !(message.transactionTimestamp && $util.isInteger(message.transactionTimestamp.low) && $util.isInteger(message.transactionTimestamp.high))) + return "transactionTimestamp: integer|Long expected"; + if (message.requestMessageKey != null && message.hasOwnProperty("requestMessageKey")) { + var error = $root.proto.MessageKey.verify(message.requestMessageKey); + if (error) + return "requestMessageKey." + error; + } + if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp")) + if (!$util.isInteger(message.expiryTimestamp) && !(message.expiryTimestamp && $util.isInteger(message.expiryTimestamp.low) && $util.isInteger(message.expiryTimestamp.high))) + return "expiryTimestamp: integer|Long expected"; + if (message.futureproofed != null && message.hasOwnProperty("futureproofed")) + if (typeof message.futureproofed !== "boolean") + return "futureproofed: boolean expected"; + if (message.currency != null && message.hasOwnProperty("currency")) + if (!$util.isString(message.currency)) + return "currency: string expected"; + if (message.txnStatus != null && message.hasOwnProperty("txnStatus")) + switch (message.txnStatus) { + default: + return "txnStatus: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + case 28: + break; + } + if (message.useNoviFiatFormat != null && message.hasOwnProperty("useNoviFiatFormat")) + if (typeof message.useNoviFiatFormat !== "boolean") + return "useNoviFiatFormat: boolean expected"; + if (message.primaryAmount != null && message.hasOwnProperty("primaryAmount")) { + var error = $root.proto.Money.verify(message.primaryAmount); + if (error) + return "primaryAmount." + error; + } + if (message.exchangeAmount != null && message.hasOwnProperty("exchangeAmount")) { + var error = $root.proto.Money.verify(message.exchangeAmount); + if (error) + return "exchangeAmount." + error; + } + return null; + }; + + /** + * Creates a PaymentInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.PaymentInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.PaymentInfo} PaymentInfo + */ + PaymentInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.PaymentInfo) + return object; + var message = new $root.proto.PaymentInfo(); + switch (object.currencyDeprecated) { + case "UNKNOWN_CURRENCY": + case 0: + message.currencyDeprecated = 0; + break; + case "INR": + case 1: + message.currencyDeprecated = 1; + break; + } + if (object.amount1000 != null) + if ($util.Long) + (message.amount1000 = $util.Long.fromValue(object.amount1000)).unsigned = true; + else if (typeof object.amount1000 === "string") + message.amount1000 = parseInt(object.amount1000, 10); + else if (typeof object.amount1000 === "number") + message.amount1000 = object.amount1000; + else if (typeof object.amount1000 === "object") + message.amount1000 = new $util.LongBits(object.amount1000.low >>> 0, object.amount1000.high >>> 0).toNumber(true); + if (object.receiverJid != null) + message.receiverJid = String(object.receiverJid); + switch (object.status) { + case "UNKNOWN_STATUS": + case 0: + message.status = 0; + break; + case "PROCESSING": + case 1: + message.status = 1; + break; + case "SENT": + case 2: + message.status = 2; + break; + case "NEED_TO_ACCEPT": + case 3: + message.status = 3; + break; + case "COMPLETE": + case 4: + message.status = 4; + break; + case "COULD_NOT_COMPLETE": + case 5: + message.status = 5; + break; + case "REFUNDED": + case 6: + message.status = 6; + break; + case "EXPIRED": + case 7: + message.status = 7; + break; + case "REJECTED": + case 8: + message.status = 8; + break; + case "CANCELLED": + case 9: + message.status = 9; + break; + case "WAITING_FOR_PAYER": + case 10: + message.status = 10; + break; + case "WAITING": + case 11: + message.status = 11; + break; + } + if (object.transactionTimestamp != null) + if ($util.Long) + (message.transactionTimestamp = $util.Long.fromValue(object.transactionTimestamp)).unsigned = true; + else if (typeof object.transactionTimestamp === "string") + message.transactionTimestamp = parseInt(object.transactionTimestamp, 10); + else if (typeof object.transactionTimestamp === "number") + message.transactionTimestamp = object.transactionTimestamp; + else if (typeof object.transactionTimestamp === "object") + message.transactionTimestamp = new $util.LongBits(object.transactionTimestamp.low >>> 0, object.transactionTimestamp.high >>> 0).toNumber(true); + if (object.requestMessageKey != null) { + if (typeof object.requestMessageKey !== "object") + throw TypeError(".proto.PaymentInfo.requestMessageKey: object expected"); + message.requestMessageKey = $root.proto.MessageKey.fromObject(object.requestMessageKey); + } + if (object.expiryTimestamp != null) + if ($util.Long) + (message.expiryTimestamp = $util.Long.fromValue(object.expiryTimestamp)).unsigned = true; + else if (typeof object.expiryTimestamp === "string") + message.expiryTimestamp = parseInt(object.expiryTimestamp, 10); + else if (typeof object.expiryTimestamp === "number") + message.expiryTimestamp = object.expiryTimestamp; + else if (typeof object.expiryTimestamp === "object") + message.expiryTimestamp = new $util.LongBits(object.expiryTimestamp.low >>> 0, object.expiryTimestamp.high >>> 0).toNumber(true); + if (object.futureproofed != null) + message.futureproofed = Boolean(object.futureproofed); + if (object.currency != null) + message.currency = String(object.currency); + switch (object.txnStatus) { + case "UNKNOWN": + case 0: + message.txnStatus = 0; + break; + case "PENDING_SETUP": + case 1: + message.txnStatus = 1; + break; + case "PENDING_RECEIVER_SETUP": + case 2: + message.txnStatus = 2; + break; + case "INIT": + case 3: + message.txnStatus = 3; + break; + case "SUCCESS": + case 4: + message.txnStatus = 4; + break; + case "COMPLETED": + case 5: + message.txnStatus = 5; + break; + case "FAILED": + case 6: + message.txnStatus = 6; + break; + case "FAILED_RISK": + case 7: + message.txnStatus = 7; + break; + case "FAILED_PROCESSING": + case 8: + message.txnStatus = 8; + break; + case "FAILED_RECEIVER_PROCESSING": + case 9: + message.txnStatus = 9; + break; + case "FAILED_DA": + case 10: + message.txnStatus = 10; + break; + case "FAILED_DA_FINAL": + case 11: + message.txnStatus = 11; + break; + case "REFUNDED_TXN": + case 12: + message.txnStatus = 12; + break; + case "REFUND_FAILED": + case 13: + message.txnStatus = 13; + break; + case "REFUND_FAILED_PROCESSING": + case 14: + message.txnStatus = 14; + break; + case "REFUND_FAILED_DA": + case 15: + message.txnStatus = 15; + break; + case "EXPIRED_TXN": + case 16: + message.txnStatus = 16; + break; + case "AUTH_CANCELED": + case 17: + message.txnStatus = 17; + break; + case "AUTH_CANCEL_FAILED_PROCESSING": + case 18: + message.txnStatus = 18; + break; + case "AUTH_CANCEL_FAILED": + case 19: + message.txnStatus = 19; + break; + case "COLLECT_INIT": + case 20: + message.txnStatus = 20; + break; + case "COLLECT_SUCCESS": + case 21: + message.txnStatus = 21; + break; + case "COLLECT_FAILED": + case 22: + message.txnStatus = 22; + break; + case "COLLECT_FAILED_RISK": + case 23: + message.txnStatus = 23; + break; + case "COLLECT_REJECTED": + case 24: + message.txnStatus = 24; + break; + case "COLLECT_EXPIRED": + case 25: + message.txnStatus = 25; + break; + case "COLLECT_CANCELED": + case 26: + message.txnStatus = 26; + break; + case "COLLECT_CANCELLING": + case 27: + message.txnStatus = 27; + break; + case "IN_REVIEW": + case 28: + message.txnStatus = 28; + break; + } + if (object.useNoviFiatFormat != null) + message.useNoviFiatFormat = Boolean(object.useNoviFiatFormat); + if (object.primaryAmount != null) { + if (typeof object.primaryAmount !== "object") + throw TypeError(".proto.PaymentInfo.primaryAmount: object expected"); + message.primaryAmount = $root.proto.Money.fromObject(object.primaryAmount); + } + if (object.exchangeAmount != null) { + if (typeof object.exchangeAmount !== "object") + throw TypeError(".proto.PaymentInfo.exchangeAmount: object expected"); + message.exchangeAmount = $root.proto.Money.fromObject(object.exchangeAmount); + } + return message; + }; + + /** + * Creates a plain object from a PaymentInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.PaymentInfo + * @static + * @param {proto.PaymentInfo} message PaymentInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + PaymentInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.currencyDeprecated = options.enums === String ? "UNKNOWN_CURRENCY" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.amount1000 = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.amount1000 = options.longs === String ? "0" : 0; + object.receiverJid = ""; + object.status = options.enums === String ? "UNKNOWN_STATUS" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.transactionTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.transactionTimestamp = options.longs === String ? "0" : 0; + object.requestMessageKey = null; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.expiryTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.expiryTimestamp = options.longs === String ? "0" : 0; + object.futureproofed = false; + object.currency = ""; + object.txnStatus = options.enums === String ? "UNKNOWN" : 0; + object.useNoviFiatFormat = false; + object.primaryAmount = null; + object.exchangeAmount = null; + } + if (message.currencyDeprecated != null && message.hasOwnProperty("currencyDeprecated")) + object.currencyDeprecated = options.enums === String ? $root.proto.PaymentInfo.PaymentInfoCurrency[message.currencyDeprecated] : message.currencyDeprecated; + if (message.amount1000 != null && message.hasOwnProperty("amount1000")) + if (typeof message.amount1000 === "number") + object.amount1000 = options.longs === String ? String(message.amount1000) : message.amount1000; + else + object.amount1000 = options.longs === String ? $util.Long.prototype.toString.call(message.amount1000) : options.longs === Number ? new $util.LongBits(message.amount1000.low >>> 0, message.amount1000.high >>> 0).toNumber(true) : message.amount1000; + if (message.receiverJid != null && message.hasOwnProperty("receiverJid")) + object.receiverJid = message.receiverJid; + if (message.status != null && message.hasOwnProperty("status")) + object.status = options.enums === String ? $root.proto.PaymentInfo.PaymentInfoStatus[message.status] : message.status; + if (message.transactionTimestamp != null && message.hasOwnProperty("transactionTimestamp")) + if (typeof message.transactionTimestamp === "number") + object.transactionTimestamp = options.longs === String ? String(message.transactionTimestamp) : message.transactionTimestamp; + else + object.transactionTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.transactionTimestamp) : options.longs === Number ? new $util.LongBits(message.transactionTimestamp.low >>> 0, message.transactionTimestamp.high >>> 0).toNumber(true) : message.transactionTimestamp; + if (message.requestMessageKey != null && message.hasOwnProperty("requestMessageKey")) + object.requestMessageKey = $root.proto.MessageKey.toObject(message.requestMessageKey, options); + if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp")) + if (typeof message.expiryTimestamp === "number") + object.expiryTimestamp = options.longs === String ? String(message.expiryTimestamp) : message.expiryTimestamp; + else + object.expiryTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.expiryTimestamp) : options.longs === Number ? new $util.LongBits(message.expiryTimestamp.low >>> 0, message.expiryTimestamp.high >>> 0).toNumber(true) : message.expiryTimestamp; + if (message.futureproofed != null && message.hasOwnProperty("futureproofed")) + object.futureproofed = message.futureproofed; + if (message.currency != null && message.hasOwnProperty("currency")) + object.currency = message.currency; + if (message.txnStatus != null && message.hasOwnProperty("txnStatus")) + object.txnStatus = options.enums === String ? $root.proto.PaymentInfo.PaymentInfoTxnStatus[message.txnStatus] : message.txnStatus; + if (message.useNoviFiatFormat != null && message.hasOwnProperty("useNoviFiatFormat")) + object.useNoviFiatFormat = message.useNoviFiatFormat; + if (message.primaryAmount != null && message.hasOwnProperty("primaryAmount")) + object.primaryAmount = $root.proto.Money.toObject(message.primaryAmount, options); + if (message.exchangeAmount != null && message.hasOwnProperty("exchangeAmount")) + object.exchangeAmount = $root.proto.Money.toObject(message.exchangeAmount, options); + return object; + }; + + /** + * Converts this PaymentInfo to JSON. + * @function toJSON + * @memberof proto.PaymentInfo + * @instance + * @returns {Object.} JSON object + */ + PaymentInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * PaymentInfoCurrency enum. + * @name proto.PaymentInfo.PaymentInfoCurrency + * @enum {number} + * @property {number} UNKNOWN_CURRENCY=0 UNKNOWN_CURRENCY value + * @property {number} INR=1 INR value + */ + PaymentInfo.PaymentInfoCurrency = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN_CURRENCY"] = 0; + values[valuesById[1] = "INR"] = 1; + return values; + })(); + + /** + * PaymentInfoStatus enum. + * @name proto.PaymentInfo.PaymentInfoStatus + * @enum {number} + * @property {number} UNKNOWN_STATUS=0 UNKNOWN_STATUS value + * @property {number} PROCESSING=1 PROCESSING value + * @property {number} SENT=2 SENT value + * @property {number} NEED_TO_ACCEPT=3 NEED_TO_ACCEPT value + * @property {number} COMPLETE=4 COMPLETE value + * @property {number} COULD_NOT_COMPLETE=5 COULD_NOT_COMPLETE value + * @property {number} REFUNDED=6 REFUNDED value + * @property {number} EXPIRED=7 EXPIRED value + * @property {number} REJECTED=8 REJECTED value + * @property {number} CANCELLED=9 CANCELLED value + * @property {number} WAITING_FOR_PAYER=10 WAITING_FOR_PAYER value + * @property {number} WAITING=11 WAITING value + */ + PaymentInfo.PaymentInfoStatus = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN_STATUS"] = 0; + values[valuesById[1] = "PROCESSING"] = 1; + values[valuesById[2] = "SENT"] = 2; + values[valuesById[3] = "NEED_TO_ACCEPT"] = 3; + values[valuesById[4] = "COMPLETE"] = 4; + values[valuesById[5] = "COULD_NOT_COMPLETE"] = 5; + values[valuesById[6] = "REFUNDED"] = 6; + values[valuesById[7] = "EXPIRED"] = 7; + values[valuesById[8] = "REJECTED"] = 8; + values[valuesById[9] = "CANCELLED"] = 9; + values[valuesById[10] = "WAITING_FOR_PAYER"] = 10; + values[valuesById[11] = "WAITING"] = 11; + return values; + })(); + + /** + * PaymentInfoTxnStatus enum. + * @name proto.PaymentInfo.PaymentInfoTxnStatus + * @enum {number} + * @property {number} UNKNOWN=0 UNKNOWN value + * @property {number} PENDING_SETUP=1 PENDING_SETUP value + * @property {number} PENDING_RECEIVER_SETUP=2 PENDING_RECEIVER_SETUP value + * @property {number} INIT=3 INIT value + * @property {number} SUCCESS=4 SUCCESS value + * @property {number} COMPLETED=5 COMPLETED value + * @property {number} FAILED=6 FAILED value + * @property {number} FAILED_RISK=7 FAILED_RISK value + * @property {number} FAILED_PROCESSING=8 FAILED_PROCESSING value + * @property {number} FAILED_RECEIVER_PROCESSING=9 FAILED_RECEIVER_PROCESSING value + * @property {number} FAILED_DA=10 FAILED_DA value + * @property {number} FAILED_DA_FINAL=11 FAILED_DA_FINAL value + * @property {number} REFUNDED_TXN=12 REFUNDED_TXN value + * @property {number} REFUND_FAILED=13 REFUND_FAILED value + * @property {number} REFUND_FAILED_PROCESSING=14 REFUND_FAILED_PROCESSING value + * @property {number} REFUND_FAILED_DA=15 REFUND_FAILED_DA value + * @property {number} EXPIRED_TXN=16 EXPIRED_TXN value + * @property {number} AUTH_CANCELED=17 AUTH_CANCELED value + * @property {number} AUTH_CANCEL_FAILED_PROCESSING=18 AUTH_CANCEL_FAILED_PROCESSING value + * @property {number} AUTH_CANCEL_FAILED=19 AUTH_CANCEL_FAILED value + * @property {number} COLLECT_INIT=20 COLLECT_INIT value + * @property {number} COLLECT_SUCCESS=21 COLLECT_SUCCESS value + * @property {number} COLLECT_FAILED=22 COLLECT_FAILED value + * @property {number} COLLECT_FAILED_RISK=23 COLLECT_FAILED_RISK value + * @property {number} COLLECT_REJECTED=24 COLLECT_REJECTED value + * @property {number} COLLECT_EXPIRED=25 COLLECT_EXPIRED value + * @property {number} COLLECT_CANCELED=26 COLLECT_CANCELED value + * @property {number} COLLECT_CANCELLING=27 COLLECT_CANCELLING value + * @property {number} IN_REVIEW=28 IN_REVIEW value + */ + PaymentInfo.PaymentInfoTxnStatus = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN"] = 0; + values[valuesById[1] = "PENDING_SETUP"] = 1; + values[valuesById[2] = "PENDING_RECEIVER_SETUP"] = 2; + values[valuesById[3] = "INIT"] = 3; + values[valuesById[4] = "SUCCESS"] = 4; + values[valuesById[5] = "COMPLETED"] = 5; + values[valuesById[6] = "FAILED"] = 6; + values[valuesById[7] = "FAILED_RISK"] = 7; + values[valuesById[8] = "FAILED_PROCESSING"] = 8; + values[valuesById[9] = "FAILED_RECEIVER_PROCESSING"] = 9; + values[valuesById[10] = "FAILED_DA"] = 10; + values[valuesById[11] = "FAILED_DA_FINAL"] = 11; + values[valuesById[12] = "REFUNDED_TXN"] = 12; + values[valuesById[13] = "REFUND_FAILED"] = 13; + values[valuesById[14] = "REFUND_FAILED_PROCESSING"] = 14; + values[valuesById[15] = "REFUND_FAILED_DA"] = 15; + values[valuesById[16] = "EXPIRED_TXN"] = 16; + values[valuesById[17] = "AUTH_CANCELED"] = 17; + values[valuesById[18] = "AUTH_CANCEL_FAILED_PROCESSING"] = 18; + values[valuesById[19] = "AUTH_CANCEL_FAILED"] = 19; + values[valuesById[20] = "COLLECT_INIT"] = 20; + values[valuesById[21] = "COLLECT_SUCCESS"] = 21; + values[valuesById[22] = "COLLECT_FAILED"] = 22; + values[valuesById[23] = "COLLECT_FAILED_RISK"] = 23; + values[valuesById[24] = "COLLECT_REJECTED"] = 24; + values[valuesById[25] = "COLLECT_EXPIRED"] = 25; + values[valuesById[26] = "COLLECT_CANCELED"] = 26; + values[valuesById[27] = "COLLECT_CANCELLING"] = 27; + values[valuesById[28] = "IN_REVIEW"] = 28; + return values; + })(); + + return PaymentInfo; + })(); + + proto.WebMessageInfo = (function() { + + /** + * Properties of a WebMessageInfo. + * @memberof proto + * @interface IWebMessageInfo + * @property {proto.IMessageKey} key WebMessageInfo key + * @property {proto.IMessage|null} [message] WebMessageInfo message + * @property {number|Long|null} [messageTimestamp] WebMessageInfo messageTimestamp + * @property {proto.WebMessageInfo.WebMessageInfoStatus|null} [status] WebMessageInfo status + * @property {string|null} [participant] WebMessageInfo participant + * @property {number|Long|null} [messageC2STimestamp] WebMessageInfo messageC2STimestamp + * @property {boolean|null} [ignore] WebMessageInfo ignore + * @property {boolean|null} [starred] WebMessageInfo starred + * @property {boolean|null} [broadcast] WebMessageInfo broadcast + * @property {string|null} [pushName] WebMessageInfo pushName + * @property {Uint8Array|null} [mediaCiphertextSha256] WebMessageInfo mediaCiphertextSha256 + * @property {boolean|null} [multicast] WebMessageInfo multicast + * @property {boolean|null} [urlText] WebMessageInfo urlText + * @property {boolean|null} [urlNumber] WebMessageInfo urlNumber + * @property {proto.WebMessageInfo.WebMessageInfoStubType|null} [messageStubType] WebMessageInfo messageStubType + * @property {boolean|null} [clearMedia] WebMessageInfo clearMedia + * @property {Array.|null} [messageStubParameters] WebMessageInfo messageStubParameters + * @property {number|null} [duration] WebMessageInfo duration + * @property {Array.|null} [labels] WebMessageInfo labels + * @property {proto.IPaymentInfo|null} [paymentInfo] WebMessageInfo paymentInfo + * @property {proto.ILiveLocationMessage|null} [finalLiveLocation] WebMessageInfo finalLiveLocation + * @property {proto.IPaymentInfo|null} [quotedPaymentInfo] WebMessageInfo quotedPaymentInfo + * @property {number|Long|null} [ephemeralStartTimestamp] WebMessageInfo ephemeralStartTimestamp + * @property {number|null} [ephemeralDuration] WebMessageInfo ephemeralDuration + * @property {boolean|null} [ephemeralOffToOn] WebMessageInfo ephemeralOffToOn + * @property {boolean|null} [ephemeralOutOfSync] WebMessageInfo ephemeralOutOfSync + * @property {proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus|null} [bizPrivacyStatus] WebMessageInfo bizPrivacyStatus + * @property {string|null} [verifiedBizName] WebMessageInfo verifiedBizName + * @property {proto.IMediaData|null} [mediaData] WebMessageInfo mediaData + * @property {proto.IPhotoChange|null} [photoChange] WebMessageInfo photoChange + */ + + /** + * Constructs a new WebMessageInfo. + * @memberof proto + * @classdesc Represents a WebMessageInfo. + * @implements IWebMessageInfo + * @constructor + * @param {proto.IWebMessageInfo=} [properties] Properties to set + */ + function WebMessageInfo(properties) { + this.messageStubParameters = []; + this.labels = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * WebMessageInfo key. + * @member {proto.IMessageKey} key + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.key = null; + + /** + * WebMessageInfo message. + * @member {proto.IMessage|null|undefined} message + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.message = null; + + /** + * WebMessageInfo messageTimestamp. + * @member {number|Long} messageTimestamp + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.messageTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * WebMessageInfo status. + * @member {proto.WebMessageInfo.WebMessageInfoStatus} status + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.status = 0; + + /** + * WebMessageInfo participant. + * @member {string} participant + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.participant = ""; + + /** + * WebMessageInfo messageC2STimestamp. + * @member {number|Long} messageC2STimestamp + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.messageC2STimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * WebMessageInfo ignore. + * @member {boolean} ignore + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.ignore = false; + + /** + * WebMessageInfo starred. + * @member {boolean} starred + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.starred = false; + + /** + * WebMessageInfo broadcast. + * @member {boolean} broadcast + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.broadcast = false; + + /** + * WebMessageInfo pushName. + * @member {string} pushName + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.pushName = ""; + + /** + * WebMessageInfo mediaCiphertextSha256. + * @member {Uint8Array} mediaCiphertextSha256 + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.mediaCiphertextSha256 = $util.newBuffer([]); + + /** + * WebMessageInfo multicast. + * @member {boolean} multicast + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.multicast = false; + + /** + * WebMessageInfo urlText. + * @member {boolean} urlText + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.urlText = false; + + /** + * WebMessageInfo urlNumber. + * @member {boolean} urlNumber + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.urlNumber = false; + + /** + * WebMessageInfo messageStubType. + * @member {proto.WebMessageInfo.WebMessageInfoStubType} messageStubType + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.messageStubType = 0; + + /** + * WebMessageInfo clearMedia. + * @member {boolean} clearMedia + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.clearMedia = false; + + /** + * WebMessageInfo messageStubParameters. + * @member {Array.} messageStubParameters + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.messageStubParameters = $util.emptyArray; + + /** + * WebMessageInfo duration. + * @member {number} duration + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.duration = 0; + + /** + * WebMessageInfo labels. + * @member {Array.} labels + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.labels = $util.emptyArray; + + /** + * WebMessageInfo paymentInfo. + * @member {proto.IPaymentInfo|null|undefined} paymentInfo + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.paymentInfo = null; + + /** + * WebMessageInfo finalLiveLocation. + * @member {proto.ILiveLocationMessage|null|undefined} finalLiveLocation + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.finalLiveLocation = null; + + /** + * WebMessageInfo quotedPaymentInfo. + * @member {proto.IPaymentInfo|null|undefined} quotedPaymentInfo + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.quotedPaymentInfo = null; + + /** + * WebMessageInfo ephemeralStartTimestamp. + * @member {number|Long} ephemeralStartTimestamp + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.ephemeralStartTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * WebMessageInfo ephemeralDuration. + * @member {number} ephemeralDuration + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.ephemeralDuration = 0; + + /** + * WebMessageInfo ephemeralOffToOn. + * @member {boolean} ephemeralOffToOn + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.ephemeralOffToOn = false; + + /** + * WebMessageInfo ephemeralOutOfSync. + * @member {boolean} ephemeralOutOfSync + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.ephemeralOutOfSync = false; + + /** + * WebMessageInfo bizPrivacyStatus. + * @member {proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus} bizPrivacyStatus + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.bizPrivacyStatus = 0; + + /** + * WebMessageInfo verifiedBizName. + * @member {string} verifiedBizName + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.verifiedBizName = ""; + + /** + * WebMessageInfo mediaData. + * @member {proto.IMediaData|null|undefined} mediaData + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.mediaData = null; + + /** + * WebMessageInfo photoChange. + * @member {proto.IPhotoChange|null|undefined} photoChange + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.photoChange = null; + + /** + * Creates a new WebMessageInfo instance using the specified properties. + * @function create + * @memberof proto.WebMessageInfo + * @static + * @param {proto.IWebMessageInfo=} [properties] Properties to set + * @returns {proto.WebMessageInfo} WebMessageInfo instance + */ + WebMessageInfo.create = function create(properties) { + return new WebMessageInfo(properties); + }; + + /** + * Encodes the specified WebMessageInfo message. Does not implicitly {@link proto.WebMessageInfo.verify|verify} messages. + * @function encode + * @memberof proto.WebMessageInfo + * @static + * @param {proto.IWebMessageInfo} message WebMessageInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WebMessageInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.message != null && Object.hasOwnProperty.call(message, "message")) + $root.proto.Message.encode(message.message, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.messageTimestamp != null && Object.hasOwnProperty.call(message, "messageTimestamp")) + writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.messageTimestamp); + if (message.status != null && Object.hasOwnProperty.call(message, "status")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.status); + if (message.participant != null && Object.hasOwnProperty.call(message, "participant")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.participant); + if (message.messageC2STimestamp != null && Object.hasOwnProperty.call(message, "messageC2STimestamp")) + writer.uint32(/* id 6, wireType 0 =*/48).uint64(message.messageC2STimestamp); + if (message.ignore != null && Object.hasOwnProperty.call(message, "ignore")) + writer.uint32(/* id 16, wireType 0 =*/128).bool(message.ignore); + if (message.starred != null && Object.hasOwnProperty.call(message, "starred")) + writer.uint32(/* id 17, wireType 0 =*/136).bool(message.starred); + if (message.broadcast != null && Object.hasOwnProperty.call(message, "broadcast")) + writer.uint32(/* id 18, wireType 0 =*/144).bool(message.broadcast); + if (message.pushName != null && Object.hasOwnProperty.call(message, "pushName")) + writer.uint32(/* id 19, wireType 2 =*/154).string(message.pushName); + if (message.mediaCiphertextSha256 != null && Object.hasOwnProperty.call(message, "mediaCiphertextSha256")) + writer.uint32(/* id 20, wireType 2 =*/162).bytes(message.mediaCiphertextSha256); + if (message.multicast != null && Object.hasOwnProperty.call(message, "multicast")) + writer.uint32(/* id 21, wireType 0 =*/168).bool(message.multicast); + if (message.urlText != null && Object.hasOwnProperty.call(message, "urlText")) + writer.uint32(/* id 22, wireType 0 =*/176).bool(message.urlText); + if (message.urlNumber != null && Object.hasOwnProperty.call(message, "urlNumber")) + writer.uint32(/* id 23, wireType 0 =*/184).bool(message.urlNumber); + if (message.messageStubType != null && Object.hasOwnProperty.call(message, "messageStubType")) + writer.uint32(/* id 24, wireType 0 =*/192).int32(message.messageStubType); + if (message.clearMedia != null && Object.hasOwnProperty.call(message, "clearMedia")) + writer.uint32(/* id 25, wireType 0 =*/200).bool(message.clearMedia); + if (message.messageStubParameters != null && message.messageStubParameters.length) + for (var i = 0; i < message.messageStubParameters.length; ++i) + writer.uint32(/* id 26, wireType 2 =*/210).string(message.messageStubParameters[i]); + if (message.duration != null && Object.hasOwnProperty.call(message, "duration")) + writer.uint32(/* id 27, wireType 0 =*/216).uint32(message.duration); + if (message.labels != null && message.labels.length) + for (var i = 0; i < message.labels.length; ++i) + writer.uint32(/* id 28, wireType 2 =*/226).string(message.labels[i]); + if (message.paymentInfo != null && Object.hasOwnProperty.call(message, "paymentInfo")) + $root.proto.PaymentInfo.encode(message.paymentInfo, writer.uint32(/* id 29, wireType 2 =*/234).fork()).ldelim(); + if (message.finalLiveLocation != null && Object.hasOwnProperty.call(message, "finalLiveLocation")) + $root.proto.LiveLocationMessage.encode(message.finalLiveLocation, writer.uint32(/* id 30, wireType 2 =*/242).fork()).ldelim(); + if (message.quotedPaymentInfo != null && Object.hasOwnProperty.call(message, "quotedPaymentInfo")) + $root.proto.PaymentInfo.encode(message.quotedPaymentInfo, writer.uint32(/* id 31, wireType 2 =*/250).fork()).ldelim(); + if (message.ephemeralStartTimestamp != null && Object.hasOwnProperty.call(message, "ephemeralStartTimestamp")) + writer.uint32(/* id 32, wireType 0 =*/256).uint64(message.ephemeralStartTimestamp); + if (message.ephemeralDuration != null && Object.hasOwnProperty.call(message, "ephemeralDuration")) + writer.uint32(/* id 33, wireType 0 =*/264).uint32(message.ephemeralDuration); + if (message.ephemeralOffToOn != null && Object.hasOwnProperty.call(message, "ephemeralOffToOn")) + writer.uint32(/* id 34, wireType 0 =*/272).bool(message.ephemeralOffToOn); + if (message.ephemeralOutOfSync != null && Object.hasOwnProperty.call(message, "ephemeralOutOfSync")) + writer.uint32(/* id 35, wireType 0 =*/280).bool(message.ephemeralOutOfSync); + if (message.bizPrivacyStatus != null && Object.hasOwnProperty.call(message, "bizPrivacyStatus")) + writer.uint32(/* id 36, wireType 0 =*/288).int32(message.bizPrivacyStatus); + if (message.verifiedBizName != null && Object.hasOwnProperty.call(message, "verifiedBizName")) + writer.uint32(/* id 37, wireType 2 =*/298).string(message.verifiedBizName); + if (message.mediaData != null && Object.hasOwnProperty.call(message, "mediaData")) + $root.proto.MediaData.encode(message.mediaData, writer.uint32(/* id 38, wireType 2 =*/306).fork()).ldelim(); + if (message.photoChange != null && Object.hasOwnProperty.call(message, "photoChange")) + $root.proto.PhotoChange.encode(message.photoChange, writer.uint32(/* id 39, wireType 2 =*/314).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified WebMessageInfo message, length delimited. Does not implicitly {@link proto.WebMessageInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.WebMessageInfo + * @static + * @param {proto.IWebMessageInfo} message WebMessageInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WebMessageInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a WebMessageInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.WebMessageInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.WebMessageInfo} WebMessageInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebMessageInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebMessageInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.key = $root.proto.MessageKey.decode(reader, reader.uint32()); + break; + case 2: + message.message = $root.proto.Message.decode(reader, reader.uint32()); + break; + case 3: + message.messageTimestamp = reader.uint64(); + break; + case 4: + message.status = reader.int32(); + break; + case 5: + message.participant = reader.string(); + break; + case 6: + message.messageC2STimestamp = reader.uint64(); + break; + case 16: + message.ignore = reader.bool(); + break; + case 17: + message.starred = reader.bool(); + break; + case 18: + message.broadcast = reader.bool(); + break; + case 19: + message.pushName = reader.string(); + break; + case 20: + message.mediaCiphertextSha256 = reader.bytes(); + break; + case 21: + message.multicast = reader.bool(); + break; + case 22: + message.urlText = reader.bool(); + break; + case 23: + message.urlNumber = reader.bool(); + break; + case 24: + message.messageStubType = reader.int32(); + break; + case 25: + message.clearMedia = reader.bool(); + break; + case 26: + if (!(message.messageStubParameters && message.messageStubParameters.length)) + message.messageStubParameters = []; + message.messageStubParameters.push(reader.string()); + break; + case 27: + message.duration = reader.uint32(); + break; + case 28: + if (!(message.labels && message.labels.length)) + message.labels = []; + message.labels.push(reader.string()); + break; + case 29: + message.paymentInfo = $root.proto.PaymentInfo.decode(reader, reader.uint32()); + break; + case 30: + message.finalLiveLocation = $root.proto.LiveLocationMessage.decode(reader, reader.uint32()); + break; + case 31: + message.quotedPaymentInfo = $root.proto.PaymentInfo.decode(reader, reader.uint32()); + break; + case 32: + message.ephemeralStartTimestamp = reader.uint64(); + break; + case 33: + message.ephemeralDuration = reader.uint32(); + break; + case 34: + message.ephemeralOffToOn = reader.bool(); + break; + case 35: + message.ephemeralOutOfSync = reader.bool(); + break; + case 36: + message.bizPrivacyStatus = reader.int32(); + break; + case 37: + message.verifiedBizName = reader.string(); + break; + case 38: + message.mediaData = $root.proto.MediaData.decode(reader, reader.uint32()); + break; + case 39: + message.photoChange = $root.proto.PhotoChange.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + if (!message.hasOwnProperty("key")) + throw $util.ProtocolError("missing required 'key'", { instance: message }); + return message; + }; + + /** + * Decodes a WebMessageInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.WebMessageInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.WebMessageInfo} WebMessageInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebMessageInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a WebMessageInfo message. + * @function verify + * @memberof proto.WebMessageInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + WebMessageInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + { + var error = $root.proto.MessageKey.verify(message.key); + if (error) + return "key." + error; + } + if (message.message != null && message.hasOwnProperty("message")) { + var error = $root.proto.Message.verify(message.message); + if (error) + return "message." + error; + } + if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) + if (!$util.isInteger(message.messageTimestamp) && !(message.messageTimestamp && $util.isInteger(message.messageTimestamp.low) && $util.isInteger(message.messageTimestamp.high))) + return "messageTimestamp: integer|Long expected"; + if (message.status != null && message.hasOwnProperty("status")) + switch (message.status) { + default: + return "status: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + break; + } + if (message.participant != null && message.hasOwnProperty("participant")) + if (!$util.isString(message.participant)) + return "participant: string expected"; + if (message.messageC2STimestamp != null && message.hasOwnProperty("messageC2STimestamp")) + if (!$util.isInteger(message.messageC2STimestamp) && !(message.messageC2STimestamp && $util.isInteger(message.messageC2STimestamp.low) && $util.isInteger(message.messageC2STimestamp.high))) + return "messageC2STimestamp: integer|Long expected"; + if (message.ignore != null && message.hasOwnProperty("ignore")) + if (typeof message.ignore !== "boolean") + return "ignore: boolean expected"; + if (message.starred != null && message.hasOwnProperty("starred")) + if (typeof message.starred !== "boolean") + return "starred: boolean expected"; + if (message.broadcast != null && message.hasOwnProperty("broadcast")) + if (typeof message.broadcast !== "boolean") + return "broadcast: boolean expected"; + if (message.pushName != null && message.hasOwnProperty("pushName")) + if (!$util.isString(message.pushName)) + return "pushName: string expected"; + if (message.mediaCiphertextSha256 != null && message.hasOwnProperty("mediaCiphertextSha256")) + if (!(message.mediaCiphertextSha256 && typeof message.mediaCiphertextSha256.length === "number" || $util.isString(message.mediaCiphertextSha256))) + return "mediaCiphertextSha256: buffer expected"; + if (message.multicast != null && message.hasOwnProperty("multicast")) + if (typeof message.multicast !== "boolean") + return "multicast: boolean expected"; + if (message.urlText != null && message.hasOwnProperty("urlText")) + if (typeof message.urlText !== "boolean") + return "urlText: boolean expected"; + if (message.urlNumber != null && message.hasOwnProperty("urlNumber")) + if (typeof message.urlNumber !== "boolean") + return "urlNumber: boolean expected"; + if (message.messageStubType != null && message.hasOwnProperty("messageStubType")) + switch (message.messageStubType) { + default: + return "messageStubType: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + case 31: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + case 38: + case 39: + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + case 48: + case 49: + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + case 79: + case 80: + case 81: + case 82: + case 83: + case 84: + case 85: + case 86: + case 87: + case 88: + case 89: + case 90: + case 91: + case 92: + case 93: + case 94: + case 95: + case 96: + case 97: + case 98: + case 99: + case 100: + case 101: + case 102: + case 103: + case 104: + case 105: + case 106: + case 107: + case 108: + case 109: + case 110: + case 111: + case 112: + case 113: + case 114: + case 115: + case 116: + case 117: + case 118: + case 119: + case 120: + case 121: + case 122: + case 123: + case 124: + case 125: + case 126: + case 127: + case 128: + case 129: + break; + } + if (message.clearMedia != null && message.hasOwnProperty("clearMedia")) + if (typeof message.clearMedia !== "boolean") + return "clearMedia: boolean expected"; + if (message.messageStubParameters != null && message.hasOwnProperty("messageStubParameters")) { + if (!Array.isArray(message.messageStubParameters)) + return "messageStubParameters: array expected"; + for (var i = 0; i < message.messageStubParameters.length; ++i) + if (!$util.isString(message.messageStubParameters[i])) + return "messageStubParameters: string[] expected"; + } + if (message.duration != null && message.hasOwnProperty("duration")) + if (!$util.isInteger(message.duration)) + return "duration: integer expected"; + if (message.labels != null && message.hasOwnProperty("labels")) { + if (!Array.isArray(message.labels)) + return "labels: array expected"; + for (var i = 0; i < message.labels.length; ++i) + if (!$util.isString(message.labels[i])) + return "labels: string[] expected"; + } + if (message.paymentInfo != null && message.hasOwnProperty("paymentInfo")) { + var error = $root.proto.PaymentInfo.verify(message.paymentInfo); + if (error) + return "paymentInfo." + error; + } + if (message.finalLiveLocation != null && message.hasOwnProperty("finalLiveLocation")) { + var error = $root.proto.LiveLocationMessage.verify(message.finalLiveLocation); + if (error) + return "finalLiveLocation." + error; + } + if (message.quotedPaymentInfo != null && message.hasOwnProperty("quotedPaymentInfo")) { + var error = $root.proto.PaymentInfo.verify(message.quotedPaymentInfo); + if (error) + return "quotedPaymentInfo." + error; + } + if (message.ephemeralStartTimestamp != null && message.hasOwnProperty("ephemeralStartTimestamp")) + if (!$util.isInteger(message.ephemeralStartTimestamp) && !(message.ephemeralStartTimestamp && $util.isInteger(message.ephemeralStartTimestamp.low) && $util.isInteger(message.ephemeralStartTimestamp.high))) + return "ephemeralStartTimestamp: integer|Long expected"; + if (message.ephemeralDuration != null && message.hasOwnProperty("ephemeralDuration")) + if (!$util.isInteger(message.ephemeralDuration)) + return "ephemeralDuration: integer expected"; + if (message.ephemeralOffToOn != null && message.hasOwnProperty("ephemeralOffToOn")) + if (typeof message.ephemeralOffToOn !== "boolean") + return "ephemeralOffToOn: boolean expected"; + if (message.ephemeralOutOfSync != null && message.hasOwnProperty("ephemeralOutOfSync")) + if (typeof message.ephemeralOutOfSync !== "boolean") + return "ephemeralOutOfSync: boolean expected"; + if (message.bizPrivacyStatus != null && message.hasOwnProperty("bizPrivacyStatus")) + switch (message.bizPrivacyStatus) { + default: + return "bizPrivacyStatus: enum value expected"; + case 0: + case 2: + case 1: + case 3: + break; + } + if (message.verifiedBizName != null && message.hasOwnProperty("verifiedBizName")) + if (!$util.isString(message.verifiedBizName)) + return "verifiedBizName: string expected"; + if (message.mediaData != null && message.hasOwnProperty("mediaData")) { + var error = $root.proto.MediaData.verify(message.mediaData); + if (error) + return "mediaData." + error; + } + if (message.photoChange != null && message.hasOwnProperty("photoChange")) { + var error = $root.proto.PhotoChange.verify(message.photoChange); + if (error) + return "photoChange." + error; + } + return null; + }; + + /** + * Creates a WebMessageInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.WebMessageInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.WebMessageInfo} WebMessageInfo + */ + WebMessageInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.WebMessageInfo) + return object; + var message = new $root.proto.WebMessageInfo(); + if (object.key != null) { + if (typeof object.key !== "object") + throw TypeError(".proto.WebMessageInfo.key: object expected"); + message.key = $root.proto.MessageKey.fromObject(object.key); + } + if (object.message != null) { + if (typeof object.message !== "object") + throw TypeError(".proto.WebMessageInfo.message: object expected"); + message.message = $root.proto.Message.fromObject(object.message); + } + if (object.messageTimestamp != null) + if ($util.Long) + (message.messageTimestamp = $util.Long.fromValue(object.messageTimestamp)).unsigned = true; + else if (typeof object.messageTimestamp === "string") + message.messageTimestamp = parseInt(object.messageTimestamp, 10); + else if (typeof object.messageTimestamp === "number") + message.messageTimestamp = object.messageTimestamp; + else if (typeof object.messageTimestamp === "object") + message.messageTimestamp = new $util.LongBits(object.messageTimestamp.low >>> 0, object.messageTimestamp.high >>> 0).toNumber(true); + switch (object.status) { + case "ERROR": + case 0: + message.status = 0; + break; + case "PENDING": + case 1: + message.status = 1; + break; + case "SERVER_ACK": + case 2: + message.status = 2; + break; + case "DELIVERY_ACK": + case 3: + message.status = 3; + break; + case "READ": + case 4: + message.status = 4; + break; + case "PLAYED": + case 5: + message.status = 5; + break; + } + if (object.participant != null) + message.participant = String(object.participant); + if (object.messageC2STimestamp != null) + if ($util.Long) + (message.messageC2STimestamp = $util.Long.fromValue(object.messageC2STimestamp)).unsigned = true; + else if (typeof object.messageC2STimestamp === "string") + message.messageC2STimestamp = parseInt(object.messageC2STimestamp, 10); + else if (typeof object.messageC2STimestamp === "number") + message.messageC2STimestamp = object.messageC2STimestamp; + else if (typeof object.messageC2STimestamp === "object") + message.messageC2STimestamp = new $util.LongBits(object.messageC2STimestamp.low >>> 0, object.messageC2STimestamp.high >>> 0).toNumber(true); + if (object.ignore != null) + message.ignore = Boolean(object.ignore); + if (object.starred != null) + message.starred = Boolean(object.starred); + if (object.broadcast != null) + message.broadcast = Boolean(object.broadcast); + if (object.pushName != null) + message.pushName = String(object.pushName); + if (object.mediaCiphertextSha256 != null) + if (typeof object.mediaCiphertextSha256 === "string") + $util.base64.decode(object.mediaCiphertextSha256, message.mediaCiphertextSha256 = $util.newBuffer($util.base64.length(object.mediaCiphertextSha256)), 0); + else if (object.mediaCiphertextSha256.length) + message.mediaCiphertextSha256 = object.mediaCiphertextSha256; + if (object.multicast != null) + message.multicast = Boolean(object.multicast); + if (object.urlText != null) + message.urlText = Boolean(object.urlText); + if (object.urlNumber != null) + message.urlNumber = Boolean(object.urlNumber); + switch (object.messageStubType) { + case "UNKNOWN": + case 0: + message.messageStubType = 0; + break; + case "REVOKE": + case 1: + message.messageStubType = 1; + break; + case "CIPHERTEXT": + case 2: + message.messageStubType = 2; + break; + case "FUTUREPROOF": + case 3: + message.messageStubType = 3; + break; + case "NON_VERIFIED_TRANSITION": + case 4: + message.messageStubType = 4; + break; + case "UNVERIFIED_TRANSITION": + case 5: + message.messageStubType = 5; + break; + case "VERIFIED_TRANSITION": + case 6: + message.messageStubType = 6; + break; + case "VERIFIED_LOW_UNKNOWN": + case 7: + message.messageStubType = 7; + break; + case "VERIFIED_HIGH": + case 8: + message.messageStubType = 8; + break; + case "VERIFIED_INITIAL_UNKNOWN": + case 9: + message.messageStubType = 9; + break; + case "VERIFIED_INITIAL_LOW": + case 10: + message.messageStubType = 10; + break; + case "VERIFIED_INITIAL_HIGH": + case 11: + message.messageStubType = 11; + break; + case "VERIFIED_TRANSITION_ANY_TO_NONE": + case 12: + message.messageStubType = 12; + break; + case "VERIFIED_TRANSITION_ANY_TO_HIGH": + case 13: + message.messageStubType = 13; + break; + case "VERIFIED_TRANSITION_HIGH_TO_LOW": + case 14: + message.messageStubType = 14; + break; + case "VERIFIED_TRANSITION_HIGH_TO_UNKNOWN": + case 15: + message.messageStubType = 15; + break; + case "VERIFIED_TRANSITION_UNKNOWN_TO_LOW": + case 16: + message.messageStubType = 16; + break; + case "VERIFIED_TRANSITION_LOW_TO_UNKNOWN": + case 17: + message.messageStubType = 17; + break; + case "VERIFIED_TRANSITION_NONE_TO_LOW": + case 18: + message.messageStubType = 18; + break; + case "VERIFIED_TRANSITION_NONE_TO_UNKNOWN": + case 19: + message.messageStubType = 19; + break; + case "GROUP_CREATE": + case 20: + message.messageStubType = 20; + break; + case "GROUP_CHANGE_SUBJECT": + case 21: + message.messageStubType = 21; + break; + case "GROUP_CHANGE_ICON": + case 22: + message.messageStubType = 22; + break; + case "GROUP_CHANGE_INVITE_LINK": + case 23: + message.messageStubType = 23; + break; + case "GROUP_CHANGE_DESCRIPTION": + case 24: + message.messageStubType = 24; + break; + case "GROUP_CHANGE_RESTRICT": + case 25: + message.messageStubType = 25; + break; + case "GROUP_CHANGE_ANNOUNCE": + case 26: + message.messageStubType = 26; + break; + case "GROUP_PARTICIPANT_ADD": + case 27: + message.messageStubType = 27; + break; + case "GROUP_PARTICIPANT_REMOVE": + case 28: + message.messageStubType = 28; + break; + case "GROUP_PARTICIPANT_PROMOTE": + case 29: + message.messageStubType = 29; + break; + case "GROUP_PARTICIPANT_DEMOTE": + case 30: + message.messageStubType = 30; + break; + case "GROUP_PARTICIPANT_INVITE": + case 31: + message.messageStubType = 31; + break; + case "GROUP_PARTICIPANT_LEAVE": + case 32: + message.messageStubType = 32; + break; + case "GROUP_PARTICIPANT_CHANGE_NUMBER": + case 33: + message.messageStubType = 33; + break; + case "BROADCAST_CREATE": + case 34: + message.messageStubType = 34; + break; + case "BROADCAST_ADD": + case 35: + message.messageStubType = 35; + break; + case "BROADCAST_REMOVE": + case 36: + message.messageStubType = 36; + break; + case "GENERIC_NOTIFICATION": + case 37: + message.messageStubType = 37; + break; + case "E2E_IDENTITY_CHANGED": + case 38: + message.messageStubType = 38; + break; + case "E2E_ENCRYPTED": + case 39: + message.messageStubType = 39; + break; + case "CALL_MISSED_VOICE": + case 40: + message.messageStubType = 40; + break; + case "CALL_MISSED_VIDEO": + case 41: + message.messageStubType = 41; + break; + case "INDIVIDUAL_CHANGE_NUMBER": + case 42: + message.messageStubType = 42; + break; + case "GROUP_DELETE": + case 43: + message.messageStubType = 43; + break; + case "GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE": + case 44: + message.messageStubType = 44; + break; + case "CALL_MISSED_GROUP_VOICE": + case 45: + message.messageStubType = 45; + break; + case "CALL_MISSED_GROUP_VIDEO": + case 46: + message.messageStubType = 46; + break; + case "PAYMENT_CIPHERTEXT": + case 47: + message.messageStubType = 47; + break; + case "PAYMENT_FUTUREPROOF": + case 48: + message.messageStubType = 48; + break; + case "PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED": + case 49: + message.messageStubType = 49; + break; + case "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED": + case 50: + message.messageStubType = 50; + break; + case "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED": + case 51: + message.messageStubType = 51; + break; + case "PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP": + case 52: + message.messageStubType = 52; + break; + case "PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP": + case 53: + message.messageStubType = 53; + break; + case "PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER": + case 54: + message.messageStubType = 54; + break; + case "PAYMENT_ACTION_SEND_PAYMENT_REMINDER": + case 55: + message.messageStubType = 55; + break; + case "PAYMENT_ACTION_SEND_PAYMENT_INVITATION": + case 56: + message.messageStubType = 56; + break; + case "PAYMENT_ACTION_REQUEST_DECLINED": + case 57: + message.messageStubType = 57; + break; + case "PAYMENT_ACTION_REQUEST_EXPIRED": + case 58: + message.messageStubType = 58; + break; + case "PAYMENT_ACTION_REQUEST_CANCELLED": + case 59: + message.messageStubType = 59; + break; + case "BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM": + case 60: + message.messageStubType = 60; + break; + case "BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP": + case 61: + message.messageStubType = 61; + break; + case "BIZ_INTRO_TOP": + case 62: + message.messageStubType = 62; + break; + case "BIZ_INTRO_BOTTOM": + case 63: + message.messageStubType = 63; + break; + case "BIZ_NAME_CHANGE": + case 64: + message.messageStubType = 64; + break; + case "BIZ_MOVE_TO_CONSUMER_APP": + case 65: + message.messageStubType = 65; + break; + case "BIZ_TWO_TIER_MIGRATION_TOP": + case 66: + message.messageStubType = 66; + break; + case "BIZ_TWO_TIER_MIGRATION_BOTTOM": + case 67: + message.messageStubType = 67; + break; + case "OVERSIZED": + case 68: + message.messageStubType = 68; + break; + case "GROUP_CHANGE_NO_FREQUENTLY_FORWARDED": + case 69: + message.messageStubType = 69; + break; + case "GROUP_V4_ADD_INVITE_SENT": + case 70: + message.messageStubType = 70; + break; + case "GROUP_PARTICIPANT_ADD_REQUEST_JOIN": + case 71: + message.messageStubType = 71; + break; + case "CHANGE_EPHEMERAL_SETTING": + case 72: + message.messageStubType = 72; + break; + case "E2E_DEVICE_CHANGED": + case 73: + message.messageStubType = 73; + break; + case "VIEWED_ONCE": + case 74: + message.messageStubType = 74; + break; + case "E2E_ENCRYPTED_NOW": + case 75: + message.messageStubType = 75; + break; + case "BLUE_MSG_BSP_FB_TO_BSP_PREMISE": + case 76: + message.messageStubType = 76; + break; + case "BLUE_MSG_BSP_FB_TO_SELF_FB": + case 77: + message.messageStubType = 77; + break; + case "BLUE_MSG_BSP_FB_TO_SELF_PREMISE": + case 78: + message.messageStubType = 78; + break; + case "BLUE_MSG_BSP_FB_UNVERIFIED": + case 79: + message.messageStubType = 79; + break; + case "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED": + case 80: + message.messageStubType = 80; + break; + case "BLUE_MSG_BSP_FB_VERIFIED": + case 81: + message.messageStubType = 81; + break; + case "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED": + case 82: + message.messageStubType = 82; + break; + case "BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE": + case 83: + message.messageStubType = 83; + break; + case "BLUE_MSG_BSP_PREMISE_UNVERIFIED": + case 84: + message.messageStubType = 84; + break; + case "BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED": + case 85: + message.messageStubType = 85; + break; + case "BLUE_MSG_BSP_PREMISE_VERIFIED": + case 86: + message.messageStubType = 86; + break; + case "BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED": + case 87: + message.messageStubType = 87; + break; + case "BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED": + case 88: + message.messageStubType = 88; + break; + case "BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED": + case 89: + message.messageStubType = 89; + break; + case "BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED": + case 90: + message.messageStubType = 90; + break; + case "BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED": + case 91: + message.messageStubType = 91; + break; + case "BLUE_MSG_SELF_FB_TO_BSP_PREMISE": + case 92: + message.messageStubType = 92; + break; + case "BLUE_MSG_SELF_FB_TO_SELF_PREMISE": + case 93: + message.messageStubType = 93; + break; + case "BLUE_MSG_SELF_FB_UNVERIFIED": + case 94: + message.messageStubType = 94; + break; + case "BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED": + case 95: + message.messageStubType = 95; + break; + case "BLUE_MSG_SELF_FB_VERIFIED": + case 96: + message.messageStubType = 96; + break; + case "BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED": + case 97: + message.messageStubType = 97; + break; + case "BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE": + case 98: + message.messageStubType = 98; + break; + case "BLUE_MSG_SELF_PREMISE_UNVERIFIED": + case 99: + message.messageStubType = 99; + break; + case "BLUE_MSG_SELF_PREMISE_VERIFIED": + case 100: + message.messageStubType = 100; + break; + case "BLUE_MSG_TO_BSP_FB": + case 101: + message.messageStubType = 101; + break; + case "BLUE_MSG_TO_CONSUMER": + case 102: + message.messageStubType = 102; + break; + case "BLUE_MSG_TO_SELF_FB": + case 103: + message.messageStubType = 103; + break; + case "BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED": + case 104: + message.messageStubType = 104; + break; + case "BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED": + case 105: + message.messageStubType = 105; + break; + case "BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED": + case 106: + message.messageStubType = 106; + break; + case "BLUE_MSG_UNVERIFIED_TO_VERIFIED": + case 107: + message.messageStubType = 107; + break; + case "BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED": + case 108: + message.messageStubType = 108; + break; + case "BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED": + case 109: + message.messageStubType = 109; + break; + case "BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED": + case 110: + message.messageStubType = 110; + break; + case "BLUE_MSG_VERIFIED_TO_UNVERIFIED": + case 111: + message.messageStubType = 111; + break; + case "BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED": + case 112: + message.messageStubType = 112; + break; + case "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED": + case 113: + message.messageStubType = 113; + break; + case "BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED": + case 114: + message.messageStubType = 114; + break; + case "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED": + case 115: + message.messageStubType = 115; + break; + case "BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED": + case 116: + message.messageStubType = 116; + break; + case "BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED": + case 117: + message.messageStubType = 117; + break; + case "E2E_IDENTITY_UNAVAILABLE": + case 118: + message.messageStubType = 118; + break; + case "GROUP_CREATING": + case 119: + message.messageStubType = 119; + break; + case "GROUP_CREATE_FAILED": + case 120: + message.messageStubType = 120; + break; + case "GROUP_BOUNCED": + case 121: + message.messageStubType = 121; + break; + case "BLOCK_CONTACT": + case 122: + message.messageStubType = 122; + break; + case "EPHEMERAL_SETTING_NOT_APPLIED": + case 123: + message.messageStubType = 123; + break; + case "SYNC_FAILED": + case 124: + message.messageStubType = 124; + break; + case "SYNCING": + case 125: + message.messageStubType = 125; + break; + case "BIZ_PRIVACY_MODE_INIT_FB": + case 126: + message.messageStubType = 126; + break; + case "BIZ_PRIVACY_MODE_INIT_BSP": + case 127: + message.messageStubType = 127; + break; + case "BIZ_PRIVACY_MODE_TO_FB": + case 128: + message.messageStubType = 128; + break; + case "BIZ_PRIVACY_MODE_TO_BSP": + case 129: + message.messageStubType = 129; + break; + } + if (object.clearMedia != null) + message.clearMedia = Boolean(object.clearMedia); + if (object.messageStubParameters) { + if (!Array.isArray(object.messageStubParameters)) + throw TypeError(".proto.WebMessageInfo.messageStubParameters: array expected"); + message.messageStubParameters = []; + for (var i = 0; i < object.messageStubParameters.length; ++i) + message.messageStubParameters[i] = String(object.messageStubParameters[i]); + } + if (object.duration != null) + message.duration = object.duration >>> 0; + if (object.labels) { + if (!Array.isArray(object.labels)) + throw TypeError(".proto.WebMessageInfo.labels: array expected"); + message.labels = []; + for (var i = 0; i < object.labels.length; ++i) + message.labels[i] = String(object.labels[i]); + } + if (object.paymentInfo != null) { + if (typeof object.paymentInfo !== "object") + throw TypeError(".proto.WebMessageInfo.paymentInfo: object expected"); + message.paymentInfo = $root.proto.PaymentInfo.fromObject(object.paymentInfo); + } + if (object.finalLiveLocation != null) { + if (typeof object.finalLiveLocation !== "object") + throw TypeError(".proto.WebMessageInfo.finalLiveLocation: object expected"); + message.finalLiveLocation = $root.proto.LiveLocationMessage.fromObject(object.finalLiveLocation); + } + if (object.quotedPaymentInfo != null) { + if (typeof object.quotedPaymentInfo !== "object") + throw TypeError(".proto.WebMessageInfo.quotedPaymentInfo: object expected"); + message.quotedPaymentInfo = $root.proto.PaymentInfo.fromObject(object.quotedPaymentInfo); + } + if (object.ephemeralStartTimestamp != null) + if ($util.Long) + (message.ephemeralStartTimestamp = $util.Long.fromValue(object.ephemeralStartTimestamp)).unsigned = true; + else if (typeof object.ephemeralStartTimestamp === "string") + message.ephemeralStartTimestamp = parseInt(object.ephemeralStartTimestamp, 10); + else if (typeof object.ephemeralStartTimestamp === "number") + message.ephemeralStartTimestamp = object.ephemeralStartTimestamp; + else if (typeof object.ephemeralStartTimestamp === "object") + message.ephemeralStartTimestamp = new $util.LongBits(object.ephemeralStartTimestamp.low >>> 0, object.ephemeralStartTimestamp.high >>> 0).toNumber(true); + if (object.ephemeralDuration != null) + message.ephemeralDuration = object.ephemeralDuration >>> 0; + if (object.ephemeralOffToOn != null) + message.ephemeralOffToOn = Boolean(object.ephemeralOffToOn); + if (object.ephemeralOutOfSync != null) + message.ephemeralOutOfSync = Boolean(object.ephemeralOutOfSync); + switch (object.bizPrivacyStatus) { + case "E2EE": + case 0: + message.bizPrivacyStatus = 0; + break; + case "FB": + case 2: + message.bizPrivacyStatus = 2; + break; + case "BSP": + case 1: + message.bizPrivacyStatus = 1; + break; + case "BSP_AND_FB": + case 3: + message.bizPrivacyStatus = 3; + break; + } + if (object.verifiedBizName != null) + message.verifiedBizName = String(object.verifiedBizName); + if (object.mediaData != null) { + if (typeof object.mediaData !== "object") + throw TypeError(".proto.WebMessageInfo.mediaData: object expected"); + message.mediaData = $root.proto.MediaData.fromObject(object.mediaData); + } + if (object.photoChange != null) { + if (typeof object.photoChange !== "object") + throw TypeError(".proto.WebMessageInfo.photoChange: object expected"); + message.photoChange = $root.proto.PhotoChange.fromObject(object.photoChange); + } + return message; + }; + + /** + * Creates a plain object from a WebMessageInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.WebMessageInfo + * @static + * @param {proto.WebMessageInfo} message WebMessageInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + WebMessageInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.messageStubParameters = []; + object.labels = []; + } + if (options.defaults) { + object.key = null; + object.message = null; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.messageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.messageTimestamp = options.longs === String ? "0" : 0; + object.status = options.enums === String ? "ERROR" : 0; + object.participant = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.messageC2STimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.messageC2STimestamp = options.longs === String ? "0" : 0; + object.ignore = false; + object.starred = false; + object.broadcast = false; + object.pushName = ""; + if (options.bytes === String) + object.mediaCiphertextSha256 = ""; + else { + object.mediaCiphertextSha256 = []; + if (options.bytes !== Array) + object.mediaCiphertextSha256 = $util.newBuffer(object.mediaCiphertextSha256); + } + object.multicast = false; + object.urlText = false; + object.urlNumber = false; + object.messageStubType = options.enums === String ? "UNKNOWN" : 0; + object.clearMedia = false; + object.duration = 0; + object.paymentInfo = null; + object.finalLiveLocation = null; + object.quotedPaymentInfo = null; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.ephemeralStartTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.ephemeralStartTimestamp = options.longs === String ? "0" : 0; + object.ephemeralDuration = 0; + object.ephemeralOffToOn = false; + object.ephemeralOutOfSync = false; + object.bizPrivacyStatus = options.enums === String ? "E2EE" : 0; + object.verifiedBizName = ""; + object.mediaData = null; + object.photoChange = null; + } + if (message.key != null && message.hasOwnProperty("key")) + object.key = $root.proto.MessageKey.toObject(message.key, options); + if (message.message != null && message.hasOwnProperty("message")) + object.message = $root.proto.Message.toObject(message.message, options); + if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) + if (typeof message.messageTimestamp === "number") + object.messageTimestamp = options.longs === String ? String(message.messageTimestamp) : message.messageTimestamp; + else + object.messageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.messageTimestamp) : options.longs === Number ? new $util.LongBits(message.messageTimestamp.low >>> 0, message.messageTimestamp.high >>> 0).toNumber(true) : message.messageTimestamp; + if (message.status != null && message.hasOwnProperty("status")) + object.status = options.enums === String ? $root.proto.WebMessageInfo.WebMessageInfoStatus[message.status] : message.status; + if (message.participant != null && message.hasOwnProperty("participant")) + object.participant = message.participant; + if (message.messageC2STimestamp != null && message.hasOwnProperty("messageC2STimestamp")) + if (typeof message.messageC2STimestamp === "number") + object.messageC2STimestamp = options.longs === String ? String(message.messageC2STimestamp) : message.messageC2STimestamp; + else + object.messageC2STimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.messageC2STimestamp) : options.longs === Number ? new $util.LongBits(message.messageC2STimestamp.low >>> 0, message.messageC2STimestamp.high >>> 0).toNumber(true) : message.messageC2STimestamp; + if (message.ignore != null && message.hasOwnProperty("ignore")) + object.ignore = message.ignore; + if (message.starred != null && message.hasOwnProperty("starred")) + object.starred = message.starred; + if (message.broadcast != null && message.hasOwnProperty("broadcast")) + object.broadcast = message.broadcast; + if (message.pushName != null && message.hasOwnProperty("pushName")) + object.pushName = message.pushName; + if (message.mediaCiphertextSha256 != null && message.hasOwnProperty("mediaCiphertextSha256")) + object.mediaCiphertextSha256 = options.bytes === String ? $util.base64.encode(message.mediaCiphertextSha256, 0, message.mediaCiphertextSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaCiphertextSha256) : message.mediaCiphertextSha256; + if (message.multicast != null && message.hasOwnProperty("multicast")) + object.multicast = message.multicast; + if (message.urlText != null && message.hasOwnProperty("urlText")) + object.urlText = message.urlText; + if (message.urlNumber != null && message.hasOwnProperty("urlNumber")) + object.urlNumber = message.urlNumber; + if (message.messageStubType != null && message.hasOwnProperty("messageStubType")) + object.messageStubType = options.enums === String ? $root.proto.WebMessageInfo.WebMessageInfoStubType[message.messageStubType] : message.messageStubType; + if (message.clearMedia != null && message.hasOwnProperty("clearMedia")) + object.clearMedia = message.clearMedia; + if (message.messageStubParameters && message.messageStubParameters.length) { + object.messageStubParameters = []; + for (var j = 0; j < message.messageStubParameters.length; ++j) + object.messageStubParameters[j] = message.messageStubParameters[j]; + } + if (message.duration != null && message.hasOwnProperty("duration")) + object.duration = message.duration; + if (message.labels && message.labels.length) { + object.labels = []; + for (var j = 0; j < message.labels.length; ++j) + object.labels[j] = message.labels[j]; + } + if (message.paymentInfo != null && message.hasOwnProperty("paymentInfo")) + object.paymentInfo = $root.proto.PaymentInfo.toObject(message.paymentInfo, options); + if (message.finalLiveLocation != null && message.hasOwnProperty("finalLiveLocation")) + object.finalLiveLocation = $root.proto.LiveLocationMessage.toObject(message.finalLiveLocation, options); + if (message.quotedPaymentInfo != null && message.hasOwnProperty("quotedPaymentInfo")) + object.quotedPaymentInfo = $root.proto.PaymentInfo.toObject(message.quotedPaymentInfo, options); + if (message.ephemeralStartTimestamp != null && message.hasOwnProperty("ephemeralStartTimestamp")) + if (typeof message.ephemeralStartTimestamp === "number") + object.ephemeralStartTimestamp = options.longs === String ? String(message.ephemeralStartTimestamp) : message.ephemeralStartTimestamp; + else + object.ephemeralStartTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.ephemeralStartTimestamp) : options.longs === Number ? new $util.LongBits(message.ephemeralStartTimestamp.low >>> 0, message.ephemeralStartTimestamp.high >>> 0).toNumber(true) : message.ephemeralStartTimestamp; + if (message.ephemeralDuration != null && message.hasOwnProperty("ephemeralDuration")) + object.ephemeralDuration = message.ephemeralDuration; + if (message.ephemeralOffToOn != null && message.hasOwnProperty("ephemeralOffToOn")) + object.ephemeralOffToOn = message.ephemeralOffToOn; + if (message.ephemeralOutOfSync != null && message.hasOwnProperty("ephemeralOutOfSync")) + object.ephemeralOutOfSync = message.ephemeralOutOfSync; + if (message.bizPrivacyStatus != null && message.hasOwnProperty("bizPrivacyStatus")) + object.bizPrivacyStatus = options.enums === String ? $root.proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus[message.bizPrivacyStatus] : message.bizPrivacyStatus; + if (message.verifiedBizName != null && message.hasOwnProperty("verifiedBizName")) + object.verifiedBizName = message.verifiedBizName; + if (message.mediaData != null && message.hasOwnProperty("mediaData")) + object.mediaData = $root.proto.MediaData.toObject(message.mediaData, options); + if (message.photoChange != null && message.hasOwnProperty("photoChange")) + object.photoChange = $root.proto.PhotoChange.toObject(message.photoChange, options); + return object; + }; + + /** + * Converts this WebMessageInfo to JSON. + * @function toJSON + * @memberof proto.WebMessageInfo + * @instance + * @returns {Object.} JSON object + */ + WebMessageInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * WebMessageInfoStatus enum. + * @name proto.WebMessageInfo.WebMessageInfoStatus + * @enum {number} + * @property {number} ERROR=0 ERROR value + * @property {number} PENDING=1 PENDING value + * @property {number} SERVER_ACK=2 SERVER_ACK value + * @property {number} DELIVERY_ACK=3 DELIVERY_ACK value + * @property {number} READ=4 READ value + * @property {number} PLAYED=5 PLAYED value + */ + WebMessageInfo.WebMessageInfoStatus = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "ERROR"] = 0; + values[valuesById[1] = "PENDING"] = 1; + values[valuesById[2] = "SERVER_ACK"] = 2; + values[valuesById[3] = "DELIVERY_ACK"] = 3; + values[valuesById[4] = "READ"] = 4; + values[valuesById[5] = "PLAYED"] = 5; + return values; + })(); + + /** + * WebMessageInfoStubType enum. + * @name proto.WebMessageInfo.WebMessageInfoStubType + * @enum {number} + * @property {number} UNKNOWN=0 UNKNOWN value + * @property {number} REVOKE=1 REVOKE value + * @property {number} CIPHERTEXT=2 CIPHERTEXT value + * @property {number} FUTUREPROOF=3 FUTUREPROOF value + * @property {number} NON_VERIFIED_TRANSITION=4 NON_VERIFIED_TRANSITION value + * @property {number} UNVERIFIED_TRANSITION=5 UNVERIFIED_TRANSITION value + * @property {number} VERIFIED_TRANSITION=6 VERIFIED_TRANSITION value + * @property {number} VERIFIED_LOW_UNKNOWN=7 VERIFIED_LOW_UNKNOWN value + * @property {number} VERIFIED_HIGH=8 VERIFIED_HIGH value + * @property {number} VERIFIED_INITIAL_UNKNOWN=9 VERIFIED_INITIAL_UNKNOWN value + * @property {number} VERIFIED_INITIAL_LOW=10 VERIFIED_INITIAL_LOW value + * @property {number} VERIFIED_INITIAL_HIGH=11 VERIFIED_INITIAL_HIGH value + * @property {number} VERIFIED_TRANSITION_ANY_TO_NONE=12 VERIFIED_TRANSITION_ANY_TO_NONE value + * @property {number} VERIFIED_TRANSITION_ANY_TO_HIGH=13 VERIFIED_TRANSITION_ANY_TO_HIGH value + * @property {number} VERIFIED_TRANSITION_HIGH_TO_LOW=14 VERIFIED_TRANSITION_HIGH_TO_LOW value + * @property {number} VERIFIED_TRANSITION_HIGH_TO_UNKNOWN=15 VERIFIED_TRANSITION_HIGH_TO_UNKNOWN value + * @property {number} VERIFIED_TRANSITION_UNKNOWN_TO_LOW=16 VERIFIED_TRANSITION_UNKNOWN_TO_LOW value + * @property {number} VERIFIED_TRANSITION_LOW_TO_UNKNOWN=17 VERIFIED_TRANSITION_LOW_TO_UNKNOWN value + * @property {number} VERIFIED_TRANSITION_NONE_TO_LOW=18 VERIFIED_TRANSITION_NONE_TO_LOW value + * @property {number} VERIFIED_TRANSITION_NONE_TO_UNKNOWN=19 VERIFIED_TRANSITION_NONE_TO_UNKNOWN value + * @property {number} GROUP_CREATE=20 GROUP_CREATE value + * @property {number} GROUP_CHANGE_SUBJECT=21 GROUP_CHANGE_SUBJECT value + * @property {number} GROUP_CHANGE_ICON=22 GROUP_CHANGE_ICON value + * @property {number} GROUP_CHANGE_INVITE_LINK=23 GROUP_CHANGE_INVITE_LINK value + * @property {number} GROUP_CHANGE_DESCRIPTION=24 GROUP_CHANGE_DESCRIPTION value + * @property {number} GROUP_CHANGE_RESTRICT=25 GROUP_CHANGE_RESTRICT value + * @property {number} GROUP_CHANGE_ANNOUNCE=26 GROUP_CHANGE_ANNOUNCE value + * @property {number} GROUP_PARTICIPANT_ADD=27 GROUP_PARTICIPANT_ADD value + * @property {number} GROUP_PARTICIPANT_REMOVE=28 GROUP_PARTICIPANT_REMOVE value + * @property {number} GROUP_PARTICIPANT_PROMOTE=29 GROUP_PARTICIPANT_PROMOTE value + * @property {number} GROUP_PARTICIPANT_DEMOTE=30 GROUP_PARTICIPANT_DEMOTE value + * @property {number} GROUP_PARTICIPANT_INVITE=31 GROUP_PARTICIPANT_INVITE value + * @property {number} GROUP_PARTICIPANT_LEAVE=32 GROUP_PARTICIPANT_LEAVE value + * @property {number} GROUP_PARTICIPANT_CHANGE_NUMBER=33 GROUP_PARTICIPANT_CHANGE_NUMBER value + * @property {number} BROADCAST_CREATE=34 BROADCAST_CREATE value + * @property {number} BROADCAST_ADD=35 BROADCAST_ADD value + * @property {number} BROADCAST_REMOVE=36 BROADCAST_REMOVE value + * @property {number} GENERIC_NOTIFICATION=37 GENERIC_NOTIFICATION value + * @property {number} E2E_IDENTITY_CHANGED=38 E2E_IDENTITY_CHANGED value + * @property {number} E2E_ENCRYPTED=39 E2E_ENCRYPTED value + * @property {number} CALL_MISSED_VOICE=40 CALL_MISSED_VOICE value + * @property {number} CALL_MISSED_VIDEO=41 CALL_MISSED_VIDEO value + * @property {number} INDIVIDUAL_CHANGE_NUMBER=42 INDIVIDUAL_CHANGE_NUMBER value + * @property {number} GROUP_DELETE=43 GROUP_DELETE value + * @property {number} GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE=44 GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE value + * @property {number} CALL_MISSED_GROUP_VOICE=45 CALL_MISSED_GROUP_VOICE value + * @property {number} CALL_MISSED_GROUP_VIDEO=46 CALL_MISSED_GROUP_VIDEO value + * @property {number} PAYMENT_CIPHERTEXT=47 PAYMENT_CIPHERTEXT value + * @property {number} PAYMENT_FUTUREPROOF=48 PAYMENT_FUTUREPROOF value + * @property {number} PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED=49 PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED value + * @property {number} PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED=50 PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED value + * @property {number} PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED=51 PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED value + * @property {number} PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP=52 PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP value + * @property {number} PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP=53 PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP value + * @property {number} PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER=54 PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER value + * @property {number} PAYMENT_ACTION_SEND_PAYMENT_REMINDER=55 PAYMENT_ACTION_SEND_PAYMENT_REMINDER value + * @property {number} PAYMENT_ACTION_SEND_PAYMENT_INVITATION=56 PAYMENT_ACTION_SEND_PAYMENT_INVITATION value + * @property {number} PAYMENT_ACTION_REQUEST_DECLINED=57 PAYMENT_ACTION_REQUEST_DECLINED value + * @property {number} PAYMENT_ACTION_REQUEST_EXPIRED=58 PAYMENT_ACTION_REQUEST_EXPIRED value + * @property {number} PAYMENT_ACTION_REQUEST_CANCELLED=59 PAYMENT_ACTION_REQUEST_CANCELLED value + * @property {number} BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM=60 BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM value + * @property {number} BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP=61 BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP value + * @property {number} BIZ_INTRO_TOP=62 BIZ_INTRO_TOP value + * @property {number} BIZ_INTRO_BOTTOM=63 BIZ_INTRO_BOTTOM value + * @property {number} BIZ_NAME_CHANGE=64 BIZ_NAME_CHANGE value + * @property {number} BIZ_MOVE_TO_CONSUMER_APP=65 BIZ_MOVE_TO_CONSUMER_APP value + * @property {number} BIZ_TWO_TIER_MIGRATION_TOP=66 BIZ_TWO_TIER_MIGRATION_TOP value + * @property {number} BIZ_TWO_TIER_MIGRATION_BOTTOM=67 BIZ_TWO_TIER_MIGRATION_BOTTOM value + * @property {number} OVERSIZED=68 OVERSIZED value + * @property {number} GROUP_CHANGE_NO_FREQUENTLY_FORWARDED=69 GROUP_CHANGE_NO_FREQUENTLY_FORWARDED value + * @property {number} GROUP_V4_ADD_INVITE_SENT=70 GROUP_V4_ADD_INVITE_SENT value + * @property {number} GROUP_PARTICIPANT_ADD_REQUEST_JOIN=71 GROUP_PARTICIPANT_ADD_REQUEST_JOIN value + * @property {number} CHANGE_EPHEMERAL_SETTING=72 CHANGE_EPHEMERAL_SETTING value + * @property {number} E2E_DEVICE_CHANGED=73 E2E_DEVICE_CHANGED value + * @property {number} VIEWED_ONCE=74 VIEWED_ONCE value + * @property {number} E2E_ENCRYPTED_NOW=75 E2E_ENCRYPTED_NOW value + * @property {number} BLUE_MSG_BSP_FB_TO_BSP_PREMISE=76 BLUE_MSG_BSP_FB_TO_BSP_PREMISE value + * @property {number} BLUE_MSG_BSP_FB_TO_SELF_FB=77 BLUE_MSG_BSP_FB_TO_SELF_FB value + * @property {number} BLUE_MSG_BSP_FB_TO_SELF_PREMISE=78 BLUE_MSG_BSP_FB_TO_SELF_PREMISE value + * @property {number} BLUE_MSG_BSP_FB_UNVERIFIED=79 BLUE_MSG_BSP_FB_UNVERIFIED value + * @property {number} BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED=80 BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED value + * @property {number} BLUE_MSG_BSP_FB_VERIFIED=81 BLUE_MSG_BSP_FB_VERIFIED value + * @property {number} BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED=82 BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED value + * @property {number} BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE=83 BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE value + * @property {number} BLUE_MSG_BSP_PREMISE_UNVERIFIED=84 BLUE_MSG_BSP_PREMISE_UNVERIFIED value + * @property {number} BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED=85 BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED value + * @property {number} BLUE_MSG_BSP_PREMISE_VERIFIED=86 BLUE_MSG_BSP_PREMISE_VERIFIED value + * @property {number} BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED=87 BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED value + * @property {number} BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED=88 BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED value + * @property {number} BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED=89 BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED value + * @property {number} BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED=90 BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED value + * @property {number} BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED=91 BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED value + * @property {number} BLUE_MSG_SELF_FB_TO_BSP_PREMISE=92 BLUE_MSG_SELF_FB_TO_BSP_PREMISE value + * @property {number} BLUE_MSG_SELF_FB_TO_SELF_PREMISE=93 BLUE_MSG_SELF_FB_TO_SELF_PREMISE value + * @property {number} BLUE_MSG_SELF_FB_UNVERIFIED=94 BLUE_MSG_SELF_FB_UNVERIFIED value + * @property {number} BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED=95 BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED value + * @property {number} BLUE_MSG_SELF_FB_VERIFIED=96 BLUE_MSG_SELF_FB_VERIFIED value + * @property {number} BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED=97 BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED value + * @property {number} BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE=98 BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE value + * @property {number} BLUE_MSG_SELF_PREMISE_UNVERIFIED=99 BLUE_MSG_SELF_PREMISE_UNVERIFIED value + * @property {number} BLUE_MSG_SELF_PREMISE_VERIFIED=100 BLUE_MSG_SELF_PREMISE_VERIFIED value + * @property {number} BLUE_MSG_TO_BSP_FB=101 BLUE_MSG_TO_BSP_FB value + * @property {number} BLUE_MSG_TO_CONSUMER=102 BLUE_MSG_TO_CONSUMER value + * @property {number} BLUE_MSG_TO_SELF_FB=103 BLUE_MSG_TO_SELF_FB value + * @property {number} BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED=104 BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED value + * @property {number} BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED=105 BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED value + * @property {number} BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED=106 BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED value + * @property {number} BLUE_MSG_UNVERIFIED_TO_VERIFIED=107 BLUE_MSG_UNVERIFIED_TO_VERIFIED value + * @property {number} BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED=108 BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED value + * @property {number} BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED=109 BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED value + * @property {number} BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED=110 BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED value + * @property {number} BLUE_MSG_VERIFIED_TO_UNVERIFIED=111 BLUE_MSG_VERIFIED_TO_UNVERIFIED value + * @property {number} BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED=112 BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED value + * @property {number} BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED=113 BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED value + * @property {number} BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED=114 BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED value + * @property {number} BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED=115 BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED value + * @property {number} BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED=116 BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED value + * @property {number} BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED=117 BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED value + * @property {number} E2E_IDENTITY_UNAVAILABLE=118 E2E_IDENTITY_UNAVAILABLE value + * @property {number} GROUP_CREATING=119 GROUP_CREATING value + * @property {number} GROUP_CREATE_FAILED=120 GROUP_CREATE_FAILED value + * @property {number} GROUP_BOUNCED=121 GROUP_BOUNCED value + * @property {number} BLOCK_CONTACT=122 BLOCK_CONTACT value + * @property {number} EPHEMERAL_SETTING_NOT_APPLIED=123 EPHEMERAL_SETTING_NOT_APPLIED value + * @property {number} SYNC_FAILED=124 SYNC_FAILED value + * @property {number} SYNCING=125 SYNCING value + * @property {number} BIZ_PRIVACY_MODE_INIT_FB=126 BIZ_PRIVACY_MODE_INIT_FB value + * @property {number} BIZ_PRIVACY_MODE_INIT_BSP=127 BIZ_PRIVACY_MODE_INIT_BSP value + * @property {number} BIZ_PRIVACY_MODE_TO_FB=128 BIZ_PRIVACY_MODE_TO_FB value + * @property {number} BIZ_PRIVACY_MODE_TO_BSP=129 BIZ_PRIVACY_MODE_TO_BSP value + */ + WebMessageInfo.WebMessageInfoStubType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN"] = 0; + values[valuesById[1] = "REVOKE"] = 1; + values[valuesById[2] = "CIPHERTEXT"] = 2; + values[valuesById[3] = "FUTUREPROOF"] = 3; + values[valuesById[4] = "NON_VERIFIED_TRANSITION"] = 4; + values[valuesById[5] = "UNVERIFIED_TRANSITION"] = 5; + values[valuesById[6] = "VERIFIED_TRANSITION"] = 6; + values[valuesById[7] = "VERIFIED_LOW_UNKNOWN"] = 7; + values[valuesById[8] = "VERIFIED_HIGH"] = 8; + values[valuesById[9] = "VERIFIED_INITIAL_UNKNOWN"] = 9; + values[valuesById[10] = "VERIFIED_INITIAL_LOW"] = 10; + values[valuesById[11] = "VERIFIED_INITIAL_HIGH"] = 11; + values[valuesById[12] = "VERIFIED_TRANSITION_ANY_TO_NONE"] = 12; + values[valuesById[13] = "VERIFIED_TRANSITION_ANY_TO_HIGH"] = 13; + values[valuesById[14] = "VERIFIED_TRANSITION_HIGH_TO_LOW"] = 14; + values[valuesById[15] = "VERIFIED_TRANSITION_HIGH_TO_UNKNOWN"] = 15; + values[valuesById[16] = "VERIFIED_TRANSITION_UNKNOWN_TO_LOW"] = 16; + values[valuesById[17] = "VERIFIED_TRANSITION_LOW_TO_UNKNOWN"] = 17; + values[valuesById[18] = "VERIFIED_TRANSITION_NONE_TO_LOW"] = 18; + values[valuesById[19] = "VERIFIED_TRANSITION_NONE_TO_UNKNOWN"] = 19; + values[valuesById[20] = "GROUP_CREATE"] = 20; + values[valuesById[21] = "GROUP_CHANGE_SUBJECT"] = 21; + values[valuesById[22] = "GROUP_CHANGE_ICON"] = 22; + values[valuesById[23] = "GROUP_CHANGE_INVITE_LINK"] = 23; + values[valuesById[24] = "GROUP_CHANGE_DESCRIPTION"] = 24; + values[valuesById[25] = "GROUP_CHANGE_RESTRICT"] = 25; + values[valuesById[26] = "GROUP_CHANGE_ANNOUNCE"] = 26; + values[valuesById[27] = "GROUP_PARTICIPANT_ADD"] = 27; + values[valuesById[28] = "GROUP_PARTICIPANT_REMOVE"] = 28; + values[valuesById[29] = "GROUP_PARTICIPANT_PROMOTE"] = 29; + values[valuesById[30] = "GROUP_PARTICIPANT_DEMOTE"] = 30; + values[valuesById[31] = "GROUP_PARTICIPANT_INVITE"] = 31; + values[valuesById[32] = "GROUP_PARTICIPANT_LEAVE"] = 32; + values[valuesById[33] = "GROUP_PARTICIPANT_CHANGE_NUMBER"] = 33; + values[valuesById[34] = "BROADCAST_CREATE"] = 34; + values[valuesById[35] = "BROADCAST_ADD"] = 35; + values[valuesById[36] = "BROADCAST_REMOVE"] = 36; + values[valuesById[37] = "GENERIC_NOTIFICATION"] = 37; + values[valuesById[38] = "E2E_IDENTITY_CHANGED"] = 38; + values[valuesById[39] = "E2E_ENCRYPTED"] = 39; + values[valuesById[40] = "CALL_MISSED_VOICE"] = 40; + values[valuesById[41] = "CALL_MISSED_VIDEO"] = 41; + values[valuesById[42] = "INDIVIDUAL_CHANGE_NUMBER"] = 42; + values[valuesById[43] = "GROUP_DELETE"] = 43; + values[valuesById[44] = "GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE"] = 44; + values[valuesById[45] = "CALL_MISSED_GROUP_VOICE"] = 45; + values[valuesById[46] = "CALL_MISSED_GROUP_VIDEO"] = 46; + values[valuesById[47] = "PAYMENT_CIPHERTEXT"] = 47; + values[valuesById[48] = "PAYMENT_FUTUREPROOF"] = 48; + values[valuesById[49] = "PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED"] = 49; + values[valuesById[50] = "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED"] = 50; + values[valuesById[51] = "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED"] = 51; + values[valuesById[52] = "PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP"] = 52; + values[valuesById[53] = "PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP"] = 53; + values[valuesById[54] = "PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER"] = 54; + values[valuesById[55] = "PAYMENT_ACTION_SEND_PAYMENT_REMINDER"] = 55; + values[valuesById[56] = "PAYMENT_ACTION_SEND_PAYMENT_INVITATION"] = 56; + values[valuesById[57] = "PAYMENT_ACTION_REQUEST_DECLINED"] = 57; + values[valuesById[58] = "PAYMENT_ACTION_REQUEST_EXPIRED"] = 58; + values[valuesById[59] = "PAYMENT_ACTION_REQUEST_CANCELLED"] = 59; + values[valuesById[60] = "BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM"] = 60; + values[valuesById[61] = "BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP"] = 61; + values[valuesById[62] = "BIZ_INTRO_TOP"] = 62; + values[valuesById[63] = "BIZ_INTRO_BOTTOM"] = 63; + values[valuesById[64] = "BIZ_NAME_CHANGE"] = 64; + values[valuesById[65] = "BIZ_MOVE_TO_CONSUMER_APP"] = 65; + values[valuesById[66] = "BIZ_TWO_TIER_MIGRATION_TOP"] = 66; + values[valuesById[67] = "BIZ_TWO_TIER_MIGRATION_BOTTOM"] = 67; + values[valuesById[68] = "OVERSIZED"] = 68; + values[valuesById[69] = "GROUP_CHANGE_NO_FREQUENTLY_FORWARDED"] = 69; + values[valuesById[70] = "GROUP_V4_ADD_INVITE_SENT"] = 70; + values[valuesById[71] = "GROUP_PARTICIPANT_ADD_REQUEST_JOIN"] = 71; + values[valuesById[72] = "CHANGE_EPHEMERAL_SETTING"] = 72; + values[valuesById[73] = "E2E_DEVICE_CHANGED"] = 73; + values[valuesById[74] = "VIEWED_ONCE"] = 74; + values[valuesById[75] = "E2E_ENCRYPTED_NOW"] = 75; + values[valuesById[76] = "BLUE_MSG_BSP_FB_TO_BSP_PREMISE"] = 76; + values[valuesById[77] = "BLUE_MSG_BSP_FB_TO_SELF_FB"] = 77; + values[valuesById[78] = "BLUE_MSG_BSP_FB_TO_SELF_PREMISE"] = 78; + values[valuesById[79] = "BLUE_MSG_BSP_FB_UNVERIFIED"] = 79; + values[valuesById[80] = "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED"] = 80; + values[valuesById[81] = "BLUE_MSG_BSP_FB_VERIFIED"] = 81; + values[valuesById[82] = "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED"] = 82; + values[valuesById[83] = "BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE"] = 83; + values[valuesById[84] = "BLUE_MSG_BSP_PREMISE_UNVERIFIED"] = 84; + values[valuesById[85] = "BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED"] = 85; + values[valuesById[86] = "BLUE_MSG_BSP_PREMISE_VERIFIED"] = 86; + values[valuesById[87] = "BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED"] = 87; + values[valuesById[88] = "BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED"] = 88; + values[valuesById[89] = "BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED"] = 89; + values[valuesById[90] = "BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED"] = 90; + values[valuesById[91] = "BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED"] = 91; + values[valuesById[92] = "BLUE_MSG_SELF_FB_TO_BSP_PREMISE"] = 92; + values[valuesById[93] = "BLUE_MSG_SELF_FB_TO_SELF_PREMISE"] = 93; + values[valuesById[94] = "BLUE_MSG_SELF_FB_UNVERIFIED"] = 94; + values[valuesById[95] = "BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED"] = 95; + values[valuesById[96] = "BLUE_MSG_SELF_FB_VERIFIED"] = 96; + values[valuesById[97] = "BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED"] = 97; + values[valuesById[98] = "BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE"] = 98; + values[valuesById[99] = "BLUE_MSG_SELF_PREMISE_UNVERIFIED"] = 99; + values[valuesById[100] = "BLUE_MSG_SELF_PREMISE_VERIFIED"] = 100; + values[valuesById[101] = "BLUE_MSG_TO_BSP_FB"] = 101; + values[valuesById[102] = "BLUE_MSG_TO_CONSUMER"] = 102; + values[valuesById[103] = "BLUE_MSG_TO_SELF_FB"] = 103; + values[valuesById[104] = "BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED"] = 104; + values[valuesById[105] = "BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED"] = 105; + values[valuesById[106] = "BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED"] = 106; + values[valuesById[107] = "BLUE_MSG_UNVERIFIED_TO_VERIFIED"] = 107; + values[valuesById[108] = "BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED"] = 108; + values[valuesById[109] = "BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED"] = 109; + values[valuesById[110] = "BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED"] = 110; + values[valuesById[111] = "BLUE_MSG_VERIFIED_TO_UNVERIFIED"] = 111; + values[valuesById[112] = "BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED"] = 112; + values[valuesById[113] = "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED"] = 113; + values[valuesById[114] = "BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED"] = 114; + values[valuesById[115] = "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED"] = 115; + values[valuesById[116] = "BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED"] = 116; + values[valuesById[117] = "BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED"] = 117; + values[valuesById[118] = "E2E_IDENTITY_UNAVAILABLE"] = 118; + values[valuesById[119] = "GROUP_CREATING"] = 119; + values[valuesById[120] = "GROUP_CREATE_FAILED"] = 120; + values[valuesById[121] = "GROUP_BOUNCED"] = 121; + values[valuesById[122] = "BLOCK_CONTACT"] = 122; + values[valuesById[123] = "EPHEMERAL_SETTING_NOT_APPLIED"] = 123; + values[valuesById[124] = "SYNC_FAILED"] = 124; + values[valuesById[125] = "SYNCING"] = 125; + values[valuesById[126] = "BIZ_PRIVACY_MODE_INIT_FB"] = 126; + values[valuesById[127] = "BIZ_PRIVACY_MODE_INIT_BSP"] = 127; + values[valuesById[128] = "BIZ_PRIVACY_MODE_TO_FB"] = 128; + values[valuesById[129] = "BIZ_PRIVACY_MODE_TO_BSP"] = 129; + return values; + })(); + + /** + * WebMessageInfoBizPrivacyStatus enum. + * @name proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus + * @enum {number} + * @property {number} E2EE=0 E2EE value + * @property {number} FB=2 FB value + * @property {number} BSP=1 BSP value + * @property {number} BSP_AND_FB=3 BSP_AND_FB value + */ + WebMessageInfo.WebMessageInfoBizPrivacyStatus = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "E2EE"] = 0; + values[valuesById[2] = "FB"] = 2; + values[valuesById[1] = "BSP"] = 1; + values[valuesById[3] = "BSP_AND_FB"] = 3; + return values; + })(); + + return WebMessageInfo; + })(); + return proto; })(); -module.exports = $root; +module.exports = $root; \ No newline at end of file diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index 3c00471..09112d7 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -1,10 +1,11 @@ import BinaryNode from "../BinaryNode"; import { Boom } from '@hapi/boom' import { EventEmitter } from 'events' -import { Chat, Presence, WAMessageCursor, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo } from "../Types"; +import { Chat, Presence, WAMessageCursor, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo, MessageInfoUpdate } from "../Types"; import { isGroupID, toNumber, whatsappID, generateWAMessage, decryptMediaMessageBuffer } from "../Utils"; import makeChatsSocket from "./chats"; import { WA_DEFAULT_EPHEMERAL } from "../Defaults"; +import { Attributes } from "../BinaryNode/types"; const STATUS_MAP = { read: WAMessageStatus.READ, @@ -308,9 +309,42 @@ const makeMessagesSocket = (config: SocketConfig) => { } } } + const onMessageInfoUpdate = ([,attributes]: [string,{[_: string]: any}]) => { + let ids = attributes.id as string[] | string + if(typeof ids === 'string') { + ids = [ids] + } + let updateKey: keyof MessageInfoUpdate['update'] + switch(attributes.ack.toString()) { + case '2': + updateKey = 'deliveries' + break + case '3': + updateKey = 'reads' + break + default: + logger.warn({ attributes }, `received unknown message info update`) + return + } + const updates = ids.map(id => ({ + key: { + remoteJid: whatsappID(attributes.to), + id, + fromMe: whatsappID(attributes.from) === getState().user?.jid, + }, + update: { + [updateKey]: { [whatsappID(attributes.participant)]: new Date(+attributes.t) } + } + })) + ev.emit('message-info.update', updates) + } + socketEvents.on('CB:action,add:relay,received', onMessageStatusUpdate) socketEvents.on('CB:action,,received', onMessageStatusUpdate) + socketEvents.on('CB:Msg', onMessageInfoUpdate) + socketEvents.on('CB:MsgInfo', onMessageInfoUpdate) + return { ...sock, relayWAMessage, @@ -325,15 +359,18 @@ const makeMessagesSocket = (config: SocketConfig) => { expect200: true, requiresPhoneConnection: true }) - const info: MessageInfo = {reads: [], deliveries: []} + const info: MessageInfo = { reads: {}, deliveries: {} } if(Array.isArray(data)) { - for(const { header, attributes } of data) { + for(const { header, data: innerData } of data) { + const [{ attributes }] = (innerData as BinaryNode[]) + const jid = whatsappID(attributes.jid) + const date = new Date(+attributes.t * 1000) switch(header) { case 'read': - info.reads.push(attributes as any) + info.reads[jid] = date break case 'delivery': - info.deliveries.push(attributes as any) + info.deliveries[jid] = date break } } diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index 8fe94fd..9aea81e 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -2,7 +2,7 @@ import type KeyedDB from "@adiwajshing/keyed-db" import type { Comparable } from "@adiwajshing/keyed-db/lib/Types" import type { Logger } from "pino" import type { Connection } from "../Connection" -import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, WAMessage, WAMessageCursor } from "../Types" +import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, MessageInfo, WAMessage, WAMessageCursor, WAMessageKey } from "../Types" import { toNumber } from "../Utils" import makeOrderedDictionary from "./ordered-dictionary" @@ -28,6 +28,7 @@ export default( const messages: { [_: string]: ReturnType } = {} const contacts: { [_: string]: Contact } = {} const groupMetadata: { [_: string]: GroupMetadata } = {} + const messageInfos: { [id: string]: MessageInfo } = { } const state: ConnectionState = { connection: 'close', phoneConnected: false @@ -101,10 +102,14 @@ export default( const list = assertMessageList(jid) list.upsert(msg, 'append') - if(type === 'notify' && !chats.get(jid)) { - ev.emit('chats.upsert', [ - { jid, t: toNumber(msg.messageTimestamp), count: 1 } - ]) + if(type === 'notify') { + if(!chats.get(jid)) { + ev.emit('chats.upsert', [ + { jid, t: toNumber(msg.messageTimestamp), count: 1 } + ]) + } + // add message infos if required + messageInfos[msg.key.id!] = messageInfos[msg.key.id!] || { reads: {}, deliveries: {} } } } break @@ -181,13 +186,27 @@ export default( } } }) + + ev.on('message-info.update', updates => { + for(const { key, update } of updates) { + const obj = messageInfos[key.id!] + if(obj) { + // add reads/deliveries + for(const key in update) { + Object.assign(obj[key], update[key]) + } + } + } + }) } + return { chats, contacts, messages, groupMetadata, + messageInfos, state, listen, loadMessages: async(jid: string, count: number, cursor: WAMessageCursor, sock: Connection | undefined) => { @@ -261,6 +280,12 @@ export default( groupMetadata[jid] = await sock?.getBroadcastListInfo(jid) } return groupMetadata[jid] + }, + fetchMessageInfo: async({remoteJid, id}: WAMessageKey, sock: Connection | undefined) => { + if(!messageInfos[id!]) { + messageInfos[id!] = await sock?.messageInfo(remoteJid, id) + } + return messageInfos[id!] } } } \ No newline at end of file diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 43905f6..01df8a3 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -129,24 +129,14 @@ export type MessageGenerationOptions = MessageContentGenerationOptions & Message export type MessageUpdateType = 'prepend' | 'append' | 'notify' | 'last' +export type MessageInfoEventMap = { [jid: string]: Date } export interface MessageInfo { - reads: {jid: string, t: string}[] - deliveries: {jid: string, t: string}[] -} - - -export interface MessageStatusUpdate { - from: string - to: string - /** Which participant caused the update (only for groups) */ - participant?: string - timestamp: Date - /** Message IDs read/delivered */ - ids: string[] - /** Status of the Message IDs */ - type: WAMessageStatus + reads: MessageInfoEventMap + deliveries: MessageInfoEventMap } export type WAMessageUpdate = { update: Partial, key: proto.IMessageKey } -export type WAMessageCursor = { before: WAMessageKey | undefined } | { after: WAMessageKey | undefined } \ No newline at end of file +export type WAMessageCursor = { before: WAMessageKey | undefined } | { after: WAMessageKey | undefined } + +export type MessageInfoUpdate = { key: proto.IMessageKey, update: Partial } \ No newline at end of file diff --git a/src/Types/index.ts b/src/Types/index.ts index ab1f493..d074864 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -16,7 +16,8 @@ import { Contact } from './Contact' import { ConnectionState } from './Store' import { GroupMetadata, ParticipantAction } from './GroupMetadata' -import { MessageUpdateType, WAMessage, WAMessageKey, WAMessageUpdate } from './Message' +import { MessageInfo, MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageKey, WAMessageUpdate } from './Message' +import { proto } from '../../WAMessage/WAMessage' /** used for binary messages */ export enum WAMetric { @@ -183,6 +184,8 @@ export type BaileysEventMap = { 'messages.update': WAMessageUpdate[] 'messages.upsert': { messages: WAMessage[], type: MessageUpdateType } + 'message-info.update': MessageInfoUpdate[] + 'groups.update': Partial[] 'group-participants.update': { jid: string, participants: string[], action: ParticipantAction } From b5ee036ae9b5ff999241bc6e292d91cc9a1e502a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 29 Jul 2021 20:33:19 +0530 Subject: [PATCH 015/311] update proto --- WAMessage/{WAMessage.d.ts => index.d.ts} | 9597 ++------ WAMessage/{WAMessage.js => index.js} | 24505 ++++----------------- package.json | 2 +- src/BinaryNode/GenerateStatics.sh | 4 +- src/BinaryNode/WAMessage.proto | 1585 +- src/BinaryNode/decode.ts | 2 +- src/BinaryNode/encode.ts | 2 +- src/BinaryNode/types.ts | 2 +- src/Connection/messages.ts | 4 +- src/Tests/Tests.Media.ts | 2 +- src/Types/Message.ts | 2 +- src/Types/index.ts | 2 +- src/index.ts | 2 +- 13 files changed, 6164 insertions(+), 29547 deletions(-) rename WAMessage/{WAMessage.d.ts => index.d.ts} (61%) rename WAMessage/{WAMessage.js => index.js} (65%) diff --git a/WAMessage/WAMessage.d.ts b/WAMessage/index.d.ts similarity index 61% rename from WAMessage/WAMessage.d.ts rename to WAMessage/index.d.ts index 51d9d1b..5412364 100644 --- a/WAMessage/WAMessage.d.ts +++ b/WAMessage/index.d.ts @@ -2,7577 +2,109 @@ import * as $protobuf from "protobufjs"; /** Namespace proto. */ export namespace proto { - /** Properties of an AppVersion. */ - interface IAppVersion { + /** Properties of a MessageKey. */ + interface IMessageKey { - /** AppVersion primary */ - primary?: (number|null); + /** MessageKey remoteJid */ + remoteJid?: (string|null); - /** AppVersion secondary */ - secondary?: (number|null); + /** MessageKey fromMe */ + fromMe?: (boolean|null); - /** AppVersion tertiary */ - tertiary?: (number|null); + /** MessageKey id */ + id?: (string|null); - /** AppVersion quaternary */ - quaternary?: (number|null); - - /** AppVersion quinary */ - quinary?: (number|null); - } - - /** Represents an AppVersion. */ - class AppVersion implements IAppVersion { - - /** - * Constructs a new AppVersion. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IAppVersion); - - /** AppVersion primary. */ - public primary: number; - - /** AppVersion secondary. */ - public secondary: number; - - /** AppVersion tertiary. */ - public tertiary: number; - - /** AppVersion quaternary. */ - public quaternary: number; - - /** AppVersion quinary. */ - public quinary: number; - - /** - * Creates a new AppVersion instance using the specified properties. - * @param [properties] Properties to set - * @returns AppVersion instance - */ - public static create(properties?: proto.IAppVersion): proto.AppVersion; - - /** - * Encodes the specified AppVersion message. Does not implicitly {@link proto.AppVersion.verify|verify} messages. - * @param message AppVersion message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IAppVersion, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified AppVersion message, length delimited. Does not implicitly {@link proto.AppVersion.verify|verify} messages. - * @param message AppVersion message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IAppVersion, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes an AppVersion message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns AppVersion - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.AppVersion; - - /** - * Decodes an AppVersion message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns AppVersion - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.AppVersion; - - /** - * Verifies an AppVersion message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates an AppVersion message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns AppVersion - */ - public static fromObject(object: { [k: string]: any }): proto.AppVersion; - - /** - * Creates a plain object from an AppVersion message. Also converts values to other types if specified. - * @param message AppVersion - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.AppVersion, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this AppVersion to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a UserAgent. */ - interface IUserAgent { - - /** UserAgent platform */ - platform?: (proto.UserAgent.UserAgentPlatform|null); - - /** UserAgent appVersion */ - appVersion?: (proto.IAppVersion|null); - - /** UserAgent mcc */ - mcc?: (string|null); - - /** UserAgent mnc */ - mnc?: (string|null); - - /** UserAgent osVersion */ - osVersion?: (string|null); - - /** UserAgent manufacturer */ - manufacturer?: (string|null); - - /** UserAgent device */ - device?: (string|null); - - /** UserAgent osBuildNumber */ - osBuildNumber?: (string|null); - - /** UserAgent phoneId */ - phoneId?: (string|null); - - /** UserAgent releaseChannel */ - releaseChannel?: (proto.UserAgent.UserAgentReleaseChannel|null); - - /** UserAgent localeLanguageIso6391 */ - localeLanguageIso6391?: (string|null); - - /** UserAgent localeCountryIso31661Alpha2 */ - localeCountryIso31661Alpha2?: (string|null); - - /** UserAgent deviceBoard */ - deviceBoard?: (string|null); - } - - /** Represents a UserAgent. */ - class UserAgent implements IUserAgent { - - /** - * Constructs a new UserAgent. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IUserAgent); - - /** UserAgent platform. */ - public platform: proto.UserAgent.UserAgentPlatform; - - /** UserAgent appVersion. */ - public appVersion?: (proto.IAppVersion|null); - - /** UserAgent mcc. */ - public mcc: string; - - /** UserAgent mnc. */ - public mnc: string; - - /** UserAgent osVersion. */ - public osVersion: string; - - /** UserAgent manufacturer. */ - public manufacturer: string; - - /** UserAgent device. */ - public device: string; - - /** UserAgent osBuildNumber. */ - public osBuildNumber: string; - - /** UserAgent phoneId. */ - public phoneId: string; - - /** UserAgent releaseChannel. */ - public releaseChannel: proto.UserAgent.UserAgentReleaseChannel; - - /** UserAgent localeLanguageIso6391. */ - public localeLanguageIso6391: string; - - /** UserAgent localeCountryIso31661Alpha2. */ - public localeCountryIso31661Alpha2: string; - - /** UserAgent deviceBoard. */ - public deviceBoard: string; - - /** - * Creates a new UserAgent instance using the specified properties. - * @param [properties] Properties to set - * @returns UserAgent instance - */ - public static create(properties?: proto.IUserAgent): proto.UserAgent; - - /** - * Encodes the specified UserAgent message. Does not implicitly {@link proto.UserAgent.verify|verify} messages. - * @param message UserAgent message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IUserAgent, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified UserAgent message, length delimited. Does not implicitly {@link proto.UserAgent.verify|verify} messages. - * @param message UserAgent message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IUserAgent, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a UserAgent message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns UserAgent - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.UserAgent; - - /** - * Decodes a UserAgent message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns UserAgent - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.UserAgent; - - /** - * Verifies a UserAgent message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a UserAgent message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns UserAgent - */ - public static fromObject(object: { [k: string]: any }): proto.UserAgent; - - /** - * Creates a plain object from a UserAgent message. Also converts values to other types if specified. - * @param message UserAgent - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.UserAgent, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this UserAgent to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - namespace UserAgent { - - /** UserAgentPlatform enum. */ - enum UserAgentPlatform { - ANDROID = 0, - IOS = 1, - WINDOWS_PHONE = 2, - BLACKBERRY = 3, - BLACKBERRYX = 4, - S40 = 5, - S60 = 6, - PYTHON_CLIENT = 7, - TIZEN = 8, - ENTERPRISE = 9, - SMB_ANDROID = 10, - KAIOS = 11, - SMB_IOS = 12, - WINDOWS = 13, - WEB = 14, - PORTAL = 15, - GREEN_ANDROID = 16, - GREEN_IPHONE = 17, - BLUE_ANDROID = 18, - BLUE_IPHONE = 19, - FBLITE_ANDROID = 20, - MLITE_ANDROID = 21, - IGLITE_ANDROID = 22, - PAGE = 23, - MACOS = 24, - VR = 25 - } - - /** UserAgentReleaseChannel enum. */ - enum UserAgentReleaseChannel { - RELEASE = 0, - BETA = 1, - ALPHA = 2, - DEBUG = 3 - } - } - - /** Properties of a WebdPayload. */ - interface IWebdPayload { - - /** WebdPayload usesParticipantInKey */ - usesParticipantInKey?: (boolean|null); - - /** WebdPayload supportsStarredMessages */ - supportsStarredMessages?: (boolean|null); - - /** WebdPayload supportsDocumentMessages */ - supportsDocumentMessages?: (boolean|null); - - /** WebdPayload supportsUrlMessages */ - supportsUrlMessages?: (boolean|null); - - /** WebdPayload supportsMediaRetry */ - supportsMediaRetry?: (boolean|null); - - /** WebdPayload supportsE2EImage */ - supportsE2EImage?: (boolean|null); - - /** WebdPayload supportsE2EVideo */ - supportsE2EVideo?: (boolean|null); - - /** WebdPayload supportsE2EAudio */ - supportsE2EAudio?: (boolean|null); - - /** WebdPayload supportsE2EDocument */ - supportsE2EDocument?: (boolean|null); - - /** WebdPayload documentTypes */ - documentTypes?: (string|null); - - /** WebdPayload features */ - features?: (Uint8Array|null); - } - - /** Represents a WebdPayload. */ - class WebdPayload implements IWebdPayload { - - /** - * Constructs a new WebdPayload. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IWebdPayload); - - /** WebdPayload usesParticipantInKey. */ - public usesParticipantInKey: boolean; - - /** WebdPayload supportsStarredMessages. */ - public supportsStarredMessages: boolean; - - /** WebdPayload supportsDocumentMessages. */ - public supportsDocumentMessages: boolean; - - /** WebdPayload supportsUrlMessages. */ - public supportsUrlMessages: boolean; - - /** WebdPayload supportsMediaRetry. */ - public supportsMediaRetry: boolean; - - /** WebdPayload supportsE2EImage. */ - public supportsE2EImage: boolean; - - /** WebdPayload supportsE2EVideo. */ - public supportsE2EVideo: boolean; - - /** WebdPayload supportsE2EAudio. */ - public supportsE2EAudio: boolean; - - /** WebdPayload supportsE2EDocument. */ - public supportsE2EDocument: boolean; - - /** WebdPayload documentTypes. */ - public documentTypes: string; - - /** WebdPayload features. */ - public features: Uint8Array; - - /** - * Creates a new WebdPayload instance using the specified properties. - * @param [properties] Properties to set - * @returns WebdPayload instance - */ - public static create(properties?: proto.IWebdPayload): proto.WebdPayload; - - /** - * Encodes the specified WebdPayload message. Does not implicitly {@link proto.WebdPayload.verify|verify} messages. - * @param message WebdPayload message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IWebdPayload, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified WebdPayload message, length delimited. Does not implicitly {@link proto.WebdPayload.verify|verify} messages. - * @param message WebdPayload message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IWebdPayload, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a WebdPayload message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns WebdPayload - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WebdPayload; - - /** - * Decodes a WebdPayload message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns WebdPayload - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WebdPayload; - - /** - * Verifies a WebdPayload message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a WebdPayload message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns WebdPayload - */ - public static fromObject(object: { [k: string]: any }): proto.WebdPayload; - - /** - * Creates a plain object from a WebdPayload message. Also converts values to other types if specified. - * @param message WebdPayload - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.WebdPayload, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this WebdPayload to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a WebInfo. */ - interface IWebInfo { - - /** WebInfo refToken */ - refToken?: (string|null); - - /** WebInfo version */ - version?: (string|null); - - /** WebInfo webdPayload */ - webdPayload?: (proto.IWebdPayload|null); - - /** WebInfo webSubPlatform */ - webSubPlatform?: (proto.WebInfo.WebInfoWebSubPlatform|null); - } - - /** Represents a WebInfo. */ - class WebInfo implements IWebInfo { - - /** - * Constructs a new WebInfo. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IWebInfo); - - /** WebInfo refToken. */ - public refToken: string; - - /** WebInfo version. */ - public version: string; - - /** WebInfo webdPayload. */ - public webdPayload?: (proto.IWebdPayload|null); - - /** WebInfo webSubPlatform. */ - public webSubPlatform: proto.WebInfo.WebInfoWebSubPlatform; - - /** - * Creates a new WebInfo instance using the specified properties. - * @param [properties] Properties to set - * @returns WebInfo instance - */ - public static create(properties?: proto.IWebInfo): proto.WebInfo; - - /** - * Encodes the specified WebInfo message. Does not implicitly {@link proto.WebInfo.verify|verify} messages. - * @param message WebInfo message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IWebInfo, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified WebInfo message, length delimited. Does not implicitly {@link proto.WebInfo.verify|verify} messages. - * @param message WebInfo message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IWebInfo, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a WebInfo message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns WebInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WebInfo; - - /** - * Decodes a WebInfo message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns WebInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WebInfo; - - /** - * Verifies a WebInfo message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a WebInfo message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns WebInfo - */ - public static fromObject(object: { [k: string]: any }): proto.WebInfo; - - /** - * Creates a plain object from a WebInfo message. Also converts values to other types if specified. - * @param message WebInfo - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.WebInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this WebInfo to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - namespace WebInfo { - - /** WebInfoWebSubPlatform enum. */ - enum WebInfoWebSubPlatform { - WEB_BROWSER = 0, - APP_STORE = 1, - WIN_STORE = 2, - DARWIN = 3, - WIN32 = 4 - } - } - - /** Properties of a DNSSource. */ - interface IDNSSource { - - /** DNSSource dnsMethod */ - dnsMethod?: (proto.DNSSource.DNSSourceDNSResolutionMethod|null); - - /** DNSSource appCached */ - appCached?: (boolean|null); - } - - /** Represents a DNSSource. */ - class DNSSource implements IDNSSource { - - /** - * Constructs a new DNSSource. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IDNSSource); - - /** DNSSource dnsMethod. */ - public dnsMethod: proto.DNSSource.DNSSourceDNSResolutionMethod; - - /** DNSSource appCached. */ - public appCached: boolean; - - /** - * Creates a new DNSSource instance using the specified properties. - * @param [properties] Properties to set - * @returns DNSSource instance - */ - public static create(properties?: proto.IDNSSource): proto.DNSSource; - - /** - * Encodes the specified DNSSource message. Does not implicitly {@link proto.DNSSource.verify|verify} messages. - * @param message DNSSource message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IDNSSource, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified DNSSource message, length delimited. Does not implicitly {@link proto.DNSSource.verify|verify} messages. - * @param message DNSSource message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IDNSSource, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a DNSSource message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns DNSSource - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DNSSource; - - /** - * Decodes a DNSSource message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns DNSSource - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DNSSource; - - /** - * Verifies a DNSSource message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a DNSSource message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns DNSSource - */ - public static fromObject(object: { [k: string]: any }): proto.DNSSource; - - /** - * Creates a plain object from a DNSSource message. Also converts values to other types if specified. - * @param message DNSSource - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.DNSSource, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this DNSSource to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - namespace DNSSource { - - /** DNSSourceDNSResolutionMethod enum. */ - enum DNSSourceDNSResolutionMethod { - SYSTEM = 0, - GOOGLE = 1, - HARDCODED = 2, - OVERRIDE = 3, - FALLBACK = 4 - } - } - - /** Properties of a CompanionRegData. */ - interface ICompanionRegData { - - /** CompanionRegData eRegid */ - eRegid?: (Uint8Array|null); - - /** CompanionRegData eKeytype */ - eKeytype?: (Uint8Array|null); - - /** CompanionRegData eIdent */ - eIdent?: (Uint8Array|null); - - /** CompanionRegData eSkeyId */ - eSkeyId?: (Uint8Array|null); - - /** CompanionRegData eSkeyVal */ - eSkeyVal?: (Uint8Array|null); - - /** CompanionRegData eSkeySig */ - eSkeySig?: (Uint8Array|null); - - /** CompanionRegData buildHash */ - buildHash?: (Uint8Array|null); - - /** CompanionRegData companionProps */ - companionProps?: (Uint8Array|null); - } - - /** Represents a CompanionRegData. */ - class CompanionRegData implements ICompanionRegData { - - /** - * Constructs a new CompanionRegData. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ICompanionRegData); - - /** CompanionRegData eRegid. */ - public eRegid: Uint8Array; - - /** CompanionRegData eKeytype. */ - public eKeytype: Uint8Array; - - /** CompanionRegData eIdent. */ - public eIdent: Uint8Array; - - /** CompanionRegData eSkeyId. */ - public eSkeyId: Uint8Array; - - /** CompanionRegData eSkeyVal. */ - public eSkeyVal: Uint8Array; - - /** CompanionRegData eSkeySig. */ - public eSkeySig: Uint8Array; - - /** CompanionRegData buildHash. */ - public buildHash: Uint8Array; - - /** CompanionRegData companionProps. */ - public companionProps: Uint8Array; - - /** - * Creates a new CompanionRegData instance using the specified properties. - * @param [properties] Properties to set - * @returns CompanionRegData instance - */ - public static create(properties?: proto.ICompanionRegData): proto.CompanionRegData; - - /** - * Encodes the specified CompanionRegData message. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages. - * @param message CompanionRegData message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ICompanionRegData, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified CompanionRegData message, length delimited. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages. - * @param message CompanionRegData message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ICompanionRegData, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a CompanionRegData message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns CompanionRegData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.CompanionRegData; - - /** - * Decodes a CompanionRegData message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns CompanionRegData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.CompanionRegData; - - /** - * Verifies a CompanionRegData message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a CompanionRegData message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns CompanionRegData - */ - public static fromObject(object: { [k: string]: any }): proto.CompanionRegData; - - /** - * Creates a plain object from a CompanionRegData message. Also converts values to other types if specified. - * @param message CompanionRegData - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.CompanionRegData, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this CompanionRegData to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a ClientPayload. */ - interface IClientPayload { - - /** ClientPayload username */ - username?: (number|Long|null); - - /** ClientPayload passive */ - passive?: (boolean|null); - - /** ClientPayload clientFeatures */ - clientFeatures?: (proto.ClientPayload.ClientPayloadClientFeature[]|null); - - /** ClientPayload userAgent */ - userAgent?: (proto.IUserAgent|null); - - /** ClientPayload webInfo */ - webInfo?: (proto.IWebInfo|null); - - /** ClientPayload pushName */ - pushName?: (string|null); - - /** ClientPayload sessionId */ - sessionId?: (number|null); - - /** ClientPayload shortConnect */ - shortConnect?: (boolean|null); - - /** ClientPayload iosAppExtension */ - iosAppExtension?: (proto.ClientPayload.ClientPayloadIOSAppExtension|null); - - /** ClientPayload connectType */ - connectType?: (proto.ClientPayload.ClientPayloadConnectType|null); - - /** ClientPayload connectReason */ - connectReason?: (proto.ClientPayload.ClientPayloadConnectReason|null); - - /** ClientPayload shards */ - shards?: (number[]|null); - - /** ClientPayload dnsSource */ - dnsSource?: (proto.IDNSSource|null); - - /** ClientPayload connectAttemptCount */ - connectAttemptCount?: (number|null); - - /** ClientPayload agent */ - agent?: (number|null); - - /** ClientPayload device */ - device?: (number|null); - - /** ClientPayload regData */ - regData?: (proto.ICompanionRegData|null); - - /** ClientPayload product */ - product?: (proto.ClientPayload.ClientPayloadProduct|null); - - /** ClientPayload fbCat */ - fbCat?: (Uint8Array|null); - - /** ClientPayload fbUserAgent */ - fbUserAgent?: (Uint8Array|null); - - /** ClientPayload oc */ - oc?: (boolean|null); - } - - /** Represents a ClientPayload. */ - class ClientPayload implements IClientPayload { - - /** - * Constructs a new ClientPayload. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IClientPayload); - - /** ClientPayload username. */ - public username: (number|Long); - - /** ClientPayload passive. */ - public passive: boolean; - - /** ClientPayload clientFeatures. */ - public clientFeatures: proto.ClientPayload.ClientPayloadClientFeature[]; - - /** ClientPayload userAgent. */ - public userAgent?: (proto.IUserAgent|null); - - /** ClientPayload webInfo. */ - public webInfo?: (proto.IWebInfo|null); - - /** ClientPayload pushName. */ - public pushName: string; - - /** ClientPayload sessionId. */ - public sessionId: number; - - /** ClientPayload shortConnect. */ - public shortConnect: boolean; - - /** ClientPayload iosAppExtension. */ - public iosAppExtension: proto.ClientPayload.ClientPayloadIOSAppExtension; - - /** ClientPayload connectType. */ - public connectType: proto.ClientPayload.ClientPayloadConnectType; - - /** ClientPayload connectReason. */ - public connectReason: proto.ClientPayload.ClientPayloadConnectReason; - - /** ClientPayload shards. */ - public shards: number[]; - - /** ClientPayload dnsSource. */ - public dnsSource?: (proto.IDNSSource|null); - - /** ClientPayload connectAttemptCount. */ - public connectAttemptCount: number; - - /** ClientPayload agent. */ - public agent: number; - - /** ClientPayload device. */ - public device: number; - - /** ClientPayload regData. */ - public regData?: (proto.ICompanionRegData|null); - - /** ClientPayload product. */ - public product: proto.ClientPayload.ClientPayloadProduct; - - /** ClientPayload fbCat. */ - public fbCat: Uint8Array; - - /** ClientPayload fbUserAgent. */ - public fbUserAgent: Uint8Array; - - /** ClientPayload oc. */ - public oc: boolean; - - /** - * Creates a new ClientPayload instance using the specified properties. - * @param [properties] Properties to set - * @returns ClientPayload instance - */ - public static create(properties?: proto.IClientPayload): proto.ClientPayload; - - /** - * Encodes the specified ClientPayload message. Does not implicitly {@link proto.ClientPayload.verify|verify} messages. - * @param message ClientPayload message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IClientPayload, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ClientPayload message, length delimited. Does not implicitly {@link proto.ClientPayload.verify|verify} messages. - * @param message ClientPayload message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IClientPayload, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ClientPayload message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ClientPayload - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ClientPayload; - - /** - * Decodes a ClientPayload message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ClientPayload - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ClientPayload; - - /** - * Verifies a ClientPayload message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ClientPayload message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ClientPayload - */ - public static fromObject(object: { [k: string]: any }): proto.ClientPayload; - - /** - * Creates a plain object from a ClientPayload message. Also converts values to other types if specified. - * @param message ClientPayload - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ClientPayload, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ClientPayload to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - namespace ClientPayload { - - /** ClientPayloadClientFeature enum. */ - enum ClientPayloadClientFeature { - NONE = 0 - } - - /** ClientPayloadIOSAppExtension enum. */ - enum ClientPayloadIOSAppExtension { - SHARE_EXTENSION = 0, - SERVICE_EXTENSION = 1, - INTENTS_EXTENSION = 2 - } - - /** ClientPayloadConnectType enum. */ - enum ClientPayloadConnectType { - CELLULAR_UNKNOWN = 0, - WIFI_UNKNOWN = 1, - CELLULAR_EDGE = 100, - CELLULAR_IDEN = 101, - CELLULAR_UMTS = 102, - CELLULAR_EVDO = 103, - CELLULAR_GPRS = 104, - CELLULAR_HSDPA = 105, - CELLULAR_HSUPA = 106, - CELLULAR_HSPA = 107, - CELLULAR_CDMA = 108, - CELLULAR_1XRTT = 109, - CELLULAR_EHRPD = 110, - CELLULAR_LTE = 111, - CELLULAR_HSPAP = 112 - } - - /** ClientPayloadConnectReason enum. */ - enum ClientPayloadConnectReason { - PUSH = 0, - USER_ACTIVATED = 1, - SCHEDULED = 2, - ERROR_RECONNECT = 3, - NETWORK_SWITCH = 4, - PING_RECONNECT = 5 - } - - /** ClientPayloadProduct enum. */ - enum ClientPayloadProduct { - WHATSAPP = 0, - MESSENGER = 1 - } - } - - /** Properties of a NoiseCertificate. */ - interface INoiseCertificate { - - /** NoiseCertificate details */ - details?: (Uint8Array|null); - - /** NoiseCertificate signature */ - signature?: (Uint8Array|null); - } - - /** Represents a NoiseCertificate. */ - class NoiseCertificate implements INoiseCertificate { - - /** - * Constructs a new NoiseCertificate. - * @param [properties] Properties to set - */ - constructor(properties?: proto.INoiseCertificate); - - /** NoiseCertificate details. */ - public details: Uint8Array; - - /** NoiseCertificate signature. */ - public signature: Uint8Array; - - /** - * Creates a new NoiseCertificate instance using the specified properties. - * @param [properties] Properties to set - * @returns NoiseCertificate instance - */ - public static create(properties?: proto.INoiseCertificate): proto.NoiseCertificate; - - /** - * Encodes the specified NoiseCertificate message. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages. - * @param message NoiseCertificate message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.INoiseCertificate, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified NoiseCertificate message, length delimited. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages. - * @param message NoiseCertificate message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.INoiseCertificate, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a NoiseCertificate message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns NoiseCertificate - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.NoiseCertificate; - - /** - * Decodes a NoiseCertificate message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns NoiseCertificate - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.NoiseCertificate; - - /** - * Verifies a NoiseCertificate message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a NoiseCertificate message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns NoiseCertificate - */ - public static fromObject(object: { [k: string]: any }): proto.NoiseCertificate; - - /** - * Creates a plain object from a NoiseCertificate message. Also converts values to other types if specified. - * @param message NoiseCertificate - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.NoiseCertificate, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this NoiseCertificate to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a ClientHello. */ - interface IClientHello { - - /** ClientHello ephemeral */ - ephemeral?: (Uint8Array|null); - - /** ClientHello static */ - "static"?: (Uint8Array|null); - - /** ClientHello payload */ - payload?: (Uint8Array|null); - } - - /** Represents a ClientHello. */ - class ClientHello implements IClientHello { - - /** - * Constructs a new ClientHello. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IClientHello); - - /** ClientHello ephemeral. */ - public ephemeral: Uint8Array; - - /** ClientHello static. */ - public static: Uint8Array; - - /** ClientHello payload. */ - public payload: Uint8Array; - - /** - * Creates a new ClientHello instance using the specified properties. - * @param [properties] Properties to set - * @returns ClientHello instance - */ - public static create(properties?: proto.IClientHello): proto.ClientHello; - - /** - * Encodes the specified ClientHello message. Does not implicitly {@link proto.ClientHello.verify|verify} messages. - * @param message ClientHello message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IClientHello, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ClientHello message, length delimited. Does not implicitly {@link proto.ClientHello.verify|verify} messages. - * @param message ClientHello message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IClientHello, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ClientHello message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ClientHello - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ClientHello; - - /** - * Decodes a ClientHello message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ClientHello - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ClientHello; - - /** - * Verifies a ClientHello message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ClientHello message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ClientHello - */ - public static fromObject(object: { [k: string]: any }): proto.ClientHello; - - /** - * Creates a plain object from a ClientHello message. Also converts values to other types if specified. - * @param message ClientHello - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ClientHello, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ClientHello to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a ServerHello. */ - interface IServerHello { - - /** ServerHello ephemeral */ - ephemeral?: (Uint8Array|null); - - /** ServerHello static */ - "static"?: (Uint8Array|null); - - /** ServerHello payload */ - payload?: (Uint8Array|null); - } - - /** Represents a ServerHello. */ - class ServerHello implements IServerHello { - - /** - * Constructs a new ServerHello. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IServerHello); - - /** ServerHello ephemeral. */ - public ephemeral: Uint8Array; - - /** ServerHello static. */ - public static: Uint8Array; - - /** ServerHello payload. */ - public payload: Uint8Array; - - /** - * Creates a new ServerHello instance using the specified properties. - * @param [properties] Properties to set - * @returns ServerHello instance - */ - public static create(properties?: proto.IServerHello): proto.ServerHello; - - /** - * Encodes the specified ServerHello message. Does not implicitly {@link proto.ServerHello.verify|verify} messages. - * @param message ServerHello message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IServerHello, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ServerHello message, length delimited. Does not implicitly {@link proto.ServerHello.verify|verify} messages. - * @param message ServerHello message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IServerHello, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ServerHello message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ServerHello - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ServerHello; - - /** - * Decodes a ServerHello message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ServerHello - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ServerHello; - - /** - * Verifies a ServerHello message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ServerHello message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ServerHello - */ - public static fromObject(object: { [k: string]: any }): proto.ServerHello; - - /** - * Creates a plain object from a ServerHello message. Also converts values to other types if specified. - * @param message ServerHello - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ServerHello, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ServerHello to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a ClientFinish. */ - interface IClientFinish { - - /** ClientFinish static */ - "static"?: (Uint8Array|null); - - /** ClientFinish payload */ - payload?: (Uint8Array|null); - } - - /** Represents a ClientFinish. */ - class ClientFinish implements IClientFinish { - - /** - * Constructs a new ClientFinish. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IClientFinish); - - /** ClientFinish static. */ - public static: Uint8Array; - - /** ClientFinish payload. */ - public payload: Uint8Array; - - /** - * Creates a new ClientFinish instance using the specified properties. - * @param [properties] Properties to set - * @returns ClientFinish instance - */ - public static create(properties?: proto.IClientFinish): proto.ClientFinish; - - /** - * Encodes the specified ClientFinish message. Does not implicitly {@link proto.ClientFinish.verify|verify} messages. - * @param message ClientFinish message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IClientFinish, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ClientFinish message, length delimited. Does not implicitly {@link proto.ClientFinish.verify|verify} messages. - * @param message ClientFinish message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IClientFinish, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ClientFinish message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ClientFinish - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ClientFinish; - - /** - * Decodes a ClientFinish message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ClientFinish - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ClientFinish; - - /** - * Verifies a ClientFinish message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ClientFinish message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ClientFinish - */ - public static fromObject(object: { [k: string]: any }): proto.ClientFinish; - - /** - * Creates a plain object from a ClientFinish message. Also converts values to other types if specified. - * @param message ClientFinish - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ClientFinish, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ClientFinish to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HandshakeMessage. */ - interface IHandshakeMessage { - - /** HandshakeMessage clientHello */ - clientHello?: (proto.IClientHello|null); - - /** HandshakeMessage serverHello */ - serverHello?: (proto.IServerHello|null); - - /** HandshakeMessage clientFinish */ - clientFinish?: (proto.IClientFinish|null); - } - - /** Represents a HandshakeMessage. */ - class HandshakeMessage implements IHandshakeMessage { - - /** - * Constructs a new HandshakeMessage. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHandshakeMessage); - - /** HandshakeMessage clientHello. */ - public clientHello?: (proto.IClientHello|null); - - /** HandshakeMessage serverHello. */ - public serverHello?: (proto.IServerHello|null); - - /** HandshakeMessage clientFinish. */ - public clientFinish?: (proto.IClientFinish|null); - - /** - * Creates a new HandshakeMessage instance using the specified properties. - * @param [properties] Properties to set - * @returns HandshakeMessage instance - */ - public static create(properties?: proto.IHandshakeMessage): proto.HandshakeMessage; - - /** - * Encodes the specified HandshakeMessage message. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages. - * @param message HandshakeMessage message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHandshakeMessage, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HandshakeMessage message, length delimited. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages. - * @param message HandshakeMessage message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHandshakeMessage, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HandshakeMessage message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HandshakeMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HandshakeMessage; - - /** - * Decodes a HandshakeMessage message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HandshakeMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HandshakeMessage; - - /** - * Verifies a HandshakeMessage message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HandshakeMessage message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HandshakeMessage - */ - public static fromObject(object: { [k: string]: any }): proto.HandshakeMessage; - - /** - * Creates a plain object from a HandshakeMessage message. Also converts values to other types if specified. - * @param message HandshakeMessage - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HandshakeMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HandshakeMessage to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a BizIdentityInfo. */ - interface IBizIdentityInfo { - - /** BizIdentityInfo vlevel */ - vlevel?: (proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue|null); - - /** BizIdentityInfo vnameCert */ - vnameCert?: (proto.IVerifiedNameCertificate|null); - - /** BizIdentityInfo signed */ - signed?: (boolean|null); - - /** BizIdentityInfo revoked */ - revoked?: (boolean|null); - - /** BizIdentityInfo hostStorage */ - hostStorage?: (proto.BizIdentityInfo.BizIdentityInfoHostStorageType|null); - - /** BizIdentityInfo actualActors */ - actualActors?: (proto.BizIdentityInfo.BizIdentityInfoActualActorsType|null); - - /** BizIdentityInfo privacyModeTs */ - privacyModeTs?: (number|Long|null); - } - - /** Represents a BizIdentityInfo. */ - class BizIdentityInfo implements IBizIdentityInfo { - - /** - * Constructs a new BizIdentityInfo. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IBizIdentityInfo); - - /** BizIdentityInfo vlevel. */ - public vlevel: proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue; - - /** BizIdentityInfo vnameCert. */ - public vnameCert?: (proto.IVerifiedNameCertificate|null); - - /** BizIdentityInfo signed. */ - public signed: boolean; - - /** BizIdentityInfo revoked. */ - public revoked: boolean; - - /** BizIdentityInfo hostStorage. */ - public hostStorage: proto.BizIdentityInfo.BizIdentityInfoHostStorageType; - - /** BizIdentityInfo actualActors. */ - public actualActors: proto.BizIdentityInfo.BizIdentityInfoActualActorsType; - - /** BizIdentityInfo privacyModeTs. */ - public privacyModeTs: (number|Long); - - /** - * Creates a new BizIdentityInfo instance using the specified properties. - * @param [properties] Properties to set - * @returns BizIdentityInfo instance - */ - public static create(properties?: proto.IBizIdentityInfo): proto.BizIdentityInfo; - - /** - * Encodes the specified BizIdentityInfo message. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages. - * @param message BizIdentityInfo message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IBizIdentityInfo, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified BizIdentityInfo message, length delimited. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages. - * @param message BizIdentityInfo message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IBizIdentityInfo, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a BizIdentityInfo message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns BizIdentityInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.BizIdentityInfo; - - /** - * Decodes a BizIdentityInfo message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns BizIdentityInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.BizIdentityInfo; - - /** - * Verifies a BizIdentityInfo message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a BizIdentityInfo message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns BizIdentityInfo - */ - public static fromObject(object: { [k: string]: any }): proto.BizIdentityInfo; - - /** - * Creates a plain object from a BizIdentityInfo message. Also converts values to other types if specified. - * @param message BizIdentityInfo - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.BizIdentityInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this BizIdentityInfo to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - namespace BizIdentityInfo { - - /** BizIdentityInfoVerifiedLevelValue enum. */ - enum BizIdentityInfoVerifiedLevelValue { - UNKNOWN = 0, - LOW = 1, - HIGH = 2 - } - - /** BizIdentityInfoHostStorageType enum. */ - enum BizIdentityInfoHostStorageType { - ON_PREMISE = 0, - FACEBOOK = 1 - } - - /** BizIdentityInfoActualActorsType enum. */ - enum BizIdentityInfoActualActorsType { - SELF = 0, - BSP = 1 - } - } - - /** Properties of a BizAccountLinkInfo. */ - interface IBizAccountLinkInfo { - - /** BizAccountLinkInfo whatsappBizAcctFbid */ - whatsappBizAcctFbid?: (number|Long|null); - - /** BizAccountLinkInfo whatsappAcctNumber */ - whatsappAcctNumber?: (string|null); - - /** BizAccountLinkInfo issueTime */ - issueTime?: (number|Long|null); - - /** BizAccountLinkInfo hostStorage */ - hostStorage?: (proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType|null); - - /** BizAccountLinkInfo accountType */ - accountType?: (proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType|null); - } - - /** Represents a BizAccountLinkInfo. */ - class BizAccountLinkInfo implements IBizAccountLinkInfo { - - /** - * Constructs a new BizAccountLinkInfo. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IBizAccountLinkInfo); - - /** BizAccountLinkInfo whatsappBizAcctFbid. */ - public whatsappBizAcctFbid: (number|Long); - - /** BizAccountLinkInfo whatsappAcctNumber. */ - public whatsappAcctNumber: string; - - /** BizAccountLinkInfo issueTime. */ - public issueTime: (number|Long); - - /** BizAccountLinkInfo hostStorage. */ - public hostStorage: proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType; - - /** BizAccountLinkInfo accountType. */ - public accountType: proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType; - - /** - * Creates a new BizAccountLinkInfo instance using the specified properties. - * @param [properties] Properties to set - * @returns BizAccountLinkInfo instance - */ - public static create(properties?: proto.IBizAccountLinkInfo): proto.BizAccountLinkInfo; - - /** - * Encodes the specified BizAccountLinkInfo message. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages. - * @param message BizAccountLinkInfo message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IBizAccountLinkInfo, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified BizAccountLinkInfo message, length delimited. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages. - * @param message BizAccountLinkInfo message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IBizAccountLinkInfo, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a BizAccountLinkInfo message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns BizAccountLinkInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.BizAccountLinkInfo; - - /** - * Decodes a BizAccountLinkInfo message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns BizAccountLinkInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.BizAccountLinkInfo; - - /** - * Verifies a BizAccountLinkInfo message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a BizAccountLinkInfo message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns BizAccountLinkInfo - */ - public static fromObject(object: { [k: string]: any }): proto.BizAccountLinkInfo; - - /** - * Creates a plain object from a BizAccountLinkInfo message. Also converts values to other types if specified. - * @param message BizAccountLinkInfo - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.BizAccountLinkInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this BizAccountLinkInfo to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - namespace BizAccountLinkInfo { - - /** BizAccountLinkInfoHostStorageType enum. */ - enum BizAccountLinkInfoHostStorageType { - ON_PREMISE = 0, - FACEBOOK = 1 - } - - /** BizAccountLinkInfoAccountType enum. */ - enum BizAccountLinkInfoAccountType { - ENTERPRISE = 0, - PAGE = 1 - } - } - - /** Properties of a BizAccountPayload. */ - interface IBizAccountPayload { - - /** BizAccountPayload vnameCert */ - vnameCert?: (proto.IVerifiedNameCertificate|null); - - /** BizAccountPayload bizAcctLinkInfo */ - bizAcctLinkInfo?: (Uint8Array|null); - } - - /** Represents a BizAccountPayload. */ - class BizAccountPayload implements IBizAccountPayload { - - /** - * Constructs a new BizAccountPayload. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IBizAccountPayload); - - /** BizAccountPayload vnameCert. */ - public vnameCert?: (proto.IVerifiedNameCertificate|null); - - /** BizAccountPayload bizAcctLinkInfo. */ - public bizAcctLinkInfo: Uint8Array; - - /** - * Creates a new BizAccountPayload instance using the specified properties. - * @param [properties] Properties to set - * @returns BizAccountPayload instance - */ - public static create(properties?: proto.IBizAccountPayload): proto.BizAccountPayload; - - /** - * Encodes the specified BizAccountPayload message. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages. - * @param message BizAccountPayload message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IBizAccountPayload, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified BizAccountPayload message, length delimited. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages. - * @param message BizAccountPayload message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IBizAccountPayload, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a BizAccountPayload message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns BizAccountPayload - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.BizAccountPayload; - - /** - * Decodes a BizAccountPayload message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns BizAccountPayload - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.BizAccountPayload; - - /** - * Verifies a BizAccountPayload message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a BizAccountPayload message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns BizAccountPayload - */ - public static fromObject(object: { [k: string]: any }): proto.BizAccountPayload; - - /** - * Creates a plain object from a BizAccountPayload message. Also converts values to other types if specified. - * @param message BizAccountPayload - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.BizAccountPayload, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this BizAccountPayload to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a VerifiedNameCertificate. */ - interface IVerifiedNameCertificate { - - /** VerifiedNameCertificate details */ - details?: (Uint8Array|null); - - /** VerifiedNameCertificate signature */ - signature?: (Uint8Array|null); - - /** VerifiedNameCertificate serverSignature */ - serverSignature?: (Uint8Array|null); - } - - /** Represents a VerifiedNameCertificate. */ - class VerifiedNameCertificate implements IVerifiedNameCertificate { - - /** - * Constructs a new VerifiedNameCertificate. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IVerifiedNameCertificate); - - /** VerifiedNameCertificate details. */ - public details: Uint8Array; - - /** VerifiedNameCertificate signature. */ - public signature: Uint8Array; - - /** VerifiedNameCertificate serverSignature. */ - public serverSignature: Uint8Array; - - /** - * Creates a new VerifiedNameCertificate instance using the specified properties. - * @param [properties] Properties to set - * @returns VerifiedNameCertificate instance - */ - public static create(properties?: proto.IVerifiedNameCertificate): proto.VerifiedNameCertificate; - - /** - * Encodes the specified VerifiedNameCertificate message. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages. - * @param message VerifiedNameCertificate message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IVerifiedNameCertificate, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified VerifiedNameCertificate message, length delimited. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages. - * @param message VerifiedNameCertificate message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IVerifiedNameCertificate, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a VerifiedNameCertificate message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns VerifiedNameCertificate - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.VerifiedNameCertificate; - - /** - * Decodes a VerifiedNameCertificate message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns VerifiedNameCertificate - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.VerifiedNameCertificate; - - /** - * Verifies a VerifiedNameCertificate message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a VerifiedNameCertificate message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns VerifiedNameCertificate - */ - public static fromObject(object: { [k: string]: any }): proto.VerifiedNameCertificate; - - /** - * Creates a plain object from a VerifiedNameCertificate message. Also converts values to other types if specified. - * @param message VerifiedNameCertificate - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.VerifiedNameCertificate, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this VerifiedNameCertificate to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a LocalizedName. */ - interface ILocalizedName { - - /** LocalizedName lg */ - lg?: (string|null); - - /** LocalizedName lc */ - lc?: (string|null); - - /** LocalizedName verifiedName */ - verifiedName?: (string|null); - } - - /** Represents a LocalizedName. */ - class LocalizedName implements ILocalizedName { - - /** - * Constructs a new LocalizedName. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ILocalizedName); - - /** LocalizedName lg. */ - public lg: string; - - /** LocalizedName lc. */ - public lc: string; - - /** LocalizedName verifiedName. */ - public verifiedName: string; - - /** - * Creates a new LocalizedName instance using the specified properties. - * @param [properties] Properties to set - * @returns LocalizedName instance - */ - public static create(properties?: proto.ILocalizedName): proto.LocalizedName; - - /** - * Encodes the specified LocalizedName message. Does not implicitly {@link proto.LocalizedName.verify|verify} messages. - * @param message LocalizedName message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ILocalizedName, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified LocalizedName message, length delimited. Does not implicitly {@link proto.LocalizedName.verify|verify} messages. - * @param message LocalizedName message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ILocalizedName, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a LocalizedName message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns LocalizedName - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.LocalizedName; - - /** - * Decodes a LocalizedName message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns LocalizedName - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.LocalizedName; - - /** - * Verifies a LocalizedName message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a LocalizedName message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns LocalizedName - */ - public static fromObject(object: { [k: string]: any }): proto.LocalizedName; - - /** - * Creates a plain object from a LocalizedName message. Also converts values to other types if specified. - * @param message LocalizedName - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.LocalizedName, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this LocalizedName to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a SyncActionData. */ - interface ISyncActionData { - - /** SyncActionData index */ - index?: (Uint8Array|null); - - /** SyncActionData value */ - value?: (proto.ISyncActionValue|null); - - /** SyncActionData padding */ - padding?: (Uint8Array|null); - - /** SyncActionData version */ - version?: (number|null); - } - - /** Represents a SyncActionData. */ - class SyncActionData implements ISyncActionData { - - /** - * Constructs a new SyncActionData. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISyncActionData); - - /** SyncActionData index. */ - public index: Uint8Array; - - /** SyncActionData value. */ - public value?: (proto.ISyncActionValue|null); - - /** SyncActionData padding. */ - public padding: Uint8Array; - - /** SyncActionData version. */ - public version: number; - - /** - * Creates a new SyncActionData instance using the specified properties. - * @param [properties] Properties to set - * @returns SyncActionData instance - */ - public static create(properties?: proto.ISyncActionData): proto.SyncActionData; - - /** - * Encodes the specified SyncActionData message. Does not implicitly {@link proto.SyncActionData.verify|verify} messages. - * @param message SyncActionData message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISyncActionData, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SyncActionData message, length delimited. Does not implicitly {@link proto.SyncActionData.verify|verify} messages. - * @param message SyncActionData message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISyncActionData, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SyncActionData message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SyncActionData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncActionData; - - /** - * Decodes a SyncActionData message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SyncActionData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncActionData; - - /** - * Verifies a SyncActionData message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SyncActionData message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SyncActionData - */ - public static fromObject(object: { [k: string]: any }): proto.SyncActionData; - - /** - * Creates a plain object from a SyncActionData message. Also converts values to other types if specified. - * @param message SyncActionData - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SyncActionData, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SyncActionData to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a StarAction. */ - interface IStarAction { - - /** StarAction starred */ - starred?: (boolean|null); - } - - /** Represents a StarAction. */ - class StarAction implements IStarAction { - - /** - * Constructs a new StarAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IStarAction); - - /** StarAction starred. */ - public starred: boolean; - - /** - * Creates a new StarAction instance using the specified properties. - * @param [properties] Properties to set - * @returns StarAction instance - */ - public static create(properties?: proto.IStarAction): proto.StarAction; - - /** - * Encodes the specified StarAction message. Does not implicitly {@link proto.StarAction.verify|verify} messages. - * @param message StarAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IStarAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified StarAction message, length delimited. Does not implicitly {@link proto.StarAction.verify|verify} messages. - * @param message StarAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IStarAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a StarAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns StarAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.StarAction; - - /** - * Decodes a StarAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns StarAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.StarAction; - - /** - * Verifies a StarAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a StarAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns StarAction - */ - public static fromObject(object: { [k: string]: any }): proto.StarAction; - - /** - * Creates a plain object from a StarAction message. Also converts values to other types if specified. - * @param message StarAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.StarAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this StarAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a ContactAction. */ - interface IContactAction { - - /** ContactAction fullName */ - fullName?: (string|null); - - /** ContactAction firstName */ - firstName?: (string|null); - } - - /** Represents a ContactAction. */ - class ContactAction implements IContactAction { - - /** - * Constructs a new ContactAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IContactAction); - - /** ContactAction fullName. */ - public fullName: string; - - /** ContactAction firstName. */ - public firstName: string; - - /** - * Creates a new ContactAction instance using the specified properties. - * @param [properties] Properties to set - * @returns ContactAction instance - */ - public static create(properties?: proto.IContactAction): proto.ContactAction; - - /** - * Encodes the specified ContactAction message. Does not implicitly {@link proto.ContactAction.verify|verify} messages. - * @param message ContactAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IContactAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ContactAction message, length delimited. Does not implicitly {@link proto.ContactAction.verify|verify} messages. - * @param message ContactAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IContactAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ContactAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ContactAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ContactAction; - - /** - * Decodes a ContactAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ContactAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ContactAction; - - /** - * Verifies a ContactAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ContactAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ContactAction - */ - public static fromObject(object: { [k: string]: any }): proto.ContactAction; - - /** - * Creates a plain object from a ContactAction message. Also converts values to other types if specified. - * @param message ContactAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ContactAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ContactAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a MuteAction. */ - interface IMuteAction { - - /** MuteAction muted */ - muted?: (boolean|null); - - /** MuteAction muteEndTimestamp */ - muteEndTimestamp?: (number|Long|null); - } - - /** Represents a MuteAction. */ - class MuteAction implements IMuteAction { - - /** - * Constructs a new MuteAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IMuteAction); - - /** MuteAction muted. */ - public muted: boolean; - - /** MuteAction muteEndTimestamp. */ - public muteEndTimestamp: (number|Long); - - /** - * Creates a new MuteAction instance using the specified properties. - * @param [properties] Properties to set - * @returns MuteAction instance - */ - public static create(properties?: proto.IMuteAction): proto.MuteAction; - - /** - * Encodes the specified MuteAction message. Does not implicitly {@link proto.MuteAction.verify|verify} messages. - * @param message MuteAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IMuteAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified MuteAction message, length delimited. Does not implicitly {@link proto.MuteAction.verify|verify} messages. - * @param message MuteAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IMuteAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a MuteAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns MuteAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MuteAction; - - /** - * Decodes a MuteAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns MuteAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MuteAction; - - /** - * Verifies a MuteAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a MuteAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns MuteAction - */ - public static fromObject(object: { [k: string]: any }): proto.MuteAction; - - /** - * Creates a plain object from a MuteAction message. Also converts values to other types if specified. - * @param message MuteAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.MuteAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this MuteAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a PinAction. */ - interface IPinAction { - - /** PinAction pinned */ - pinned?: (boolean|null); - } - - /** Represents a PinAction. */ - class PinAction implements IPinAction { - - /** - * Constructs a new PinAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IPinAction); - - /** PinAction pinned. */ - public pinned: boolean; - - /** - * Creates a new PinAction instance using the specified properties. - * @param [properties] Properties to set - * @returns PinAction instance - */ - public static create(properties?: proto.IPinAction): proto.PinAction; - - /** - * Encodes the specified PinAction message. Does not implicitly {@link proto.PinAction.verify|verify} messages. - * @param message PinAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IPinAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified PinAction message, length delimited. Does not implicitly {@link proto.PinAction.verify|verify} messages. - * @param message PinAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IPinAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a PinAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns PinAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PinAction; - - /** - * Decodes a PinAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns PinAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PinAction; - - /** - * Verifies a PinAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a PinAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns PinAction - */ - public static fromObject(object: { [k: string]: any }): proto.PinAction; - - /** - * Creates a plain object from a PinAction message. Also converts values to other types if specified. - * @param message PinAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.PinAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this PinAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a SecurityNotificationSetting. */ - interface ISecurityNotificationSetting { - - /** SecurityNotificationSetting showNotification */ - showNotification?: (boolean|null); - } - - /** Represents a SecurityNotificationSetting. */ - class SecurityNotificationSetting implements ISecurityNotificationSetting { - - /** - * Constructs a new SecurityNotificationSetting. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISecurityNotificationSetting); - - /** SecurityNotificationSetting showNotification. */ - public showNotification: boolean; - - /** - * Creates a new SecurityNotificationSetting instance using the specified properties. - * @param [properties] Properties to set - * @returns SecurityNotificationSetting instance - */ - public static create(properties?: proto.ISecurityNotificationSetting): proto.SecurityNotificationSetting; - - /** - * Encodes the specified SecurityNotificationSetting message. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages. - * @param message SecurityNotificationSetting message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISecurityNotificationSetting, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SecurityNotificationSetting message, length delimited. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages. - * @param message SecurityNotificationSetting message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISecurityNotificationSetting, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SecurityNotificationSetting message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SecurityNotificationSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SecurityNotificationSetting; - - /** - * Decodes a SecurityNotificationSetting message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SecurityNotificationSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SecurityNotificationSetting; - - /** - * Verifies a SecurityNotificationSetting message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SecurityNotificationSetting message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SecurityNotificationSetting - */ - public static fromObject(object: { [k: string]: any }): proto.SecurityNotificationSetting; - - /** - * Creates a plain object from a SecurityNotificationSetting message. Also converts values to other types if specified. - * @param message SecurityNotificationSetting - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SecurityNotificationSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SecurityNotificationSetting to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a PushNameSetting. */ - interface IPushNameSetting { - - /** PushNameSetting name */ - name?: (string|null); - } - - /** Represents a PushNameSetting. */ - class PushNameSetting implements IPushNameSetting { - - /** - * Constructs a new PushNameSetting. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IPushNameSetting); - - /** PushNameSetting name. */ - public name: string; - - /** - * Creates a new PushNameSetting instance using the specified properties. - * @param [properties] Properties to set - * @returns PushNameSetting instance - */ - public static create(properties?: proto.IPushNameSetting): proto.PushNameSetting; - - /** - * Encodes the specified PushNameSetting message. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages. - * @param message PushNameSetting message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IPushNameSetting, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified PushNameSetting message, length delimited. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages. - * @param message PushNameSetting message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IPushNameSetting, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a PushNameSetting message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns PushNameSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PushNameSetting; - - /** - * Decodes a PushNameSetting message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns PushNameSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PushNameSetting; - - /** - * Verifies a PushNameSetting message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a PushNameSetting message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns PushNameSetting - */ - public static fromObject(object: { [k: string]: any }): proto.PushNameSetting; - - /** - * Creates a plain object from a PushNameSetting message. Also converts values to other types if specified. - * @param message PushNameSetting - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.PushNameSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this PushNameSetting to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a LocaleSetting. */ - interface ILocaleSetting { - - /** LocaleSetting locale */ - locale?: (string|null); - } - - /** Represents a LocaleSetting. */ - class LocaleSetting implements ILocaleSetting { - - /** - * Constructs a new LocaleSetting. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ILocaleSetting); - - /** LocaleSetting locale. */ - public locale: string; - - /** - * Creates a new LocaleSetting instance using the specified properties. - * @param [properties] Properties to set - * @returns LocaleSetting instance - */ - public static create(properties?: proto.ILocaleSetting): proto.LocaleSetting; - - /** - * Encodes the specified LocaleSetting message. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages. - * @param message LocaleSetting message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ILocaleSetting, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified LocaleSetting message, length delimited. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages. - * @param message LocaleSetting message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ILocaleSetting, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a LocaleSetting message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns LocaleSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.LocaleSetting; - - /** - * Decodes a LocaleSetting message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns LocaleSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.LocaleSetting; - - /** - * Verifies a LocaleSetting message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a LocaleSetting message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns LocaleSetting - */ - public static fromObject(object: { [k: string]: any }): proto.LocaleSetting; - - /** - * Creates a plain object from a LocaleSetting message. Also converts values to other types if specified. - * @param message LocaleSetting - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.LocaleSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this LocaleSetting to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a QuickReplyAction. */ - interface IQuickReplyAction { - - /** QuickReplyAction shortcut */ - shortcut?: (string|null); - - /** QuickReplyAction message */ - message?: (string|null); - - /** QuickReplyAction keywords */ - keywords?: (string[]|null); - - /** QuickReplyAction count */ - count?: (number|null); - - /** QuickReplyAction deleted */ - deleted?: (boolean|null); - } - - /** Represents a QuickReplyAction. */ - class QuickReplyAction implements IQuickReplyAction { - - /** - * Constructs a new QuickReplyAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IQuickReplyAction); - - /** QuickReplyAction shortcut. */ - public shortcut: string; - - /** QuickReplyAction message. */ - public message: string; - - /** QuickReplyAction keywords. */ - public keywords: string[]; - - /** QuickReplyAction count. */ - public count: number; - - /** QuickReplyAction deleted. */ - public deleted: boolean; - - /** - * Creates a new QuickReplyAction instance using the specified properties. - * @param [properties] Properties to set - * @returns QuickReplyAction instance - */ - public static create(properties?: proto.IQuickReplyAction): proto.QuickReplyAction; - - /** - * Encodes the specified QuickReplyAction message. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages. - * @param message QuickReplyAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IQuickReplyAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified QuickReplyAction message, length delimited. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages. - * @param message QuickReplyAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IQuickReplyAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a QuickReplyAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns QuickReplyAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.QuickReplyAction; - - /** - * Decodes a QuickReplyAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns QuickReplyAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.QuickReplyAction; - - /** - * Verifies a QuickReplyAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a QuickReplyAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns QuickReplyAction - */ - public static fromObject(object: { [k: string]: any }): proto.QuickReplyAction; - - /** - * Creates a plain object from a QuickReplyAction message. Also converts values to other types if specified. - * @param message QuickReplyAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.QuickReplyAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this QuickReplyAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a LabelAssociationAction. */ - interface ILabelAssociationAction { - - /** LabelAssociationAction labeled */ - labeled?: (boolean|null); - } - - /** Represents a LabelAssociationAction. */ - class LabelAssociationAction implements ILabelAssociationAction { - - /** - * Constructs a new LabelAssociationAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ILabelAssociationAction); - - /** LabelAssociationAction labeled. */ - public labeled: boolean; - - /** - * Creates a new LabelAssociationAction instance using the specified properties. - * @param [properties] Properties to set - * @returns LabelAssociationAction instance - */ - public static create(properties?: proto.ILabelAssociationAction): proto.LabelAssociationAction; - - /** - * Encodes the specified LabelAssociationAction message. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages. - * @param message LabelAssociationAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ILabelAssociationAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified LabelAssociationAction message, length delimited. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages. - * @param message LabelAssociationAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ILabelAssociationAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a LabelAssociationAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns LabelAssociationAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.LabelAssociationAction; - - /** - * Decodes a LabelAssociationAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns LabelAssociationAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.LabelAssociationAction; - - /** - * Verifies a LabelAssociationAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a LabelAssociationAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns LabelAssociationAction - */ - public static fromObject(object: { [k: string]: any }): proto.LabelAssociationAction; - - /** - * Creates a plain object from a LabelAssociationAction message. Also converts values to other types if specified. - * @param message LabelAssociationAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.LabelAssociationAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this LabelAssociationAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a LabelEditAction. */ - interface ILabelEditAction { - - /** LabelEditAction name */ - name?: (string|null); - - /** LabelEditAction color */ - color?: (number|null); - - /** LabelEditAction predefinedId */ - predefinedId?: (number|null); - - /** LabelEditAction deleted */ - deleted?: (boolean|null); - } - - /** Represents a LabelEditAction. */ - class LabelEditAction implements ILabelEditAction { - - /** - * Constructs a new LabelEditAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ILabelEditAction); - - /** LabelEditAction name. */ - public name: string; - - /** LabelEditAction color. */ - public color: number; - - /** LabelEditAction predefinedId. */ - public predefinedId: number; - - /** LabelEditAction deleted. */ - public deleted: boolean; - - /** - * Creates a new LabelEditAction instance using the specified properties. - * @param [properties] Properties to set - * @returns LabelEditAction instance - */ - public static create(properties?: proto.ILabelEditAction): proto.LabelEditAction; - - /** - * Encodes the specified LabelEditAction message. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages. - * @param message LabelEditAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ILabelEditAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified LabelEditAction message, length delimited. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages. - * @param message LabelEditAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ILabelEditAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a LabelEditAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns LabelEditAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.LabelEditAction; - - /** - * Decodes a LabelEditAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns LabelEditAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.LabelEditAction; - - /** - * Verifies a LabelEditAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a LabelEditAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns LabelEditAction - */ - public static fromObject(object: { [k: string]: any }): proto.LabelEditAction; - - /** - * Creates a plain object from a LabelEditAction message. Also converts values to other types if specified. - * @param message LabelEditAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.LabelEditAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this LabelEditAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a RecentStickerWeightsAction. */ - interface IRecentStickerWeightsAction { - - /** RecentStickerWeightsAction weights */ - weights?: (proto.IRecentStickerWeight[]|null); - } - - /** Represents a RecentStickerWeightsAction. */ - class RecentStickerWeightsAction implements IRecentStickerWeightsAction { - - /** - * Constructs a new RecentStickerWeightsAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IRecentStickerWeightsAction); - - /** RecentStickerWeightsAction weights. */ - public weights: proto.IRecentStickerWeight[]; - - /** - * Creates a new RecentStickerWeightsAction instance using the specified properties. - * @param [properties] Properties to set - * @returns RecentStickerWeightsAction instance - */ - public static create(properties?: proto.IRecentStickerWeightsAction): proto.RecentStickerWeightsAction; - - /** - * Encodes the specified RecentStickerWeightsAction message. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages. - * @param message RecentStickerWeightsAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IRecentStickerWeightsAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified RecentStickerWeightsAction message, length delimited. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages. - * @param message RecentStickerWeightsAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IRecentStickerWeightsAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a RecentStickerWeightsAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns RecentStickerWeightsAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentStickerWeightsAction; - - /** - * Decodes a RecentStickerWeightsAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns RecentStickerWeightsAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentStickerWeightsAction; - - /** - * Verifies a RecentStickerWeightsAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a RecentStickerWeightsAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns RecentStickerWeightsAction - */ - public static fromObject(object: { [k: string]: any }): proto.RecentStickerWeightsAction; - - /** - * Creates a plain object from a RecentStickerWeightsAction message. Also converts values to other types if specified. - * @param message RecentStickerWeightsAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.RecentStickerWeightsAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this RecentStickerWeightsAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a RecentStickerMetadata. */ - interface IRecentStickerMetadata { - - /** RecentStickerMetadata directPath */ - directPath?: (string|null); - - /** RecentStickerMetadata encFilehash */ - encFilehash?: (string|null); - - /** RecentStickerMetadata mediaKey */ - mediaKey?: (string|null); - - /** RecentStickerMetadata stanzaId */ - stanzaId?: (string|null); - - /** RecentStickerMetadata chatJid */ - chatJid?: (string|null); - - /** RecentStickerMetadata participant */ + /** MessageKey participant */ participant?: (string|null); - - /** RecentStickerMetadata isSentByMe */ - isSentByMe?: (boolean|null); } - /** Represents a RecentStickerMetadata. */ - class RecentStickerMetadata implements IRecentStickerMetadata { + /** Represents a MessageKey. */ + class MessageKey implements IMessageKey { /** - * Constructs a new RecentStickerMetadata. + * Constructs a new MessageKey. * @param [properties] Properties to set */ - constructor(properties?: proto.IRecentStickerMetadata); + constructor(properties?: proto.IMessageKey); - /** RecentStickerMetadata directPath. */ - public directPath: string; + /** MessageKey remoteJid. */ + public remoteJid: string; - /** RecentStickerMetadata encFilehash. */ - public encFilehash: string; + /** MessageKey fromMe. */ + public fromMe: boolean; - /** RecentStickerMetadata mediaKey. */ - public mediaKey: string; + /** MessageKey id. */ + public id: string; - /** RecentStickerMetadata stanzaId. */ - public stanzaId: string; - - /** RecentStickerMetadata chatJid. */ - public chatJid: string; - - /** RecentStickerMetadata participant. */ + /** MessageKey participant. */ public participant: string; - /** RecentStickerMetadata isSentByMe. */ - public isSentByMe: boolean; - /** - * Creates a new RecentStickerMetadata instance using the specified properties. + * Creates a new MessageKey instance using the specified properties. * @param [properties] Properties to set - * @returns RecentStickerMetadata instance + * @returns MessageKey instance */ - public static create(properties?: proto.IRecentStickerMetadata): proto.RecentStickerMetadata; + public static create(properties?: proto.IMessageKey): proto.MessageKey; /** - * Encodes the specified RecentStickerMetadata message. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages. - * @param message RecentStickerMetadata message or plain object to encode + * Encodes the specified MessageKey message. Does not implicitly {@link proto.MessageKey.verify|verify} messages. + * @param message MessageKey message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encode(message: proto.IRecentStickerMetadata, writer?: $protobuf.Writer): $protobuf.Writer; + public static encode(message: proto.IMessageKey, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Encodes the specified RecentStickerMetadata message, length delimited. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages. - * @param message RecentStickerMetadata message or plain object to encode + * Encodes the specified MessageKey message, length delimited. Does not implicitly {@link proto.MessageKey.verify|verify} messages. + * @param message MessageKey message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encodeDelimited(message: proto.IRecentStickerMetadata, writer?: $protobuf.Writer): $protobuf.Writer; + public static encodeDelimited(message: proto.IMessageKey, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Decodes a RecentStickerMetadata message from the specified reader or buffer. + * Decodes a MessageKey message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns RecentStickerMetadata + * @returns MessageKey * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentStickerMetadata; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MessageKey; /** - * Decodes a RecentStickerMetadata message from the specified reader or buffer, length delimited. + * Decodes a MessageKey message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns RecentStickerMetadata + * @returns MessageKey * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentStickerMetadata; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MessageKey; /** - * Verifies a RecentStickerMetadata message. + * Verifies a MessageKey message. * @param message Plain object to verify * @returns `null` if valid, otherwise the reason why it is not */ public static verify(message: { [k: string]: any }): (string|null); /** - * Creates a RecentStickerMetadata message from a plain object. Also converts values to their respective internal types. + * Creates a MessageKey message from a plain object. Also converts values to their respective internal types. * @param object Plain object - * @returns RecentStickerMetadata + * @returns MessageKey */ - public static fromObject(object: { [k: string]: any }): proto.RecentStickerMetadata; + public static fromObject(object: { [k: string]: any }): proto.MessageKey; /** - * Creates a plain object from a RecentStickerMetadata message. Also converts values to other types if specified. - * @param message RecentStickerMetadata + * Creates a plain object from a MessageKey message. Also converts values to other types if specified. + * @param message MessageKey * @param [options] Conversion options * @returns Plain object */ - public static toObject(message: proto.RecentStickerMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any }; + public static toObject(message: proto.MessageKey, options?: $protobuf.IConversionOptions): { [k: string]: any }; /** - * Converts this RecentStickerMetadata to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a RecentEmojiWeightsAction. */ - interface IRecentEmojiWeightsAction { - - /** RecentEmojiWeightsAction weights */ - weights?: (proto.IRecentEmojiWeight[]|null); - } - - /** Represents a RecentEmojiWeightsAction. */ - class RecentEmojiWeightsAction implements IRecentEmojiWeightsAction { - - /** - * Constructs a new RecentEmojiWeightsAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IRecentEmojiWeightsAction); - - /** RecentEmojiWeightsAction weights. */ - public weights: proto.IRecentEmojiWeight[]; - - /** - * Creates a new RecentEmojiWeightsAction instance using the specified properties. - * @param [properties] Properties to set - * @returns RecentEmojiWeightsAction instance - */ - public static create(properties?: proto.IRecentEmojiWeightsAction): proto.RecentEmojiWeightsAction; - - /** - * Encodes the specified RecentEmojiWeightsAction message. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages. - * @param message RecentEmojiWeightsAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IRecentEmojiWeightsAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified RecentEmojiWeightsAction message, length delimited. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages. - * @param message RecentEmojiWeightsAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IRecentEmojiWeightsAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns RecentEmojiWeightsAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentEmojiWeightsAction; - - /** - * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns RecentEmojiWeightsAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentEmojiWeightsAction; - - /** - * Verifies a RecentEmojiWeightsAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a RecentEmojiWeightsAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns RecentEmojiWeightsAction - */ - public static fromObject(object: { [k: string]: any }): proto.RecentEmojiWeightsAction; - - /** - * Creates a plain object from a RecentEmojiWeightsAction message. Also converts values to other types if specified. - * @param message RecentEmojiWeightsAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.RecentEmojiWeightsAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this RecentEmojiWeightsAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of an ArchiveChatAction. */ - interface IArchiveChatAction { - - /** ArchiveChatAction archived */ - archived?: (boolean|null); - - /** ArchiveChatAction messageRange */ - messageRange?: (proto.ISyncActionMessageRange|null); - } - - /** Represents an ArchiveChatAction. */ - class ArchiveChatAction implements IArchiveChatAction { - - /** - * Constructs a new ArchiveChatAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IArchiveChatAction); - - /** ArchiveChatAction archived. */ - public archived: boolean; - - /** ArchiveChatAction messageRange. */ - public messageRange?: (proto.ISyncActionMessageRange|null); - - /** - * Creates a new ArchiveChatAction instance using the specified properties. - * @param [properties] Properties to set - * @returns ArchiveChatAction instance - */ - public static create(properties?: proto.IArchiveChatAction): proto.ArchiveChatAction; - - /** - * Encodes the specified ArchiveChatAction message. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages. - * @param message ArchiveChatAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IArchiveChatAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ArchiveChatAction message, length delimited. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages. - * @param message ArchiveChatAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IArchiveChatAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes an ArchiveChatAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ArchiveChatAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ArchiveChatAction; - - /** - * Decodes an ArchiveChatAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ArchiveChatAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ArchiveChatAction; - - /** - * Verifies an ArchiveChatAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates an ArchiveChatAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ArchiveChatAction - */ - public static fromObject(object: { [k: string]: any }): proto.ArchiveChatAction; - - /** - * Creates a plain object from an ArchiveChatAction message. Also converts values to other types if specified. - * @param message ArchiveChatAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ArchiveChatAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ArchiveChatAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a DeleteMessageForMeAction. */ - interface IDeleteMessageForMeAction { - - /** DeleteMessageForMeAction deleteMedia */ - deleteMedia?: (boolean|null); - - /** DeleteMessageForMeAction messageTimestamp */ - messageTimestamp?: (number|Long|null); - } - - /** Represents a DeleteMessageForMeAction. */ - class DeleteMessageForMeAction implements IDeleteMessageForMeAction { - - /** - * Constructs a new DeleteMessageForMeAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IDeleteMessageForMeAction); - - /** DeleteMessageForMeAction deleteMedia. */ - public deleteMedia: boolean; - - /** DeleteMessageForMeAction messageTimestamp. */ - public messageTimestamp: (number|Long); - - /** - * Creates a new DeleteMessageForMeAction instance using the specified properties. - * @param [properties] Properties to set - * @returns DeleteMessageForMeAction instance - */ - public static create(properties?: proto.IDeleteMessageForMeAction): proto.DeleteMessageForMeAction; - - /** - * Encodes the specified DeleteMessageForMeAction message. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages. - * @param message DeleteMessageForMeAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IDeleteMessageForMeAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified DeleteMessageForMeAction message, length delimited. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages. - * @param message DeleteMessageForMeAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IDeleteMessageForMeAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a DeleteMessageForMeAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns DeleteMessageForMeAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DeleteMessageForMeAction; - - /** - * Decodes a DeleteMessageForMeAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns DeleteMessageForMeAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DeleteMessageForMeAction; - - /** - * Verifies a DeleteMessageForMeAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a DeleteMessageForMeAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns DeleteMessageForMeAction - */ - public static fromObject(object: { [k: string]: any }): proto.DeleteMessageForMeAction; - - /** - * Creates a plain object from a DeleteMessageForMeAction message. Also converts values to other types if specified. - * @param message DeleteMessageForMeAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.DeleteMessageForMeAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this DeleteMessageForMeAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a MarkChatAsReadAction. */ - interface IMarkChatAsReadAction { - - /** MarkChatAsReadAction read */ - read?: (boolean|null); - - /** MarkChatAsReadAction messageRange */ - messageRange?: (proto.ISyncActionMessageRange|null); - } - - /** Represents a MarkChatAsReadAction. */ - class MarkChatAsReadAction implements IMarkChatAsReadAction { - - /** - * Constructs a new MarkChatAsReadAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IMarkChatAsReadAction); - - /** MarkChatAsReadAction read. */ - public read: boolean; - - /** MarkChatAsReadAction messageRange. */ - public messageRange?: (proto.ISyncActionMessageRange|null); - - /** - * Creates a new MarkChatAsReadAction instance using the specified properties. - * @param [properties] Properties to set - * @returns MarkChatAsReadAction instance - */ - public static create(properties?: proto.IMarkChatAsReadAction): proto.MarkChatAsReadAction; - - /** - * Encodes the specified MarkChatAsReadAction message. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages. - * @param message MarkChatAsReadAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IMarkChatAsReadAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified MarkChatAsReadAction message, length delimited. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages. - * @param message MarkChatAsReadAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IMarkChatAsReadAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a MarkChatAsReadAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns MarkChatAsReadAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MarkChatAsReadAction; - - /** - * Decodes a MarkChatAsReadAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns MarkChatAsReadAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MarkChatAsReadAction; - - /** - * Verifies a MarkChatAsReadAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a MarkChatAsReadAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns MarkChatAsReadAction - */ - public static fromObject(object: { [k: string]: any }): proto.MarkChatAsReadAction; - - /** - * Creates a plain object from a MarkChatAsReadAction message. Also converts values to other types if specified. - * @param message MarkChatAsReadAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.MarkChatAsReadAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this MarkChatAsReadAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a ClearChatAction. */ - interface IClearChatAction { - - /** ClearChatAction messageRange */ - messageRange?: (proto.ISyncActionMessageRange|null); - } - - /** Represents a ClearChatAction. */ - class ClearChatAction implements IClearChatAction { - - /** - * Constructs a new ClearChatAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IClearChatAction); - - /** ClearChatAction messageRange. */ - public messageRange?: (proto.ISyncActionMessageRange|null); - - /** - * Creates a new ClearChatAction instance using the specified properties. - * @param [properties] Properties to set - * @returns ClearChatAction instance - */ - public static create(properties?: proto.IClearChatAction): proto.ClearChatAction; - - /** - * Encodes the specified ClearChatAction message. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages. - * @param message ClearChatAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IClearChatAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ClearChatAction message, length delimited. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages. - * @param message ClearChatAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IClearChatAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ClearChatAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ClearChatAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ClearChatAction; - - /** - * Decodes a ClearChatAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ClearChatAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ClearChatAction; - - /** - * Verifies a ClearChatAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ClearChatAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ClearChatAction - */ - public static fromObject(object: { [k: string]: any }): proto.ClearChatAction; - - /** - * Creates a plain object from a ClearChatAction message. Also converts values to other types if specified. - * @param message ClearChatAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ClearChatAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ClearChatAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a DeleteChatAction. */ - interface IDeleteChatAction { - - /** DeleteChatAction messageRange */ - messageRange?: (proto.ISyncActionMessageRange|null); - } - - /** Represents a DeleteChatAction. */ - class DeleteChatAction implements IDeleteChatAction { - - /** - * Constructs a new DeleteChatAction. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IDeleteChatAction); - - /** DeleteChatAction messageRange. */ - public messageRange?: (proto.ISyncActionMessageRange|null); - - /** - * Creates a new DeleteChatAction instance using the specified properties. - * @param [properties] Properties to set - * @returns DeleteChatAction instance - */ - public static create(properties?: proto.IDeleteChatAction): proto.DeleteChatAction; - - /** - * Encodes the specified DeleteChatAction message. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages. - * @param message DeleteChatAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IDeleteChatAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified DeleteChatAction message, length delimited. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages. - * @param message DeleteChatAction message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IDeleteChatAction, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a DeleteChatAction message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns DeleteChatAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DeleteChatAction; - - /** - * Decodes a DeleteChatAction message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns DeleteChatAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DeleteChatAction; - - /** - * Verifies a DeleteChatAction message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a DeleteChatAction message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns DeleteChatAction - */ - public static fromObject(object: { [k: string]: any }): proto.DeleteChatAction; - - /** - * Creates a plain object from a DeleteChatAction message. Also converts values to other types if specified. - * @param message DeleteChatAction - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.DeleteChatAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this DeleteChatAction to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of an UnarchiveChatsSetting. */ - interface IUnarchiveChatsSetting { - - /** UnarchiveChatsSetting unarchiveChats */ - unarchiveChats?: (boolean|null); - } - - /** Represents an UnarchiveChatsSetting. */ - class UnarchiveChatsSetting implements IUnarchiveChatsSetting { - - /** - * Constructs a new UnarchiveChatsSetting. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IUnarchiveChatsSetting); - - /** UnarchiveChatsSetting unarchiveChats. */ - public unarchiveChats: boolean; - - /** - * Creates a new UnarchiveChatsSetting instance using the specified properties. - * @param [properties] Properties to set - * @returns UnarchiveChatsSetting instance - */ - public static create(properties?: proto.IUnarchiveChatsSetting): proto.UnarchiveChatsSetting; - - /** - * Encodes the specified UnarchiveChatsSetting message. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages. - * @param message UnarchiveChatsSetting message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IUnarchiveChatsSetting, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified UnarchiveChatsSetting message, length delimited. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages. - * @param message UnarchiveChatsSetting message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IUnarchiveChatsSetting, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes an UnarchiveChatsSetting message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns UnarchiveChatsSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.UnarchiveChatsSetting; - - /** - * Decodes an UnarchiveChatsSetting message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns UnarchiveChatsSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.UnarchiveChatsSetting; - - /** - * Verifies an UnarchiveChatsSetting message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates an UnarchiveChatsSetting message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns UnarchiveChatsSetting - */ - public static fromObject(object: { [k: string]: any }): proto.UnarchiveChatsSetting; - - /** - * Creates a plain object from an UnarchiveChatsSetting message. Also converts values to other types if specified. - * @param message UnarchiveChatsSetting - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.UnarchiveChatsSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this UnarchiveChatsSetting to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a SyncActionMessageRange. */ - interface ISyncActionMessageRange { - - /** SyncActionMessageRange lastMessageTimestamp */ - lastMessageTimestamp?: (number|Long|null); - - /** SyncActionMessageRange lastSystemMessageTimestamp */ - lastSystemMessageTimestamp?: (number|Long|null); - - /** SyncActionMessageRange messages */ - messages?: (proto.ISyncActionMessage[]|null); - } - - /** Represents a SyncActionMessageRange. */ - class SyncActionMessageRange implements ISyncActionMessageRange { - - /** - * Constructs a new SyncActionMessageRange. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISyncActionMessageRange); - - /** SyncActionMessageRange lastMessageTimestamp. */ - public lastMessageTimestamp: (number|Long); - - /** SyncActionMessageRange lastSystemMessageTimestamp. */ - public lastSystemMessageTimestamp: (number|Long); - - /** SyncActionMessageRange messages. */ - public messages: proto.ISyncActionMessage[]; - - /** - * Creates a new SyncActionMessageRange instance using the specified properties. - * @param [properties] Properties to set - * @returns SyncActionMessageRange instance - */ - public static create(properties?: proto.ISyncActionMessageRange): proto.SyncActionMessageRange; - - /** - * Encodes the specified SyncActionMessageRange message. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages. - * @param message SyncActionMessageRange message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISyncActionMessageRange, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SyncActionMessageRange message, length delimited. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages. - * @param message SyncActionMessageRange message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISyncActionMessageRange, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SyncActionMessageRange message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SyncActionMessageRange - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncActionMessageRange; - - /** - * Decodes a SyncActionMessageRange message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SyncActionMessageRange - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncActionMessageRange; - - /** - * Verifies a SyncActionMessageRange message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SyncActionMessageRange message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SyncActionMessageRange - */ - public static fromObject(object: { [k: string]: any }): proto.SyncActionMessageRange; - - /** - * Creates a plain object from a SyncActionMessageRange message. Also converts values to other types if specified. - * @param message SyncActionMessageRange - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SyncActionMessageRange, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SyncActionMessageRange to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a SyncActionMessage. */ - interface ISyncActionMessage { - - /** SyncActionMessage key */ - key?: (proto.IMessageKey|null); - - /** SyncActionMessage timestamp */ - timestamp?: (number|Long|null); - } - - /** Represents a SyncActionMessage. */ - class SyncActionMessage implements ISyncActionMessage { - - /** - * Constructs a new SyncActionMessage. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISyncActionMessage); - - /** SyncActionMessage key. */ - public key?: (proto.IMessageKey|null); - - /** SyncActionMessage timestamp. */ - public timestamp: (number|Long); - - /** - * Creates a new SyncActionMessage instance using the specified properties. - * @param [properties] Properties to set - * @returns SyncActionMessage instance - */ - public static create(properties?: proto.ISyncActionMessage): proto.SyncActionMessage; - - /** - * Encodes the specified SyncActionMessage message. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages. - * @param message SyncActionMessage message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISyncActionMessage, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SyncActionMessage message, length delimited. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages. - * @param message SyncActionMessage message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISyncActionMessage, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SyncActionMessage message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SyncActionMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncActionMessage; - - /** - * Decodes a SyncActionMessage message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SyncActionMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncActionMessage; - - /** - * Verifies a SyncActionMessage message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SyncActionMessage message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SyncActionMessage - */ - public static fromObject(object: { [k: string]: any }): proto.SyncActionMessage; - - /** - * Creates a plain object from a SyncActionMessage message. Also converts values to other types if specified. - * @param message SyncActionMessage - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SyncActionMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SyncActionMessage to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a KeyExpiration. */ - interface IKeyExpiration { - - /** KeyExpiration expiredKeyEpoch */ - expiredKeyEpoch?: (number|null); - } - - /** Represents a KeyExpiration. */ - class KeyExpiration implements IKeyExpiration { - - /** - * Constructs a new KeyExpiration. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IKeyExpiration); - - /** KeyExpiration expiredKeyEpoch. */ - public expiredKeyEpoch: number; - - /** - * Creates a new KeyExpiration instance using the specified properties. - * @param [properties] Properties to set - * @returns KeyExpiration instance - */ - public static create(properties?: proto.IKeyExpiration): proto.KeyExpiration; - - /** - * Encodes the specified KeyExpiration message. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages. - * @param message KeyExpiration message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IKeyExpiration, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified KeyExpiration message, length delimited. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages. - * @param message KeyExpiration message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IKeyExpiration, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a KeyExpiration message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns KeyExpiration - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.KeyExpiration; - - /** - * Decodes a KeyExpiration message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns KeyExpiration - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.KeyExpiration; - - /** - * Verifies a KeyExpiration message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a KeyExpiration message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns KeyExpiration - */ - public static fromObject(object: { [k: string]: any }): proto.KeyExpiration; - - /** - * Creates a plain object from a KeyExpiration message. Also converts values to other types if specified. - * @param message KeyExpiration - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.KeyExpiration, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this KeyExpiration to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a SyncActionValue. */ - interface ISyncActionValue { - - /** SyncActionValue timestamp */ - timestamp?: (number|Long|null); - - /** SyncActionValue starAction */ - starAction?: (proto.IStarAction|null); - - /** SyncActionValue contactAction */ - contactAction?: (proto.IContactAction|null); - - /** SyncActionValue muteAction */ - muteAction?: (proto.IMuteAction|null); - - /** SyncActionValue pinAction */ - pinAction?: (proto.IPinAction|null); - - /** SyncActionValue securityNotificationSetting */ - securityNotificationSetting?: (proto.ISecurityNotificationSetting|null); - - /** SyncActionValue pushNameSetting */ - pushNameSetting?: (proto.IPushNameSetting|null); - - /** SyncActionValue quickReplyAction */ - quickReplyAction?: (proto.IQuickReplyAction|null); - - /** SyncActionValue recentStickerWeightsAction */ - recentStickerWeightsAction?: (proto.IRecentStickerWeightsAction|null); - - /** SyncActionValue recentStickerMetadata */ - recentStickerMetadata?: (proto.IRecentStickerMetadata|null); - - /** SyncActionValue recentEmojiWeightsAction */ - recentEmojiWeightsAction?: (proto.IRecentEmojiWeightsAction|null); - - /** SyncActionValue labelEditAction */ - labelEditAction?: (proto.ILabelEditAction|null); - - /** SyncActionValue labelAssociationAction */ - labelAssociationAction?: (proto.ILabelAssociationAction|null); - - /** SyncActionValue localeSetting */ - localeSetting?: (proto.ILocaleSetting|null); - - /** SyncActionValue archiveChatAction */ - archiveChatAction?: (proto.IArchiveChatAction|null); - - /** SyncActionValue deleteMessageForMeAction */ - deleteMessageForMeAction?: (proto.IDeleteMessageForMeAction|null); - - /** SyncActionValue keyExpiration */ - keyExpiration?: (proto.IKeyExpiration|null); - - /** SyncActionValue markChatAsReadAction */ - markChatAsReadAction?: (proto.IMarkChatAsReadAction|null); - - /** SyncActionValue clearChatAction */ - clearChatAction?: (proto.IClearChatAction|null); - - /** SyncActionValue deleteChatAction */ - deleteChatAction?: (proto.IDeleteChatAction|null); - - /** SyncActionValue unarchiveChatsSetting */ - unarchiveChatsSetting?: (proto.IUnarchiveChatsSetting|null); - } - - /** Represents a SyncActionValue. */ - class SyncActionValue implements ISyncActionValue { - - /** - * Constructs a new SyncActionValue. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISyncActionValue); - - /** SyncActionValue timestamp. */ - public timestamp: (number|Long); - - /** SyncActionValue starAction. */ - public starAction?: (proto.IStarAction|null); - - /** SyncActionValue contactAction. */ - public contactAction?: (proto.IContactAction|null); - - /** SyncActionValue muteAction. */ - public muteAction?: (proto.IMuteAction|null); - - /** SyncActionValue pinAction. */ - public pinAction?: (proto.IPinAction|null); - - /** SyncActionValue securityNotificationSetting. */ - public securityNotificationSetting?: (proto.ISecurityNotificationSetting|null); - - /** SyncActionValue pushNameSetting. */ - public pushNameSetting?: (proto.IPushNameSetting|null); - - /** SyncActionValue quickReplyAction. */ - public quickReplyAction?: (proto.IQuickReplyAction|null); - - /** SyncActionValue recentStickerWeightsAction. */ - public recentStickerWeightsAction?: (proto.IRecentStickerWeightsAction|null); - - /** SyncActionValue recentStickerMetadata. */ - public recentStickerMetadata?: (proto.IRecentStickerMetadata|null); - - /** SyncActionValue recentEmojiWeightsAction. */ - public recentEmojiWeightsAction?: (proto.IRecentEmojiWeightsAction|null); - - /** SyncActionValue labelEditAction. */ - public labelEditAction?: (proto.ILabelEditAction|null); - - /** SyncActionValue labelAssociationAction. */ - public labelAssociationAction?: (proto.ILabelAssociationAction|null); - - /** SyncActionValue localeSetting. */ - public localeSetting?: (proto.ILocaleSetting|null); - - /** SyncActionValue archiveChatAction. */ - public archiveChatAction?: (proto.IArchiveChatAction|null); - - /** SyncActionValue deleteMessageForMeAction. */ - public deleteMessageForMeAction?: (proto.IDeleteMessageForMeAction|null); - - /** SyncActionValue keyExpiration. */ - public keyExpiration?: (proto.IKeyExpiration|null); - - /** SyncActionValue markChatAsReadAction. */ - public markChatAsReadAction?: (proto.IMarkChatAsReadAction|null); - - /** SyncActionValue clearChatAction. */ - public clearChatAction?: (proto.IClearChatAction|null); - - /** SyncActionValue deleteChatAction. */ - public deleteChatAction?: (proto.IDeleteChatAction|null); - - /** SyncActionValue unarchiveChatsSetting. */ - public unarchiveChatsSetting?: (proto.IUnarchiveChatsSetting|null); - - /** - * Creates a new SyncActionValue instance using the specified properties. - * @param [properties] Properties to set - * @returns SyncActionValue instance - */ - public static create(properties?: proto.ISyncActionValue): proto.SyncActionValue; - - /** - * Encodes the specified SyncActionValue message. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages. - * @param message SyncActionValue message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISyncActionValue, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SyncActionValue message, length delimited. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages. - * @param message SyncActionValue message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISyncActionValue, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SyncActionValue message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SyncActionValue - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncActionValue; - - /** - * Decodes a SyncActionValue message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SyncActionValue - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncActionValue; - - /** - * Verifies a SyncActionValue message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SyncActionValue message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SyncActionValue - */ - public static fromObject(object: { [k: string]: any }): proto.SyncActionValue; - - /** - * Creates a plain object from a SyncActionValue message. Also converts values to other types if specified. - * @param message SyncActionValue - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SyncActionValue, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SyncActionValue to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a RecentEmojiWeight. */ - interface IRecentEmojiWeight { - - /** RecentEmojiWeight emoji */ - emoji?: (string|null); - - /** RecentEmojiWeight weight */ - weight?: (number|null); - } - - /** Represents a RecentEmojiWeight. */ - class RecentEmojiWeight implements IRecentEmojiWeight { - - /** - * Constructs a new RecentEmojiWeight. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IRecentEmojiWeight); - - /** RecentEmojiWeight emoji. */ - public emoji: string; - - /** RecentEmojiWeight weight. */ - public weight: number; - - /** - * Creates a new RecentEmojiWeight instance using the specified properties. - * @param [properties] Properties to set - * @returns RecentEmojiWeight instance - */ - public static create(properties?: proto.IRecentEmojiWeight): proto.RecentEmojiWeight; - - /** - * Encodes the specified RecentEmojiWeight message. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages. - * @param message RecentEmojiWeight message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IRecentEmojiWeight, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified RecentEmojiWeight message, length delimited. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages. - * @param message RecentEmojiWeight message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IRecentEmojiWeight, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a RecentEmojiWeight message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns RecentEmojiWeight - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentEmojiWeight; - - /** - * Decodes a RecentEmojiWeight message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns RecentEmojiWeight - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentEmojiWeight; - - /** - * Verifies a RecentEmojiWeight message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a RecentEmojiWeight message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns RecentEmojiWeight - */ - public static fromObject(object: { [k: string]: any }): proto.RecentEmojiWeight; - - /** - * Creates a plain object from a RecentEmojiWeight message. Also converts values to other types if specified. - * @param message RecentEmojiWeight - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.RecentEmojiWeight, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this RecentEmojiWeight to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a RecentStickerWeight. */ - interface IRecentStickerWeight { - - /** RecentStickerWeight filehash */ - filehash?: (string|null); - - /** RecentStickerWeight weight */ - weight?: (number|null); - } - - /** Represents a RecentStickerWeight. */ - class RecentStickerWeight implements IRecentStickerWeight { - - /** - * Constructs a new RecentStickerWeight. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IRecentStickerWeight); - - /** RecentStickerWeight filehash. */ - public filehash: string; - - /** RecentStickerWeight weight. */ - public weight: number; - - /** - * Creates a new RecentStickerWeight instance using the specified properties. - * @param [properties] Properties to set - * @returns RecentStickerWeight instance - */ - public static create(properties?: proto.IRecentStickerWeight): proto.RecentStickerWeight; - - /** - * Encodes the specified RecentStickerWeight message. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages. - * @param message RecentStickerWeight message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IRecentStickerWeight, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified RecentStickerWeight message, length delimited. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages. - * @param message RecentStickerWeight message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IRecentStickerWeight, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a RecentStickerWeight message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns RecentStickerWeight - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentStickerWeight; - - /** - * Decodes a RecentStickerWeight message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns RecentStickerWeight - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentStickerWeight; - - /** - * Verifies a RecentStickerWeight message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a RecentStickerWeight message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns RecentStickerWeight - */ - public static fromObject(object: { [k: string]: any }): proto.RecentStickerWeight; - - /** - * Creates a plain object from a RecentStickerWeight message. Also converts values to other types if specified. - * @param message RecentStickerWeight - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.RecentStickerWeight, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this RecentStickerWeight to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a SyncdPatch. */ - interface ISyncdPatch { - - /** SyncdPatch version */ - version?: (proto.ISyncdVersion|null); - - /** SyncdPatch mutations */ - mutations?: (proto.ISyncdMutation[]|null); - - /** SyncdPatch externalMutations */ - externalMutations?: (proto.IExternalBlobReference|null); - - /** SyncdPatch snapshotMac */ - snapshotMac?: (Uint8Array|null); - - /** SyncdPatch patchMac */ - patchMac?: (Uint8Array|null); - - /** SyncdPatch keyId */ - keyId?: (proto.IKeyId|null); - - /** SyncdPatch exitCode */ - exitCode?: (proto.IExitCode|null); - - /** SyncdPatch deviceIndex */ - deviceIndex?: (number|null); - } - - /** Represents a SyncdPatch. */ - class SyncdPatch implements ISyncdPatch { - - /** - * Constructs a new SyncdPatch. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISyncdPatch); - - /** SyncdPatch version. */ - public version?: (proto.ISyncdVersion|null); - - /** SyncdPatch mutations. */ - public mutations: proto.ISyncdMutation[]; - - /** SyncdPatch externalMutations. */ - public externalMutations?: (proto.IExternalBlobReference|null); - - /** SyncdPatch snapshotMac. */ - public snapshotMac: Uint8Array; - - /** SyncdPatch patchMac. */ - public patchMac: Uint8Array; - - /** SyncdPatch keyId. */ - public keyId?: (proto.IKeyId|null); - - /** SyncdPatch exitCode. */ - public exitCode?: (proto.IExitCode|null); - - /** SyncdPatch deviceIndex. */ - public deviceIndex: number; - - /** - * Creates a new SyncdPatch instance using the specified properties. - * @param [properties] Properties to set - * @returns SyncdPatch instance - */ - public static create(properties?: proto.ISyncdPatch): proto.SyncdPatch; - - /** - * Encodes the specified SyncdPatch message. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages. - * @param message SyncdPatch message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISyncdPatch, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SyncdPatch message, length delimited. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages. - * @param message SyncdPatch message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISyncdPatch, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SyncdPatch message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SyncdPatch - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdPatch; - - /** - * Decodes a SyncdPatch message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SyncdPatch - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdPatch; - - /** - * Verifies a SyncdPatch message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SyncdPatch message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SyncdPatch - */ - public static fromObject(object: { [k: string]: any }): proto.SyncdPatch; - - /** - * Creates a plain object from a SyncdPatch message. Also converts values to other types if specified. - * @param message SyncdPatch - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SyncdPatch, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SyncdPatch to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a SyncdMutation. */ - interface ISyncdMutation { - - /** SyncdMutation operation */ - operation?: (proto.SyncdMutation.SyncdMutationSyncdOperation|null); - - /** SyncdMutation record */ - record?: (proto.ISyncdRecord|null); - } - - /** Represents a SyncdMutation. */ - class SyncdMutation implements ISyncdMutation { - - /** - * Constructs a new SyncdMutation. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISyncdMutation); - - /** SyncdMutation operation. */ - public operation: proto.SyncdMutation.SyncdMutationSyncdOperation; - - /** SyncdMutation record. */ - public record?: (proto.ISyncdRecord|null); - - /** - * Creates a new SyncdMutation instance using the specified properties. - * @param [properties] Properties to set - * @returns SyncdMutation instance - */ - public static create(properties?: proto.ISyncdMutation): proto.SyncdMutation; - - /** - * Encodes the specified SyncdMutation message. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages. - * @param message SyncdMutation message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISyncdMutation, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SyncdMutation message, length delimited. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages. - * @param message SyncdMutation message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISyncdMutation, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SyncdMutation message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SyncdMutation - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdMutation; - - /** - * Decodes a SyncdMutation message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SyncdMutation - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdMutation; - - /** - * Verifies a SyncdMutation message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SyncdMutation message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SyncdMutation - */ - public static fromObject(object: { [k: string]: any }): proto.SyncdMutation; - - /** - * Creates a plain object from a SyncdMutation message. Also converts values to other types if specified. - * @param message SyncdMutation - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SyncdMutation, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SyncdMutation to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - namespace SyncdMutation { - - /** SyncdMutationSyncdOperation enum. */ - enum SyncdMutationSyncdOperation { - SET = 0, - REMOVE = 1 - } - } - - /** Properties of a SyncdMutations. */ - interface ISyncdMutations { - - /** SyncdMutations mutations */ - mutations?: (proto.ISyncdMutation[]|null); - } - - /** Represents a SyncdMutations. */ - class SyncdMutations implements ISyncdMutations { - - /** - * Constructs a new SyncdMutations. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISyncdMutations); - - /** SyncdMutations mutations. */ - public mutations: proto.ISyncdMutation[]; - - /** - * Creates a new SyncdMutations instance using the specified properties. - * @param [properties] Properties to set - * @returns SyncdMutations instance - */ - public static create(properties?: proto.ISyncdMutations): proto.SyncdMutations; - - /** - * Encodes the specified SyncdMutations message. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages. - * @param message SyncdMutations message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISyncdMutations, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SyncdMutations message, length delimited. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages. - * @param message SyncdMutations message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISyncdMutations, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SyncdMutations message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SyncdMutations - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdMutations; - - /** - * Decodes a SyncdMutations message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SyncdMutations - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdMutations; - - /** - * Verifies a SyncdMutations message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SyncdMutations message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SyncdMutations - */ - public static fromObject(object: { [k: string]: any }): proto.SyncdMutations; - - /** - * Creates a plain object from a SyncdMutations message. Also converts values to other types if specified. - * @param message SyncdMutations - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SyncdMutations, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SyncdMutations to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a SyncdSnapshot. */ - interface ISyncdSnapshot { - - /** SyncdSnapshot version */ - version?: (proto.ISyncdVersion|null); - - /** SyncdSnapshot records */ - records?: (proto.ISyncdRecord[]|null); - - /** SyncdSnapshot mac */ - mac?: (Uint8Array|null); - - /** SyncdSnapshot keyId */ - keyId?: (proto.IKeyId|null); - } - - /** Represents a SyncdSnapshot. */ - class SyncdSnapshot implements ISyncdSnapshot { - - /** - * Constructs a new SyncdSnapshot. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISyncdSnapshot); - - /** SyncdSnapshot version. */ - public version?: (proto.ISyncdVersion|null); - - /** SyncdSnapshot records. */ - public records: proto.ISyncdRecord[]; - - /** SyncdSnapshot mac. */ - public mac: Uint8Array; - - /** SyncdSnapshot keyId. */ - public keyId?: (proto.IKeyId|null); - - /** - * Creates a new SyncdSnapshot instance using the specified properties. - * @param [properties] Properties to set - * @returns SyncdSnapshot instance - */ - public static create(properties?: proto.ISyncdSnapshot): proto.SyncdSnapshot; - - /** - * Encodes the specified SyncdSnapshot message. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages. - * @param message SyncdSnapshot message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISyncdSnapshot, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SyncdSnapshot message, length delimited. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages. - * @param message SyncdSnapshot message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISyncdSnapshot, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SyncdSnapshot message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SyncdSnapshot - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdSnapshot; - - /** - * Decodes a SyncdSnapshot message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SyncdSnapshot - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdSnapshot; - - /** - * Verifies a SyncdSnapshot message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SyncdSnapshot message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SyncdSnapshot - */ - public static fromObject(object: { [k: string]: any }): proto.SyncdSnapshot; - - /** - * Creates a plain object from a SyncdSnapshot message. Also converts values to other types if specified. - * @param message SyncdSnapshot - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SyncdSnapshot, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SyncdSnapshot to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of an ExternalBlobReference. */ - interface IExternalBlobReference { - - /** ExternalBlobReference mediaKey */ - mediaKey?: (Uint8Array|null); - - /** ExternalBlobReference directPath */ - directPath?: (string|null); - - /** ExternalBlobReference handle */ - handle?: (string|null); - - /** ExternalBlobReference fileSizeBytes */ - fileSizeBytes?: (number|Long|null); - - /** ExternalBlobReference fileSha256 */ - fileSha256?: (Uint8Array|null); - - /** ExternalBlobReference fileEncSha256 */ - fileEncSha256?: (Uint8Array|null); - } - - /** Represents an ExternalBlobReference. */ - class ExternalBlobReference implements IExternalBlobReference { - - /** - * Constructs a new ExternalBlobReference. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IExternalBlobReference); - - /** ExternalBlobReference mediaKey. */ - public mediaKey: Uint8Array; - - /** ExternalBlobReference directPath. */ - public directPath: string; - - /** ExternalBlobReference handle. */ - public handle: string; - - /** ExternalBlobReference fileSizeBytes. */ - public fileSizeBytes: (number|Long); - - /** ExternalBlobReference fileSha256. */ - public fileSha256: Uint8Array; - - /** ExternalBlobReference fileEncSha256. */ - public fileEncSha256: Uint8Array; - - /** - * Creates a new ExternalBlobReference instance using the specified properties. - * @param [properties] Properties to set - * @returns ExternalBlobReference instance - */ - public static create(properties?: proto.IExternalBlobReference): proto.ExternalBlobReference; - - /** - * Encodes the specified ExternalBlobReference message. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages. - * @param message ExternalBlobReference message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IExternalBlobReference, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ExternalBlobReference message, length delimited. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages. - * @param message ExternalBlobReference message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IExternalBlobReference, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes an ExternalBlobReference message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ExternalBlobReference - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ExternalBlobReference; - - /** - * Decodes an ExternalBlobReference message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ExternalBlobReference - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ExternalBlobReference; - - /** - * Verifies an ExternalBlobReference message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates an ExternalBlobReference message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ExternalBlobReference - */ - public static fromObject(object: { [k: string]: any }): proto.ExternalBlobReference; - - /** - * Creates a plain object from an ExternalBlobReference message. Also converts values to other types if specified. - * @param message ExternalBlobReference - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ExternalBlobReference, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ExternalBlobReference to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a SyncdRecord. */ - interface ISyncdRecord { - - /** SyncdRecord index */ - index?: (proto.ISyncdIndex|null); - - /** SyncdRecord value */ - value?: (proto.ISyncdValue|null); - - /** SyncdRecord keyId */ - keyId?: (proto.IKeyId|null); - } - - /** Represents a SyncdRecord. */ - class SyncdRecord implements ISyncdRecord { - - /** - * Constructs a new SyncdRecord. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISyncdRecord); - - /** SyncdRecord index. */ - public index?: (proto.ISyncdIndex|null); - - /** SyncdRecord value. */ - public value?: (proto.ISyncdValue|null); - - /** SyncdRecord keyId. */ - public keyId?: (proto.IKeyId|null); - - /** - * Creates a new SyncdRecord instance using the specified properties. - * @param [properties] Properties to set - * @returns SyncdRecord instance - */ - public static create(properties?: proto.ISyncdRecord): proto.SyncdRecord; - - /** - * Encodes the specified SyncdRecord message. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages. - * @param message SyncdRecord message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISyncdRecord, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SyncdRecord message, length delimited. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages. - * @param message SyncdRecord message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISyncdRecord, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SyncdRecord message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SyncdRecord - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdRecord; - - /** - * Decodes a SyncdRecord message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SyncdRecord - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdRecord; - - /** - * Verifies a SyncdRecord message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SyncdRecord message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SyncdRecord - */ - public static fromObject(object: { [k: string]: any }): proto.SyncdRecord; - - /** - * Creates a plain object from a SyncdRecord message. Also converts values to other types if specified. - * @param message SyncdRecord - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SyncdRecord, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SyncdRecord to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a KeyId. */ - interface IKeyId { - - /** KeyId id */ - id?: (Uint8Array|null); - } - - /** Represents a KeyId. */ - class KeyId implements IKeyId { - - /** - * Constructs a new KeyId. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IKeyId); - - /** KeyId id. */ - public id: Uint8Array; - - /** - * Creates a new KeyId instance using the specified properties. - * @param [properties] Properties to set - * @returns KeyId instance - */ - public static create(properties?: proto.IKeyId): proto.KeyId; - - /** - * Encodes the specified KeyId message. Does not implicitly {@link proto.KeyId.verify|verify} messages. - * @param message KeyId message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IKeyId, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified KeyId message, length delimited. Does not implicitly {@link proto.KeyId.verify|verify} messages. - * @param message KeyId message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IKeyId, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a KeyId message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns KeyId - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.KeyId; - - /** - * Decodes a KeyId message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns KeyId - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.KeyId; - - /** - * Verifies a KeyId message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a KeyId message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns KeyId - */ - public static fromObject(object: { [k: string]: any }): proto.KeyId; - - /** - * Creates a plain object from a KeyId message. Also converts values to other types if specified. - * @param message KeyId - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.KeyId, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this KeyId to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a SyncdValue. */ - interface ISyncdValue { - - /** SyncdValue blob */ - blob?: (Uint8Array|null); - } - - /** Represents a SyncdValue. */ - class SyncdValue implements ISyncdValue { - - /** - * Constructs a new SyncdValue. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISyncdValue); - - /** SyncdValue blob. */ - public blob: Uint8Array; - - /** - * Creates a new SyncdValue instance using the specified properties. - * @param [properties] Properties to set - * @returns SyncdValue instance - */ - public static create(properties?: proto.ISyncdValue): proto.SyncdValue; - - /** - * Encodes the specified SyncdValue message. Does not implicitly {@link proto.SyncdValue.verify|verify} messages. - * @param message SyncdValue message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISyncdValue, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SyncdValue message, length delimited. Does not implicitly {@link proto.SyncdValue.verify|verify} messages. - * @param message SyncdValue message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISyncdValue, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SyncdValue message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SyncdValue - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdValue; - - /** - * Decodes a SyncdValue message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SyncdValue - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdValue; - - /** - * Verifies a SyncdValue message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SyncdValue message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SyncdValue - */ - public static fromObject(object: { [k: string]: any }): proto.SyncdValue; - - /** - * Creates a plain object from a SyncdValue message. Also converts values to other types if specified. - * @param message SyncdValue - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SyncdValue, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SyncdValue to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a SyncdIndex. */ - interface ISyncdIndex { - - /** SyncdIndex blob */ - blob?: (Uint8Array|null); - } - - /** Represents a SyncdIndex. */ - class SyncdIndex implements ISyncdIndex { - - /** - * Constructs a new SyncdIndex. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISyncdIndex); - - /** SyncdIndex blob. */ - public blob: Uint8Array; - - /** - * Creates a new SyncdIndex instance using the specified properties. - * @param [properties] Properties to set - * @returns SyncdIndex instance - */ - public static create(properties?: proto.ISyncdIndex): proto.SyncdIndex; - - /** - * Encodes the specified SyncdIndex message. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages. - * @param message SyncdIndex message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISyncdIndex, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SyncdIndex message, length delimited. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages. - * @param message SyncdIndex message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISyncdIndex, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SyncdIndex message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SyncdIndex - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdIndex; - - /** - * Decodes a SyncdIndex message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SyncdIndex - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdIndex; - - /** - * Verifies a SyncdIndex message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SyncdIndex message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SyncdIndex - */ - public static fromObject(object: { [k: string]: any }): proto.SyncdIndex; - - /** - * Creates a plain object from a SyncdIndex message. Also converts values to other types if specified. - * @param message SyncdIndex - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SyncdIndex, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SyncdIndex to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of an ExitCode. */ - interface IExitCode { - - /** ExitCode code */ - code?: (number|Long|null); - - /** ExitCode text */ - text?: (string|null); - } - - /** Represents an ExitCode. */ - class ExitCode implements IExitCode { - - /** - * Constructs a new ExitCode. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IExitCode); - - /** ExitCode code. */ - public code: (number|Long); - - /** ExitCode text. */ - public text: string; - - /** - * Creates a new ExitCode instance using the specified properties. - * @param [properties] Properties to set - * @returns ExitCode instance - */ - public static create(properties?: proto.IExitCode): proto.ExitCode; - - /** - * Encodes the specified ExitCode message. Does not implicitly {@link proto.ExitCode.verify|verify} messages. - * @param message ExitCode message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IExitCode, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ExitCode message, length delimited. Does not implicitly {@link proto.ExitCode.verify|verify} messages. - * @param message ExitCode message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IExitCode, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes an ExitCode message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ExitCode - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ExitCode; - - /** - * Decodes an ExitCode message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ExitCode - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ExitCode; - - /** - * Verifies an ExitCode message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates an ExitCode message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ExitCode - */ - public static fromObject(object: { [k: string]: any }): proto.ExitCode; - - /** - * Creates a plain object from an ExitCode message. Also converts values to other types if specified. - * @param message ExitCode - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ExitCode, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ExitCode to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a SyncdVersion. */ - interface ISyncdVersion { - - /** SyncdVersion version */ - version?: (number|Long|null); - } - - /** Represents a SyncdVersion. */ - class SyncdVersion implements ISyncdVersion { - - /** - * Constructs a new SyncdVersion. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ISyncdVersion); - - /** SyncdVersion version. */ - public version: (number|Long); - - /** - * Creates a new SyncdVersion instance using the specified properties. - * @param [properties] Properties to set - * @returns SyncdVersion instance - */ - public static create(properties?: proto.ISyncdVersion): proto.SyncdVersion; - - /** - * Encodes the specified SyncdVersion message. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages. - * @param message SyncdVersion message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ISyncdVersion, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified SyncdVersion message, length delimited. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages. - * @param message SyncdVersion message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ISyncdVersion, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a SyncdVersion message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns SyncdVersion - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdVersion; - - /** - * Decodes a SyncdVersion message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns SyncdVersion - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdVersion; - - /** - * Verifies a SyncdVersion message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a SyncdVersion message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns SyncdVersion - */ - public static fromObject(object: { [k: string]: any }): proto.SyncdVersion; - - /** - * Creates a plain object from a SyncdVersion message. Also converts values to other types if specified. - * @param message SyncdVersion - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.SyncdVersion, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this SyncdVersion to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a ServerErrorReceipt. */ - interface IServerErrorReceipt { - - /** ServerErrorReceipt stanzaId */ - stanzaId?: (string|null); - } - - /** Represents a ServerErrorReceipt. */ - class ServerErrorReceipt implements IServerErrorReceipt { - - /** - * Constructs a new ServerErrorReceipt. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IServerErrorReceipt); - - /** ServerErrorReceipt stanzaId. */ - public stanzaId: string; - - /** - * Creates a new ServerErrorReceipt instance using the specified properties. - * @param [properties] Properties to set - * @returns ServerErrorReceipt instance - */ - public static create(properties?: proto.IServerErrorReceipt): proto.ServerErrorReceipt; - - /** - * Encodes the specified ServerErrorReceipt message. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages. - * @param message ServerErrorReceipt message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IServerErrorReceipt, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ServerErrorReceipt message, length delimited. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages. - * @param message ServerErrorReceipt message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IServerErrorReceipt, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ServerErrorReceipt message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ServerErrorReceipt - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ServerErrorReceipt; - - /** - * Decodes a ServerErrorReceipt message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ServerErrorReceipt - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ServerErrorReceipt; - - /** - * Verifies a ServerErrorReceipt message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ServerErrorReceipt message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ServerErrorReceipt - */ - public static fromObject(object: { [k: string]: any }): proto.ServerErrorReceipt; - - /** - * Creates a plain object from a ServerErrorReceipt message. Also converts values to other types if specified. - * @param message ServerErrorReceipt - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ServerErrorReceipt, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ServerErrorReceipt to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a MediaRetryNotification. */ - interface IMediaRetryNotification { - - /** MediaRetryNotification stanzaId */ - stanzaId?: (string|null); - - /** MediaRetryNotification directPath */ - directPath?: (string|null); - - /** MediaRetryNotification result */ - result?: (proto.MediaRetryNotification.MediaRetryNotificationResultType|null); - } - - /** Represents a MediaRetryNotification. */ - class MediaRetryNotification implements IMediaRetryNotification { - - /** - * Constructs a new MediaRetryNotification. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IMediaRetryNotification); - - /** MediaRetryNotification stanzaId. */ - public stanzaId: string; - - /** MediaRetryNotification directPath. */ - public directPath: string; - - /** MediaRetryNotification result. */ - public result: proto.MediaRetryNotification.MediaRetryNotificationResultType; - - /** - * Creates a new MediaRetryNotification instance using the specified properties. - * @param [properties] Properties to set - * @returns MediaRetryNotification instance - */ - public static create(properties?: proto.IMediaRetryNotification): proto.MediaRetryNotification; - - /** - * Encodes the specified MediaRetryNotification message. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages. - * @param message MediaRetryNotification message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IMediaRetryNotification, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified MediaRetryNotification message, length delimited. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages. - * @param message MediaRetryNotification message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IMediaRetryNotification, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a MediaRetryNotification message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns MediaRetryNotification - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MediaRetryNotification; - - /** - * Decodes a MediaRetryNotification message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns MediaRetryNotification - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MediaRetryNotification; - - /** - * Verifies a MediaRetryNotification message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a MediaRetryNotification message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns MediaRetryNotification - */ - public static fromObject(object: { [k: string]: any }): proto.MediaRetryNotification; - - /** - * Creates a plain object from a MediaRetryNotification message. Also converts values to other types if specified. - * @param message MediaRetryNotification - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.MediaRetryNotification, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this MediaRetryNotification to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - namespace MediaRetryNotification { - - /** MediaRetryNotificationResultType enum. */ - enum MediaRetryNotificationResultType { - GENERAL_ERROR = 0, - SUCCESS = 1, - NOT_FOUND = 2, - DECRYPTION_ERROR = 3 - } - } - - /** Properties of a MsgOpaqueData. */ - interface IMsgOpaqueData { - - /** MsgOpaqueData body */ - body?: (string|null); - - /** MsgOpaqueData caption */ - caption?: (string|null); - - /** MsgOpaqueData clientUrl */ - clientUrl?: (string|null); - - /** MsgOpaqueData lng */ - lng?: (number|null); - - /** MsgOpaqueData lat */ - lat?: (number|null); - - /** MsgOpaqueData paymentAmount1000 */ - paymentAmount1000?: (number|null); - - /** MsgOpaqueData paymentNoteMsgBody */ - paymentNoteMsgBody?: (string|null); - - /** MsgOpaqueData canonicalUrl */ - canonicalUrl?: (string|null); - - /** MsgOpaqueData matchedText */ - matchedText?: (string|null); - - /** MsgOpaqueData title */ - title?: (string|null); - - /** MsgOpaqueData description */ - description?: (string|null); - } - - /** Represents a MsgOpaqueData. */ - class MsgOpaqueData implements IMsgOpaqueData { - - /** - * Constructs a new MsgOpaqueData. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IMsgOpaqueData); - - /** MsgOpaqueData body. */ - public body: string; - - /** MsgOpaqueData caption. */ - public caption: string; - - /** MsgOpaqueData clientUrl. */ - public clientUrl: string; - - /** MsgOpaqueData lng. */ - public lng: number; - - /** MsgOpaqueData lat. */ - public lat: number; - - /** MsgOpaqueData paymentAmount1000. */ - public paymentAmount1000: number; - - /** MsgOpaqueData paymentNoteMsgBody. */ - public paymentNoteMsgBody: string; - - /** MsgOpaqueData canonicalUrl. */ - public canonicalUrl: string; - - /** MsgOpaqueData matchedText. */ - public matchedText: string; - - /** MsgOpaqueData title. */ - public title: string; - - /** MsgOpaqueData description. */ - public description: string; - - /** - * Creates a new MsgOpaqueData instance using the specified properties. - * @param [properties] Properties to set - * @returns MsgOpaqueData instance - */ - public static create(properties?: proto.IMsgOpaqueData): proto.MsgOpaqueData; - - /** - * Encodes the specified MsgOpaqueData message. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages. - * @param message MsgOpaqueData message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IMsgOpaqueData, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified MsgOpaqueData message, length delimited. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages. - * @param message MsgOpaqueData message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IMsgOpaqueData, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a MsgOpaqueData message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns MsgOpaqueData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MsgOpaqueData; - - /** - * Decodes a MsgOpaqueData message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns MsgOpaqueData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MsgOpaqueData; - - /** - * Verifies a MsgOpaqueData message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a MsgOpaqueData message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns MsgOpaqueData - */ - public static fromObject(object: { [k: string]: any }): proto.MsgOpaqueData; - - /** - * Creates a plain object from a MsgOpaqueData message. Also converts values to other types if specified. - * @param message MsgOpaqueData - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.MsgOpaqueData, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this MsgOpaqueData to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a MsgRowOpaqueData. */ - interface IMsgRowOpaqueData { - - /** MsgRowOpaqueData currentMsg */ - currentMsg?: (proto.IMsgOpaqueData|null); - - /** MsgRowOpaqueData quotedMsg */ - quotedMsg?: (proto.IMsgOpaqueData|null); - } - - /** Represents a MsgRowOpaqueData. */ - class MsgRowOpaqueData implements IMsgRowOpaqueData { - - /** - * Constructs a new MsgRowOpaqueData. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IMsgRowOpaqueData); - - /** MsgRowOpaqueData currentMsg. */ - public currentMsg?: (proto.IMsgOpaqueData|null); - - /** MsgRowOpaqueData quotedMsg. */ - public quotedMsg?: (proto.IMsgOpaqueData|null); - - /** - * Creates a new MsgRowOpaqueData instance using the specified properties. - * @param [properties] Properties to set - * @returns MsgRowOpaqueData instance - */ - public static create(properties?: proto.IMsgRowOpaqueData): proto.MsgRowOpaqueData; - - /** - * Encodes the specified MsgRowOpaqueData message. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages. - * @param message MsgRowOpaqueData message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IMsgRowOpaqueData, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified MsgRowOpaqueData message, length delimited. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages. - * @param message MsgRowOpaqueData message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IMsgRowOpaqueData, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a MsgRowOpaqueData message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns MsgRowOpaqueData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MsgRowOpaqueData; - - /** - * Decodes a MsgRowOpaqueData message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns MsgRowOpaqueData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MsgRowOpaqueData; - - /** - * Verifies a MsgRowOpaqueData message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a MsgRowOpaqueData message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns MsgRowOpaqueData - */ - public static fromObject(object: { [k: string]: any }): proto.MsgRowOpaqueData; - - /** - * Creates a plain object from a MsgRowOpaqueData message. Also converts values to other types if specified. - * @param message MsgRowOpaqueData - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.MsgRowOpaqueData, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this MsgRowOpaqueData to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a Pushname. */ - interface IPushname { - - /** Pushname id */ - id?: (string|null); - - /** Pushname pushname */ - pushname?: (string|null); - } - - /** Represents a Pushname. */ - class Pushname implements IPushname { - - /** - * Constructs a new Pushname. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IPushname); - - /** Pushname id. */ - public id: string; - - /** Pushname pushname. */ - public pushname: string; - - /** - * Creates a new Pushname instance using the specified properties. - * @param [properties] Properties to set - * @returns Pushname instance - */ - public static create(properties?: proto.IPushname): proto.Pushname; - - /** - * Encodes the specified Pushname message. Does not implicitly {@link proto.Pushname.verify|verify} messages. - * @param message Pushname message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IPushname, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified Pushname message, length delimited. Does not implicitly {@link proto.Pushname.verify|verify} messages. - * @param message Pushname message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IPushname, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a Pushname message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns Pushname - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Pushname; - - /** - * Decodes a Pushname message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns Pushname - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Pushname; - - /** - * Verifies a Pushname message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a Pushname message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns Pushname - */ - public static fromObject(object: { [k: string]: any }): proto.Pushname; - - /** - * Creates a plain object from a Pushname message. Also converts values to other types if specified. - * @param message Pushname - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.Pushname, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this Pushname to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HistorySyncMsg. */ - interface IHistorySyncMsg { - - /** HistorySyncMsg message */ - message?: (proto.IWebMessageInfo|null); - - /** HistorySyncMsg msgOrderId */ - msgOrderId?: (number|Long|null); - } - - /** Represents a HistorySyncMsg. */ - class HistorySyncMsg implements IHistorySyncMsg { - - /** - * Constructs a new HistorySyncMsg. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHistorySyncMsg); - - /** HistorySyncMsg message. */ - public message?: (proto.IWebMessageInfo|null); - - /** HistorySyncMsg msgOrderId. */ - public msgOrderId: (number|Long); - - /** - * Creates a new HistorySyncMsg instance using the specified properties. - * @param [properties] Properties to set - * @returns HistorySyncMsg instance - */ - public static create(properties?: proto.IHistorySyncMsg): proto.HistorySyncMsg; - - /** - * Encodes the specified HistorySyncMsg message. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages. - * @param message HistorySyncMsg message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHistorySyncMsg, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HistorySyncMsg message, length delimited. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages. - * @param message HistorySyncMsg message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHistorySyncMsg, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HistorySyncMsg message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HistorySyncMsg - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HistorySyncMsg; - - /** - * Decodes a HistorySyncMsg message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HistorySyncMsg - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HistorySyncMsg; - - /** - * Verifies a HistorySyncMsg message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HistorySyncMsg message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HistorySyncMsg - */ - public static fromObject(object: { [k: string]: any }): proto.HistorySyncMsg; - - /** - * Creates a plain object from a HistorySyncMsg message. Also converts values to other types if specified. - * @param message HistorySyncMsg - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HistorySyncMsg, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HistorySyncMsg to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a Conversation. */ - interface IConversation { - - /** Conversation id */ - id: string; - - /** Conversation messages */ - messages?: (proto.IHistorySyncMsg[]|null); - - /** Conversation newJid */ - newJid?: (string|null); - - /** Conversation oldJid */ - oldJid?: (string|null); - - /** Conversation lastMsgTimestamp */ - lastMsgTimestamp?: (number|Long|null); - - /** Conversation unreadCount */ - unreadCount?: (number|null); - - /** Conversation readOnly */ - readOnly?: (boolean|null); - - /** Conversation endOfHistoryTransfer */ - endOfHistoryTransfer?: (boolean|null); - - /** Conversation ephemeralExpiration */ - ephemeralExpiration?: (number|null); - - /** Conversation ephemeralSettingTimestamp */ - ephemeralSettingTimestamp?: (number|Long|null); - - /** Conversation endOfHistoryTransferType */ - endOfHistoryTransferType?: (proto.Conversation.ConversationEndOfHistoryTransferType|null); - - /** Conversation conversationTimestamp */ - conversationTimestamp?: (number|Long|null); - - /** Conversation name */ - name?: (string|null); - - /** Conversation pHash */ - pHash?: (string|null); - - /** Conversation notSpam */ - notSpam?: (boolean|null); - } - - /** Represents a Conversation. */ - class Conversation implements IConversation { - - /** - * Constructs a new Conversation. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IConversation); - - /** Conversation id. */ - public id: string; - - /** Conversation messages. */ - public messages: proto.IHistorySyncMsg[]; - - /** Conversation newJid. */ - public newJid: string; - - /** Conversation oldJid. */ - public oldJid: string; - - /** Conversation lastMsgTimestamp. */ - public lastMsgTimestamp: (number|Long); - - /** Conversation unreadCount. */ - public unreadCount: number; - - /** Conversation readOnly. */ - public readOnly: boolean; - - /** Conversation endOfHistoryTransfer. */ - public endOfHistoryTransfer: boolean; - - /** Conversation ephemeralExpiration. */ - public ephemeralExpiration: number; - - /** Conversation ephemeralSettingTimestamp. */ - public ephemeralSettingTimestamp: (number|Long); - - /** Conversation endOfHistoryTransferType. */ - public endOfHistoryTransferType: proto.Conversation.ConversationEndOfHistoryTransferType; - - /** Conversation conversationTimestamp. */ - public conversationTimestamp: (number|Long); - - /** Conversation name. */ - public name: string; - - /** Conversation pHash. */ - public pHash: string; - - /** Conversation notSpam. */ - public notSpam: boolean; - - /** - * Creates a new Conversation instance using the specified properties. - * @param [properties] Properties to set - * @returns Conversation instance - */ - public static create(properties?: proto.IConversation): proto.Conversation; - - /** - * Encodes the specified Conversation message. Does not implicitly {@link proto.Conversation.verify|verify} messages. - * @param message Conversation message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IConversation, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified Conversation message, length delimited. Does not implicitly {@link proto.Conversation.verify|verify} messages. - * @param message Conversation message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IConversation, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a Conversation message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns Conversation - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Conversation; - - /** - * Decodes a Conversation message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns Conversation - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Conversation; - - /** - * Verifies a Conversation message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a Conversation message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns Conversation - */ - public static fromObject(object: { [k: string]: any }): proto.Conversation; - - /** - * Creates a plain object from a Conversation message. Also converts values to other types if specified. - * @param message Conversation - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.Conversation, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this Conversation to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - namespace Conversation { - - /** ConversationEndOfHistoryTransferType enum. */ - enum ConversationEndOfHistoryTransferType { - COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY = 0, - COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY = 1 - } - } - - /** Properties of a HistorySync. */ - interface IHistorySync { - - /** HistorySync syncType */ - syncType: proto.HistorySync.HistorySyncHistorySyncType; - - /** HistorySync conversations */ - conversations?: (proto.IConversation[]|null); - - /** HistorySync statusV3Messages */ - statusV3Messages?: (proto.IWebMessageInfo[]|null); - - /** HistorySync chunkOrder */ - chunkOrder?: (number|null); - - /** HistorySync progress */ - progress?: (number|null); - - /** HistorySync pushnames */ - pushnames?: (proto.IPushname[]|null); - } - - /** Represents a HistorySync. */ - class HistorySync implements IHistorySync { - - /** - * Constructs a new HistorySync. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHistorySync); - - /** HistorySync syncType. */ - public syncType: proto.HistorySync.HistorySyncHistorySyncType; - - /** HistorySync conversations. */ - public conversations: proto.IConversation[]; - - /** HistorySync statusV3Messages. */ - public statusV3Messages: proto.IWebMessageInfo[]; - - /** HistorySync chunkOrder. */ - public chunkOrder: number; - - /** HistorySync progress. */ - public progress: number; - - /** HistorySync pushnames. */ - public pushnames: proto.IPushname[]; - - /** - * Creates a new HistorySync instance using the specified properties. - * @param [properties] Properties to set - * @returns HistorySync instance - */ - public static create(properties?: proto.IHistorySync): proto.HistorySync; - - /** - * Encodes the specified HistorySync message. Does not implicitly {@link proto.HistorySync.verify|verify} messages. - * @param message HistorySync message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHistorySync, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HistorySync message, length delimited. Does not implicitly {@link proto.HistorySync.verify|verify} messages. - * @param message HistorySync message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHistorySync, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HistorySync message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HistorySync - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HistorySync; - - /** - * Decodes a HistorySync message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HistorySync - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HistorySync; - - /** - * Verifies a HistorySync message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HistorySync message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HistorySync - */ - public static fromObject(object: { [k: string]: any }): proto.HistorySync; - - /** - * Creates a plain object from a HistorySync message. Also converts values to other types if specified. - * @param message HistorySync - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HistorySync, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HistorySync to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - namespace HistorySync { - - /** HistorySyncHistorySyncType enum. */ - enum HistorySyncHistorySyncType { - INITIAL_BOOTSTRAP = 0, - INITIAL_STATUS_V3 = 1, - FULL = 2, - RECENT = 3, - PUSH_NAME = 4 - } - } - - /** Properties of an EphemeralSetting. */ - interface IEphemeralSetting { - - /** EphemeralSetting duration */ - duration?: (number|null); - - /** EphemeralSetting timestamp */ - timestamp?: (number|Long|null); - } - - /** Represents an EphemeralSetting. */ - class EphemeralSetting implements IEphemeralSetting { - - /** - * Constructs a new EphemeralSetting. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IEphemeralSetting); - - /** EphemeralSetting duration. */ - public duration: number; - - /** EphemeralSetting timestamp. */ - public timestamp: (number|Long); - - /** - * Creates a new EphemeralSetting instance using the specified properties. - * @param [properties] Properties to set - * @returns EphemeralSetting instance - */ - public static create(properties?: proto.IEphemeralSetting): proto.EphemeralSetting; - - /** - * Encodes the specified EphemeralSetting message. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. - * @param message EphemeralSetting message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IEphemeralSetting, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified EphemeralSetting message, length delimited. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. - * @param message EphemeralSetting message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IEphemeralSetting, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes an EphemeralSetting message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns EphemeralSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.EphemeralSetting; - - /** - * Decodes an EphemeralSetting message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns EphemeralSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.EphemeralSetting; - - /** - * Verifies an EphemeralSetting message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates an EphemeralSetting message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns EphemeralSetting - */ - public static fromObject(object: { [k: string]: any }): proto.EphemeralSetting; - - /** - * Creates a plain object from an EphemeralSetting message. Also converts values to other types if specified. - * @param message EphemeralSetting - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.EphemeralSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this EphemeralSetting to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a PaymentBackground. */ - interface IPaymentBackground { - - /** PaymentBackground id */ - id?: (string|null); - - /** PaymentBackground fileLength */ - fileLength?: (string|null); - - /** PaymentBackground width */ - width?: (number|null); - - /** PaymentBackground height */ - height?: (number|null); - - /** PaymentBackground mimetype */ - mimetype?: (string|null); - - /** PaymentBackground placeholderArgb */ - placeholderArgb?: (number|null); - - /** PaymentBackground textArgb */ - textArgb?: (number|null); - - /** PaymentBackground subtextArgb */ - subtextArgb?: (number|null); - } - - /** Represents a PaymentBackground. */ - class PaymentBackground implements IPaymentBackground { - - /** - * Constructs a new PaymentBackground. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IPaymentBackground); - - /** PaymentBackground id. */ - public id: string; - - /** PaymentBackground fileLength. */ - public fileLength: string; - - /** PaymentBackground width. */ - public width: number; - - /** PaymentBackground height. */ - public height: number; - - /** PaymentBackground mimetype. */ - public mimetype: string; - - /** PaymentBackground placeholderArgb. */ - public placeholderArgb: number; - - /** PaymentBackground textArgb. */ - public textArgb: number; - - /** PaymentBackground subtextArgb. */ - public subtextArgb: number; - - /** - * Creates a new PaymentBackground instance using the specified properties. - * @param [properties] Properties to set - * @returns PaymentBackground instance - */ - public static create(properties?: proto.IPaymentBackground): proto.PaymentBackground; - - /** - * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. - * @param message PaymentBackground message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. - * @param message PaymentBackground message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a PaymentBackground message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns PaymentBackground - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PaymentBackground; - - /** - * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns PaymentBackground - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PaymentBackground; - - /** - * Verifies a PaymentBackground message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns PaymentBackground - */ - public static fromObject(object: { [k: string]: any }): proto.PaymentBackground; - - /** - * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. - * @param message PaymentBackground - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.PaymentBackground, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this PaymentBackground to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a Money. */ - interface IMoney { - - /** Money value */ - value?: (number|Long|null); - - /** Money offset */ - offset?: (number|null); - - /** Money currencyCode */ - currencyCode?: (string|null); - } - - /** Represents a Money. */ - class Money implements IMoney { - - /** - * Constructs a new Money. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IMoney); - - /** Money value. */ - public value: (number|Long); - - /** Money offset. */ - public offset: number; - - /** Money currencyCode. */ - public currencyCode: string; - - /** - * Creates a new Money instance using the specified properties. - * @param [properties] Properties to set - * @returns Money instance - */ - public static create(properties?: proto.IMoney): proto.Money; - - /** - * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. - * @param message Money message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. - * @param message Money message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a Money message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns Money - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Money; - - /** - * Decodes a Money message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns Money - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Money; - - /** - * Verifies a Money message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a Money message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns Money - */ - public static fromObject(object: { [k: string]: any }): proto.Money; - - /** - * Creates a plain object from a Money message. Also converts values to other types if specified. - * @param message Money - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.Money, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this Money to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HydratedQuickReplyButton. */ - interface IHydratedQuickReplyButton { - - /** HydratedQuickReplyButton displayText */ - displayText?: (string|null); - - /** HydratedQuickReplyButton id */ - id?: (string|null); - } - - /** Represents a HydratedQuickReplyButton. */ - class HydratedQuickReplyButton implements IHydratedQuickReplyButton { - - /** - * Constructs a new HydratedQuickReplyButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHydratedQuickReplyButton); - - /** HydratedQuickReplyButton displayText. */ - public displayText: string; - - /** HydratedQuickReplyButton id. */ - public id: string; - - /** - * Creates a new HydratedQuickReplyButton instance using the specified properties. - * @param [properties] Properties to set - * @returns HydratedQuickReplyButton instance - */ - public static create(properties?: proto.IHydratedQuickReplyButton): proto.HydratedQuickReplyButton; - - /** - * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. - * @param message HydratedQuickReplyButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHydratedQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. - * @param message HydratedQuickReplyButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHydratedQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HydratedQuickReplyButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HydratedQuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedQuickReplyButton; - - /** - * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HydratedQuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedQuickReplyButton; - - /** - * Verifies a HydratedQuickReplyButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HydratedQuickReplyButton - */ - public static fromObject(object: { [k: string]: any }): proto.HydratedQuickReplyButton; - - /** - * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified. - * @param message HydratedQuickReplyButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HydratedQuickReplyButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HydratedQuickReplyButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HydratedURLButton. */ - interface IHydratedURLButton { - - /** HydratedURLButton displayText */ - displayText?: (string|null); - - /** HydratedURLButton url */ - url?: (string|null); - } - - /** Represents a HydratedURLButton. */ - class HydratedURLButton implements IHydratedURLButton { - - /** - * Constructs a new HydratedURLButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHydratedURLButton); - - /** HydratedURLButton displayText. */ - public displayText: string; - - /** HydratedURLButton url. */ - public url: string; - - /** - * Creates a new HydratedURLButton instance using the specified properties. - * @param [properties] Properties to set - * @returns HydratedURLButton instance - */ - public static create(properties?: proto.IHydratedURLButton): proto.HydratedURLButton; - - /** - * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. - * @param message HydratedURLButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHydratedURLButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. - * @param message HydratedURLButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHydratedURLButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HydratedURLButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HydratedURLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedURLButton; - - /** - * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HydratedURLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedURLButton; - - /** - * Verifies a HydratedURLButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HydratedURLButton - */ - public static fromObject(object: { [k: string]: any }): proto.HydratedURLButton; - - /** - * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified. - * @param message HydratedURLButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HydratedURLButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HydratedURLButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HydratedCallButton. */ - interface IHydratedCallButton { - - /** HydratedCallButton displayText */ - displayText?: (string|null); - - /** HydratedCallButton phoneNumber */ - phoneNumber?: (string|null); - } - - /** Represents a HydratedCallButton. */ - class HydratedCallButton implements IHydratedCallButton { - - /** - * Constructs a new HydratedCallButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHydratedCallButton); - - /** HydratedCallButton displayText. */ - public displayText: string; - - /** HydratedCallButton phoneNumber. */ - public phoneNumber: string; - - /** - * Creates a new HydratedCallButton instance using the specified properties. - * @param [properties] Properties to set - * @returns HydratedCallButton instance - */ - public static create(properties?: proto.IHydratedCallButton): proto.HydratedCallButton; - - /** - * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. - * @param message HydratedCallButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHydratedCallButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. - * @param message HydratedCallButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHydratedCallButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HydratedCallButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HydratedCallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedCallButton; - - /** - * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HydratedCallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedCallButton; - - /** - * Verifies a HydratedCallButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HydratedCallButton - */ - public static fromObject(object: { [k: string]: any }): proto.HydratedCallButton; - - /** - * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified. - * @param message HydratedCallButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HydratedCallButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HydratedCallButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HydratedTemplateButton. */ - interface IHydratedTemplateButton { - - /** HydratedTemplateButton index */ - index?: (number|null); - - /** HydratedTemplateButton quickReplyButton */ - quickReplyButton?: (proto.IHydratedQuickReplyButton|null); - - /** HydratedTemplateButton urlButton */ - urlButton?: (proto.IHydratedURLButton|null); - - /** HydratedTemplateButton callButton */ - callButton?: (proto.IHydratedCallButton|null); - } - - /** Represents a HydratedTemplateButton. */ - class HydratedTemplateButton implements IHydratedTemplateButton { - - /** - * Constructs a new HydratedTemplateButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHydratedTemplateButton); - - /** HydratedTemplateButton index. */ - public index: number; - - /** HydratedTemplateButton quickReplyButton. */ - public quickReplyButton?: (proto.IHydratedQuickReplyButton|null); - - /** HydratedTemplateButton urlButton. */ - public urlButton?: (proto.IHydratedURLButton|null); - - /** HydratedTemplateButton callButton. */ - public callButton?: (proto.IHydratedCallButton|null); - - /** HydratedTemplateButton hydratedButton. */ - public hydratedButton?: ("quickReplyButton"|"urlButton"|"callButton"); - - /** - * Creates a new HydratedTemplateButton instance using the specified properties. - * @param [properties] Properties to set - * @returns HydratedTemplateButton instance - */ - public static create(properties?: proto.IHydratedTemplateButton): proto.HydratedTemplateButton; - - /** - * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. - * @param message HydratedTemplateButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHydratedTemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. - * @param message HydratedTemplateButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHydratedTemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HydratedTemplateButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HydratedTemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedTemplateButton; - - /** - * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HydratedTemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedTemplateButton; - - /** - * Verifies a HydratedTemplateButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HydratedTemplateButton - */ - public static fromObject(object: { [k: string]: any }): proto.HydratedTemplateButton; - - /** - * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified. - * @param message HydratedTemplateButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HydratedTemplateButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HydratedTemplateButton to JSON. + * Converts this MessageKey to JSON. * @returns JSON object */ public toJSON(): { [k: string]: any }; @@ -8827,6 +1359,9 @@ export namespace proto { /** ContextInfo entryPointConversionDelaySeconds */ entryPointConversionDelaySeconds?: (number|null); + + /** ContextInfo disappearingMode */ + disappearingMode?: (proto.IDisappearingMode|null); } /** Represents a ContextInfo. */ @@ -8895,6 +1430,9 @@ export namespace proto { /** ContextInfo entryPointConversionDelaySeconds. */ public entryPointConversionDelaySeconds: number; + /** ContextInfo disappearingMode. */ + public disappearingMode?: (proto.IDisappearingMode|null); + /** * Creates a new ContextInfo instance using the specified properties. * @param [properties] Properties to set @@ -9139,6 +1677,9 @@ export namespace proto { /** ImageMessage thumbnailEncSha256 */ thumbnailEncSha256?: (Uint8Array|null); + + /** ImageMessage staticUrl */ + staticUrl?: (string|null); } /** Represents an ImageMessage. */ @@ -9225,6 +1766,9 @@ export namespace proto { /** ImageMessage thumbnailEncSha256. */ public thumbnailEncSha256: Uint8Array; + /** ImageMessage staticUrl. */ + public staticUrl: string; + /** * Creates a new ImageMessage instance using the specified properties. * @param [properties] Properties to set @@ -10346,6 +2890,9 @@ export namespace proto { /** VideoMessage thumbnailEncSha256 */ thumbnailEncSha256?: (Uint8Array|null); + + /** VideoMessage staticUrl */ + staticUrl?: (string|null); } /** Represents a VideoMessage. */ @@ -10423,6 +2970,9 @@ export namespace proto { /** VideoMessage thumbnailEncSha256. */ public thumbnailEncSha256: Uint8Array; + /** VideoMessage staticUrl. */ + public staticUrl: string; + /** * Creates a new VideoMessage instance using the specified properties. * @param [properties] Properties to set @@ -10737,6 +3287,9 @@ export namespace proto { /** ProtocolMessage appStateFatalExceptionNotification */ appStateFatalExceptionNotification?: (proto.IAppStateFatalExceptionNotification|null); + + /** ProtocolMessage disappearingMode */ + disappearingMode?: (proto.IDisappearingMode|null); } /** Represents a ProtocolMessage. */ @@ -10775,6 +3328,9 @@ export namespace proto { /** ProtocolMessage appStateFatalExceptionNotification. */ public appStateFatalExceptionNotification?: (proto.IAppStateFatalExceptionNotification|null); + /** ProtocolMessage disappearingMode. */ + public disappearingMode?: (proto.IDisappearingMode|null); + /** * Creates a new ProtocolMessage instance using the specified properties. * @param [properties] Properties to set @@ -15332,6 +7888,649 @@ export namespace proto { } } + /** Properties of a Header. */ + interface IHeader { + + /** Header title */ + title?: (string|null); + + /** Header subtitle */ + subtitle?: (string|null); + + /** Header documentMessage */ + documentMessage?: (proto.IDocumentMessage|null); + + /** Header imageMessage */ + imageMessage?: (proto.IImageMessage|null); + } + + /** Represents a Header. */ + class Header implements IHeader { + + /** + * Constructs a new Header. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHeader); + + /** Header title. */ + public title: string; + + /** Header subtitle. */ + public subtitle: string; + + /** Header documentMessage. */ + public documentMessage?: (proto.IDocumentMessage|null); + + /** Header imageMessage. */ + public imageMessage?: (proto.IImageMessage|null); + + /** Header media. */ + public media?: ("documentMessage"|"imageMessage"); + + /** + * Creates a new Header instance using the specified properties. + * @param [properties] Properties to set + * @returns Header instance + */ + public static create(properties?: proto.IHeader): proto.Header; + + /** + * Encodes the specified Header message. Does not implicitly {@link proto.Header.verify|verify} messages. + * @param message Header message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHeader, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Header message, length delimited. Does not implicitly {@link proto.Header.verify|verify} messages. + * @param message Header message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHeader, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Header message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Header + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Header; + + /** + * Decodes a Header message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Header + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Header; + + /** + * Verifies a Header message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Header message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Header + */ + public static fromObject(object: { [k: string]: any }): proto.Header; + + /** + * Creates a plain object from a Header message. Also converts values to other types if specified. + * @param message Header + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Header, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Header to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Body. */ + interface IBody { + + /** Body text */ + text?: (string|null); + } + + /** Represents a Body. */ + class Body implements IBody { + + /** + * Constructs a new Body. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IBody); + + /** Body text. */ + public text: string; + + /** + * Creates a new Body instance using the specified properties. + * @param [properties] Properties to set + * @returns Body instance + */ + public static create(properties?: proto.IBody): proto.Body; + + /** + * Encodes the specified Body message. Does not implicitly {@link proto.Body.verify|verify} messages. + * @param message Body message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IBody, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Body message, length delimited. Does not implicitly {@link proto.Body.verify|verify} messages. + * @param message Body message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IBody, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Body message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Body + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Body; + + /** + * Decodes a Body message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Body + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Body; + + /** + * Verifies a Body message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Body message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Body + */ + public static fromObject(object: { [k: string]: any }): proto.Body; + + /** + * Creates a plain object from a Body message. Also converts values to other types if specified. + * @param message Body + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Body, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Body to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Footer. */ + interface IFooter { + + /** Footer text */ + text?: (string|null); + } + + /** Represents a Footer. */ + class Footer implements IFooter { + + /** + * Constructs a new Footer. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IFooter); + + /** Footer text. */ + public text: string; + + /** + * Creates a new Footer instance using the specified properties. + * @param [properties] Properties to set + * @returns Footer instance + */ + public static create(properties?: proto.IFooter): proto.Footer; + + /** + * Encodes the specified Footer message. Does not implicitly {@link proto.Footer.verify|verify} messages. + * @param message Footer message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IFooter, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Footer message, length delimited. Does not implicitly {@link proto.Footer.verify|verify} messages. + * @param message Footer message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IFooter, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Footer message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Footer + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Footer; + + /** + * Decodes a Footer message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Footer + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Footer; + + /** + * Verifies a Footer message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Footer message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Footer + */ + public static fromObject(object: { [k: string]: any }): proto.Footer; + + /** + * Creates a plain object from a Footer message. Also converts values to other types if specified. + * @param message Footer + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Footer, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Footer to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ShopsMessage. */ + interface IShopsMessage { + + /** ShopsMessage id */ + id?: (string|null); + + /** ShopsMessage surface */ + surface?: (proto.ShopsMessage.ShopsMessageSurface|null); + + /** ShopsMessage type */ + type?: (proto.ShopsMessage.ShopsMessageType|null); + + /** ShopsMessage messageVersion */ + messageVersion?: (number|null); + } + + /** Represents a ShopsMessage. */ + class ShopsMessage implements IShopsMessage { + + /** + * Constructs a new ShopsMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IShopsMessage); + + /** ShopsMessage id. */ + public id: string; + + /** ShopsMessage surface. */ + public surface: proto.ShopsMessage.ShopsMessageSurface; + + /** ShopsMessage type. */ + public type: proto.ShopsMessage.ShopsMessageType; + + /** ShopsMessage messageVersion. */ + public messageVersion: number; + + /** + * Creates a new ShopsMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns ShopsMessage instance + */ + public static create(properties?: proto.IShopsMessage): proto.ShopsMessage; + + /** + * Encodes the specified ShopsMessage message. Does not implicitly {@link proto.ShopsMessage.verify|verify} messages. + * @param message ShopsMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IShopsMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ShopsMessage message, length delimited. Does not implicitly {@link proto.ShopsMessage.verify|verify} messages. + * @param message ShopsMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IShopsMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ShopsMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ShopsMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ShopsMessage; + + /** + * Decodes a ShopsMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ShopsMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ShopsMessage; + + /** + * Verifies a ShopsMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ShopsMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ShopsMessage + */ + public static fromObject(object: { [k: string]: any }): proto.ShopsMessage; + + /** + * Creates a plain object from a ShopsMessage message. Also converts values to other types if specified. + * @param message ShopsMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ShopsMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ShopsMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace ShopsMessage { + + /** ShopsMessageSurface enum. */ + enum ShopsMessageSurface { + UNKNOWN_SURFACE = 0, + FB = 1, + IG = 2, + WA = 3 + } + + /** ShopsMessageType enum. */ + enum ShopsMessageType { + UNKNOWN_TYPE = 0, + PRODUCT = 1, + STOREFRONT = 2, + COLLECTION = 3 + } + } + + /** Properties of a CollectionMessage. */ + interface ICollectionMessage { + + /** CollectionMessage bizJid */ + bizJid?: (string|null); + + /** CollectionMessage id */ + id?: (string|null); + + /** CollectionMessage messageVersion */ + messageVersion?: (number|null); + } + + /** Represents a CollectionMessage. */ + class CollectionMessage implements ICollectionMessage { + + /** + * Constructs a new CollectionMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ICollectionMessage); + + /** CollectionMessage bizJid. */ + public bizJid: string; + + /** CollectionMessage id. */ + public id: string; + + /** CollectionMessage messageVersion. */ + public messageVersion: number; + + /** + * Creates a new CollectionMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns CollectionMessage instance + */ + public static create(properties?: proto.ICollectionMessage): proto.CollectionMessage; + + /** + * Encodes the specified CollectionMessage message. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages. + * @param message CollectionMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ICollectionMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified CollectionMessage message, length delimited. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages. + * @param message CollectionMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ICollectionMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a CollectionMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns CollectionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.CollectionMessage; + + /** + * Decodes a CollectionMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns CollectionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.CollectionMessage; + + /** + * Verifies a CollectionMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a CollectionMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns CollectionMessage + */ + public static fromObject(object: { [k: string]: any }): proto.CollectionMessage; + + /** + * Creates a plain object from a CollectionMessage message. Also converts values to other types if specified. + * @param message CollectionMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.CollectionMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this CollectionMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an InteractiveMessage. */ + interface IInteractiveMessage { + + /** InteractiveMessage header */ + header?: (proto.IHeader|null); + + /** InteractiveMessage body */ + body?: (proto.IBody|null); + + /** InteractiveMessage footer */ + footer?: (proto.IFooter|null); + + /** InteractiveMessage contextInfo */ + contextInfo?: (proto.IContextInfo|null); + + /** InteractiveMessage shopsMessage */ + shopsMessage?: (proto.IShopsMessage|null); + + /** InteractiveMessage collectionMessage */ + collectionMessage?: (proto.ICollectionMessage|null); + } + + /** Represents an InteractiveMessage. */ + class InteractiveMessage implements IInteractiveMessage { + + /** + * Constructs a new InteractiveMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IInteractiveMessage); + + /** InteractiveMessage header. */ + public header?: (proto.IHeader|null); + + /** InteractiveMessage body. */ + public body?: (proto.IBody|null); + + /** InteractiveMessage footer. */ + public footer?: (proto.IFooter|null); + + /** InteractiveMessage contextInfo. */ + public contextInfo?: (proto.IContextInfo|null); + + /** InteractiveMessage shopsMessage. */ + public shopsMessage?: (proto.IShopsMessage|null); + + /** InteractiveMessage collectionMessage. */ + public collectionMessage?: (proto.ICollectionMessage|null); + + /** InteractiveMessage interactiveMessage. */ + public interactiveMessage?: ("shopsMessage"|"collectionMessage"); + + /** + * Creates a new InteractiveMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns InteractiveMessage instance + */ + public static create(properties?: proto.IInteractiveMessage): proto.InteractiveMessage; + + /** + * Encodes the specified InteractiveMessage message. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages. + * @param message InteractiveMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IInteractiveMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified InteractiveMessage message, length delimited. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages. + * @param message InteractiveMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IInteractiveMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an InteractiveMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns InteractiveMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.InteractiveMessage; + + /** + * Decodes an InteractiveMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns InteractiveMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.InteractiveMessage; + + /** + * Verifies an InteractiveMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an InteractiveMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns InteractiveMessage + */ + public static fromObject(object: { [k: string]: any }): proto.InteractiveMessage; + + /** + * Creates a plain object from an InteractiveMessage message. Also converts values to other types if specified. + * @param message InteractiveMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.InteractiveMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this InteractiveMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of a GroupInviteMessage. */ interface IGroupInviteMessage { @@ -16345,6 +9544,9 @@ export namespace proto { /** Message paymentInviteMessage */ paymentInviteMessage?: (proto.IPaymentInviteMessage|null); + + /** Message interactiveMessage */ + interactiveMessage?: (proto.IInteractiveMessage|null); } /** Represents a Message. */ @@ -16464,6 +9666,9 @@ export namespace proto { /** Message paymentInviteMessage. */ public paymentInviteMessage?: (proto.IPaymentInviteMessage|null); + /** Message interactiveMessage. */ + public interactiveMessage?: (proto.IInteractiveMessage|null); + /** * Creates a new Message instance using the specified properties. * @param [properties] Properties to set @@ -16535,747 +9740,854 @@ export namespace proto { public toJSON(): { [k: string]: any }; } - /** Properties of a CompanionProps. */ - interface ICompanionProps { + /** Properties of a DisappearingMode. */ + interface IDisappearingMode { - /** CompanionProps os */ - os?: (string|null); - - /** CompanionProps version */ - version?: (proto.IAppVersion|null); - - /** CompanionProps platformType */ - platformType?: (proto.CompanionProps.CompanionPropsPlatformType|null); - - /** CompanionProps requireFullSync */ - requireFullSync?: (boolean|null); + /** DisappearingMode initiator */ + initiator?: (proto.DisappearingMode.DisappearingModeInitiator|null); } - /** Represents a CompanionProps. */ - class CompanionProps implements ICompanionProps { + /** Represents a DisappearingMode. */ + class DisappearingMode implements IDisappearingMode { /** - * Constructs a new CompanionProps. + * Constructs a new DisappearingMode. * @param [properties] Properties to set */ - constructor(properties?: proto.ICompanionProps); + constructor(properties?: proto.IDisappearingMode); - /** CompanionProps os. */ - public os: string; - - /** CompanionProps version. */ - public version?: (proto.IAppVersion|null); - - /** CompanionProps platformType. */ - public platformType: proto.CompanionProps.CompanionPropsPlatformType; - - /** CompanionProps requireFullSync. */ - public requireFullSync: boolean; + /** DisappearingMode initiator. */ + public initiator: proto.DisappearingMode.DisappearingModeInitiator; /** - * Creates a new CompanionProps instance using the specified properties. + * Creates a new DisappearingMode instance using the specified properties. * @param [properties] Properties to set - * @returns CompanionProps instance + * @returns DisappearingMode instance */ - public static create(properties?: proto.ICompanionProps): proto.CompanionProps; + public static create(properties?: proto.IDisappearingMode): proto.DisappearingMode; /** - * Encodes the specified CompanionProps message. Does not implicitly {@link proto.CompanionProps.verify|verify} messages. - * @param message CompanionProps message or plain object to encode + * Encodes the specified DisappearingMode message. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages. + * @param message DisappearingMode message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encode(message: proto.ICompanionProps, writer?: $protobuf.Writer): $protobuf.Writer; + public static encode(message: proto.IDisappearingMode, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Encodes the specified CompanionProps message, length delimited. Does not implicitly {@link proto.CompanionProps.verify|verify} messages. - * @param message CompanionProps message or plain object to encode + * Encodes the specified DisappearingMode message, length delimited. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages. + * @param message DisappearingMode message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encodeDelimited(message: proto.ICompanionProps, writer?: $protobuf.Writer): $protobuf.Writer; + public static encodeDelimited(message: proto.IDisappearingMode, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Decodes a CompanionProps message from the specified reader or buffer. + * Decodes a DisappearingMode message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns CompanionProps + * @returns DisappearingMode * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.CompanionProps; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DisappearingMode; /** - * Decodes a CompanionProps message from the specified reader or buffer, length delimited. + * Decodes a DisappearingMode message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns CompanionProps + * @returns DisappearingMode * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.CompanionProps; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DisappearingMode; /** - * Verifies a CompanionProps message. + * Verifies a DisappearingMode message. * @param message Plain object to verify * @returns `null` if valid, otherwise the reason why it is not */ public static verify(message: { [k: string]: any }): (string|null); /** - * Creates a CompanionProps message from a plain object. Also converts values to their respective internal types. + * Creates a DisappearingMode message from a plain object. Also converts values to their respective internal types. * @param object Plain object - * @returns CompanionProps + * @returns DisappearingMode */ - public static fromObject(object: { [k: string]: any }): proto.CompanionProps; + public static fromObject(object: { [k: string]: any }): proto.DisappearingMode; /** - * Creates a plain object from a CompanionProps message. Also converts values to other types if specified. - * @param message CompanionProps + * Creates a plain object from a DisappearingMode message. Also converts values to other types if specified. + * @param message DisappearingMode * @param [options] Conversion options * @returns Plain object */ - public static toObject(message: proto.CompanionProps, options?: $protobuf.IConversionOptions): { [k: string]: any }; + public static toObject(message: proto.DisappearingMode, options?: $protobuf.IConversionOptions): { [k: string]: any }; /** - * Converts this CompanionProps to JSON. + * Converts this DisappearingMode to JSON. * @returns JSON object */ public toJSON(): { [k: string]: any }; } - namespace CompanionProps { + namespace DisappearingMode { - /** CompanionPropsPlatformType enum. */ - enum CompanionPropsPlatformType { - UNKNOWN = 0, - CHROME = 1, - FIREFOX = 2, - IE = 3, - OPERA = 4, - SAFARI = 5, - EDGE = 6, - DESKTOP = 7, - IPAD = 8, - ANDROID_TABLET = 9, - OHANA = 10, - ALOHA = 11, - CATALINA = 12 + /** DisappearingModeInitiator enum. */ + enum DisappearingModeInitiator { + CHANGED_IN_CHAT = 0, + INITIATED_BY_ME = 1, + INITIATED_BY_OTHER = 2 } } - /** Properties of a ADVSignedDeviceIdentityHMAC. */ - interface IADVSignedDeviceIdentityHMAC { + /** Properties of a PaymentBackground. */ + interface IPaymentBackground { - /** ADVSignedDeviceIdentityHMAC details */ - details?: (Uint8Array|null); - - /** ADVSignedDeviceIdentityHMAC hmac */ - hmac?: (Uint8Array|null); - } - - /** Represents a ADVSignedDeviceIdentityHMAC. */ - class ADVSignedDeviceIdentityHMAC implements IADVSignedDeviceIdentityHMAC { - - /** - * Constructs a new ADVSignedDeviceIdentityHMAC. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IADVSignedDeviceIdentityHMAC); - - /** ADVSignedDeviceIdentityHMAC details. */ - public details: Uint8Array; - - /** ADVSignedDeviceIdentityHMAC hmac. */ - public hmac: Uint8Array; - - /** - * Creates a new ADVSignedDeviceIdentityHMAC instance using the specified properties. - * @param [properties] Properties to set - * @returns ADVSignedDeviceIdentityHMAC instance - */ - public static create(properties?: proto.IADVSignedDeviceIdentityHMAC): proto.ADVSignedDeviceIdentityHMAC; - - /** - * Encodes the specified ADVSignedDeviceIdentityHMAC message. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages. - * @param message ADVSignedDeviceIdentityHMAC message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IADVSignedDeviceIdentityHMAC, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ADVSignedDeviceIdentityHMAC message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages. - * @param message ADVSignedDeviceIdentityHMAC message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IADVSignedDeviceIdentityHMAC, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ADVSignedDeviceIdentityHMAC - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVSignedDeviceIdentityHMAC; - - /** - * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ADVSignedDeviceIdentityHMAC - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVSignedDeviceIdentityHMAC; - - /** - * Verifies a ADVSignedDeviceIdentityHMAC message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ADVSignedDeviceIdentityHMAC message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ADVSignedDeviceIdentityHMAC - */ - public static fromObject(object: { [k: string]: any }): proto.ADVSignedDeviceIdentityHMAC; - - /** - * Creates a plain object from a ADVSignedDeviceIdentityHMAC message. Also converts values to other types if specified. - * @param message ADVSignedDeviceIdentityHMAC - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ADVSignedDeviceIdentityHMAC, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ADVSignedDeviceIdentityHMAC to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a ADVSignedDeviceIdentity. */ - interface IADVSignedDeviceIdentity { - - /** ADVSignedDeviceIdentity details */ - details?: (Uint8Array|null); - - /** ADVSignedDeviceIdentity accountSignatureKey */ - accountSignatureKey?: (Uint8Array|null); - - /** ADVSignedDeviceIdentity accountSignature */ - accountSignature?: (Uint8Array|null); - - /** ADVSignedDeviceIdentity deviceSignature */ - deviceSignature?: (Uint8Array|null); - } - - /** Represents a ADVSignedDeviceIdentity. */ - class ADVSignedDeviceIdentity implements IADVSignedDeviceIdentity { - - /** - * Constructs a new ADVSignedDeviceIdentity. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IADVSignedDeviceIdentity); - - /** ADVSignedDeviceIdentity details. */ - public details: Uint8Array; - - /** ADVSignedDeviceIdentity accountSignatureKey. */ - public accountSignatureKey: Uint8Array; - - /** ADVSignedDeviceIdentity accountSignature. */ - public accountSignature: Uint8Array; - - /** ADVSignedDeviceIdentity deviceSignature. */ - public deviceSignature: Uint8Array; - - /** - * Creates a new ADVSignedDeviceIdentity instance using the specified properties. - * @param [properties] Properties to set - * @returns ADVSignedDeviceIdentity instance - */ - public static create(properties?: proto.IADVSignedDeviceIdentity): proto.ADVSignedDeviceIdentity; - - /** - * Encodes the specified ADVSignedDeviceIdentity message. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages. - * @param message ADVSignedDeviceIdentity message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IADVSignedDeviceIdentity, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ADVSignedDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages. - * @param message ADVSignedDeviceIdentity message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IADVSignedDeviceIdentity, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ADVSignedDeviceIdentity - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVSignedDeviceIdentity; - - /** - * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ADVSignedDeviceIdentity - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVSignedDeviceIdentity; - - /** - * Verifies a ADVSignedDeviceIdentity message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ADVSignedDeviceIdentity message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ADVSignedDeviceIdentity - */ - public static fromObject(object: { [k: string]: any }): proto.ADVSignedDeviceIdentity; - - /** - * Creates a plain object from a ADVSignedDeviceIdentity message. Also converts values to other types if specified. - * @param message ADVSignedDeviceIdentity - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ADVSignedDeviceIdentity, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ADVSignedDeviceIdentity to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a ADVDeviceIdentity. */ - interface IADVDeviceIdentity { - - /** ADVDeviceIdentity rawId */ - rawId?: (number|null); - - /** ADVDeviceIdentity timestamp */ - timestamp?: (number|Long|null); - - /** ADVDeviceIdentity keyIndex */ - keyIndex?: (number|null); - } - - /** Represents a ADVDeviceIdentity. */ - class ADVDeviceIdentity implements IADVDeviceIdentity { - - /** - * Constructs a new ADVDeviceIdentity. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IADVDeviceIdentity); - - /** ADVDeviceIdentity rawId. */ - public rawId: number; - - /** ADVDeviceIdentity timestamp. */ - public timestamp: (number|Long); - - /** ADVDeviceIdentity keyIndex. */ - public keyIndex: number; - - /** - * Creates a new ADVDeviceIdentity instance using the specified properties. - * @param [properties] Properties to set - * @returns ADVDeviceIdentity instance - */ - public static create(properties?: proto.IADVDeviceIdentity): proto.ADVDeviceIdentity; - - /** - * Encodes the specified ADVDeviceIdentity message. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages. - * @param message ADVDeviceIdentity message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IADVDeviceIdentity, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ADVDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages. - * @param message ADVDeviceIdentity message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IADVDeviceIdentity, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ADVDeviceIdentity message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ADVDeviceIdentity - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVDeviceIdentity; - - /** - * Decodes a ADVDeviceIdentity message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ADVDeviceIdentity - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVDeviceIdentity; - - /** - * Verifies a ADVDeviceIdentity message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ADVDeviceIdentity message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ADVDeviceIdentity - */ - public static fromObject(object: { [k: string]: any }): proto.ADVDeviceIdentity; - - /** - * Creates a plain object from a ADVDeviceIdentity message. Also converts values to other types if specified. - * @param message ADVDeviceIdentity - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ADVDeviceIdentity, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ADVDeviceIdentity to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a ADVSignedKeyIndexList. */ - interface IADVSignedKeyIndexList { - - /** ADVSignedKeyIndexList details */ - details?: (Uint8Array|null); - - /** ADVSignedKeyIndexList accountSignature */ - accountSignature?: (Uint8Array|null); - } - - /** Represents a ADVSignedKeyIndexList. */ - class ADVSignedKeyIndexList implements IADVSignedKeyIndexList { - - /** - * Constructs a new ADVSignedKeyIndexList. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IADVSignedKeyIndexList); - - /** ADVSignedKeyIndexList details. */ - public details: Uint8Array; - - /** ADVSignedKeyIndexList accountSignature. */ - public accountSignature: Uint8Array; - - /** - * Creates a new ADVSignedKeyIndexList instance using the specified properties. - * @param [properties] Properties to set - * @returns ADVSignedKeyIndexList instance - */ - public static create(properties?: proto.IADVSignedKeyIndexList): proto.ADVSignedKeyIndexList; - - /** - * Encodes the specified ADVSignedKeyIndexList message. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages. - * @param message ADVSignedKeyIndexList message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IADVSignedKeyIndexList, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ADVSignedKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages. - * @param message ADVSignedKeyIndexList message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IADVSignedKeyIndexList, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ADVSignedKeyIndexList - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVSignedKeyIndexList; - - /** - * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ADVSignedKeyIndexList - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVSignedKeyIndexList; - - /** - * Verifies a ADVSignedKeyIndexList message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ADVSignedKeyIndexList message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ADVSignedKeyIndexList - */ - public static fromObject(object: { [k: string]: any }): proto.ADVSignedKeyIndexList; - - /** - * Creates a plain object from a ADVSignedKeyIndexList message. Also converts values to other types if specified. - * @param message ADVSignedKeyIndexList - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ADVSignedKeyIndexList, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ADVSignedKeyIndexList to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a ADVKeyIndexList. */ - interface IADVKeyIndexList { - - /** ADVKeyIndexList rawId */ - rawId?: (number|null); - - /** ADVKeyIndexList timestamp */ - timestamp?: (number|Long|null); - - /** ADVKeyIndexList currentIndex */ - currentIndex?: (number|null); - - /** ADVKeyIndexList validIndexes */ - validIndexes?: (number[]|null); - } - - /** Represents a ADVKeyIndexList. */ - class ADVKeyIndexList implements IADVKeyIndexList { - - /** - * Constructs a new ADVKeyIndexList. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IADVKeyIndexList); - - /** ADVKeyIndexList rawId. */ - public rawId: number; - - /** ADVKeyIndexList timestamp. */ - public timestamp: (number|Long); - - /** ADVKeyIndexList currentIndex. */ - public currentIndex: number; - - /** ADVKeyIndexList validIndexes. */ - public validIndexes: number[]; - - /** - * Creates a new ADVKeyIndexList instance using the specified properties. - * @param [properties] Properties to set - * @returns ADVKeyIndexList instance - */ - public static create(properties?: proto.IADVKeyIndexList): proto.ADVKeyIndexList; - - /** - * Encodes the specified ADVKeyIndexList message. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages. - * @param message ADVKeyIndexList message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IADVKeyIndexList, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ADVKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages. - * @param message ADVKeyIndexList message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IADVKeyIndexList, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ADVKeyIndexList message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ADVKeyIndexList - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVKeyIndexList; - - /** - * Decodes a ADVKeyIndexList message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ADVKeyIndexList - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVKeyIndexList; - - /** - * Verifies a ADVKeyIndexList message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ADVKeyIndexList message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ADVKeyIndexList - */ - public static fromObject(object: { [k: string]: any }): proto.ADVKeyIndexList; - - /** - * Creates a plain object from a ADVKeyIndexList message. Also converts values to other types if specified. - * @param message ADVKeyIndexList - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ADVKeyIndexList, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ADVKeyIndexList to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a MessageKey. */ - interface IMessageKey { - - /** MessageKey remoteJid */ - remoteJid?: (string|null); - - /** MessageKey fromMe */ - fromMe?: (boolean|null); - - /** MessageKey id */ + /** PaymentBackground id */ id?: (string|null); - /** MessageKey participant */ - participant?: (string|null); + /** PaymentBackground fileLength */ + fileLength?: (number|Long|null); + + /** PaymentBackground width */ + width?: (number|null); + + /** PaymentBackground height */ + height?: (number|null); + + /** PaymentBackground mimetype */ + mimetype?: (string|null); + + /** PaymentBackground placeholderArgb */ + placeholderArgb?: (number|null); + + /** PaymentBackground textArgb */ + textArgb?: (number|null); + + /** PaymentBackground subtextArgb */ + subtextArgb?: (number|null); } - /** Represents a MessageKey. */ - class MessageKey implements IMessageKey { + /** Represents a PaymentBackground. */ + class PaymentBackground implements IPaymentBackground { /** - * Constructs a new MessageKey. + * Constructs a new PaymentBackground. * @param [properties] Properties to set */ - constructor(properties?: proto.IMessageKey); + constructor(properties?: proto.IPaymentBackground); - /** MessageKey remoteJid. */ - public remoteJid: string; - - /** MessageKey fromMe. */ - public fromMe: boolean; - - /** MessageKey id. */ + /** PaymentBackground id. */ public id: string; - /** MessageKey participant. */ - public participant: string; + /** PaymentBackground fileLength. */ + public fileLength: (number|Long); + + /** PaymentBackground width. */ + public width: number; + + /** PaymentBackground height. */ + public height: number; + + /** PaymentBackground mimetype. */ + public mimetype: string; + + /** PaymentBackground placeholderArgb. */ + public placeholderArgb: number; + + /** PaymentBackground textArgb. */ + public textArgb: number; + + /** PaymentBackground subtextArgb. */ + public subtextArgb: number; /** - * Creates a new MessageKey instance using the specified properties. + * Creates a new PaymentBackground instance using the specified properties. * @param [properties] Properties to set - * @returns MessageKey instance + * @returns PaymentBackground instance */ - public static create(properties?: proto.IMessageKey): proto.MessageKey; + public static create(properties?: proto.IPaymentBackground): proto.PaymentBackground; /** - * Encodes the specified MessageKey message. Does not implicitly {@link proto.MessageKey.verify|verify} messages. - * @param message MessageKey message or plain object to encode + * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @param message PaymentBackground message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encode(message: proto.IMessageKey, writer?: $protobuf.Writer): $protobuf.Writer; + public static encode(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Encodes the specified MessageKey message, length delimited. Does not implicitly {@link proto.MessageKey.verify|verify} messages. - * @param message MessageKey message or plain object to encode + * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @param message PaymentBackground message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encodeDelimited(message: proto.IMessageKey, writer?: $protobuf.Writer): $protobuf.Writer; + public static encodeDelimited(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Decodes a MessageKey message from the specified reader or buffer. + * Decodes a PaymentBackground message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns MessageKey + * @returns PaymentBackground * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MessageKey; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PaymentBackground; /** - * Decodes a MessageKey message from the specified reader or buffer, length delimited. + * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns MessageKey + * @returns PaymentBackground * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MessageKey; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PaymentBackground; /** - * Verifies a MessageKey message. + * Verifies a PaymentBackground message. * @param message Plain object to verify * @returns `null` if valid, otherwise the reason why it is not */ public static verify(message: { [k: string]: any }): (string|null); /** - * Creates a MessageKey message from a plain object. Also converts values to their respective internal types. + * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. * @param object Plain object - * @returns MessageKey + * @returns PaymentBackground */ - public static fromObject(object: { [k: string]: any }): proto.MessageKey; + public static fromObject(object: { [k: string]: any }): proto.PaymentBackground; /** - * Creates a plain object from a MessageKey message. Also converts values to other types if specified. - * @param message MessageKey + * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. + * @param message PaymentBackground * @param [options] Conversion options * @returns Plain object */ - public static toObject(message: proto.MessageKey, options?: $protobuf.IConversionOptions): { [k: string]: any }; + public static toObject(message: proto.PaymentBackground, options?: $protobuf.IConversionOptions): { [k: string]: any }; /** - * Converts this MessageKey to JSON. + * Converts this PaymentBackground to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Money. */ + interface IMoney { + + /** Money value */ + value?: (number|Long|null); + + /** Money offset */ + offset?: (number|null); + + /** Money currencyCode */ + currencyCode?: (string|null); + } + + /** Represents a Money. */ + class Money implements IMoney { + + /** + * Constructs a new Money. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMoney); + + /** Money value. */ + public value: (number|Long); + + /** Money offset. */ + public offset: number; + + /** Money currencyCode. */ + public currencyCode: string; + + /** + * Creates a new Money instance using the specified properties. + * @param [properties] Properties to set + * @returns Money instance + */ + public static create(properties?: proto.IMoney): proto.Money; + + /** + * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. + * @param message Money message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. + * @param message Money message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Money message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Money; + + /** + * Decodes a Money message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Money; + + /** + * Verifies a Money message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Money message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Money + */ + public static fromObject(object: { [k: string]: any }): proto.Money; + + /** + * Creates a plain object from a Money message. Also converts values to other types if specified. + * @param message Money + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Money, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Money to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HydratedQuickReplyButton. */ + interface IHydratedQuickReplyButton { + + /** HydratedQuickReplyButton displayText */ + displayText?: (string|null); + + /** HydratedQuickReplyButton id */ + id?: (string|null); + } + + /** Represents a HydratedQuickReplyButton. */ + class HydratedQuickReplyButton implements IHydratedQuickReplyButton { + + /** + * Constructs a new HydratedQuickReplyButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHydratedQuickReplyButton); + + /** HydratedQuickReplyButton displayText. */ + public displayText: string; + + /** HydratedQuickReplyButton id. */ + public id: string; + + /** + * Creates a new HydratedQuickReplyButton instance using the specified properties. + * @param [properties] Properties to set + * @returns HydratedQuickReplyButton instance + */ + public static create(properties?: proto.IHydratedQuickReplyButton): proto.HydratedQuickReplyButton; + + /** + * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * @param message HydratedQuickReplyButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHydratedQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * @param message HydratedQuickReplyButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHydratedQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HydratedQuickReplyButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HydratedQuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedQuickReplyButton; + + /** + * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HydratedQuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedQuickReplyButton; + + /** + * Verifies a HydratedQuickReplyButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HydratedQuickReplyButton + */ + public static fromObject(object: { [k: string]: any }): proto.HydratedQuickReplyButton; + + /** + * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified. + * @param message HydratedQuickReplyButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HydratedQuickReplyButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HydratedQuickReplyButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HydratedURLButton. */ + interface IHydratedURLButton { + + /** HydratedURLButton displayText */ + displayText?: (string|null); + + /** HydratedURLButton url */ + url?: (string|null); + } + + /** Represents a HydratedURLButton. */ + class HydratedURLButton implements IHydratedURLButton { + + /** + * Constructs a new HydratedURLButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHydratedURLButton); + + /** HydratedURLButton displayText. */ + public displayText: string; + + /** HydratedURLButton url. */ + public url: string; + + /** + * Creates a new HydratedURLButton instance using the specified properties. + * @param [properties] Properties to set + * @returns HydratedURLButton instance + */ + public static create(properties?: proto.IHydratedURLButton): proto.HydratedURLButton; + + /** + * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. + * @param message HydratedURLButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHydratedURLButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. + * @param message HydratedURLButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHydratedURLButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HydratedURLButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HydratedURLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedURLButton; + + /** + * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HydratedURLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedURLButton; + + /** + * Verifies a HydratedURLButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HydratedURLButton + */ + public static fromObject(object: { [k: string]: any }): proto.HydratedURLButton; + + /** + * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified. + * @param message HydratedURLButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HydratedURLButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HydratedURLButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HydratedCallButton. */ + interface IHydratedCallButton { + + /** HydratedCallButton displayText */ + displayText?: (string|null); + + /** HydratedCallButton phoneNumber */ + phoneNumber?: (string|null); + } + + /** Represents a HydratedCallButton. */ + class HydratedCallButton implements IHydratedCallButton { + + /** + * Constructs a new HydratedCallButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHydratedCallButton); + + /** HydratedCallButton displayText. */ + public displayText: string; + + /** HydratedCallButton phoneNumber. */ + public phoneNumber: string; + + /** + * Creates a new HydratedCallButton instance using the specified properties. + * @param [properties] Properties to set + * @returns HydratedCallButton instance + */ + public static create(properties?: proto.IHydratedCallButton): proto.HydratedCallButton; + + /** + * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. + * @param message HydratedCallButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHydratedCallButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. + * @param message HydratedCallButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHydratedCallButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HydratedCallButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HydratedCallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedCallButton; + + /** + * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HydratedCallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedCallButton; + + /** + * Verifies a HydratedCallButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HydratedCallButton + */ + public static fromObject(object: { [k: string]: any }): proto.HydratedCallButton; + + /** + * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified. + * @param message HydratedCallButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HydratedCallButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HydratedCallButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HydratedTemplateButton. */ + interface IHydratedTemplateButton { + + /** HydratedTemplateButton index */ + index?: (number|null); + + /** HydratedTemplateButton quickReplyButton */ + quickReplyButton?: (proto.IHydratedQuickReplyButton|null); + + /** HydratedTemplateButton urlButton */ + urlButton?: (proto.IHydratedURLButton|null); + + /** HydratedTemplateButton callButton */ + callButton?: (proto.IHydratedCallButton|null); + } + + /** Represents a HydratedTemplateButton. */ + class HydratedTemplateButton implements IHydratedTemplateButton { + + /** + * Constructs a new HydratedTemplateButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHydratedTemplateButton); + + /** HydratedTemplateButton index. */ + public index: number; + + /** HydratedTemplateButton quickReplyButton. */ + public quickReplyButton?: (proto.IHydratedQuickReplyButton|null); + + /** HydratedTemplateButton urlButton. */ + public urlButton?: (proto.IHydratedURLButton|null); + + /** HydratedTemplateButton callButton. */ + public callButton?: (proto.IHydratedCallButton|null); + + /** HydratedTemplateButton hydratedButton. */ + public hydratedButton?: ("quickReplyButton"|"urlButton"|"callButton"); + + /** + * Creates a new HydratedTemplateButton instance using the specified properties. + * @param [properties] Properties to set + * @returns HydratedTemplateButton instance + */ + public static create(properties?: proto.IHydratedTemplateButton): proto.HydratedTemplateButton; + + /** + * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. + * @param message HydratedTemplateButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHydratedTemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. + * @param message HydratedTemplateButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHydratedTemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HydratedTemplateButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HydratedTemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedTemplateButton; + + /** + * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HydratedTemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedTemplateButton; + + /** + * Verifies a HydratedTemplateButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HydratedTemplateButton + */ + public static fromObject(object: { [k: string]: any }): proto.HydratedTemplateButton; + + /** + * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified. + * @param message HydratedTemplateButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HydratedTemplateButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HydratedTemplateButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a UserReceipt. */ + interface IUserReceipt { + + /** UserReceipt userJid */ + userJid: string; + + /** UserReceipt receiptTimestamp */ + receiptTimestamp?: (number|Long|null); + + /** UserReceipt readTimestamp */ + readTimestamp?: (number|Long|null); + + /** UserReceipt playedTimestamp */ + playedTimestamp?: (number|Long|null); + + /** UserReceipt pendingDeviceJid */ + pendingDeviceJid?: (string[]|null); + + /** UserReceipt deliveredDeviceJid */ + deliveredDeviceJid?: (string[]|null); + } + + /** Represents a UserReceipt. */ + class UserReceipt implements IUserReceipt { + + /** + * Constructs a new UserReceipt. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IUserReceipt); + + /** UserReceipt userJid. */ + public userJid: string; + + /** UserReceipt receiptTimestamp. */ + public receiptTimestamp: (number|Long); + + /** UserReceipt readTimestamp. */ + public readTimestamp: (number|Long); + + /** UserReceipt playedTimestamp. */ + public playedTimestamp: (number|Long); + + /** UserReceipt pendingDeviceJid. */ + public pendingDeviceJid: string[]; + + /** UserReceipt deliveredDeviceJid. */ + public deliveredDeviceJid: string[]; + + /** + * Creates a new UserReceipt instance using the specified properties. + * @param [properties] Properties to set + * @returns UserReceipt instance + */ + public static create(properties?: proto.IUserReceipt): proto.UserReceipt; + + /** + * Encodes the specified UserReceipt message. Does not implicitly {@link proto.UserReceipt.verify|verify} messages. + * @param message UserReceipt message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IUserReceipt, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified UserReceipt message, length delimited. Does not implicitly {@link proto.UserReceipt.verify|verify} messages. + * @param message UserReceipt message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IUserReceipt, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a UserReceipt message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns UserReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.UserReceipt; + + /** + * Decodes a UserReceipt message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns UserReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.UserReceipt; + + /** + * Verifies a UserReceipt message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a UserReceipt message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns UserReceipt + */ + public static fromObject(object: { [k: string]: any }): proto.UserReceipt; + + /** + * Creates a plain object from a UserReceipt message. Also converts values to other types if specified. + * @param message UserReceipt + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.UserReceipt, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this UserReceipt to JSON. * @returns JSON object */ public toJSON(): { [k: string]: any }; @@ -17601,6 +10913,9 @@ export namespace proto { /** WebFeatures mdForceUpgrade */ mdForceUpgrade?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures disappearingMode */ + disappearingMode?: (proto.WebFeatures.WebFeaturesFlag|null); } /** Represents a WebFeatures. */ @@ -17738,6 +11053,9 @@ export namespace proto { /** WebFeatures mdForceUpgrade. */ public mdForceUpgrade: proto.WebFeatures.WebFeaturesFlag; + /** WebFeatures disappearingMode. */ + public disappearingMode: proto.WebFeatures.WebFeaturesFlag; + /** * Creates a new WebFeatures instance using the specified properties. * @param [properties] Properties to set @@ -18348,6 +11666,9 @@ export namespace proto { /** WebMessageInfo photoChange */ photoChange?: (proto.IPhotoChange|null); + + /** WebMessageInfo userReceipt */ + userReceipt?: (proto.IUserReceipt[]|null); } /** Represents a WebMessageInfo. */ @@ -18449,6 +11770,9 @@ export namespace proto { /** WebMessageInfo photoChange. */ public photoChange?: (proto.IPhotoChange|null); + /** WebMessageInfo userReceipt. */ + public userReceipt: proto.IUserReceipt[]; + /** * Creates a new WebMessageInfo instance using the specified properties. * @param [properties] Properties to set @@ -18663,7 +11987,8 @@ export namespace proto { BIZ_PRIVACY_MODE_INIT_FB = 126, BIZ_PRIVACY_MODE_INIT_BSP = 127, BIZ_PRIVACY_MODE_TO_FB = 128, - BIZ_PRIVACY_MODE_TO_BSP = 129 + BIZ_PRIVACY_MODE_TO_BSP = 129, + DISAPPEARING_MODE = 130 } /** WebMessageInfoBizPrivacyStatus enum. */ diff --git a/WAMessage/WAMessage.js b/WAMessage/index.js similarity index 65% rename from WAMessage/WAMessage.js rename to WAMessage/index.js index 140aede..5f73b72 100644 --- a/WAMessage/WAMessage.js +++ b/WAMessage/index.js @@ -18,28 +18,27 @@ $root.proto = (function() { */ var proto = {}; - proto.AppVersion = (function() { + proto.MessageKey = (function() { /** - * Properties of an AppVersion. + * Properties of a MessageKey. * @memberof proto - * @interface IAppVersion - * @property {number|null} [primary] AppVersion primary - * @property {number|null} [secondary] AppVersion secondary - * @property {number|null} [tertiary] AppVersion tertiary - * @property {number|null} [quaternary] AppVersion quaternary - * @property {number|null} [quinary] AppVersion quinary + * @interface IMessageKey + * @property {string|null} [remoteJid] MessageKey remoteJid + * @property {boolean|null} [fromMe] MessageKey fromMe + * @property {string|null} [id] MessageKey id + * @property {string|null} [participant] MessageKey participant */ /** - * Constructs a new AppVersion. + * Constructs a new MessageKey. * @memberof proto - * @classdesc Represents an AppVersion. - * @implements IAppVersion + * @classdesc Represents a MessageKey. + * @implements IMessageKey * @constructor - * @param {proto.IAppVersion=} [properties] Properties to set + * @param {proto.IMessageKey=} [properties] Properties to set */ - function AppVersion(properties) { + function MessageKey(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -47,8810 +46,115 @@ $root.proto = (function() { } /** - * AppVersion primary. - * @member {number} primary - * @memberof proto.AppVersion + * MessageKey remoteJid. + * @member {string} remoteJid + * @memberof proto.MessageKey * @instance */ - AppVersion.prototype.primary = 0; + MessageKey.prototype.remoteJid = ""; /** - * AppVersion secondary. - * @member {number} secondary - * @memberof proto.AppVersion + * MessageKey fromMe. + * @member {boolean} fromMe + * @memberof proto.MessageKey * @instance */ - AppVersion.prototype.secondary = 0; + MessageKey.prototype.fromMe = false; /** - * AppVersion tertiary. - * @member {number} tertiary - * @memberof proto.AppVersion + * MessageKey id. + * @member {string} id + * @memberof proto.MessageKey * @instance */ - AppVersion.prototype.tertiary = 0; + MessageKey.prototype.id = ""; /** - * AppVersion quaternary. - * @member {number} quaternary - * @memberof proto.AppVersion - * @instance - */ - AppVersion.prototype.quaternary = 0; - - /** - * AppVersion quinary. - * @member {number} quinary - * @memberof proto.AppVersion - * @instance - */ - AppVersion.prototype.quinary = 0; - - /** - * Creates a new AppVersion instance using the specified properties. - * @function create - * @memberof proto.AppVersion - * @static - * @param {proto.IAppVersion=} [properties] Properties to set - * @returns {proto.AppVersion} AppVersion instance - */ - AppVersion.create = function create(properties) { - return new AppVersion(properties); - }; - - /** - * Encodes the specified AppVersion message. Does not implicitly {@link proto.AppVersion.verify|verify} messages. - * @function encode - * @memberof proto.AppVersion - * @static - * @param {proto.IAppVersion} message AppVersion message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - AppVersion.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.primary != null && Object.hasOwnProperty.call(message, "primary")) - writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.primary); - if (message.secondary != null && Object.hasOwnProperty.call(message, "secondary")) - writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.secondary); - if (message.tertiary != null && Object.hasOwnProperty.call(message, "tertiary")) - writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.tertiary); - if (message.quaternary != null && Object.hasOwnProperty.call(message, "quaternary")) - writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.quaternary); - if (message.quinary != null && Object.hasOwnProperty.call(message, "quinary")) - writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.quinary); - return writer; - }; - - /** - * Encodes the specified AppVersion message, length delimited. Does not implicitly {@link proto.AppVersion.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.AppVersion - * @static - * @param {proto.IAppVersion} message AppVersion message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - AppVersion.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes an AppVersion message from the specified reader or buffer. - * @function decode - * @memberof proto.AppVersion - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.AppVersion} AppVersion - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - AppVersion.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AppVersion(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.primary = reader.uint32(); - break; - case 2: - message.secondary = reader.uint32(); - break; - case 3: - message.tertiary = reader.uint32(); - break; - case 4: - message.quaternary = reader.uint32(); - break; - case 5: - message.quinary = reader.uint32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes an AppVersion message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.AppVersion - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.AppVersion} AppVersion - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - AppVersion.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies an AppVersion message. - * @function verify - * @memberof proto.AppVersion - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - AppVersion.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.primary != null && message.hasOwnProperty("primary")) - if (!$util.isInteger(message.primary)) - return "primary: integer expected"; - if (message.secondary != null && message.hasOwnProperty("secondary")) - if (!$util.isInteger(message.secondary)) - return "secondary: integer expected"; - if (message.tertiary != null && message.hasOwnProperty("tertiary")) - if (!$util.isInteger(message.tertiary)) - return "tertiary: integer expected"; - if (message.quaternary != null && message.hasOwnProperty("quaternary")) - if (!$util.isInteger(message.quaternary)) - return "quaternary: integer expected"; - if (message.quinary != null && message.hasOwnProperty("quinary")) - if (!$util.isInteger(message.quinary)) - return "quinary: integer expected"; - return null; - }; - - /** - * Creates an AppVersion message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.AppVersion - * @static - * @param {Object.} object Plain object - * @returns {proto.AppVersion} AppVersion - */ - AppVersion.fromObject = function fromObject(object) { - if (object instanceof $root.proto.AppVersion) - return object; - var message = new $root.proto.AppVersion(); - if (object.primary != null) - message.primary = object.primary >>> 0; - if (object.secondary != null) - message.secondary = object.secondary >>> 0; - if (object.tertiary != null) - message.tertiary = object.tertiary >>> 0; - if (object.quaternary != null) - message.quaternary = object.quaternary >>> 0; - if (object.quinary != null) - message.quinary = object.quinary >>> 0; - return message; - }; - - /** - * Creates a plain object from an AppVersion message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.AppVersion - * @static - * @param {proto.AppVersion} message AppVersion - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - AppVersion.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.primary = 0; - object.secondary = 0; - object.tertiary = 0; - object.quaternary = 0; - object.quinary = 0; - } - if (message.primary != null && message.hasOwnProperty("primary")) - object.primary = message.primary; - if (message.secondary != null && message.hasOwnProperty("secondary")) - object.secondary = message.secondary; - if (message.tertiary != null && message.hasOwnProperty("tertiary")) - object.tertiary = message.tertiary; - if (message.quaternary != null && message.hasOwnProperty("quaternary")) - object.quaternary = message.quaternary; - if (message.quinary != null && message.hasOwnProperty("quinary")) - object.quinary = message.quinary; - return object; - }; - - /** - * Converts this AppVersion to JSON. - * @function toJSON - * @memberof proto.AppVersion - * @instance - * @returns {Object.} JSON object - */ - AppVersion.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return AppVersion; - })(); - - proto.UserAgent = (function() { - - /** - * Properties of a UserAgent. - * @memberof proto - * @interface IUserAgent - * @property {proto.UserAgent.UserAgentPlatform|null} [platform] UserAgent platform - * @property {proto.IAppVersion|null} [appVersion] UserAgent appVersion - * @property {string|null} [mcc] UserAgent mcc - * @property {string|null} [mnc] UserAgent mnc - * @property {string|null} [osVersion] UserAgent osVersion - * @property {string|null} [manufacturer] UserAgent manufacturer - * @property {string|null} [device] UserAgent device - * @property {string|null} [osBuildNumber] UserAgent osBuildNumber - * @property {string|null} [phoneId] UserAgent phoneId - * @property {proto.UserAgent.UserAgentReleaseChannel|null} [releaseChannel] UserAgent releaseChannel - * @property {string|null} [localeLanguageIso6391] UserAgent localeLanguageIso6391 - * @property {string|null} [localeCountryIso31661Alpha2] UserAgent localeCountryIso31661Alpha2 - * @property {string|null} [deviceBoard] UserAgent deviceBoard - */ - - /** - * Constructs a new UserAgent. - * @memberof proto - * @classdesc Represents a UserAgent. - * @implements IUserAgent - * @constructor - * @param {proto.IUserAgent=} [properties] Properties to set - */ - function UserAgent(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * UserAgent platform. - * @member {proto.UserAgent.UserAgentPlatform} platform - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.platform = 0; - - /** - * UserAgent appVersion. - * @member {proto.IAppVersion|null|undefined} appVersion - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.appVersion = null; - - /** - * UserAgent mcc. - * @member {string} mcc - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.mcc = ""; - - /** - * UserAgent mnc. - * @member {string} mnc - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.mnc = ""; - - /** - * UserAgent osVersion. - * @member {string} osVersion - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.osVersion = ""; - - /** - * UserAgent manufacturer. - * @member {string} manufacturer - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.manufacturer = ""; - - /** - * UserAgent device. - * @member {string} device - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.device = ""; - - /** - * UserAgent osBuildNumber. - * @member {string} osBuildNumber - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.osBuildNumber = ""; - - /** - * UserAgent phoneId. - * @member {string} phoneId - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.phoneId = ""; - - /** - * UserAgent releaseChannel. - * @member {proto.UserAgent.UserAgentReleaseChannel} releaseChannel - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.releaseChannel = 0; - - /** - * UserAgent localeLanguageIso6391. - * @member {string} localeLanguageIso6391 - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.localeLanguageIso6391 = ""; - - /** - * UserAgent localeCountryIso31661Alpha2. - * @member {string} localeCountryIso31661Alpha2 - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.localeCountryIso31661Alpha2 = ""; - - /** - * UserAgent deviceBoard. - * @member {string} deviceBoard - * @memberof proto.UserAgent - * @instance - */ - UserAgent.prototype.deviceBoard = ""; - - /** - * Creates a new UserAgent instance using the specified properties. - * @function create - * @memberof proto.UserAgent - * @static - * @param {proto.IUserAgent=} [properties] Properties to set - * @returns {proto.UserAgent} UserAgent instance - */ - UserAgent.create = function create(properties) { - return new UserAgent(properties); - }; - - /** - * Encodes the specified UserAgent message. Does not implicitly {@link proto.UserAgent.verify|verify} messages. - * @function encode - * @memberof proto.UserAgent - * @static - * @param {proto.IUserAgent} message UserAgent message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - UserAgent.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.platform != null && Object.hasOwnProperty.call(message, "platform")) - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.platform); - if (message.appVersion != null && Object.hasOwnProperty.call(message, "appVersion")) - $root.proto.AppVersion.encode(message.appVersion, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.mcc != null && Object.hasOwnProperty.call(message, "mcc")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.mcc); - if (message.mnc != null && Object.hasOwnProperty.call(message, "mnc")) - writer.uint32(/* id 4, wireType 2 =*/34).string(message.mnc); - if (message.osVersion != null && Object.hasOwnProperty.call(message, "osVersion")) - writer.uint32(/* id 5, wireType 2 =*/42).string(message.osVersion); - if (message.manufacturer != null && Object.hasOwnProperty.call(message, "manufacturer")) - writer.uint32(/* id 6, wireType 2 =*/50).string(message.manufacturer); - if (message.device != null && Object.hasOwnProperty.call(message, "device")) - writer.uint32(/* id 7, wireType 2 =*/58).string(message.device); - if (message.osBuildNumber != null && Object.hasOwnProperty.call(message, "osBuildNumber")) - writer.uint32(/* id 8, wireType 2 =*/66).string(message.osBuildNumber); - if (message.phoneId != null && Object.hasOwnProperty.call(message, "phoneId")) - writer.uint32(/* id 9, wireType 2 =*/74).string(message.phoneId); - if (message.releaseChannel != null && Object.hasOwnProperty.call(message, "releaseChannel")) - writer.uint32(/* id 10, wireType 0 =*/80).int32(message.releaseChannel); - if (message.localeLanguageIso6391 != null && Object.hasOwnProperty.call(message, "localeLanguageIso6391")) - writer.uint32(/* id 11, wireType 2 =*/90).string(message.localeLanguageIso6391); - if (message.localeCountryIso31661Alpha2 != null && Object.hasOwnProperty.call(message, "localeCountryIso31661Alpha2")) - writer.uint32(/* id 12, wireType 2 =*/98).string(message.localeCountryIso31661Alpha2); - if (message.deviceBoard != null && Object.hasOwnProperty.call(message, "deviceBoard")) - writer.uint32(/* id 13, wireType 2 =*/106).string(message.deviceBoard); - return writer; - }; - - /** - * Encodes the specified UserAgent message, length delimited. Does not implicitly {@link proto.UserAgent.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.UserAgent - * @static - * @param {proto.IUserAgent} message UserAgent message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - UserAgent.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a UserAgent message from the specified reader or buffer. - * @function decode - * @memberof proto.UserAgent - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.UserAgent} UserAgent - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - UserAgent.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.UserAgent(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.platform = reader.int32(); - break; - case 2: - message.appVersion = $root.proto.AppVersion.decode(reader, reader.uint32()); - break; - case 3: - message.mcc = reader.string(); - break; - case 4: - message.mnc = reader.string(); - break; - case 5: - message.osVersion = reader.string(); - break; - case 6: - message.manufacturer = reader.string(); - break; - case 7: - message.device = reader.string(); - break; - case 8: - message.osBuildNumber = reader.string(); - break; - case 9: - message.phoneId = reader.string(); - break; - case 10: - message.releaseChannel = reader.int32(); - break; - case 11: - message.localeLanguageIso6391 = reader.string(); - break; - case 12: - message.localeCountryIso31661Alpha2 = reader.string(); - break; - case 13: - message.deviceBoard = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a UserAgent message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.UserAgent - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.UserAgent} UserAgent - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - UserAgent.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a UserAgent message. - * @function verify - * @memberof proto.UserAgent - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - UserAgent.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.platform != null && message.hasOwnProperty("platform")) - switch (message.platform) { - default: - return "platform: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: - case 20: - case 21: - case 22: - case 23: - case 24: - case 25: - break; - } - if (message.appVersion != null && message.hasOwnProperty("appVersion")) { - var error = $root.proto.AppVersion.verify(message.appVersion); - if (error) - return "appVersion." + error; - } - if (message.mcc != null && message.hasOwnProperty("mcc")) - if (!$util.isString(message.mcc)) - return "mcc: string expected"; - if (message.mnc != null && message.hasOwnProperty("mnc")) - if (!$util.isString(message.mnc)) - return "mnc: string expected"; - if (message.osVersion != null && message.hasOwnProperty("osVersion")) - if (!$util.isString(message.osVersion)) - return "osVersion: string expected"; - if (message.manufacturer != null && message.hasOwnProperty("manufacturer")) - if (!$util.isString(message.manufacturer)) - return "manufacturer: string expected"; - if (message.device != null && message.hasOwnProperty("device")) - if (!$util.isString(message.device)) - return "device: string expected"; - if (message.osBuildNumber != null && message.hasOwnProperty("osBuildNumber")) - if (!$util.isString(message.osBuildNumber)) - return "osBuildNumber: string expected"; - if (message.phoneId != null && message.hasOwnProperty("phoneId")) - if (!$util.isString(message.phoneId)) - return "phoneId: string expected"; - if (message.releaseChannel != null && message.hasOwnProperty("releaseChannel")) - switch (message.releaseChannel) { - default: - return "releaseChannel: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.localeLanguageIso6391 != null && message.hasOwnProperty("localeLanguageIso6391")) - if (!$util.isString(message.localeLanguageIso6391)) - return "localeLanguageIso6391: string expected"; - if (message.localeCountryIso31661Alpha2 != null && message.hasOwnProperty("localeCountryIso31661Alpha2")) - if (!$util.isString(message.localeCountryIso31661Alpha2)) - return "localeCountryIso31661Alpha2: string expected"; - if (message.deviceBoard != null && message.hasOwnProperty("deviceBoard")) - if (!$util.isString(message.deviceBoard)) - return "deviceBoard: string expected"; - return null; - }; - - /** - * Creates a UserAgent message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.UserAgent - * @static - * @param {Object.} object Plain object - * @returns {proto.UserAgent} UserAgent - */ - UserAgent.fromObject = function fromObject(object) { - if (object instanceof $root.proto.UserAgent) - return object; - var message = new $root.proto.UserAgent(); - switch (object.platform) { - case "ANDROID": - case 0: - message.platform = 0; - break; - case "IOS": - case 1: - message.platform = 1; - break; - case "WINDOWS_PHONE": - case 2: - message.platform = 2; - break; - case "BLACKBERRY": - case 3: - message.platform = 3; - break; - case "BLACKBERRYX": - case 4: - message.platform = 4; - break; - case "S40": - case 5: - message.platform = 5; - break; - case "S60": - case 6: - message.platform = 6; - break; - case "PYTHON_CLIENT": - case 7: - message.platform = 7; - break; - case "TIZEN": - case 8: - message.platform = 8; - break; - case "ENTERPRISE": - case 9: - message.platform = 9; - break; - case "SMB_ANDROID": - case 10: - message.platform = 10; - break; - case "KAIOS": - case 11: - message.platform = 11; - break; - case "SMB_IOS": - case 12: - message.platform = 12; - break; - case "WINDOWS": - case 13: - message.platform = 13; - break; - case "WEB": - case 14: - message.platform = 14; - break; - case "PORTAL": - case 15: - message.platform = 15; - break; - case "GREEN_ANDROID": - case 16: - message.platform = 16; - break; - case "GREEN_IPHONE": - case 17: - message.platform = 17; - break; - case "BLUE_ANDROID": - case 18: - message.platform = 18; - break; - case "BLUE_IPHONE": - case 19: - message.platform = 19; - break; - case "FBLITE_ANDROID": - case 20: - message.platform = 20; - break; - case "MLITE_ANDROID": - case 21: - message.platform = 21; - break; - case "IGLITE_ANDROID": - case 22: - message.platform = 22; - break; - case "PAGE": - case 23: - message.platform = 23; - break; - case "MACOS": - case 24: - message.platform = 24; - break; - case "VR": - case 25: - message.platform = 25; - break; - } - if (object.appVersion != null) { - if (typeof object.appVersion !== "object") - throw TypeError(".proto.UserAgent.appVersion: object expected"); - message.appVersion = $root.proto.AppVersion.fromObject(object.appVersion); - } - if (object.mcc != null) - message.mcc = String(object.mcc); - if (object.mnc != null) - message.mnc = String(object.mnc); - if (object.osVersion != null) - message.osVersion = String(object.osVersion); - if (object.manufacturer != null) - message.manufacturer = String(object.manufacturer); - if (object.device != null) - message.device = String(object.device); - if (object.osBuildNumber != null) - message.osBuildNumber = String(object.osBuildNumber); - if (object.phoneId != null) - message.phoneId = String(object.phoneId); - switch (object.releaseChannel) { - case "RELEASE": - case 0: - message.releaseChannel = 0; - break; - case "BETA": - case 1: - message.releaseChannel = 1; - break; - case "ALPHA": - case 2: - message.releaseChannel = 2; - break; - case "DEBUG": - case 3: - message.releaseChannel = 3; - break; - } - if (object.localeLanguageIso6391 != null) - message.localeLanguageIso6391 = String(object.localeLanguageIso6391); - if (object.localeCountryIso31661Alpha2 != null) - message.localeCountryIso31661Alpha2 = String(object.localeCountryIso31661Alpha2); - if (object.deviceBoard != null) - message.deviceBoard = String(object.deviceBoard); - return message; - }; - - /** - * Creates a plain object from a UserAgent message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.UserAgent - * @static - * @param {proto.UserAgent} message UserAgent - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - UserAgent.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.platform = options.enums === String ? "ANDROID" : 0; - object.appVersion = null; - object.mcc = ""; - object.mnc = ""; - object.osVersion = ""; - object.manufacturer = ""; - object.device = ""; - object.osBuildNumber = ""; - object.phoneId = ""; - object.releaseChannel = options.enums === String ? "RELEASE" : 0; - object.localeLanguageIso6391 = ""; - object.localeCountryIso31661Alpha2 = ""; - object.deviceBoard = ""; - } - if (message.platform != null && message.hasOwnProperty("platform")) - object.platform = options.enums === String ? $root.proto.UserAgent.UserAgentPlatform[message.platform] : message.platform; - if (message.appVersion != null && message.hasOwnProperty("appVersion")) - object.appVersion = $root.proto.AppVersion.toObject(message.appVersion, options); - if (message.mcc != null && message.hasOwnProperty("mcc")) - object.mcc = message.mcc; - if (message.mnc != null && message.hasOwnProperty("mnc")) - object.mnc = message.mnc; - if (message.osVersion != null && message.hasOwnProperty("osVersion")) - object.osVersion = message.osVersion; - if (message.manufacturer != null && message.hasOwnProperty("manufacturer")) - object.manufacturer = message.manufacturer; - if (message.device != null && message.hasOwnProperty("device")) - object.device = message.device; - if (message.osBuildNumber != null && message.hasOwnProperty("osBuildNumber")) - object.osBuildNumber = message.osBuildNumber; - if (message.phoneId != null && message.hasOwnProperty("phoneId")) - object.phoneId = message.phoneId; - if (message.releaseChannel != null && message.hasOwnProperty("releaseChannel")) - object.releaseChannel = options.enums === String ? $root.proto.UserAgent.UserAgentReleaseChannel[message.releaseChannel] : message.releaseChannel; - if (message.localeLanguageIso6391 != null && message.hasOwnProperty("localeLanguageIso6391")) - object.localeLanguageIso6391 = message.localeLanguageIso6391; - if (message.localeCountryIso31661Alpha2 != null && message.hasOwnProperty("localeCountryIso31661Alpha2")) - object.localeCountryIso31661Alpha2 = message.localeCountryIso31661Alpha2; - if (message.deviceBoard != null && message.hasOwnProperty("deviceBoard")) - object.deviceBoard = message.deviceBoard; - return object; - }; - - /** - * Converts this UserAgent to JSON. - * @function toJSON - * @memberof proto.UserAgent - * @instance - * @returns {Object.} JSON object - */ - UserAgent.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * UserAgentPlatform enum. - * @name proto.UserAgent.UserAgentPlatform - * @enum {number} - * @property {number} ANDROID=0 ANDROID value - * @property {number} IOS=1 IOS value - * @property {number} WINDOWS_PHONE=2 WINDOWS_PHONE value - * @property {number} BLACKBERRY=3 BLACKBERRY value - * @property {number} BLACKBERRYX=4 BLACKBERRYX value - * @property {number} S40=5 S40 value - * @property {number} S60=6 S60 value - * @property {number} PYTHON_CLIENT=7 PYTHON_CLIENT value - * @property {number} TIZEN=8 TIZEN value - * @property {number} ENTERPRISE=9 ENTERPRISE value - * @property {number} SMB_ANDROID=10 SMB_ANDROID value - * @property {number} KAIOS=11 KAIOS value - * @property {number} SMB_IOS=12 SMB_IOS value - * @property {number} WINDOWS=13 WINDOWS value - * @property {number} WEB=14 WEB value - * @property {number} PORTAL=15 PORTAL value - * @property {number} GREEN_ANDROID=16 GREEN_ANDROID value - * @property {number} GREEN_IPHONE=17 GREEN_IPHONE value - * @property {number} BLUE_ANDROID=18 BLUE_ANDROID value - * @property {number} BLUE_IPHONE=19 BLUE_IPHONE value - * @property {number} FBLITE_ANDROID=20 FBLITE_ANDROID value - * @property {number} MLITE_ANDROID=21 MLITE_ANDROID value - * @property {number} IGLITE_ANDROID=22 IGLITE_ANDROID value - * @property {number} PAGE=23 PAGE value - * @property {number} MACOS=24 MACOS value - * @property {number} VR=25 VR value - */ - UserAgent.UserAgentPlatform = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "ANDROID"] = 0; - values[valuesById[1] = "IOS"] = 1; - values[valuesById[2] = "WINDOWS_PHONE"] = 2; - values[valuesById[3] = "BLACKBERRY"] = 3; - values[valuesById[4] = "BLACKBERRYX"] = 4; - values[valuesById[5] = "S40"] = 5; - values[valuesById[6] = "S60"] = 6; - values[valuesById[7] = "PYTHON_CLIENT"] = 7; - values[valuesById[8] = "TIZEN"] = 8; - values[valuesById[9] = "ENTERPRISE"] = 9; - values[valuesById[10] = "SMB_ANDROID"] = 10; - values[valuesById[11] = "KAIOS"] = 11; - values[valuesById[12] = "SMB_IOS"] = 12; - values[valuesById[13] = "WINDOWS"] = 13; - values[valuesById[14] = "WEB"] = 14; - values[valuesById[15] = "PORTAL"] = 15; - values[valuesById[16] = "GREEN_ANDROID"] = 16; - values[valuesById[17] = "GREEN_IPHONE"] = 17; - values[valuesById[18] = "BLUE_ANDROID"] = 18; - values[valuesById[19] = "BLUE_IPHONE"] = 19; - values[valuesById[20] = "FBLITE_ANDROID"] = 20; - values[valuesById[21] = "MLITE_ANDROID"] = 21; - values[valuesById[22] = "IGLITE_ANDROID"] = 22; - values[valuesById[23] = "PAGE"] = 23; - values[valuesById[24] = "MACOS"] = 24; - values[valuesById[25] = "VR"] = 25; - return values; - })(); - - /** - * UserAgentReleaseChannel enum. - * @name proto.UserAgent.UserAgentReleaseChannel - * @enum {number} - * @property {number} RELEASE=0 RELEASE value - * @property {number} BETA=1 BETA value - * @property {number} ALPHA=2 ALPHA value - * @property {number} DEBUG=3 DEBUG value - */ - UserAgent.UserAgentReleaseChannel = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "RELEASE"] = 0; - values[valuesById[1] = "BETA"] = 1; - values[valuesById[2] = "ALPHA"] = 2; - values[valuesById[3] = "DEBUG"] = 3; - return values; - })(); - - return UserAgent; - })(); - - proto.WebdPayload = (function() { - - /** - * Properties of a WebdPayload. - * @memberof proto - * @interface IWebdPayload - * @property {boolean|null} [usesParticipantInKey] WebdPayload usesParticipantInKey - * @property {boolean|null} [supportsStarredMessages] WebdPayload supportsStarredMessages - * @property {boolean|null} [supportsDocumentMessages] WebdPayload supportsDocumentMessages - * @property {boolean|null} [supportsUrlMessages] WebdPayload supportsUrlMessages - * @property {boolean|null} [supportsMediaRetry] WebdPayload supportsMediaRetry - * @property {boolean|null} [supportsE2EImage] WebdPayload supportsE2EImage - * @property {boolean|null} [supportsE2EVideo] WebdPayload supportsE2EVideo - * @property {boolean|null} [supportsE2EAudio] WebdPayload supportsE2EAudio - * @property {boolean|null} [supportsE2EDocument] WebdPayload supportsE2EDocument - * @property {string|null} [documentTypes] WebdPayload documentTypes - * @property {Uint8Array|null} [features] WebdPayload features - */ - - /** - * Constructs a new WebdPayload. - * @memberof proto - * @classdesc Represents a WebdPayload. - * @implements IWebdPayload - * @constructor - * @param {proto.IWebdPayload=} [properties] Properties to set - */ - function WebdPayload(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * WebdPayload usesParticipantInKey. - * @member {boolean} usesParticipantInKey - * @memberof proto.WebdPayload - * @instance - */ - WebdPayload.prototype.usesParticipantInKey = false; - - /** - * WebdPayload supportsStarredMessages. - * @member {boolean} supportsStarredMessages - * @memberof proto.WebdPayload - * @instance - */ - WebdPayload.prototype.supportsStarredMessages = false; - - /** - * WebdPayload supportsDocumentMessages. - * @member {boolean} supportsDocumentMessages - * @memberof proto.WebdPayload - * @instance - */ - WebdPayload.prototype.supportsDocumentMessages = false; - - /** - * WebdPayload supportsUrlMessages. - * @member {boolean} supportsUrlMessages - * @memberof proto.WebdPayload - * @instance - */ - WebdPayload.prototype.supportsUrlMessages = false; - - /** - * WebdPayload supportsMediaRetry. - * @member {boolean} supportsMediaRetry - * @memberof proto.WebdPayload - * @instance - */ - WebdPayload.prototype.supportsMediaRetry = false; - - /** - * WebdPayload supportsE2EImage. - * @member {boolean} supportsE2EImage - * @memberof proto.WebdPayload - * @instance - */ - WebdPayload.prototype.supportsE2EImage = false; - - /** - * WebdPayload supportsE2EVideo. - * @member {boolean} supportsE2EVideo - * @memberof proto.WebdPayload - * @instance - */ - WebdPayload.prototype.supportsE2EVideo = false; - - /** - * WebdPayload supportsE2EAudio. - * @member {boolean} supportsE2EAudio - * @memberof proto.WebdPayload - * @instance - */ - WebdPayload.prototype.supportsE2EAudio = false; - - /** - * WebdPayload supportsE2EDocument. - * @member {boolean} supportsE2EDocument - * @memberof proto.WebdPayload - * @instance - */ - WebdPayload.prototype.supportsE2EDocument = false; - - /** - * WebdPayload documentTypes. - * @member {string} documentTypes - * @memberof proto.WebdPayload - * @instance - */ - WebdPayload.prototype.documentTypes = ""; - - /** - * WebdPayload features. - * @member {Uint8Array} features - * @memberof proto.WebdPayload - * @instance - */ - WebdPayload.prototype.features = $util.newBuffer([]); - - /** - * Creates a new WebdPayload instance using the specified properties. - * @function create - * @memberof proto.WebdPayload - * @static - * @param {proto.IWebdPayload=} [properties] Properties to set - * @returns {proto.WebdPayload} WebdPayload instance - */ - WebdPayload.create = function create(properties) { - return new WebdPayload(properties); - }; - - /** - * Encodes the specified WebdPayload message. Does not implicitly {@link proto.WebdPayload.verify|verify} messages. - * @function encode - * @memberof proto.WebdPayload - * @static - * @param {proto.IWebdPayload} message WebdPayload message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - WebdPayload.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.usesParticipantInKey != null && Object.hasOwnProperty.call(message, "usesParticipantInKey")) - writer.uint32(/* id 1, wireType 0 =*/8).bool(message.usesParticipantInKey); - if (message.supportsStarredMessages != null && Object.hasOwnProperty.call(message, "supportsStarredMessages")) - writer.uint32(/* id 2, wireType 0 =*/16).bool(message.supportsStarredMessages); - if (message.supportsDocumentMessages != null && Object.hasOwnProperty.call(message, "supportsDocumentMessages")) - writer.uint32(/* id 3, wireType 0 =*/24).bool(message.supportsDocumentMessages); - if (message.supportsUrlMessages != null && Object.hasOwnProperty.call(message, "supportsUrlMessages")) - writer.uint32(/* id 4, wireType 0 =*/32).bool(message.supportsUrlMessages); - if (message.supportsMediaRetry != null && Object.hasOwnProperty.call(message, "supportsMediaRetry")) - writer.uint32(/* id 5, wireType 0 =*/40).bool(message.supportsMediaRetry); - if (message.supportsE2EImage != null && Object.hasOwnProperty.call(message, "supportsE2EImage")) - writer.uint32(/* id 6, wireType 0 =*/48).bool(message.supportsE2EImage); - if (message.supportsE2EVideo != null && Object.hasOwnProperty.call(message, "supportsE2EVideo")) - writer.uint32(/* id 7, wireType 0 =*/56).bool(message.supportsE2EVideo); - if (message.supportsE2EAudio != null && Object.hasOwnProperty.call(message, "supportsE2EAudio")) - writer.uint32(/* id 8, wireType 0 =*/64).bool(message.supportsE2EAudio); - if (message.supportsE2EDocument != null && Object.hasOwnProperty.call(message, "supportsE2EDocument")) - writer.uint32(/* id 9, wireType 0 =*/72).bool(message.supportsE2EDocument); - if (message.documentTypes != null && Object.hasOwnProperty.call(message, "documentTypes")) - writer.uint32(/* id 10, wireType 2 =*/82).string(message.documentTypes); - if (message.features != null && Object.hasOwnProperty.call(message, "features")) - writer.uint32(/* id 11, wireType 2 =*/90).bytes(message.features); - return writer; - }; - - /** - * Encodes the specified WebdPayload message, length delimited. Does not implicitly {@link proto.WebdPayload.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.WebdPayload - * @static - * @param {proto.IWebdPayload} message WebdPayload message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - WebdPayload.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a WebdPayload message from the specified reader or buffer. - * @function decode - * @memberof proto.WebdPayload - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.WebdPayload} WebdPayload - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - WebdPayload.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebdPayload(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.usesParticipantInKey = reader.bool(); - break; - case 2: - message.supportsStarredMessages = reader.bool(); - break; - case 3: - message.supportsDocumentMessages = reader.bool(); - break; - case 4: - message.supportsUrlMessages = reader.bool(); - break; - case 5: - message.supportsMediaRetry = reader.bool(); - break; - case 6: - message.supportsE2EImage = reader.bool(); - break; - case 7: - message.supportsE2EVideo = reader.bool(); - break; - case 8: - message.supportsE2EAudio = reader.bool(); - break; - case 9: - message.supportsE2EDocument = reader.bool(); - break; - case 10: - message.documentTypes = reader.string(); - break; - case 11: - message.features = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a WebdPayload message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.WebdPayload - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.WebdPayload} WebdPayload - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - WebdPayload.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a WebdPayload message. - * @function verify - * @memberof proto.WebdPayload - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - WebdPayload.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.usesParticipantInKey != null && message.hasOwnProperty("usesParticipantInKey")) - if (typeof message.usesParticipantInKey !== "boolean") - return "usesParticipantInKey: boolean expected"; - if (message.supportsStarredMessages != null && message.hasOwnProperty("supportsStarredMessages")) - if (typeof message.supportsStarredMessages !== "boolean") - return "supportsStarredMessages: boolean expected"; - if (message.supportsDocumentMessages != null && message.hasOwnProperty("supportsDocumentMessages")) - if (typeof message.supportsDocumentMessages !== "boolean") - return "supportsDocumentMessages: boolean expected"; - if (message.supportsUrlMessages != null && message.hasOwnProperty("supportsUrlMessages")) - if (typeof message.supportsUrlMessages !== "boolean") - return "supportsUrlMessages: boolean expected"; - if (message.supportsMediaRetry != null && message.hasOwnProperty("supportsMediaRetry")) - if (typeof message.supportsMediaRetry !== "boolean") - return "supportsMediaRetry: boolean expected"; - if (message.supportsE2EImage != null && message.hasOwnProperty("supportsE2EImage")) - if (typeof message.supportsE2EImage !== "boolean") - return "supportsE2EImage: boolean expected"; - if (message.supportsE2EVideo != null && message.hasOwnProperty("supportsE2EVideo")) - if (typeof message.supportsE2EVideo !== "boolean") - return "supportsE2EVideo: boolean expected"; - if (message.supportsE2EAudio != null && message.hasOwnProperty("supportsE2EAudio")) - if (typeof message.supportsE2EAudio !== "boolean") - return "supportsE2EAudio: boolean expected"; - if (message.supportsE2EDocument != null && message.hasOwnProperty("supportsE2EDocument")) - if (typeof message.supportsE2EDocument !== "boolean") - return "supportsE2EDocument: boolean expected"; - if (message.documentTypes != null && message.hasOwnProperty("documentTypes")) - if (!$util.isString(message.documentTypes)) - return "documentTypes: string expected"; - if (message.features != null && message.hasOwnProperty("features")) - if (!(message.features && typeof message.features.length === "number" || $util.isString(message.features))) - return "features: buffer expected"; - return null; - }; - - /** - * Creates a WebdPayload message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.WebdPayload - * @static - * @param {Object.} object Plain object - * @returns {proto.WebdPayload} WebdPayload - */ - WebdPayload.fromObject = function fromObject(object) { - if (object instanceof $root.proto.WebdPayload) - return object; - var message = new $root.proto.WebdPayload(); - if (object.usesParticipantInKey != null) - message.usesParticipantInKey = Boolean(object.usesParticipantInKey); - if (object.supportsStarredMessages != null) - message.supportsStarredMessages = Boolean(object.supportsStarredMessages); - if (object.supportsDocumentMessages != null) - message.supportsDocumentMessages = Boolean(object.supportsDocumentMessages); - if (object.supportsUrlMessages != null) - message.supportsUrlMessages = Boolean(object.supportsUrlMessages); - if (object.supportsMediaRetry != null) - message.supportsMediaRetry = Boolean(object.supportsMediaRetry); - if (object.supportsE2EImage != null) - message.supportsE2EImage = Boolean(object.supportsE2EImage); - if (object.supportsE2EVideo != null) - message.supportsE2EVideo = Boolean(object.supportsE2EVideo); - if (object.supportsE2EAudio != null) - message.supportsE2EAudio = Boolean(object.supportsE2EAudio); - if (object.supportsE2EDocument != null) - message.supportsE2EDocument = Boolean(object.supportsE2EDocument); - if (object.documentTypes != null) - message.documentTypes = String(object.documentTypes); - if (object.features != null) - if (typeof object.features === "string") - $util.base64.decode(object.features, message.features = $util.newBuffer($util.base64.length(object.features)), 0); - else if (object.features.length) - message.features = object.features; - return message; - }; - - /** - * Creates a plain object from a WebdPayload message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.WebdPayload - * @static - * @param {proto.WebdPayload} message WebdPayload - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - WebdPayload.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.usesParticipantInKey = false; - object.supportsStarredMessages = false; - object.supportsDocumentMessages = false; - object.supportsUrlMessages = false; - object.supportsMediaRetry = false; - object.supportsE2EImage = false; - object.supportsE2EVideo = false; - object.supportsE2EAudio = false; - object.supportsE2EDocument = false; - object.documentTypes = ""; - if (options.bytes === String) - object.features = ""; - else { - object.features = []; - if (options.bytes !== Array) - object.features = $util.newBuffer(object.features); - } - } - if (message.usesParticipantInKey != null && message.hasOwnProperty("usesParticipantInKey")) - object.usesParticipantInKey = message.usesParticipantInKey; - if (message.supportsStarredMessages != null && message.hasOwnProperty("supportsStarredMessages")) - object.supportsStarredMessages = message.supportsStarredMessages; - if (message.supportsDocumentMessages != null && message.hasOwnProperty("supportsDocumentMessages")) - object.supportsDocumentMessages = message.supportsDocumentMessages; - if (message.supportsUrlMessages != null && message.hasOwnProperty("supportsUrlMessages")) - object.supportsUrlMessages = message.supportsUrlMessages; - if (message.supportsMediaRetry != null && message.hasOwnProperty("supportsMediaRetry")) - object.supportsMediaRetry = message.supportsMediaRetry; - if (message.supportsE2EImage != null && message.hasOwnProperty("supportsE2EImage")) - object.supportsE2EImage = message.supportsE2EImage; - if (message.supportsE2EVideo != null && message.hasOwnProperty("supportsE2EVideo")) - object.supportsE2EVideo = message.supportsE2EVideo; - if (message.supportsE2EAudio != null && message.hasOwnProperty("supportsE2EAudio")) - object.supportsE2EAudio = message.supportsE2EAudio; - if (message.supportsE2EDocument != null && message.hasOwnProperty("supportsE2EDocument")) - object.supportsE2EDocument = message.supportsE2EDocument; - if (message.documentTypes != null && message.hasOwnProperty("documentTypes")) - object.documentTypes = message.documentTypes; - if (message.features != null && message.hasOwnProperty("features")) - object.features = options.bytes === String ? $util.base64.encode(message.features, 0, message.features.length) : options.bytes === Array ? Array.prototype.slice.call(message.features) : message.features; - return object; - }; - - /** - * Converts this WebdPayload to JSON. - * @function toJSON - * @memberof proto.WebdPayload - * @instance - * @returns {Object.} JSON object - */ - WebdPayload.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return WebdPayload; - })(); - - proto.WebInfo = (function() { - - /** - * Properties of a WebInfo. - * @memberof proto - * @interface IWebInfo - * @property {string|null} [refToken] WebInfo refToken - * @property {string|null} [version] WebInfo version - * @property {proto.IWebdPayload|null} [webdPayload] WebInfo webdPayload - * @property {proto.WebInfo.WebInfoWebSubPlatform|null} [webSubPlatform] WebInfo webSubPlatform - */ - - /** - * Constructs a new WebInfo. - * @memberof proto - * @classdesc Represents a WebInfo. - * @implements IWebInfo - * @constructor - * @param {proto.IWebInfo=} [properties] Properties to set - */ - function WebInfo(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * WebInfo refToken. - * @member {string} refToken - * @memberof proto.WebInfo - * @instance - */ - WebInfo.prototype.refToken = ""; - - /** - * WebInfo version. - * @member {string} version - * @memberof proto.WebInfo - * @instance - */ - WebInfo.prototype.version = ""; - - /** - * WebInfo webdPayload. - * @member {proto.IWebdPayload|null|undefined} webdPayload - * @memberof proto.WebInfo - * @instance - */ - WebInfo.prototype.webdPayload = null; - - /** - * WebInfo webSubPlatform. - * @member {proto.WebInfo.WebInfoWebSubPlatform} webSubPlatform - * @memberof proto.WebInfo - * @instance - */ - WebInfo.prototype.webSubPlatform = 0; - - /** - * Creates a new WebInfo instance using the specified properties. - * @function create - * @memberof proto.WebInfo - * @static - * @param {proto.IWebInfo=} [properties] Properties to set - * @returns {proto.WebInfo} WebInfo instance - */ - WebInfo.create = function create(properties) { - return new WebInfo(properties); - }; - - /** - * Encodes the specified WebInfo message. Does not implicitly {@link proto.WebInfo.verify|verify} messages. - * @function encode - * @memberof proto.WebInfo - * @static - * @param {proto.IWebInfo} message WebInfo message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - WebInfo.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.refToken != null && Object.hasOwnProperty.call(message, "refToken")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.refToken); - if (message.version != null && Object.hasOwnProperty.call(message, "version")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.version); - if (message.webdPayload != null && Object.hasOwnProperty.call(message, "webdPayload")) - $root.proto.WebdPayload.encode(message.webdPayload, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - if (message.webSubPlatform != null && Object.hasOwnProperty.call(message, "webSubPlatform")) - writer.uint32(/* id 4, wireType 0 =*/32).int32(message.webSubPlatform); - return writer; - }; - - /** - * Encodes the specified WebInfo message, length delimited. Does not implicitly {@link proto.WebInfo.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.WebInfo - * @static - * @param {proto.IWebInfo} message WebInfo message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - WebInfo.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a WebInfo message from the specified reader or buffer. - * @function decode - * @memberof proto.WebInfo - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.WebInfo} WebInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - WebInfo.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebInfo(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.refToken = reader.string(); - break; - case 2: - message.version = reader.string(); - break; - case 3: - message.webdPayload = $root.proto.WebdPayload.decode(reader, reader.uint32()); - break; - case 4: - message.webSubPlatform = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a WebInfo message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.WebInfo - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.WebInfo} WebInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - WebInfo.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a WebInfo message. - * @function verify - * @memberof proto.WebInfo - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - WebInfo.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.refToken != null && message.hasOwnProperty("refToken")) - if (!$util.isString(message.refToken)) - return "refToken: string expected"; - if (message.version != null && message.hasOwnProperty("version")) - if (!$util.isString(message.version)) - return "version: string expected"; - if (message.webdPayload != null && message.hasOwnProperty("webdPayload")) { - var error = $root.proto.WebdPayload.verify(message.webdPayload); - if (error) - return "webdPayload." + error; - } - if (message.webSubPlatform != null && message.hasOwnProperty("webSubPlatform")) - switch (message.webSubPlatform) { - default: - return "webSubPlatform: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - break; - } - return null; - }; - - /** - * Creates a WebInfo message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.WebInfo - * @static - * @param {Object.} object Plain object - * @returns {proto.WebInfo} WebInfo - */ - WebInfo.fromObject = function fromObject(object) { - if (object instanceof $root.proto.WebInfo) - return object; - var message = new $root.proto.WebInfo(); - if (object.refToken != null) - message.refToken = String(object.refToken); - if (object.version != null) - message.version = String(object.version); - if (object.webdPayload != null) { - if (typeof object.webdPayload !== "object") - throw TypeError(".proto.WebInfo.webdPayload: object expected"); - message.webdPayload = $root.proto.WebdPayload.fromObject(object.webdPayload); - } - switch (object.webSubPlatform) { - case "WEB_BROWSER": - case 0: - message.webSubPlatform = 0; - break; - case "APP_STORE": - case 1: - message.webSubPlatform = 1; - break; - case "WIN_STORE": - case 2: - message.webSubPlatform = 2; - break; - case "DARWIN": - case 3: - message.webSubPlatform = 3; - break; - case "WIN32": - case 4: - message.webSubPlatform = 4; - break; - } - return message; - }; - - /** - * Creates a plain object from a WebInfo message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.WebInfo - * @static - * @param {proto.WebInfo} message WebInfo - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - WebInfo.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.refToken = ""; - object.version = ""; - object.webdPayload = null; - object.webSubPlatform = options.enums === String ? "WEB_BROWSER" : 0; - } - if (message.refToken != null && message.hasOwnProperty("refToken")) - object.refToken = message.refToken; - if (message.version != null && message.hasOwnProperty("version")) - object.version = message.version; - if (message.webdPayload != null && message.hasOwnProperty("webdPayload")) - object.webdPayload = $root.proto.WebdPayload.toObject(message.webdPayload, options); - if (message.webSubPlatform != null && message.hasOwnProperty("webSubPlatform")) - object.webSubPlatform = options.enums === String ? $root.proto.WebInfo.WebInfoWebSubPlatform[message.webSubPlatform] : message.webSubPlatform; - return object; - }; - - /** - * Converts this WebInfo to JSON. - * @function toJSON - * @memberof proto.WebInfo - * @instance - * @returns {Object.} JSON object - */ - WebInfo.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * WebInfoWebSubPlatform enum. - * @name proto.WebInfo.WebInfoWebSubPlatform - * @enum {number} - * @property {number} WEB_BROWSER=0 WEB_BROWSER value - * @property {number} APP_STORE=1 APP_STORE value - * @property {number} WIN_STORE=2 WIN_STORE value - * @property {number} DARWIN=3 DARWIN value - * @property {number} WIN32=4 WIN32 value - */ - WebInfo.WebInfoWebSubPlatform = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "WEB_BROWSER"] = 0; - values[valuesById[1] = "APP_STORE"] = 1; - values[valuesById[2] = "WIN_STORE"] = 2; - values[valuesById[3] = "DARWIN"] = 3; - values[valuesById[4] = "WIN32"] = 4; - return values; - })(); - - return WebInfo; - })(); - - proto.DNSSource = (function() { - - /** - * Properties of a DNSSource. - * @memberof proto - * @interface IDNSSource - * @property {proto.DNSSource.DNSSourceDNSResolutionMethod|null} [dnsMethod] DNSSource dnsMethod - * @property {boolean|null} [appCached] DNSSource appCached - */ - - /** - * Constructs a new DNSSource. - * @memberof proto - * @classdesc Represents a DNSSource. - * @implements IDNSSource - * @constructor - * @param {proto.IDNSSource=} [properties] Properties to set - */ - function DNSSource(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * DNSSource dnsMethod. - * @member {proto.DNSSource.DNSSourceDNSResolutionMethod} dnsMethod - * @memberof proto.DNSSource - * @instance - */ - DNSSource.prototype.dnsMethod = 0; - - /** - * DNSSource appCached. - * @member {boolean} appCached - * @memberof proto.DNSSource - * @instance - */ - DNSSource.prototype.appCached = false; - - /** - * Creates a new DNSSource instance using the specified properties. - * @function create - * @memberof proto.DNSSource - * @static - * @param {proto.IDNSSource=} [properties] Properties to set - * @returns {proto.DNSSource} DNSSource instance - */ - DNSSource.create = function create(properties) { - return new DNSSource(properties); - }; - - /** - * Encodes the specified DNSSource message. Does not implicitly {@link proto.DNSSource.verify|verify} messages. - * @function encode - * @memberof proto.DNSSource - * @static - * @param {proto.IDNSSource} message DNSSource message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - DNSSource.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.dnsMethod != null && Object.hasOwnProperty.call(message, "dnsMethod")) - writer.uint32(/* id 15, wireType 0 =*/120).int32(message.dnsMethod); - if (message.appCached != null && Object.hasOwnProperty.call(message, "appCached")) - writer.uint32(/* id 16, wireType 0 =*/128).bool(message.appCached); - return writer; - }; - - /** - * Encodes the specified DNSSource message, length delimited. Does not implicitly {@link proto.DNSSource.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.DNSSource - * @static - * @param {proto.IDNSSource} message DNSSource message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - DNSSource.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a DNSSource message from the specified reader or buffer. - * @function decode - * @memberof proto.DNSSource - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.DNSSource} DNSSource - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - DNSSource.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DNSSource(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 15: - message.dnsMethod = reader.int32(); - break; - case 16: - message.appCached = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a DNSSource message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.DNSSource - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.DNSSource} DNSSource - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - DNSSource.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a DNSSource message. - * @function verify - * @memberof proto.DNSSource - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - DNSSource.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.dnsMethod != null && message.hasOwnProperty("dnsMethod")) - switch (message.dnsMethod) { - default: - return "dnsMethod: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - break; - } - if (message.appCached != null && message.hasOwnProperty("appCached")) - if (typeof message.appCached !== "boolean") - return "appCached: boolean expected"; - return null; - }; - - /** - * Creates a DNSSource message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.DNSSource - * @static - * @param {Object.} object Plain object - * @returns {proto.DNSSource} DNSSource - */ - DNSSource.fromObject = function fromObject(object) { - if (object instanceof $root.proto.DNSSource) - return object; - var message = new $root.proto.DNSSource(); - switch (object.dnsMethod) { - case "SYSTEM": - case 0: - message.dnsMethod = 0; - break; - case "GOOGLE": - case 1: - message.dnsMethod = 1; - break; - case "HARDCODED": - case 2: - message.dnsMethod = 2; - break; - case "OVERRIDE": - case 3: - message.dnsMethod = 3; - break; - case "FALLBACK": - case 4: - message.dnsMethod = 4; - break; - } - if (object.appCached != null) - message.appCached = Boolean(object.appCached); - return message; - }; - - /** - * Creates a plain object from a DNSSource message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.DNSSource - * @static - * @param {proto.DNSSource} message DNSSource - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - DNSSource.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.dnsMethod = options.enums === String ? "SYSTEM" : 0; - object.appCached = false; - } - if (message.dnsMethod != null && message.hasOwnProperty("dnsMethod")) - object.dnsMethod = options.enums === String ? $root.proto.DNSSource.DNSSourceDNSResolutionMethod[message.dnsMethod] : message.dnsMethod; - if (message.appCached != null && message.hasOwnProperty("appCached")) - object.appCached = message.appCached; - return object; - }; - - /** - * Converts this DNSSource to JSON. - * @function toJSON - * @memberof proto.DNSSource - * @instance - * @returns {Object.} JSON object - */ - DNSSource.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * DNSSourceDNSResolutionMethod enum. - * @name proto.DNSSource.DNSSourceDNSResolutionMethod - * @enum {number} - * @property {number} SYSTEM=0 SYSTEM value - * @property {number} GOOGLE=1 GOOGLE value - * @property {number} HARDCODED=2 HARDCODED value - * @property {number} OVERRIDE=3 OVERRIDE value - * @property {number} FALLBACK=4 FALLBACK value - */ - DNSSource.DNSSourceDNSResolutionMethod = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "SYSTEM"] = 0; - values[valuesById[1] = "GOOGLE"] = 1; - values[valuesById[2] = "HARDCODED"] = 2; - values[valuesById[3] = "OVERRIDE"] = 3; - values[valuesById[4] = "FALLBACK"] = 4; - return values; - })(); - - return DNSSource; - })(); - - proto.CompanionRegData = (function() { - - /** - * Properties of a CompanionRegData. - * @memberof proto - * @interface ICompanionRegData - * @property {Uint8Array|null} [eRegid] CompanionRegData eRegid - * @property {Uint8Array|null} [eKeytype] CompanionRegData eKeytype - * @property {Uint8Array|null} [eIdent] CompanionRegData eIdent - * @property {Uint8Array|null} [eSkeyId] CompanionRegData eSkeyId - * @property {Uint8Array|null} [eSkeyVal] CompanionRegData eSkeyVal - * @property {Uint8Array|null} [eSkeySig] CompanionRegData eSkeySig - * @property {Uint8Array|null} [buildHash] CompanionRegData buildHash - * @property {Uint8Array|null} [companionProps] CompanionRegData companionProps - */ - - /** - * Constructs a new CompanionRegData. - * @memberof proto - * @classdesc Represents a CompanionRegData. - * @implements ICompanionRegData - * @constructor - * @param {proto.ICompanionRegData=} [properties] Properties to set - */ - function CompanionRegData(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * CompanionRegData eRegid. - * @member {Uint8Array} eRegid - * @memberof proto.CompanionRegData - * @instance - */ - CompanionRegData.prototype.eRegid = $util.newBuffer([]); - - /** - * CompanionRegData eKeytype. - * @member {Uint8Array} eKeytype - * @memberof proto.CompanionRegData - * @instance - */ - CompanionRegData.prototype.eKeytype = $util.newBuffer([]); - - /** - * CompanionRegData eIdent. - * @member {Uint8Array} eIdent - * @memberof proto.CompanionRegData - * @instance - */ - CompanionRegData.prototype.eIdent = $util.newBuffer([]); - - /** - * CompanionRegData eSkeyId. - * @member {Uint8Array} eSkeyId - * @memberof proto.CompanionRegData - * @instance - */ - CompanionRegData.prototype.eSkeyId = $util.newBuffer([]); - - /** - * CompanionRegData eSkeyVal. - * @member {Uint8Array} eSkeyVal - * @memberof proto.CompanionRegData - * @instance - */ - CompanionRegData.prototype.eSkeyVal = $util.newBuffer([]); - - /** - * CompanionRegData eSkeySig. - * @member {Uint8Array} eSkeySig - * @memberof proto.CompanionRegData - * @instance - */ - CompanionRegData.prototype.eSkeySig = $util.newBuffer([]); - - /** - * CompanionRegData buildHash. - * @member {Uint8Array} buildHash - * @memberof proto.CompanionRegData - * @instance - */ - CompanionRegData.prototype.buildHash = $util.newBuffer([]); - - /** - * CompanionRegData companionProps. - * @member {Uint8Array} companionProps - * @memberof proto.CompanionRegData - * @instance - */ - CompanionRegData.prototype.companionProps = $util.newBuffer([]); - - /** - * Creates a new CompanionRegData instance using the specified properties. - * @function create - * @memberof proto.CompanionRegData - * @static - * @param {proto.ICompanionRegData=} [properties] Properties to set - * @returns {proto.CompanionRegData} CompanionRegData instance - */ - CompanionRegData.create = function create(properties) { - return new CompanionRegData(properties); - }; - - /** - * Encodes the specified CompanionRegData message. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages. - * @function encode - * @memberof proto.CompanionRegData - * @static - * @param {proto.ICompanionRegData} message CompanionRegData message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - CompanionRegData.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.eRegid != null && Object.hasOwnProperty.call(message, "eRegid")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.eRegid); - if (message.eKeytype != null && Object.hasOwnProperty.call(message, "eKeytype")) - writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.eKeytype); - if (message.eIdent != null && Object.hasOwnProperty.call(message, "eIdent")) - writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.eIdent); - if (message.eSkeyId != null && Object.hasOwnProperty.call(message, "eSkeyId")) - writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.eSkeyId); - if (message.eSkeyVal != null && Object.hasOwnProperty.call(message, "eSkeyVal")) - writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.eSkeyVal); - if (message.eSkeySig != null && Object.hasOwnProperty.call(message, "eSkeySig")) - writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.eSkeySig); - if (message.buildHash != null && Object.hasOwnProperty.call(message, "buildHash")) - writer.uint32(/* id 7, wireType 2 =*/58).bytes(message.buildHash); - if (message.companionProps != null && Object.hasOwnProperty.call(message, "companionProps")) - writer.uint32(/* id 8, wireType 2 =*/66).bytes(message.companionProps); - return writer; - }; - - /** - * Encodes the specified CompanionRegData message, length delimited. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.CompanionRegData - * @static - * @param {proto.ICompanionRegData} message CompanionRegData message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - CompanionRegData.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a CompanionRegData message from the specified reader or buffer. - * @function decode - * @memberof proto.CompanionRegData - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.CompanionRegData} CompanionRegData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - CompanionRegData.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CompanionRegData(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.eRegid = reader.bytes(); - break; - case 2: - message.eKeytype = reader.bytes(); - break; - case 3: - message.eIdent = reader.bytes(); - break; - case 4: - message.eSkeyId = reader.bytes(); - break; - case 5: - message.eSkeyVal = reader.bytes(); - break; - case 6: - message.eSkeySig = reader.bytes(); - break; - case 7: - message.buildHash = reader.bytes(); - break; - case 8: - message.companionProps = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a CompanionRegData message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.CompanionRegData - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.CompanionRegData} CompanionRegData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - CompanionRegData.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a CompanionRegData message. - * @function verify - * @memberof proto.CompanionRegData - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - CompanionRegData.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.eRegid != null && message.hasOwnProperty("eRegid")) - if (!(message.eRegid && typeof message.eRegid.length === "number" || $util.isString(message.eRegid))) - return "eRegid: buffer expected"; - if (message.eKeytype != null && message.hasOwnProperty("eKeytype")) - if (!(message.eKeytype && typeof message.eKeytype.length === "number" || $util.isString(message.eKeytype))) - return "eKeytype: buffer expected"; - if (message.eIdent != null && message.hasOwnProperty("eIdent")) - if (!(message.eIdent && typeof message.eIdent.length === "number" || $util.isString(message.eIdent))) - return "eIdent: buffer expected"; - if (message.eSkeyId != null && message.hasOwnProperty("eSkeyId")) - if (!(message.eSkeyId && typeof message.eSkeyId.length === "number" || $util.isString(message.eSkeyId))) - return "eSkeyId: buffer expected"; - if (message.eSkeyVal != null && message.hasOwnProperty("eSkeyVal")) - if (!(message.eSkeyVal && typeof message.eSkeyVal.length === "number" || $util.isString(message.eSkeyVal))) - return "eSkeyVal: buffer expected"; - if (message.eSkeySig != null && message.hasOwnProperty("eSkeySig")) - if (!(message.eSkeySig && typeof message.eSkeySig.length === "number" || $util.isString(message.eSkeySig))) - return "eSkeySig: buffer expected"; - if (message.buildHash != null && message.hasOwnProperty("buildHash")) - if (!(message.buildHash && typeof message.buildHash.length === "number" || $util.isString(message.buildHash))) - return "buildHash: buffer expected"; - if (message.companionProps != null && message.hasOwnProperty("companionProps")) - if (!(message.companionProps && typeof message.companionProps.length === "number" || $util.isString(message.companionProps))) - return "companionProps: buffer expected"; - return null; - }; - - /** - * Creates a CompanionRegData message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.CompanionRegData - * @static - * @param {Object.} object Plain object - * @returns {proto.CompanionRegData} CompanionRegData - */ - CompanionRegData.fromObject = function fromObject(object) { - if (object instanceof $root.proto.CompanionRegData) - return object; - var message = new $root.proto.CompanionRegData(); - if (object.eRegid != null) - if (typeof object.eRegid === "string") - $util.base64.decode(object.eRegid, message.eRegid = $util.newBuffer($util.base64.length(object.eRegid)), 0); - else if (object.eRegid.length) - message.eRegid = object.eRegid; - if (object.eKeytype != null) - if (typeof object.eKeytype === "string") - $util.base64.decode(object.eKeytype, message.eKeytype = $util.newBuffer($util.base64.length(object.eKeytype)), 0); - else if (object.eKeytype.length) - message.eKeytype = object.eKeytype; - if (object.eIdent != null) - if (typeof object.eIdent === "string") - $util.base64.decode(object.eIdent, message.eIdent = $util.newBuffer($util.base64.length(object.eIdent)), 0); - else if (object.eIdent.length) - message.eIdent = object.eIdent; - if (object.eSkeyId != null) - if (typeof object.eSkeyId === "string") - $util.base64.decode(object.eSkeyId, message.eSkeyId = $util.newBuffer($util.base64.length(object.eSkeyId)), 0); - else if (object.eSkeyId.length) - message.eSkeyId = object.eSkeyId; - if (object.eSkeyVal != null) - if (typeof object.eSkeyVal === "string") - $util.base64.decode(object.eSkeyVal, message.eSkeyVal = $util.newBuffer($util.base64.length(object.eSkeyVal)), 0); - else if (object.eSkeyVal.length) - message.eSkeyVal = object.eSkeyVal; - if (object.eSkeySig != null) - if (typeof object.eSkeySig === "string") - $util.base64.decode(object.eSkeySig, message.eSkeySig = $util.newBuffer($util.base64.length(object.eSkeySig)), 0); - else if (object.eSkeySig.length) - message.eSkeySig = object.eSkeySig; - if (object.buildHash != null) - if (typeof object.buildHash === "string") - $util.base64.decode(object.buildHash, message.buildHash = $util.newBuffer($util.base64.length(object.buildHash)), 0); - else if (object.buildHash.length) - message.buildHash = object.buildHash; - if (object.companionProps != null) - if (typeof object.companionProps === "string") - $util.base64.decode(object.companionProps, message.companionProps = $util.newBuffer($util.base64.length(object.companionProps)), 0); - else if (object.companionProps.length) - message.companionProps = object.companionProps; - return message; - }; - - /** - * Creates a plain object from a CompanionRegData message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.CompanionRegData - * @static - * @param {proto.CompanionRegData} message CompanionRegData - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - CompanionRegData.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if (options.bytes === String) - object.eRegid = ""; - else { - object.eRegid = []; - if (options.bytes !== Array) - object.eRegid = $util.newBuffer(object.eRegid); - } - if (options.bytes === String) - object.eKeytype = ""; - else { - object.eKeytype = []; - if (options.bytes !== Array) - object.eKeytype = $util.newBuffer(object.eKeytype); - } - if (options.bytes === String) - object.eIdent = ""; - else { - object.eIdent = []; - if (options.bytes !== Array) - object.eIdent = $util.newBuffer(object.eIdent); - } - if (options.bytes === String) - object.eSkeyId = ""; - else { - object.eSkeyId = []; - if (options.bytes !== Array) - object.eSkeyId = $util.newBuffer(object.eSkeyId); - } - if (options.bytes === String) - object.eSkeyVal = ""; - else { - object.eSkeyVal = []; - if (options.bytes !== Array) - object.eSkeyVal = $util.newBuffer(object.eSkeyVal); - } - if (options.bytes === String) - object.eSkeySig = ""; - else { - object.eSkeySig = []; - if (options.bytes !== Array) - object.eSkeySig = $util.newBuffer(object.eSkeySig); - } - if (options.bytes === String) - object.buildHash = ""; - else { - object.buildHash = []; - if (options.bytes !== Array) - object.buildHash = $util.newBuffer(object.buildHash); - } - if (options.bytes === String) - object.companionProps = ""; - else { - object.companionProps = []; - if (options.bytes !== Array) - object.companionProps = $util.newBuffer(object.companionProps); - } - } - if (message.eRegid != null && message.hasOwnProperty("eRegid")) - object.eRegid = options.bytes === String ? $util.base64.encode(message.eRegid, 0, message.eRegid.length) : options.bytes === Array ? Array.prototype.slice.call(message.eRegid) : message.eRegid; - if (message.eKeytype != null && message.hasOwnProperty("eKeytype")) - object.eKeytype = options.bytes === String ? $util.base64.encode(message.eKeytype, 0, message.eKeytype.length) : options.bytes === Array ? Array.prototype.slice.call(message.eKeytype) : message.eKeytype; - if (message.eIdent != null && message.hasOwnProperty("eIdent")) - object.eIdent = options.bytes === String ? $util.base64.encode(message.eIdent, 0, message.eIdent.length) : options.bytes === Array ? Array.prototype.slice.call(message.eIdent) : message.eIdent; - if (message.eSkeyId != null && message.hasOwnProperty("eSkeyId")) - object.eSkeyId = options.bytes === String ? $util.base64.encode(message.eSkeyId, 0, message.eSkeyId.length) : options.bytes === Array ? Array.prototype.slice.call(message.eSkeyId) : message.eSkeyId; - if (message.eSkeyVal != null && message.hasOwnProperty("eSkeyVal")) - object.eSkeyVal = options.bytes === String ? $util.base64.encode(message.eSkeyVal, 0, message.eSkeyVal.length) : options.bytes === Array ? Array.prototype.slice.call(message.eSkeyVal) : message.eSkeyVal; - if (message.eSkeySig != null && message.hasOwnProperty("eSkeySig")) - object.eSkeySig = options.bytes === String ? $util.base64.encode(message.eSkeySig, 0, message.eSkeySig.length) : options.bytes === Array ? Array.prototype.slice.call(message.eSkeySig) : message.eSkeySig; - if (message.buildHash != null && message.hasOwnProperty("buildHash")) - object.buildHash = options.bytes === String ? $util.base64.encode(message.buildHash, 0, message.buildHash.length) : options.bytes === Array ? Array.prototype.slice.call(message.buildHash) : message.buildHash; - if (message.companionProps != null && message.hasOwnProperty("companionProps")) - object.companionProps = options.bytes === String ? $util.base64.encode(message.companionProps, 0, message.companionProps.length) : options.bytes === Array ? Array.prototype.slice.call(message.companionProps) : message.companionProps; - return object; - }; - - /** - * Converts this CompanionRegData to JSON. - * @function toJSON - * @memberof proto.CompanionRegData - * @instance - * @returns {Object.} JSON object - */ - CompanionRegData.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return CompanionRegData; - })(); - - proto.ClientPayload = (function() { - - /** - * Properties of a ClientPayload. - * @memberof proto - * @interface IClientPayload - * @property {number|Long|null} [username] ClientPayload username - * @property {boolean|null} [passive] ClientPayload passive - * @property {Array.|null} [clientFeatures] ClientPayload clientFeatures - * @property {proto.IUserAgent|null} [userAgent] ClientPayload userAgent - * @property {proto.IWebInfo|null} [webInfo] ClientPayload webInfo - * @property {string|null} [pushName] ClientPayload pushName - * @property {number|null} [sessionId] ClientPayload sessionId - * @property {boolean|null} [shortConnect] ClientPayload shortConnect - * @property {proto.ClientPayload.ClientPayloadIOSAppExtension|null} [iosAppExtension] ClientPayload iosAppExtension - * @property {proto.ClientPayload.ClientPayloadConnectType|null} [connectType] ClientPayload connectType - * @property {proto.ClientPayload.ClientPayloadConnectReason|null} [connectReason] ClientPayload connectReason - * @property {Array.|null} [shards] ClientPayload shards - * @property {proto.IDNSSource|null} [dnsSource] ClientPayload dnsSource - * @property {number|null} [connectAttemptCount] ClientPayload connectAttemptCount - * @property {number|null} [agent] ClientPayload agent - * @property {number|null} [device] ClientPayload device - * @property {proto.ICompanionRegData|null} [regData] ClientPayload regData - * @property {proto.ClientPayload.ClientPayloadProduct|null} [product] ClientPayload product - * @property {Uint8Array|null} [fbCat] ClientPayload fbCat - * @property {Uint8Array|null} [fbUserAgent] ClientPayload fbUserAgent - * @property {boolean|null} [oc] ClientPayload oc - */ - - /** - * Constructs a new ClientPayload. - * @memberof proto - * @classdesc Represents a ClientPayload. - * @implements IClientPayload - * @constructor - * @param {proto.IClientPayload=} [properties] Properties to set - */ - function ClientPayload(properties) { - this.clientFeatures = []; - this.shards = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ClientPayload username. - * @member {number|Long} username - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.username = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * ClientPayload passive. - * @member {boolean} passive - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.passive = false; - - /** - * ClientPayload clientFeatures. - * @member {Array.} clientFeatures - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.clientFeatures = $util.emptyArray; - - /** - * ClientPayload userAgent. - * @member {proto.IUserAgent|null|undefined} userAgent - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.userAgent = null; - - /** - * ClientPayload webInfo. - * @member {proto.IWebInfo|null|undefined} webInfo - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.webInfo = null; - - /** - * ClientPayload pushName. - * @member {string} pushName - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.pushName = ""; - - /** - * ClientPayload sessionId. - * @member {number} sessionId - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.sessionId = 0; - - /** - * ClientPayload shortConnect. - * @member {boolean} shortConnect - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.shortConnect = false; - - /** - * ClientPayload iosAppExtension. - * @member {proto.ClientPayload.ClientPayloadIOSAppExtension} iosAppExtension - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.iosAppExtension = 0; - - /** - * ClientPayload connectType. - * @member {proto.ClientPayload.ClientPayloadConnectType} connectType - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.connectType = 0; - - /** - * ClientPayload connectReason. - * @member {proto.ClientPayload.ClientPayloadConnectReason} connectReason - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.connectReason = 0; - - /** - * ClientPayload shards. - * @member {Array.} shards - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.shards = $util.emptyArray; - - /** - * ClientPayload dnsSource. - * @member {proto.IDNSSource|null|undefined} dnsSource - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.dnsSource = null; - - /** - * ClientPayload connectAttemptCount. - * @member {number} connectAttemptCount - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.connectAttemptCount = 0; - - /** - * ClientPayload agent. - * @member {number} agent - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.agent = 0; - - /** - * ClientPayload device. - * @member {number} device - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.device = 0; - - /** - * ClientPayload regData. - * @member {proto.ICompanionRegData|null|undefined} regData - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.regData = null; - - /** - * ClientPayload product. - * @member {proto.ClientPayload.ClientPayloadProduct} product - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.product = 0; - - /** - * ClientPayload fbCat. - * @member {Uint8Array} fbCat - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.fbCat = $util.newBuffer([]); - - /** - * ClientPayload fbUserAgent. - * @member {Uint8Array} fbUserAgent - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.fbUserAgent = $util.newBuffer([]); - - /** - * ClientPayload oc. - * @member {boolean} oc - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.oc = false; - - /** - * Creates a new ClientPayload instance using the specified properties. - * @function create - * @memberof proto.ClientPayload - * @static - * @param {proto.IClientPayload=} [properties] Properties to set - * @returns {proto.ClientPayload} ClientPayload instance - */ - ClientPayload.create = function create(properties) { - return new ClientPayload(properties); - }; - - /** - * Encodes the specified ClientPayload message. Does not implicitly {@link proto.ClientPayload.verify|verify} messages. - * @function encode - * @memberof proto.ClientPayload - * @static - * @param {proto.IClientPayload} message ClientPayload message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ClientPayload.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.username != null && Object.hasOwnProperty.call(message, "username")) - writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.username); - if (message.passive != null && Object.hasOwnProperty.call(message, "passive")) - writer.uint32(/* id 3, wireType 0 =*/24).bool(message.passive); - if (message.clientFeatures != null && message.clientFeatures.length) - for (var i = 0; i < message.clientFeatures.length; ++i) - writer.uint32(/* id 4, wireType 0 =*/32).int32(message.clientFeatures[i]); - if (message.userAgent != null && Object.hasOwnProperty.call(message, "userAgent")) - $root.proto.UserAgent.encode(message.userAgent, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); - if (message.webInfo != null && Object.hasOwnProperty.call(message, "webInfo")) - $root.proto.WebInfo.encode(message.webInfo, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); - if (message.pushName != null && Object.hasOwnProperty.call(message, "pushName")) - writer.uint32(/* id 7, wireType 2 =*/58).string(message.pushName); - if (message.sessionId != null && Object.hasOwnProperty.call(message, "sessionId")) - writer.uint32(/* id 9, wireType 5 =*/77).sfixed32(message.sessionId); - if (message.shortConnect != null && Object.hasOwnProperty.call(message, "shortConnect")) - writer.uint32(/* id 10, wireType 0 =*/80).bool(message.shortConnect); - if (message.connectType != null && Object.hasOwnProperty.call(message, "connectType")) - writer.uint32(/* id 12, wireType 0 =*/96).int32(message.connectType); - if (message.connectReason != null && Object.hasOwnProperty.call(message, "connectReason")) - writer.uint32(/* id 13, wireType 0 =*/104).int32(message.connectReason); - if (message.shards != null && message.shards.length) - for (var i = 0; i < message.shards.length; ++i) - writer.uint32(/* id 14, wireType 0 =*/112).int32(message.shards[i]); - if (message.dnsSource != null && Object.hasOwnProperty.call(message, "dnsSource")) - $root.proto.DNSSource.encode(message.dnsSource, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim(); - if (message.connectAttemptCount != null && Object.hasOwnProperty.call(message, "connectAttemptCount")) - writer.uint32(/* id 16, wireType 0 =*/128).uint32(message.connectAttemptCount); - if (message.agent != null && Object.hasOwnProperty.call(message, "agent")) - writer.uint32(/* id 17, wireType 0 =*/136).uint32(message.agent); - if (message.device != null && Object.hasOwnProperty.call(message, "device")) - writer.uint32(/* id 18, wireType 0 =*/144).uint32(message.device); - if (message.regData != null && Object.hasOwnProperty.call(message, "regData")) - $root.proto.CompanionRegData.encode(message.regData, writer.uint32(/* id 19, wireType 2 =*/154).fork()).ldelim(); - if (message.product != null && Object.hasOwnProperty.call(message, "product")) - writer.uint32(/* id 20, wireType 0 =*/160).int32(message.product); - if (message.fbCat != null && Object.hasOwnProperty.call(message, "fbCat")) - writer.uint32(/* id 21, wireType 2 =*/170).bytes(message.fbCat); - if (message.fbUserAgent != null && Object.hasOwnProperty.call(message, "fbUserAgent")) - writer.uint32(/* id 22, wireType 2 =*/178).bytes(message.fbUserAgent); - if (message.oc != null && Object.hasOwnProperty.call(message, "oc")) - writer.uint32(/* id 23, wireType 0 =*/184).bool(message.oc); - if (message.iosAppExtension != null && Object.hasOwnProperty.call(message, "iosAppExtension")) - writer.uint32(/* id 30, wireType 0 =*/240).int32(message.iosAppExtension); - return writer; - }; - - /** - * Encodes the specified ClientPayload message, length delimited. Does not implicitly {@link proto.ClientPayload.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ClientPayload - * @static - * @param {proto.IClientPayload} message ClientPayload message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ClientPayload.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ClientPayload message from the specified reader or buffer. - * @function decode - * @memberof proto.ClientPayload - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ClientPayload} ClientPayload - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ClientPayload.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClientPayload(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.username = reader.uint64(); - break; - case 3: - message.passive = reader.bool(); - break; - case 4: - if (!(message.clientFeatures && message.clientFeatures.length)) - message.clientFeatures = []; - if ((tag & 7) === 2) { - var end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) - message.clientFeatures.push(reader.int32()); - } else - message.clientFeatures.push(reader.int32()); - break; - case 5: - message.userAgent = $root.proto.UserAgent.decode(reader, reader.uint32()); - break; - case 6: - message.webInfo = $root.proto.WebInfo.decode(reader, reader.uint32()); - break; - case 7: - message.pushName = reader.string(); - break; - case 9: - message.sessionId = reader.sfixed32(); - break; - case 10: - message.shortConnect = reader.bool(); - break; - case 30: - message.iosAppExtension = reader.int32(); - break; - case 12: - message.connectType = reader.int32(); - break; - case 13: - message.connectReason = reader.int32(); - break; - case 14: - if (!(message.shards && message.shards.length)) - message.shards = []; - if ((tag & 7) === 2) { - var end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) - message.shards.push(reader.int32()); - } else - message.shards.push(reader.int32()); - break; - case 15: - message.dnsSource = $root.proto.DNSSource.decode(reader, reader.uint32()); - break; - case 16: - message.connectAttemptCount = reader.uint32(); - break; - case 17: - message.agent = reader.uint32(); - break; - case 18: - message.device = reader.uint32(); - break; - case 19: - message.regData = $root.proto.CompanionRegData.decode(reader, reader.uint32()); - break; - case 20: - message.product = reader.int32(); - break; - case 21: - message.fbCat = reader.bytes(); - break; - case 22: - message.fbUserAgent = reader.bytes(); - break; - case 23: - message.oc = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ClientPayload message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ClientPayload - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ClientPayload} ClientPayload - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ClientPayload.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ClientPayload message. - * @function verify - * @memberof proto.ClientPayload - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ClientPayload.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.username != null && message.hasOwnProperty("username")) - if (!$util.isInteger(message.username) && !(message.username && $util.isInteger(message.username.low) && $util.isInteger(message.username.high))) - return "username: integer|Long expected"; - if (message.passive != null && message.hasOwnProperty("passive")) - if (typeof message.passive !== "boolean") - return "passive: boolean expected"; - if (message.clientFeatures != null && message.hasOwnProperty("clientFeatures")) { - if (!Array.isArray(message.clientFeatures)) - return "clientFeatures: array expected"; - for (var i = 0; i < message.clientFeatures.length; ++i) - switch (message.clientFeatures[i]) { - default: - return "clientFeatures: enum value[] expected"; - case 0: - break; - } - } - if (message.userAgent != null && message.hasOwnProperty("userAgent")) { - var error = $root.proto.UserAgent.verify(message.userAgent); - if (error) - return "userAgent." + error; - } - if (message.webInfo != null && message.hasOwnProperty("webInfo")) { - var error = $root.proto.WebInfo.verify(message.webInfo); - if (error) - return "webInfo." + error; - } - if (message.pushName != null && message.hasOwnProperty("pushName")) - if (!$util.isString(message.pushName)) - return "pushName: string expected"; - if (message.sessionId != null && message.hasOwnProperty("sessionId")) - if (!$util.isInteger(message.sessionId)) - return "sessionId: integer expected"; - if (message.shortConnect != null && message.hasOwnProperty("shortConnect")) - if (typeof message.shortConnect !== "boolean") - return "shortConnect: boolean expected"; - if (message.iosAppExtension != null && message.hasOwnProperty("iosAppExtension")) - switch (message.iosAppExtension) { - default: - return "iosAppExtension: enum value expected"; - case 0: - case 1: - case 2: - break; - } - if (message.connectType != null && message.hasOwnProperty("connectType")) - switch (message.connectType) { - default: - return "connectType: enum value expected"; - case 0: - case 1: - case 100: - case 101: - case 102: - case 103: - case 104: - case 105: - case 106: - case 107: - case 108: - case 109: - case 110: - case 111: - case 112: - break; - } - if (message.connectReason != null && message.hasOwnProperty("connectReason")) - switch (message.connectReason) { - default: - return "connectReason: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - break; - } - if (message.shards != null && message.hasOwnProperty("shards")) { - if (!Array.isArray(message.shards)) - return "shards: array expected"; - for (var i = 0; i < message.shards.length; ++i) - if (!$util.isInteger(message.shards[i])) - return "shards: integer[] expected"; - } - if (message.dnsSource != null && message.hasOwnProperty("dnsSource")) { - var error = $root.proto.DNSSource.verify(message.dnsSource); - if (error) - return "dnsSource." + error; - } - if (message.connectAttemptCount != null && message.hasOwnProperty("connectAttemptCount")) - if (!$util.isInteger(message.connectAttemptCount)) - return "connectAttemptCount: integer expected"; - if (message.agent != null && message.hasOwnProperty("agent")) - if (!$util.isInteger(message.agent)) - return "agent: integer expected"; - if (message.device != null && message.hasOwnProperty("device")) - if (!$util.isInteger(message.device)) - return "device: integer expected"; - if (message.regData != null && message.hasOwnProperty("regData")) { - var error = $root.proto.CompanionRegData.verify(message.regData); - if (error) - return "regData." + error; - } - if (message.product != null && message.hasOwnProperty("product")) - switch (message.product) { - default: - return "product: enum value expected"; - case 0: - case 1: - break; - } - if (message.fbCat != null && message.hasOwnProperty("fbCat")) - if (!(message.fbCat && typeof message.fbCat.length === "number" || $util.isString(message.fbCat))) - return "fbCat: buffer expected"; - if (message.fbUserAgent != null && message.hasOwnProperty("fbUserAgent")) - if (!(message.fbUserAgent && typeof message.fbUserAgent.length === "number" || $util.isString(message.fbUserAgent))) - return "fbUserAgent: buffer expected"; - if (message.oc != null && message.hasOwnProperty("oc")) - if (typeof message.oc !== "boolean") - return "oc: boolean expected"; - return null; - }; - - /** - * Creates a ClientPayload message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ClientPayload - * @static - * @param {Object.} object Plain object - * @returns {proto.ClientPayload} ClientPayload - */ - ClientPayload.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ClientPayload) - return object; - var message = new $root.proto.ClientPayload(); - if (object.username != null) - if ($util.Long) - (message.username = $util.Long.fromValue(object.username)).unsigned = true; - else if (typeof object.username === "string") - message.username = parseInt(object.username, 10); - else if (typeof object.username === "number") - message.username = object.username; - else if (typeof object.username === "object") - message.username = new $util.LongBits(object.username.low >>> 0, object.username.high >>> 0).toNumber(true); - if (object.passive != null) - message.passive = Boolean(object.passive); - if (object.clientFeatures) { - if (!Array.isArray(object.clientFeatures)) - throw TypeError(".proto.ClientPayload.clientFeatures: array expected"); - message.clientFeatures = []; - for (var i = 0; i < object.clientFeatures.length; ++i) - switch (object.clientFeatures[i]) { - default: - case "NONE": - case 0: - message.clientFeatures[i] = 0; - break; - } - } - if (object.userAgent != null) { - if (typeof object.userAgent !== "object") - throw TypeError(".proto.ClientPayload.userAgent: object expected"); - message.userAgent = $root.proto.UserAgent.fromObject(object.userAgent); - } - if (object.webInfo != null) { - if (typeof object.webInfo !== "object") - throw TypeError(".proto.ClientPayload.webInfo: object expected"); - message.webInfo = $root.proto.WebInfo.fromObject(object.webInfo); - } - if (object.pushName != null) - message.pushName = String(object.pushName); - if (object.sessionId != null) - message.sessionId = object.sessionId | 0; - if (object.shortConnect != null) - message.shortConnect = Boolean(object.shortConnect); - switch (object.iosAppExtension) { - case "SHARE_EXTENSION": - case 0: - message.iosAppExtension = 0; - break; - case "SERVICE_EXTENSION": - case 1: - message.iosAppExtension = 1; - break; - case "INTENTS_EXTENSION": - case 2: - message.iosAppExtension = 2; - break; - } - switch (object.connectType) { - case "CELLULAR_UNKNOWN": - case 0: - message.connectType = 0; - break; - case "WIFI_UNKNOWN": - case 1: - message.connectType = 1; - break; - case "CELLULAR_EDGE": - case 100: - message.connectType = 100; - break; - case "CELLULAR_IDEN": - case 101: - message.connectType = 101; - break; - case "CELLULAR_UMTS": - case 102: - message.connectType = 102; - break; - case "CELLULAR_EVDO": - case 103: - message.connectType = 103; - break; - case "CELLULAR_GPRS": - case 104: - message.connectType = 104; - break; - case "CELLULAR_HSDPA": - case 105: - message.connectType = 105; - break; - case "CELLULAR_HSUPA": - case 106: - message.connectType = 106; - break; - case "CELLULAR_HSPA": - case 107: - message.connectType = 107; - break; - case "CELLULAR_CDMA": - case 108: - message.connectType = 108; - break; - case "CELLULAR_1XRTT": - case 109: - message.connectType = 109; - break; - case "CELLULAR_EHRPD": - case 110: - message.connectType = 110; - break; - case "CELLULAR_LTE": - case 111: - message.connectType = 111; - break; - case "CELLULAR_HSPAP": - case 112: - message.connectType = 112; - break; - } - switch (object.connectReason) { - case "PUSH": - case 0: - message.connectReason = 0; - break; - case "USER_ACTIVATED": - case 1: - message.connectReason = 1; - break; - case "SCHEDULED": - case 2: - message.connectReason = 2; - break; - case "ERROR_RECONNECT": - case 3: - message.connectReason = 3; - break; - case "NETWORK_SWITCH": - case 4: - message.connectReason = 4; - break; - case "PING_RECONNECT": - case 5: - message.connectReason = 5; - break; - } - if (object.shards) { - if (!Array.isArray(object.shards)) - throw TypeError(".proto.ClientPayload.shards: array expected"); - message.shards = []; - for (var i = 0; i < object.shards.length; ++i) - message.shards[i] = object.shards[i] | 0; - } - if (object.dnsSource != null) { - if (typeof object.dnsSource !== "object") - throw TypeError(".proto.ClientPayload.dnsSource: object expected"); - message.dnsSource = $root.proto.DNSSource.fromObject(object.dnsSource); - } - if (object.connectAttemptCount != null) - message.connectAttemptCount = object.connectAttemptCount >>> 0; - if (object.agent != null) - message.agent = object.agent >>> 0; - if (object.device != null) - message.device = object.device >>> 0; - if (object.regData != null) { - if (typeof object.regData !== "object") - throw TypeError(".proto.ClientPayload.regData: object expected"); - message.regData = $root.proto.CompanionRegData.fromObject(object.regData); - } - switch (object.product) { - case "WHATSAPP": - case 0: - message.product = 0; - break; - case "MESSENGER": - case 1: - message.product = 1; - break; - } - if (object.fbCat != null) - if (typeof object.fbCat === "string") - $util.base64.decode(object.fbCat, message.fbCat = $util.newBuffer($util.base64.length(object.fbCat)), 0); - else if (object.fbCat.length) - message.fbCat = object.fbCat; - if (object.fbUserAgent != null) - if (typeof object.fbUserAgent === "string") - $util.base64.decode(object.fbUserAgent, message.fbUserAgent = $util.newBuffer($util.base64.length(object.fbUserAgent)), 0); - else if (object.fbUserAgent.length) - message.fbUserAgent = object.fbUserAgent; - if (object.oc != null) - message.oc = Boolean(object.oc); - return message; - }; - - /** - * Creates a plain object from a ClientPayload message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ClientPayload - * @static - * @param {proto.ClientPayload} message ClientPayload - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ClientPayload.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) { - object.clientFeatures = []; - object.shards = []; - } - if (options.defaults) { - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.username = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.username = options.longs === String ? "0" : 0; - object.passive = false; - object.userAgent = null; - object.webInfo = null; - object.pushName = ""; - object.sessionId = 0; - object.shortConnect = false; - object.connectType = options.enums === String ? "CELLULAR_UNKNOWN" : 0; - object.connectReason = options.enums === String ? "PUSH" : 0; - object.dnsSource = null; - object.connectAttemptCount = 0; - object.agent = 0; - object.device = 0; - object.regData = null; - object.product = options.enums === String ? "WHATSAPP" : 0; - if (options.bytes === String) - object.fbCat = ""; - else { - object.fbCat = []; - if (options.bytes !== Array) - object.fbCat = $util.newBuffer(object.fbCat); - } - if (options.bytes === String) - object.fbUserAgent = ""; - else { - object.fbUserAgent = []; - if (options.bytes !== Array) - object.fbUserAgent = $util.newBuffer(object.fbUserAgent); - } - object.oc = false; - object.iosAppExtension = options.enums === String ? "SHARE_EXTENSION" : 0; - } - if (message.username != null && message.hasOwnProperty("username")) - if (typeof message.username === "number") - object.username = options.longs === String ? String(message.username) : message.username; - else - object.username = options.longs === String ? $util.Long.prototype.toString.call(message.username) : options.longs === Number ? new $util.LongBits(message.username.low >>> 0, message.username.high >>> 0).toNumber(true) : message.username; - if (message.passive != null && message.hasOwnProperty("passive")) - object.passive = message.passive; - if (message.clientFeatures && message.clientFeatures.length) { - object.clientFeatures = []; - for (var j = 0; j < message.clientFeatures.length; ++j) - object.clientFeatures[j] = options.enums === String ? $root.proto.ClientPayload.ClientPayloadClientFeature[message.clientFeatures[j]] : message.clientFeatures[j]; - } - if (message.userAgent != null && message.hasOwnProperty("userAgent")) - object.userAgent = $root.proto.UserAgent.toObject(message.userAgent, options); - if (message.webInfo != null && message.hasOwnProperty("webInfo")) - object.webInfo = $root.proto.WebInfo.toObject(message.webInfo, options); - if (message.pushName != null && message.hasOwnProperty("pushName")) - object.pushName = message.pushName; - if (message.sessionId != null && message.hasOwnProperty("sessionId")) - object.sessionId = message.sessionId; - if (message.shortConnect != null && message.hasOwnProperty("shortConnect")) - object.shortConnect = message.shortConnect; - if (message.connectType != null && message.hasOwnProperty("connectType")) - object.connectType = options.enums === String ? $root.proto.ClientPayload.ClientPayloadConnectType[message.connectType] : message.connectType; - if (message.connectReason != null && message.hasOwnProperty("connectReason")) - object.connectReason = options.enums === String ? $root.proto.ClientPayload.ClientPayloadConnectReason[message.connectReason] : message.connectReason; - if (message.shards && message.shards.length) { - object.shards = []; - for (var j = 0; j < message.shards.length; ++j) - object.shards[j] = message.shards[j]; - } - if (message.dnsSource != null && message.hasOwnProperty("dnsSource")) - object.dnsSource = $root.proto.DNSSource.toObject(message.dnsSource, options); - if (message.connectAttemptCount != null && message.hasOwnProperty("connectAttemptCount")) - object.connectAttemptCount = message.connectAttemptCount; - if (message.agent != null && message.hasOwnProperty("agent")) - object.agent = message.agent; - if (message.device != null && message.hasOwnProperty("device")) - object.device = message.device; - if (message.regData != null && message.hasOwnProperty("regData")) - object.regData = $root.proto.CompanionRegData.toObject(message.regData, options); - if (message.product != null && message.hasOwnProperty("product")) - object.product = options.enums === String ? $root.proto.ClientPayload.ClientPayloadProduct[message.product] : message.product; - if (message.fbCat != null && message.hasOwnProperty("fbCat")) - object.fbCat = options.bytes === String ? $util.base64.encode(message.fbCat, 0, message.fbCat.length) : options.bytes === Array ? Array.prototype.slice.call(message.fbCat) : message.fbCat; - if (message.fbUserAgent != null && message.hasOwnProperty("fbUserAgent")) - object.fbUserAgent = options.bytes === String ? $util.base64.encode(message.fbUserAgent, 0, message.fbUserAgent.length) : options.bytes === Array ? Array.prototype.slice.call(message.fbUserAgent) : message.fbUserAgent; - if (message.oc != null && message.hasOwnProperty("oc")) - object.oc = message.oc; - if (message.iosAppExtension != null && message.hasOwnProperty("iosAppExtension")) - object.iosAppExtension = options.enums === String ? $root.proto.ClientPayload.ClientPayloadIOSAppExtension[message.iosAppExtension] : message.iosAppExtension; - return object; - }; - - /** - * Converts this ClientPayload to JSON. - * @function toJSON - * @memberof proto.ClientPayload - * @instance - * @returns {Object.} JSON object - */ - ClientPayload.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * ClientPayloadClientFeature enum. - * @name proto.ClientPayload.ClientPayloadClientFeature - * @enum {number} - * @property {number} NONE=0 NONE value - */ - ClientPayload.ClientPayloadClientFeature = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "NONE"] = 0; - return values; - })(); - - /** - * ClientPayloadIOSAppExtension enum. - * @name proto.ClientPayload.ClientPayloadIOSAppExtension - * @enum {number} - * @property {number} SHARE_EXTENSION=0 SHARE_EXTENSION value - * @property {number} SERVICE_EXTENSION=1 SERVICE_EXTENSION value - * @property {number} INTENTS_EXTENSION=2 INTENTS_EXTENSION value - */ - ClientPayload.ClientPayloadIOSAppExtension = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "SHARE_EXTENSION"] = 0; - values[valuesById[1] = "SERVICE_EXTENSION"] = 1; - values[valuesById[2] = "INTENTS_EXTENSION"] = 2; - return values; - })(); - - /** - * ClientPayloadConnectType enum. - * @name proto.ClientPayload.ClientPayloadConnectType - * @enum {number} - * @property {number} CELLULAR_UNKNOWN=0 CELLULAR_UNKNOWN value - * @property {number} WIFI_UNKNOWN=1 WIFI_UNKNOWN value - * @property {number} CELLULAR_EDGE=100 CELLULAR_EDGE value - * @property {number} CELLULAR_IDEN=101 CELLULAR_IDEN value - * @property {number} CELLULAR_UMTS=102 CELLULAR_UMTS value - * @property {number} CELLULAR_EVDO=103 CELLULAR_EVDO value - * @property {number} CELLULAR_GPRS=104 CELLULAR_GPRS value - * @property {number} CELLULAR_HSDPA=105 CELLULAR_HSDPA value - * @property {number} CELLULAR_HSUPA=106 CELLULAR_HSUPA value - * @property {number} CELLULAR_HSPA=107 CELLULAR_HSPA value - * @property {number} CELLULAR_CDMA=108 CELLULAR_CDMA value - * @property {number} CELLULAR_1XRTT=109 CELLULAR_1XRTT value - * @property {number} CELLULAR_EHRPD=110 CELLULAR_EHRPD value - * @property {number} CELLULAR_LTE=111 CELLULAR_LTE value - * @property {number} CELLULAR_HSPAP=112 CELLULAR_HSPAP value - */ - ClientPayload.ClientPayloadConnectType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "CELLULAR_UNKNOWN"] = 0; - values[valuesById[1] = "WIFI_UNKNOWN"] = 1; - values[valuesById[100] = "CELLULAR_EDGE"] = 100; - values[valuesById[101] = "CELLULAR_IDEN"] = 101; - values[valuesById[102] = "CELLULAR_UMTS"] = 102; - values[valuesById[103] = "CELLULAR_EVDO"] = 103; - values[valuesById[104] = "CELLULAR_GPRS"] = 104; - values[valuesById[105] = "CELLULAR_HSDPA"] = 105; - values[valuesById[106] = "CELLULAR_HSUPA"] = 106; - values[valuesById[107] = "CELLULAR_HSPA"] = 107; - values[valuesById[108] = "CELLULAR_CDMA"] = 108; - values[valuesById[109] = "CELLULAR_1XRTT"] = 109; - values[valuesById[110] = "CELLULAR_EHRPD"] = 110; - values[valuesById[111] = "CELLULAR_LTE"] = 111; - values[valuesById[112] = "CELLULAR_HSPAP"] = 112; - return values; - })(); - - /** - * ClientPayloadConnectReason enum. - * @name proto.ClientPayload.ClientPayloadConnectReason - * @enum {number} - * @property {number} PUSH=0 PUSH value - * @property {number} USER_ACTIVATED=1 USER_ACTIVATED value - * @property {number} SCHEDULED=2 SCHEDULED value - * @property {number} ERROR_RECONNECT=3 ERROR_RECONNECT value - * @property {number} NETWORK_SWITCH=4 NETWORK_SWITCH value - * @property {number} PING_RECONNECT=5 PING_RECONNECT value - */ - ClientPayload.ClientPayloadConnectReason = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "PUSH"] = 0; - values[valuesById[1] = "USER_ACTIVATED"] = 1; - values[valuesById[2] = "SCHEDULED"] = 2; - values[valuesById[3] = "ERROR_RECONNECT"] = 3; - values[valuesById[4] = "NETWORK_SWITCH"] = 4; - values[valuesById[5] = "PING_RECONNECT"] = 5; - return values; - })(); - - /** - * ClientPayloadProduct enum. - * @name proto.ClientPayload.ClientPayloadProduct - * @enum {number} - * @property {number} WHATSAPP=0 WHATSAPP value - * @property {number} MESSENGER=1 MESSENGER value - */ - ClientPayload.ClientPayloadProduct = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "WHATSAPP"] = 0; - values[valuesById[1] = "MESSENGER"] = 1; - return values; - })(); - - return ClientPayload; - })(); - - proto.NoiseCertificate = (function() { - - /** - * Properties of a NoiseCertificate. - * @memberof proto - * @interface INoiseCertificate - * @property {Uint8Array|null} [details] NoiseCertificate details - * @property {Uint8Array|null} [signature] NoiseCertificate signature - */ - - /** - * Constructs a new NoiseCertificate. - * @memberof proto - * @classdesc Represents a NoiseCertificate. - * @implements INoiseCertificate - * @constructor - * @param {proto.INoiseCertificate=} [properties] Properties to set - */ - function NoiseCertificate(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * NoiseCertificate details. - * @member {Uint8Array} details - * @memberof proto.NoiseCertificate - * @instance - */ - NoiseCertificate.prototype.details = $util.newBuffer([]); - - /** - * NoiseCertificate signature. - * @member {Uint8Array} signature - * @memberof proto.NoiseCertificate - * @instance - */ - NoiseCertificate.prototype.signature = $util.newBuffer([]); - - /** - * Creates a new NoiseCertificate instance using the specified properties. - * @function create - * @memberof proto.NoiseCertificate - * @static - * @param {proto.INoiseCertificate=} [properties] Properties to set - * @returns {proto.NoiseCertificate} NoiseCertificate instance - */ - NoiseCertificate.create = function create(properties) { - return new NoiseCertificate(properties); - }; - - /** - * Encodes the specified NoiseCertificate message. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages. - * @function encode - * @memberof proto.NoiseCertificate - * @static - * @param {proto.INoiseCertificate} message NoiseCertificate message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - NoiseCertificate.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.details != null && Object.hasOwnProperty.call(message, "details")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); - if (message.signature != null && Object.hasOwnProperty.call(message, "signature")) - writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.signature); - return writer; - }; - - /** - * Encodes the specified NoiseCertificate message, length delimited. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.NoiseCertificate - * @static - * @param {proto.INoiseCertificate} message NoiseCertificate message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - NoiseCertificate.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a NoiseCertificate message from the specified reader or buffer. - * @function decode - * @memberof proto.NoiseCertificate - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.NoiseCertificate} NoiseCertificate - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - NoiseCertificate.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NoiseCertificate(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.details = reader.bytes(); - break; - case 2: - message.signature = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a NoiseCertificate message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.NoiseCertificate - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.NoiseCertificate} NoiseCertificate - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - NoiseCertificate.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a NoiseCertificate message. - * @function verify - * @memberof proto.NoiseCertificate - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - NoiseCertificate.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.details != null && message.hasOwnProperty("details")) - if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) - return "details: buffer expected"; - if (message.signature != null && message.hasOwnProperty("signature")) - if (!(message.signature && typeof message.signature.length === "number" || $util.isString(message.signature))) - return "signature: buffer expected"; - return null; - }; - - /** - * Creates a NoiseCertificate message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.NoiseCertificate - * @static - * @param {Object.} object Plain object - * @returns {proto.NoiseCertificate} NoiseCertificate - */ - NoiseCertificate.fromObject = function fromObject(object) { - if (object instanceof $root.proto.NoiseCertificate) - return object; - var message = new $root.proto.NoiseCertificate(); - if (object.details != null) - if (typeof object.details === "string") - $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); - else if (object.details.length) - message.details = object.details; - if (object.signature != null) - if (typeof object.signature === "string") - $util.base64.decode(object.signature, message.signature = $util.newBuffer($util.base64.length(object.signature)), 0); - else if (object.signature.length) - message.signature = object.signature; - return message; - }; - - /** - * Creates a plain object from a NoiseCertificate message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.NoiseCertificate - * @static - * @param {proto.NoiseCertificate} message NoiseCertificate - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - NoiseCertificate.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if (options.bytes === String) - object.details = ""; - else { - object.details = []; - if (options.bytes !== Array) - object.details = $util.newBuffer(object.details); - } - if (options.bytes === String) - object.signature = ""; - else { - object.signature = []; - if (options.bytes !== Array) - object.signature = $util.newBuffer(object.signature); - } - } - if (message.details != null && message.hasOwnProperty("details")) - object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; - if (message.signature != null && message.hasOwnProperty("signature")) - object.signature = options.bytes === String ? $util.base64.encode(message.signature, 0, message.signature.length) : options.bytes === Array ? Array.prototype.slice.call(message.signature) : message.signature; - return object; - }; - - /** - * Converts this NoiseCertificate to JSON. - * @function toJSON - * @memberof proto.NoiseCertificate - * @instance - * @returns {Object.} JSON object - */ - NoiseCertificate.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return NoiseCertificate; - })(); - - proto.ClientHello = (function() { - - /** - * Properties of a ClientHello. - * @memberof proto - * @interface IClientHello - * @property {Uint8Array|null} [ephemeral] ClientHello ephemeral - * @property {Uint8Array|null} ["static"] ClientHello static - * @property {Uint8Array|null} [payload] ClientHello payload - */ - - /** - * Constructs a new ClientHello. - * @memberof proto - * @classdesc Represents a ClientHello. - * @implements IClientHello - * @constructor - * @param {proto.IClientHello=} [properties] Properties to set - */ - function ClientHello(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ClientHello ephemeral. - * @member {Uint8Array} ephemeral - * @memberof proto.ClientHello - * @instance - */ - ClientHello.prototype.ephemeral = $util.newBuffer([]); - - /** - * ClientHello static. - * @member {Uint8Array} static - * @memberof proto.ClientHello - * @instance - */ - ClientHello.prototype["static"] = $util.newBuffer([]); - - /** - * ClientHello payload. - * @member {Uint8Array} payload - * @memberof proto.ClientHello - * @instance - */ - ClientHello.prototype.payload = $util.newBuffer([]); - - /** - * Creates a new ClientHello instance using the specified properties. - * @function create - * @memberof proto.ClientHello - * @static - * @param {proto.IClientHello=} [properties] Properties to set - * @returns {proto.ClientHello} ClientHello instance - */ - ClientHello.create = function create(properties) { - return new ClientHello(properties); - }; - - /** - * Encodes the specified ClientHello message. Does not implicitly {@link proto.ClientHello.verify|verify} messages. - * @function encode - * @memberof proto.ClientHello - * @static - * @param {proto.IClientHello} message ClientHello message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ClientHello.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.ephemeral != null && Object.hasOwnProperty.call(message, "ephemeral")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.ephemeral); - if (message["static"] != null && Object.hasOwnProperty.call(message, "static")) - writer.uint32(/* id 2, wireType 2 =*/18).bytes(message["static"]); - if (message.payload != null && Object.hasOwnProperty.call(message, "payload")) - writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.payload); - return writer; - }; - - /** - * Encodes the specified ClientHello message, length delimited. Does not implicitly {@link proto.ClientHello.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ClientHello - * @static - * @param {proto.IClientHello} message ClientHello message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ClientHello.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ClientHello message from the specified reader or buffer. - * @function decode - * @memberof proto.ClientHello - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ClientHello} ClientHello - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ClientHello.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClientHello(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.ephemeral = reader.bytes(); - break; - case 2: - message["static"] = reader.bytes(); - break; - case 3: - message.payload = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ClientHello message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ClientHello - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ClientHello} ClientHello - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ClientHello.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ClientHello message. - * @function verify - * @memberof proto.ClientHello - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ClientHello.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.ephemeral != null && message.hasOwnProperty("ephemeral")) - if (!(message.ephemeral && typeof message.ephemeral.length === "number" || $util.isString(message.ephemeral))) - return "ephemeral: buffer expected"; - if (message["static"] != null && message.hasOwnProperty("static")) - if (!(message["static"] && typeof message["static"].length === "number" || $util.isString(message["static"]))) - return "static: buffer expected"; - if (message.payload != null && message.hasOwnProperty("payload")) - if (!(message.payload && typeof message.payload.length === "number" || $util.isString(message.payload))) - return "payload: buffer expected"; - return null; - }; - - /** - * Creates a ClientHello message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ClientHello - * @static - * @param {Object.} object Plain object - * @returns {proto.ClientHello} ClientHello - */ - ClientHello.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ClientHello) - return object; - var message = new $root.proto.ClientHello(); - if (object.ephemeral != null) - if (typeof object.ephemeral === "string") - $util.base64.decode(object.ephemeral, message.ephemeral = $util.newBuffer($util.base64.length(object.ephemeral)), 0); - else if (object.ephemeral.length) - message.ephemeral = object.ephemeral; - if (object["static"] != null) - if (typeof object["static"] === "string") - $util.base64.decode(object["static"], message["static"] = $util.newBuffer($util.base64.length(object["static"])), 0); - else if (object["static"].length) - message["static"] = object["static"]; - if (object.payload != null) - if (typeof object.payload === "string") - $util.base64.decode(object.payload, message.payload = $util.newBuffer($util.base64.length(object.payload)), 0); - else if (object.payload.length) - message.payload = object.payload; - return message; - }; - - /** - * Creates a plain object from a ClientHello message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ClientHello - * @static - * @param {proto.ClientHello} message ClientHello - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ClientHello.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if (options.bytes === String) - object.ephemeral = ""; - else { - object.ephemeral = []; - if (options.bytes !== Array) - object.ephemeral = $util.newBuffer(object.ephemeral); - } - if (options.bytes === String) - object["static"] = ""; - else { - object["static"] = []; - if (options.bytes !== Array) - object["static"] = $util.newBuffer(object["static"]); - } - if (options.bytes === String) - object.payload = ""; - else { - object.payload = []; - if (options.bytes !== Array) - object.payload = $util.newBuffer(object.payload); - } - } - if (message.ephemeral != null && message.hasOwnProperty("ephemeral")) - object.ephemeral = options.bytes === String ? $util.base64.encode(message.ephemeral, 0, message.ephemeral.length) : options.bytes === Array ? Array.prototype.slice.call(message.ephemeral) : message.ephemeral; - if (message["static"] != null && message.hasOwnProperty("static")) - object["static"] = options.bytes === String ? $util.base64.encode(message["static"], 0, message["static"].length) : options.bytes === Array ? Array.prototype.slice.call(message["static"]) : message["static"]; - if (message.payload != null && message.hasOwnProperty("payload")) - object.payload = options.bytes === String ? $util.base64.encode(message.payload, 0, message.payload.length) : options.bytes === Array ? Array.prototype.slice.call(message.payload) : message.payload; - return object; - }; - - /** - * Converts this ClientHello to JSON. - * @function toJSON - * @memberof proto.ClientHello - * @instance - * @returns {Object.} JSON object - */ - ClientHello.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ClientHello; - })(); - - proto.ServerHello = (function() { - - /** - * Properties of a ServerHello. - * @memberof proto - * @interface IServerHello - * @property {Uint8Array|null} [ephemeral] ServerHello ephemeral - * @property {Uint8Array|null} ["static"] ServerHello static - * @property {Uint8Array|null} [payload] ServerHello payload - */ - - /** - * Constructs a new ServerHello. - * @memberof proto - * @classdesc Represents a ServerHello. - * @implements IServerHello - * @constructor - * @param {proto.IServerHello=} [properties] Properties to set - */ - function ServerHello(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ServerHello ephemeral. - * @member {Uint8Array} ephemeral - * @memberof proto.ServerHello - * @instance - */ - ServerHello.prototype.ephemeral = $util.newBuffer([]); - - /** - * ServerHello static. - * @member {Uint8Array} static - * @memberof proto.ServerHello - * @instance - */ - ServerHello.prototype["static"] = $util.newBuffer([]); - - /** - * ServerHello payload. - * @member {Uint8Array} payload - * @memberof proto.ServerHello - * @instance - */ - ServerHello.prototype.payload = $util.newBuffer([]); - - /** - * Creates a new ServerHello instance using the specified properties. - * @function create - * @memberof proto.ServerHello - * @static - * @param {proto.IServerHello=} [properties] Properties to set - * @returns {proto.ServerHello} ServerHello instance - */ - ServerHello.create = function create(properties) { - return new ServerHello(properties); - }; - - /** - * Encodes the specified ServerHello message. Does not implicitly {@link proto.ServerHello.verify|verify} messages. - * @function encode - * @memberof proto.ServerHello - * @static - * @param {proto.IServerHello} message ServerHello message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ServerHello.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.ephemeral != null && Object.hasOwnProperty.call(message, "ephemeral")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.ephemeral); - if (message["static"] != null && Object.hasOwnProperty.call(message, "static")) - writer.uint32(/* id 2, wireType 2 =*/18).bytes(message["static"]); - if (message.payload != null && Object.hasOwnProperty.call(message, "payload")) - writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.payload); - return writer; - }; - - /** - * Encodes the specified ServerHello message, length delimited. Does not implicitly {@link proto.ServerHello.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ServerHello - * @static - * @param {proto.IServerHello} message ServerHello message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ServerHello.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ServerHello message from the specified reader or buffer. - * @function decode - * @memberof proto.ServerHello - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ServerHello} ServerHello - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ServerHello.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ServerHello(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.ephemeral = reader.bytes(); - break; - case 2: - message["static"] = reader.bytes(); - break; - case 3: - message.payload = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ServerHello message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ServerHello - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ServerHello} ServerHello - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ServerHello.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ServerHello message. - * @function verify - * @memberof proto.ServerHello - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ServerHello.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.ephemeral != null && message.hasOwnProperty("ephemeral")) - if (!(message.ephemeral && typeof message.ephemeral.length === "number" || $util.isString(message.ephemeral))) - return "ephemeral: buffer expected"; - if (message["static"] != null && message.hasOwnProperty("static")) - if (!(message["static"] && typeof message["static"].length === "number" || $util.isString(message["static"]))) - return "static: buffer expected"; - if (message.payload != null && message.hasOwnProperty("payload")) - if (!(message.payload && typeof message.payload.length === "number" || $util.isString(message.payload))) - return "payload: buffer expected"; - return null; - }; - - /** - * Creates a ServerHello message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ServerHello - * @static - * @param {Object.} object Plain object - * @returns {proto.ServerHello} ServerHello - */ - ServerHello.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ServerHello) - return object; - var message = new $root.proto.ServerHello(); - if (object.ephemeral != null) - if (typeof object.ephemeral === "string") - $util.base64.decode(object.ephemeral, message.ephemeral = $util.newBuffer($util.base64.length(object.ephemeral)), 0); - else if (object.ephemeral.length) - message.ephemeral = object.ephemeral; - if (object["static"] != null) - if (typeof object["static"] === "string") - $util.base64.decode(object["static"], message["static"] = $util.newBuffer($util.base64.length(object["static"])), 0); - else if (object["static"].length) - message["static"] = object["static"]; - if (object.payload != null) - if (typeof object.payload === "string") - $util.base64.decode(object.payload, message.payload = $util.newBuffer($util.base64.length(object.payload)), 0); - else if (object.payload.length) - message.payload = object.payload; - return message; - }; - - /** - * Creates a plain object from a ServerHello message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ServerHello - * @static - * @param {proto.ServerHello} message ServerHello - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ServerHello.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if (options.bytes === String) - object.ephemeral = ""; - else { - object.ephemeral = []; - if (options.bytes !== Array) - object.ephemeral = $util.newBuffer(object.ephemeral); - } - if (options.bytes === String) - object["static"] = ""; - else { - object["static"] = []; - if (options.bytes !== Array) - object["static"] = $util.newBuffer(object["static"]); - } - if (options.bytes === String) - object.payload = ""; - else { - object.payload = []; - if (options.bytes !== Array) - object.payload = $util.newBuffer(object.payload); - } - } - if (message.ephemeral != null && message.hasOwnProperty("ephemeral")) - object.ephemeral = options.bytes === String ? $util.base64.encode(message.ephemeral, 0, message.ephemeral.length) : options.bytes === Array ? Array.prototype.slice.call(message.ephemeral) : message.ephemeral; - if (message["static"] != null && message.hasOwnProperty("static")) - object["static"] = options.bytes === String ? $util.base64.encode(message["static"], 0, message["static"].length) : options.bytes === Array ? Array.prototype.slice.call(message["static"]) : message["static"]; - if (message.payload != null && message.hasOwnProperty("payload")) - object.payload = options.bytes === String ? $util.base64.encode(message.payload, 0, message.payload.length) : options.bytes === Array ? Array.prototype.slice.call(message.payload) : message.payload; - return object; - }; - - /** - * Converts this ServerHello to JSON. - * @function toJSON - * @memberof proto.ServerHello - * @instance - * @returns {Object.} JSON object - */ - ServerHello.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ServerHello; - })(); - - proto.ClientFinish = (function() { - - /** - * Properties of a ClientFinish. - * @memberof proto - * @interface IClientFinish - * @property {Uint8Array|null} ["static"] ClientFinish static - * @property {Uint8Array|null} [payload] ClientFinish payload - */ - - /** - * Constructs a new ClientFinish. - * @memberof proto - * @classdesc Represents a ClientFinish. - * @implements IClientFinish - * @constructor - * @param {proto.IClientFinish=} [properties] Properties to set - */ - function ClientFinish(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ClientFinish static. - * @member {Uint8Array} static - * @memberof proto.ClientFinish - * @instance - */ - ClientFinish.prototype["static"] = $util.newBuffer([]); - - /** - * ClientFinish payload. - * @member {Uint8Array} payload - * @memberof proto.ClientFinish - * @instance - */ - ClientFinish.prototype.payload = $util.newBuffer([]); - - /** - * Creates a new ClientFinish instance using the specified properties. - * @function create - * @memberof proto.ClientFinish - * @static - * @param {proto.IClientFinish=} [properties] Properties to set - * @returns {proto.ClientFinish} ClientFinish instance - */ - ClientFinish.create = function create(properties) { - return new ClientFinish(properties); - }; - - /** - * Encodes the specified ClientFinish message. Does not implicitly {@link proto.ClientFinish.verify|verify} messages. - * @function encode - * @memberof proto.ClientFinish - * @static - * @param {proto.IClientFinish} message ClientFinish message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ClientFinish.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message["static"] != null && Object.hasOwnProperty.call(message, "static")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message["static"]); - if (message.payload != null && Object.hasOwnProperty.call(message, "payload")) - writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.payload); - return writer; - }; - - /** - * Encodes the specified ClientFinish message, length delimited. Does not implicitly {@link proto.ClientFinish.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ClientFinish - * @static - * @param {proto.IClientFinish} message ClientFinish message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ClientFinish.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ClientFinish message from the specified reader or buffer. - * @function decode - * @memberof proto.ClientFinish - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ClientFinish} ClientFinish - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ClientFinish.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClientFinish(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message["static"] = reader.bytes(); - break; - case 2: - message.payload = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ClientFinish message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ClientFinish - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ClientFinish} ClientFinish - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ClientFinish.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ClientFinish message. - * @function verify - * @memberof proto.ClientFinish - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ClientFinish.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message["static"] != null && message.hasOwnProperty("static")) - if (!(message["static"] && typeof message["static"].length === "number" || $util.isString(message["static"]))) - return "static: buffer expected"; - if (message.payload != null && message.hasOwnProperty("payload")) - if (!(message.payload && typeof message.payload.length === "number" || $util.isString(message.payload))) - return "payload: buffer expected"; - return null; - }; - - /** - * Creates a ClientFinish message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ClientFinish - * @static - * @param {Object.} object Plain object - * @returns {proto.ClientFinish} ClientFinish - */ - ClientFinish.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ClientFinish) - return object; - var message = new $root.proto.ClientFinish(); - if (object["static"] != null) - if (typeof object["static"] === "string") - $util.base64.decode(object["static"], message["static"] = $util.newBuffer($util.base64.length(object["static"])), 0); - else if (object["static"].length) - message["static"] = object["static"]; - if (object.payload != null) - if (typeof object.payload === "string") - $util.base64.decode(object.payload, message.payload = $util.newBuffer($util.base64.length(object.payload)), 0); - else if (object.payload.length) - message.payload = object.payload; - return message; - }; - - /** - * Creates a plain object from a ClientFinish message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ClientFinish - * @static - * @param {proto.ClientFinish} message ClientFinish - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ClientFinish.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if (options.bytes === String) - object["static"] = ""; - else { - object["static"] = []; - if (options.bytes !== Array) - object["static"] = $util.newBuffer(object["static"]); - } - if (options.bytes === String) - object.payload = ""; - else { - object.payload = []; - if (options.bytes !== Array) - object.payload = $util.newBuffer(object.payload); - } - } - if (message["static"] != null && message.hasOwnProperty("static")) - object["static"] = options.bytes === String ? $util.base64.encode(message["static"], 0, message["static"].length) : options.bytes === Array ? Array.prototype.slice.call(message["static"]) : message["static"]; - if (message.payload != null && message.hasOwnProperty("payload")) - object.payload = options.bytes === String ? $util.base64.encode(message.payload, 0, message.payload.length) : options.bytes === Array ? Array.prototype.slice.call(message.payload) : message.payload; - return object; - }; - - /** - * Converts this ClientFinish to JSON. - * @function toJSON - * @memberof proto.ClientFinish - * @instance - * @returns {Object.} JSON object - */ - ClientFinish.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ClientFinish; - })(); - - proto.HandshakeMessage = (function() { - - /** - * Properties of a HandshakeMessage. - * @memberof proto - * @interface IHandshakeMessage - * @property {proto.IClientHello|null} [clientHello] HandshakeMessage clientHello - * @property {proto.IServerHello|null} [serverHello] HandshakeMessage serverHello - * @property {proto.IClientFinish|null} [clientFinish] HandshakeMessage clientFinish - */ - - /** - * Constructs a new HandshakeMessage. - * @memberof proto - * @classdesc Represents a HandshakeMessage. - * @implements IHandshakeMessage - * @constructor - * @param {proto.IHandshakeMessage=} [properties] Properties to set - */ - function HandshakeMessage(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HandshakeMessage clientHello. - * @member {proto.IClientHello|null|undefined} clientHello - * @memberof proto.HandshakeMessage - * @instance - */ - HandshakeMessage.prototype.clientHello = null; - - /** - * HandshakeMessage serverHello. - * @member {proto.IServerHello|null|undefined} serverHello - * @memberof proto.HandshakeMessage - * @instance - */ - HandshakeMessage.prototype.serverHello = null; - - /** - * HandshakeMessage clientFinish. - * @member {proto.IClientFinish|null|undefined} clientFinish - * @memberof proto.HandshakeMessage - * @instance - */ - HandshakeMessage.prototype.clientFinish = null; - - /** - * Creates a new HandshakeMessage instance using the specified properties. - * @function create - * @memberof proto.HandshakeMessage - * @static - * @param {proto.IHandshakeMessage=} [properties] Properties to set - * @returns {proto.HandshakeMessage} HandshakeMessage instance - */ - HandshakeMessage.create = function create(properties) { - return new HandshakeMessage(properties); - }; - - /** - * Encodes the specified HandshakeMessage message. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages. - * @function encode - * @memberof proto.HandshakeMessage - * @static - * @param {proto.IHandshakeMessage} message HandshakeMessage message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HandshakeMessage.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.clientHello != null && Object.hasOwnProperty.call(message, "clientHello")) - $root.proto.ClientHello.encode(message.clientHello, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.serverHello != null && Object.hasOwnProperty.call(message, "serverHello")) - $root.proto.ServerHello.encode(message.serverHello, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - if (message.clientFinish != null && Object.hasOwnProperty.call(message, "clientFinish")) - $root.proto.ClientFinish.encode(message.clientFinish, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified HandshakeMessage message, length delimited. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HandshakeMessage - * @static - * @param {proto.IHandshakeMessage} message HandshakeMessage message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HandshakeMessage.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HandshakeMessage message from the specified reader or buffer. - * @function decode - * @memberof proto.HandshakeMessage - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HandshakeMessage} HandshakeMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HandshakeMessage.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HandshakeMessage(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 2: - message.clientHello = $root.proto.ClientHello.decode(reader, reader.uint32()); - break; - case 3: - message.serverHello = $root.proto.ServerHello.decode(reader, reader.uint32()); - break; - case 4: - message.clientFinish = $root.proto.ClientFinish.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HandshakeMessage message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HandshakeMessage - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HandshakeMessage} HandshakeMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HandshakeMessage.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HandshakeMessage message. - * @function verify - * @memberof proto.HandshakeMessage - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HandshakeMessage.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.clientHello != null && message.hasOwnProperty("clientHello")) { - var error = $root.proto.ClientHello.verify(message.clientHello); - if (error) - return "clientHello." + error; - } - if (message.serverHello != null && message.hasOwnProperty("serverHello")) { - var error = $root.proto.ServerHello.verify(message.serverHello); - if (error) - return "serverHello." + error; - } - if (message.clientFinish != null && message.hasOwnProperty("clientFinish")) { - var error = $root.proto.ClientFinish.verify(message.clientFinish); - if (error) - return "clientFinish." + error; - } - return null; - }; - - /** - * Creates a HandshakeMessage message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HandshakeMessage - * @static - * @param {Object.} object Plain object - * @returns {proto.HandshakeMessage} HandshakeMessage - */ - HandshakeMessage.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HandshakeMessage) - return object; - var message = new $root.proto.HandshakeMessage(); - if (object.clientHello != null) { - if (typeof object.clientHello !== "object") - throw TypeError(".proto.HandshakeMessage.clientHello: object expected"); - message.clientHello = $root.proto.ClientHello.fromObject(object.clientHello); - } - if (object.serverHello != null) { - if (typeof object.serverHello !== "object") - throw TypeError(".proto.HandshakeMessage.serverHello: object expected"); - message.serverHello = $root.proto.ServerHello.fromObject(object.serverHello); - } - if (object.clientFinish != null) { - if (typeof object.clientFinish !== "object") - throw TypeError(".proto.HandshakeMessage.clientFinish: object expected"); - message.clientFinish = $root.proto.ClientFinish.fromObject(object.clientFinish); - } - return message; - }; - - /** - * Creates a plain object from a HandshakeMessage message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HandshakeMessage - * @static - * @param {proto.HandshakeMessage} message HandshakeMessage - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HandshakeMessage.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.clientHello = null; - object.serverHello = null; - object.clientFinish = null; - } - if (message.clientHello != null && message.hasOwnProperty("clientHello")) - object.clientHello = $root.proto.ClientHello.toObject(message.clientHello, options); - if (message.serverHello != null && message.hasOwnProperty("serverHello")) - object.serverHello = $root.proto.ServerHello.toObject(message.serverHello, options); - if (message.clientFinish != null && message.hasOwnProperty("clientFinish")) - object.clientFinish = $root.proto.ClientFinish.toObject(message.clientFinish, options); - return object; - }; - - /** - * Converts this HandshakeMessage to JSON. - * @function toJSON - * @memberof proto.HandshakeMessage - * @instance - * @returns {Object.} JSON object - */ - HandshakeMessage.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HandshakeMessage; - })(); - - proto.BizIdentityInfo = (function() { - - /** - * Properties of a BizIdentityInfo. - * @memberof proto - * @interface IBizIdentityInfo - * @property {proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue|null} [vlevel] BizIdentityInfo vlevel - * @property {proto.IVerifiedNameCertificate|null} [vnameCert] BizIdentityInfo vnameCert - * @property {boolean|null} [signed] BizIdentityInfo signed - * @property {boolean|null} [revoked] BizIdentityInfo revoked - * @property {proto.BizIdentityInfo.BizIdentityInfoHostStorageType|null} [hostStorage] BizIdentityInfo hostStorage - * @property {proto.BizIdentityInfo.BizIdentityInfoActualActorsType|null} [actualActors] BizIdentityInfo actualActors - * @property {number|Long|null} [privacyModeTs] BizIdentityInfo privacyModeTs - */ - - /** - * Constructs a new BizIdentityInfo. - * @memberof proto - * @classdesc Represents a BizIdentityInfo. - * @implements IBizIdentityInfo - * @constructor - * @param {proto.IBizIdentityInfo=} [properties] Properties to set - */ - function BizIdentityInfo(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * BizIdentityInfo vlevel. - * @member {proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue} vlevel - * @memberof proto.BizIdentityInfo - * @instance - */ - BizIdentityInfo.prototype.vlevel = 0; - - /** - * BizIdentityInfo vnameCert. - * @member {proto.IVerifiedNameCertificate|null|undefined} vnameCert - * @memberof proto.BizIdentityInfo - * @instance - */ - BizIdentityInfo.prototype.vnameCert = null; - - /** - * BizIdentityInfo signed. - * @member {boolean} signed - * @memberof proto.BizIdentityInfo - * @instance - */ - BizIdentityInfo.prototype.signed = false; - - /** - * BizIdentityInfo revoked. - * @member {boolean} revoked - * @memberof proto.BizIdentityInfo - * @instance - */ - BizIdentityInfo.prototype.revoked = false; - - /** - * BizIdentityInfo hostStorage. - * @member {proto.BizIdentityInfo.BizIdentityInfoHostStorageType} hostStorage - * @memberof proto.BizIdentityInfo - * @instance - */ - BizIdentityInfo.prototype.hostStorage = 0; - - /** - * BizIdentityInfo actualActors. - * @member {proto.BizIdentityInfo.BizIdentityInfoActualActorsType} actualActors - * @memberof proto.BizIdentityInfo - * @instance - */ - BizIdentityInfo.prototype.actualActors = 0; - - /** - * BizIdentityInfo privacyModeTs. - * @member {number|Long} privacyModeTs - * @memberof proto.BizIdentityInfo - * @instance - */ - BizIdentityInfo.prototype.privacyModeTs = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * Creates a new BizIdentityInfo instance using the specified properties. - * @function create - * @memberof proto.BizIdentityInfo - * @static - * @param {proto.IBizIdentityInfo=} [properties] Properties to set - * @returns {proto.BizIdentityInfo} BizIdentityInfo instance - */ - BizIdentityInfo.create = function create(properties) { - return new BizIdentityInfo(properties); - }; - - /** - * Encodes the specified BizIdentityInfo message. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages. - * @function encode - * @memberof proto.BizIdentityInfo - * @static - * @param {proto.IBizIdentityInfo} message BizIdentityInfo message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - BizIdentityInfo.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.vlevel != null && Object.hasOwnProperty.call(message, "vlevel")) - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.vlevel); - if (message.vnameCert != null && Object.hasOwnProperty.call(message, "vnameCert")) - $root.proto.VerifiedNameCertificate.encode(message.vnameCert, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.signed != null && Object.hasOwnProperty.call(message, "signed")) - writer.uint32(/* id 3, wireType 0 =*/24).bool(message.signed); - if (message.revoked != null && Object.hasOwnProperty.call(message, "revoked")) - writer.uint32(/* id 4, wireType 0 =*/32).bool(message.revoked); - if (message.hostStorage != null && Object.hasOwnProperty.call(message, "hostStorage")) - writer.uint32(/* id 5, wireType 0 =*/40).int32(message.hostStorage); - if (message.actualActors != null && Object.hasOwnProperty.call(message, "actualActors")) - writer.uint32(/* id 6, wireType 0 =*/48).int32(message.actualActors); - if (message.privacyModeTs != null && Object.hasOwnProperty.call(message, "privacyModeTs")) - writer.uint32(/* id 7, wireType 0 =*/56).uint64(message.privacyModeTs); - return writer; - }; - - /** - * Encodes the specified BizIdentityInfo message, length delimited. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.BizIdentityInfo - * @static - * @param {proto.IBizIdentityInfo} message BizIdentityInfo message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - BizIdentityInfo.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a BizIdentityInfo message from the specified reader or buffer. - * @function decode - * @memberof proto.BizIdentityInfo - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.BizIdentityInfo} BizIdentityInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - BizIdentityInfo.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.BizIdentityInfo(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.vlevel = reader.int32(); - break; - case 2: - message.vnameCert = $root.proto.VerifiedNameCertificate.decode(reader, reader.uint32()); - break; - case 3: - message.signed = reader.bool(); - break; - case 4: - message.revoked = reader.bool(); - break; - case 5: - message.hostStorage = reader.int32(); - break; - case 6: - message.actualActors = reader.int32(); - break; - case 7: - message.privacyModeTs = reader.uint64(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a BizIdentityInfo message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.BizIdentityInfo - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.BizIdentityInfo} BizIdentityInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - BizIdentityInfo.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a BizIdentityInfo message. - * @function verify - * @memberof proto.BizIdentityInfo - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - BizIdentityInfo.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.vlevel != null && message.hasOwnProperty("vlevel")) - switch (message.vlevel) { - default: - return "vlevel: enum value expected"; - case 0: - case 1: - case 2: - break; - } - if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) { - var error = $root.proto.VerifiedNameCertificate.verify(message.vnameCert); - if (error) - return "vnameCert." + error; - } - if (message.signed != null && message.hasOwnProperty("signed")) - if (typeof message.signed !== "boolean") - return "signed: boolean expected"; - if (message.revoked != null && message.hasOwnProperty("revoked")) - if (typeof message.revoked !== "boolean") - return "revoked: boolean expected"; - if (message.hostStorage != null && message.hasOwnProperty("hostStorage")) - switch (message.hostStorage) { - default: - return "hostStorage: enum value expected"; - case 0: - case 1: - break; - } - if (message.actualActors != null && message.hasOwnProperty("actualActors")) - switch (message.actualActors) { - default: - return "actualActors: enum value expected"; - case 0: - case 1: - break; - } - if (message.privacyModeTs != null && message.hasOwnProperty("privacyModeTs")) - if (!$util.isInteger(message.privacyModeTs) && !(message.privacyModeTs && $util.isInteger(message.privacyModeTs.low) && $util.isInteger(message.privacyModeTs.high))) - return "privacyModeTs: integer|Long expected"; - return null; - }; - - /** - * Creates a BizIdentityInfo message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.BizIdentityInfo - * @static - * @param {Object.} object Plain object - * @returns {proto.BizIdentityInfo} BizIdentityInfo - */ - BizIdentityInfo.fromObject = function fromObject(object) { - if (object instanceof $root.proto.BizIdentityInfo) - return object; - var message = new $root.proto.BizIdentityInfo(); - switch (object.vlevel) { - case "UNKNOWN": - case 0: - message.vlevel = 0; - break; - case "LOW": - case 1: - message.vlevel = 1; - break; - case "HIGH": - case 2: - message.vlevel = 2; - break; - } - if (object.vnameCert != null) { - if (typeof object.vnameCert !== "object") - throw TypeError(".proto.BizIdentityInfo.vnameCert: object expected"); - message.vnameCert = $root.proto.VerifiedNameCertificate.fromObject(object.vnameCert); - } - if (object.signed != null) - message.signed = Boolean(object.signed); - if (object.revoked != null) - message.revoked = Boolean(object.revoked); - switch (object.hostStorage) { - case "ON_PREMISE": - case 0: - message.hostStorage = 0; - break; - case "FACEBOOK": - case 1: - message.hostStorage = 1; - break; - } - switch (object.actualActors) { - case "SELF": - case 0: - message.actualActors = 0; - break; - case "BSP": - case 1: - message.actualActors = 1; - break; - } - if (object.privacyModeTs != null) - if ($util.Long) - (message.privacyModeTs = $util.Long.fromValue(object.privacyModeTs)).unsigned = true; - else if (typeof object.privacyModeTs === "string") - message.privacyModeTs = parseInt(object.privacyModeTs, 10); - else if (typeof object.privacyModeTs === "number") - message.privacyModeTs = object.privacyModeTs; - else if (typeof object.privacyModeTs === "object") - message.privacyModeTs = new $util.LongBits(object.privacyModeTs.low >>> 0, object.privacyModeTs.high >>> 0).toNumber(true); - return message; - }; - - /** - * Creates a plain object from a BizIdentityInfo message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.BizIdentityInfo - * @static - * @param {proto.BizIdentityInfo} message BizIdentityInfo - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - BizIdentityInfo.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.vlevel = options.enums === String ? "UNKNOWN" : 0; - object.vnameCert = null; - object.signed = false; - object.revoked = false; - object.hostStorage = options.enums === String ? "ON_PREMISE" : 0; - object.actualActors = options.enums === String ? "SELF" : 0; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.privacyModeTs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.privacyModeTs = options.longs === String ? "0" : 0; - } - if (message.vlevel != null && message.hasOwnProperty("vlevel")) - object.vlevel = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue[message.vlevel] : message.vlevel; - if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) - object.vnameCert = $root.proto.VerifiedNameCertificate.toObject(message.vnameCert, options); - if (message.signed != null && message.hasOwnProperty("signed")) - object.signed = message.signed; - if (message.revoked != null && message.hasOwnProperty("revoked")) - object.revoked = message.revoked; - if (message.hostStorage != null && message.hasOwnProperty("hostStorage")) - object.hostStorage = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoHostStorageType[message.hostStorage] : message.hostStorage; - if (message.actualActors != null && message.hasOwnProperty("actualActors")) - object.actualActors = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoActualActorsType[message.actualActors] : message.actualActors; - if (message.privacyModeTs != null && message.hasOwnProperty("privacyModeTs")) - if (typeof message.privacyModeTs === "number") - object.privacyModeTs = options.longs === String ? String(message.privacyModeTs) : message.privacyModeTs; - else - object.privacyModeTs = options.longs === String ? $util.Long.prototype.toString.call(message.privacyModeTs) : options.longs === Number ? new $util.LongBits(message.privacyModeTs.low >>> 0, message.privacyModeTs.high >>> 0).toNumber(true) : message.privacyModeTs; - return object; - }; - - /** - * Converts this BizIdentityInfo to JSON. - * @function toJSON - * @memberof proto.BizIdentityInfo - * @instance - * @returns {Object.} JSON object - */ - BizIdentityInfo.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * BizIdentityInfoVerifiedLevelValue enum. - * @name proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue - * @enum {number} - * @property {number} UNKNOWN=0 UNKNOWN value - * @property {number} LOW=1 LOW value - * @property {number} HIGH=2 HIGH value - */ - BizIdentityInfo.BizIdentityInfoVerifiedLevelValue = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "UNKNOWN"] = 0; - values[valuesById[1] = "LOW"] = 1; - values[valuesById[2] = "HIGH"] = 2; - return values; - })(); - - /** - * BizIdentityInfoHostStorageType enum. - * @name proto.BizIdentityInfo.BizIdentityInfoHostStorageType - * @enum {number} - * @property {number} ON_PREMISE=0 ON_PREMISE value - * @property {number} FACEBOOK=1 FACEBOOK value - */ - BizIdentityInfo.BizIdentityInfoHostStorageType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "ON_PREMISE"] = 0; - values[valuesById[1] = "FACEBOOK"] = 1; - return values; - })(); - - /** - * BizIdentityInfoActualActorsType enum. - * @name proto.BizIdentityInfo.BizIdentityInfoActualActorsType - * @enum {number} - * @property {number} SELF=0 SELF value - * @property {number} BSP=1 BSP value - */ - BizIdentityInfo.BizIdentityInfoActualActorsType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "SELF"] = 0; - values[valuesById[1] = "BSP"] = 1; - return values; - })(); - - return BizIdentityInfo; - })(); - - proto.BizAccountLinkInfo = (function() { - - /** - * Properties of a BizAccountLinkInfo. - * @memberof proto - * @interface IBizAccountLinkInfo - * @property {number|Long|null} [whatsappBizAcctFbid] BizAccountLinkInfo whatsappBizAcctFbid - * @property {string|null} [whatsappAcctNumber] BizAccountLinkInfo whatsappAcctNumber - * @property {number|Long|null} [issueTime] BizAccountLinkInfo issueTime - * @property {proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType|null} [hostStorage] BizAccountLinkInfo hostStorage - * @property {proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType|null} [accountType] BizAccountLinkInfo accountType - */ - - /** - * Constructs a new BizAccountLinkInfo. - * @memberof proto - * @classdesc Represents a BizAccountLinkInfo. - * @implements IBizAccountLinkInfo - * @constructor - * @param {proto.IBizAccountLinkInfo=} [properties] Properties to set - */ - function BizAccountLinkInfo(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * BizAccountLinkInfo whatsappBizAcctFbid. - * @member {number|Long} whatsappBizAcctFbid - * @memberof proto.BizAccountLinkInfo - * @instance - */ - BizAccountLinkInfo.prototype.whatsappBizAcctFbid = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * BizAccountLinkInfo whatsappAcctNumber. - * @member {string} whatsappAcctNumber - * @memberof proto.BizAccountLinkInfo - * @instance - */ - BizAccountLinkInfo.prototype.whatsappAcctNumber = ""; - - /** - * BizAccountLinkInfo issueTime. - * @member {number|Long} issueTime - * @memberof proto.BizAccountLinkInfo - * @instance - */ - BizAccountLinkInfo.prototype.issueTime = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * BizAccountLinkInfo hostStorage. - * @member {proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType} hostStorage - * @memberof proto.BizAccountLinkInfo - * @instance - */ - BizAccountLinkInfo.prototype.hostStorage = 0; - - /** - * BizAccountLinkInfo accountType. - * @member {proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType} accountType - * @memberof proto.BizAccountLinkInfo - * @instance - */ - BizAccountLinkInfo.prototype.accountType = 0; - - /** - * Creates a new BizAccountLinkInfo instance using the specified properties. - * @function create - * @memberof proto.BizAccountLinkInfo - * @static - * @param {proto.IBizAccountLinkInfo=} [properties] Properties to set - * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo instance - */ - BizAccountLinkInfo.create = function create(properties) { - return new BizAccountLinkInfo(properties); - }; - - /** - * Encodes the specified BizAccountLinkInfo message. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages. - * @function encode - * @memberof proto.BizAccountLinkInfo - * @static - * @param {proto.IBizAccountLinkInfo} message BizAccountLinkInfo message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - BizAccountLinkInfo.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.whatsappBizAcctFbid != null && Object.hasOwnProperty.call(message, "whatsappBizAcctFbid")) - writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.whatsappBizAcctFbid); - if (message.whatsappAcctNumber != null && Object.hasOwnProperty.call(message, "whatsappAcctNumber")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.whatsappAcctNumber); - if (message.issueTime != null && Object.hasOwnProperty.call(message, "issueTime")) - writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.issueTime); - if (message.hostStorage != null && Object.hasOwnProperty.call(message, "hostStorage")) - writer.uint32(/* id 4, wireType 0 =*/32).int32(message.hostStorage); - if (message.accountType != null && Object.hasOwnProperty.call(message, "accountType")) - writer.uint32(/* id 5, wireType 0 =*/40).int32(message.accountType); - return writer; - }; - - /** - * Encodes the specified BizAccountLinkInfo message, length delimited. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.BizAccountLinkInfo - * @static - * @param {proto.IBizAccountLinkInfo} message BizAccountLinkInfo message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - BizAccountLinkInfo.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a BizAccountLinkInfo message from the specified reader or buffer. - * @function decode - * @memberof proto.BizAccountLinkInfo - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - BizAccountLinkInfo.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.BizAccountLinkInfo(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.whatsappBizAcctFbid = reader.uint64(); - break; - case 2: - message.whatsappAcctNumber = reader.string(); - break; - case 3: - message.issueTime = reader.uint64(); - break; - case 4: - message.hostStorage = reader.int32(); - break; - case 5: - message.accountType = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a BizAccountLinkInfo message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.BizAccountLinkInfo - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - BizAccountLinkInfo.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a BizAccountLinkInfo message. - * @function verify - * @memberof proto.BizAccountLinkInfo - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - BizAccountLinkInfo.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.whatsappBizAcctFbid != null && message.hasOwnProperty("whatsappBizAcctFbid")) - if (!$util.isInteger(message.whatsappBizAcctFbid) && !(message.whatsappBizAcctFbid && $util.isInteger(message.whatsappBizAcctFbid.low) && $util.isInteger(message.whatsappBizAcctFbid.high))) - return "whatsappBizAcctFbid: integer|Long expected"; - if (message.whatsappAcctNumber != null && message.hasOwnProperty("whatsappAcctNumber")) - if (!$util.isString(message.whatsappAcctNumber)) - return "whatsappAcctNumber: string expected"; - if (message.issueTime != null && message.hasOwnProperty("issueTime")) - if (!$util.isInteger(message.issueTime) && !(message.issueTime && $util.isInteger(message.issueTime.low) && $util.isInteger(message.issueTime.high))) - return "issueTime: integer|Long expected"; - if (message.hostStorage != null && message.hasOwnProperty("hostStorage")) - switch (message.hostStorage) { - default: - return "hostStorage: enum value expected"; - case 0: - case 1: - break; - } - if (message.accountType != null && message.hasOwnProperty("accountType")) - switch (message.accountType) { - default: - return "accountType: enum value expected"; - case 0: - case 1: - break; - } - return null; - }; - - /** - * Creates a BizAccountLinkInfo message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.BizAccountLinkInfo - * @static - * @param {Object.} object Plain object - * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo - */ - BizAccountLinkInfo.fromObject = function fromObject(object) { - if (object instanceof $root.proto.BizAccountLinkInfo) - return object; - var message = new $root.proto.BizAccountLinkInfo(); - if (object.whatsappBizAcctFbid != null) - if ($util.Long) - (message.whatsappBizAcctFbid = $util.Long.fromValue(object.whatsappBizAcctFbid)).unsigned = true; - else if (typeof object.whatsappBizAcctFbid === "string") - message.whatsappBizAcctFbid = parseInt(object.whatsappBizAcctFbid, 10); - else if (typeof object.whatsappBizAcctFbid === "number") - message.whatsappBizAcctFbid = object.whatsappBizAcctFbid; - else if (typeof object.whatsappBizAcctFbid === "object") - message.whatsappBizAcctFbid = new $util.LongBits(object.whatsappBizAcctFbid.low >>> 0, object.whatsappBizAcctFbid.high >>> 0).toNumber(true); - if (object.whatsappAcctNumber != null) - message.whatsappAcctNumber = String(object.whatsappAcctNumber); - if (object.issueTime != null) - if ($util.Long) - (message.issueTime = $util.Long.fromValue(object.issueTime)).unsigned = true; - else if (typeof object.issueTime === "string") - message.issueTime = parseInt(object.issueTime, 10); - else if (typeof object.issueTime === "number") - message.issueTime = object.issueTime; - else if (typeof object.issueTime === "object") - message.issueTime = new $util.LongBits(object.issueTime.low >>> 0, object.issueTime.high >>> 0).toNumber(true); - switch (object.hostStorage) { - case "ON_PREMISE": - case 0: - message.hostStorage = 0; - break; - case "FACEBOOK": - case 1: - message.hostStorage = 1; - break; - } - switch (object.accountType) { - case "ENTERPRISE": - case 0: - message.accountType = 0; - break; - case "PAGE": - case 1: - message.accountType = 1; - break; - } - return message; - }; - - /** - * Creates a plain object from a BizAccountLinkInfo message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.BizAccountLinkInfo - * @static - * @param {proto.BizAccountLinkInfo} message BizAccountLinkInfo - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - BizAccountLinkInfo.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.whatsappBizAcctFbid = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.whatsappBizAcctFbid = options.longs === String ? "0" : 0; - object.whatsappAcctNumber = ""; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.issueTime = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.issueTime = options.longs === String ? "0" : 0; - object.hostStorage = options.enums === String ? "ON_PREMISE" : 0; - object.accountType = options.enums === String ? "ENTERPRISE" : 0; - } - if (message.whatsappBizAcctFbid != null && message.hasOwnProperty("whatsappBizAcctFbid")) - if (typeof message.whatsappBizAcctFbid === "number") - object.whatsappBizAcctFbid = options.longs === String ? String(message.whatsappBizAcctFbid) : message.whatsappBizAcctFbid; - else - object.whatsappBizAcctFbid = options.longs === String ? $util.Long.prototype.toString.call(message.whatsappBizAcctFbid) : options.longs === Number ? new $util.LongBits(message.whatsappBizAcctFbid.low >>> 0, message.whatsappBizAcctFbid.high >>> 0).toNumber(true) : message.whatsappBizAcctFbid; - if (message.whatsappAcctNumber != null && message.hasOwnProperty("whatsappAcctNumber")) - object.whatsappAcctNumber = message.whatsappAcctNumber; - if (message.issueTime != null && message.hasOwnProperty("issueTime")) - if (typeof message.issueTime === "number") - object.issueTime = options.longs === String ? String(message.issueTime) : message.issueTime; - else - object.issueTime = options.longs === String ? $util.Long.prototype.toString.call(message.issueTime) : options.longs === Number ? new $util.LongBits(message.issueTime.low >>> 0, message.issueTime.high >>> 0).toNumber(true) : message.issueTime; - if (message.hostStorage != null && message.hasOwnProperty("hostStorage")) - object.hostStorage = options.enums === String ? $root.proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType[message.hostStorage] : message.hostStorage; - if (message.accountType != null && message.hasOwnProperty("accountType")) - object.accountType = options.enums === String ? $root.proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType[message.accountType] : message.accountType; - return object; - }; - - /** - * Converts this BizAccountLinkInfo to JSON. - * @function toJSON - * @memberof proto.BizAccountLinkInfo - * @instance - * @returns {Object.} JSON object - */ - BizAccountLinkInfo.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * BizAccountLinkInfoHostStorageType enum. - * @name proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType - * @enum {number} - * @property {number} ON_PREMISE=0 ON_PREMISE value - * @property {number} FACEBOOK=1 FACEBOOK value - */ - BizAccountLinkInfo.BizAccountLinkInfoHostStorageType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "ON_PREMISE"] = 0; - values[valuesById[1] = "FACEBOOK"] = 1; - return values; - })(); - - /** - * BizAccountLinkInfoAccountType enum. - * @name proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType - * @enum {number} - * @property {number} ENTERPRISE=0 ENTERPRISE value - * @property {number} PAGE=1 PAGE value - */ - BizAccountLinkInfo.BizAccountLinkInfoAccountType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "ENTERPRISE"] = 0; - values[valuesById[1] = "PAGE"] = 1; - return values; - })(); - - return BizAccountLinkInfo; - })(); - - proto.BizAccountPayload = (function() { - - /** - * Properties of a BizAccountPayload. - * @memberof proto - * @interface IBizAccountPayload - * @property {proto.IVerifiedNameCertificate|null} [vnameCert] BizAccountPayload vnameCert - * @property {Uint8Array|null} [bizAcctLinkInfo] BizAccountPayload bizAcctLinkInfo - */ - - /** - * Constructs a new BizAccountPayload. - * @memberof proto - * @classdesc Represents a BizAccountPayload. - * @implements IBizAccountPayload - * @constructor - * @param {proto.IBizAccountPayload=} [properties] Properties to set - */ - function BizAccountPayload(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * BizAccountPayload vnameCert. - * @member {proto.IVerifiedNameCertificate|null|undefined} vnameCert - * @memberof proto.BizAccountPayload - * @instance - */ - BizAccountPayload.prototype.vnameCert = null; - - /** - * BizAccountPayload bizAcctLinkInfo. - * @member {Uint8Array} bizAcctLinkInfo - * @memberof proto.BizAccountPayload - * @instance - */ - BizAccountPayload.prototype.bizAcctLinkInfo = $util.newBuffer([]); - - /** - * Creates a new BizAccountPayload instance using the specified properties. - * @function create - * @memberof proto.BizAccountPayload - * @static - * @param {proto.IBizAccountPayload=} [properties] Properties to set - * @returns {proto.BizAccountPayload} BizAccountPayload instance - */ - BizAccountPayload.create = function create(properties) { - return new BizAccountPayload(properties); - }; - - /** - * Encodes the specified BizAccountPayload message. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages. - * @function encode - * @memberof proto.BizAccountPayload - * @static - * @param {proto.IBizAccountPayload} message BizAccountPayload message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - BizAccountPayload.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.vnameCert != null && Object.hasOwnProperty.call(message, "vnameCert")) - $root.proto.VerifiedNameCertificate.encode(message.vnameCert, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.bizAcctLinkInfo != null && Object.hasOwnProperty.call(message, "bizAcctLinkInfo")) - writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.bizAcctLinkInfo); - return writer; - }; - - /** - * Encodes the specified BizAccountPayload message, length delimited. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.BizAccountPayload - * @static - * @param {proto.IBizAccountPayload} message BizAccountPayload message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - BizAccountPayload.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a BizAccountPayload message from the specified reader or buffer. - * @function decode - * @memberof proto.BizAccountPayload - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.BizAccountPayload} BizAccountPayload - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - BizAccountPayload.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.BizAccountPayload(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.vnameCert = $root.proto.VerifiedNameCertificate.decode(reader, reader.uint32()); - break; - case 2: - message.bizAcctLinkInfo = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a BizAccountPayload message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.BizAccountPayload - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.BizAccountPayload} BizAccountPayload - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - BizAccountPayload.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a BizAccountPayload message. - * @function verify - * @memberof proto.BizAccountPayload - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - BizAccountPayload.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) { - var error = $root.proto.VerifiedNameCertificate.verify(message.vnameCert); - if (error) - return "vnameCert." + error; - } - if (message.bizAcctLinkInfo != null && message.hasOwnProperty("bizAcctLinkInfo")) - if (!(message.bizAcctLinkInfo && typeof message.bizAcctLinkInfo.length === "number" || $util.isString(message.bizAcctLinkInfo))) - return "bizAcctLinkInfo: buffer expected"; - return null; - }; - - /** - * Creates a BizAccountPayload message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.BizAccountPayload - * @static - * @param {Object.} object Plain object - * @returns {proto.BizAccountPayload} BizAccountPayload - */ - BizAccountPayload.fromObject = function fromObject(object) { - if (object instanceof $root.proto.BizAccountPayload) - return object; - var message = new $root.proto.BizAccountPayload(); - if (object.vnameCert != null) { - if (typeof object.vnameCert !== "object") - throw TypeError(".proto.BizAccountPayload.vnameCert: object expected"); - message.vnameCert = $root.proto.VerifiedNameCertificate.fromObject(object.vnameCert); - } - if (object.bizAcctLinkInfo != null) - if (typeof object.bizAcctLinkInfo === "string") - $util.base64.decode(object.bizAcctLinkInfo, message.bizAcctLinkInfo = $util.newBuffer($util.base64.length(object.bizAcctLinkInfo)), 0); - else if (object.bizAcctLinkInfo.length) - message.bizAcctLinkInfo = object.bizAcctLinkInfo; - return message; - }; - - /** - * Creates a plain object from a BizAccountPayload message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.BizAccountPayload - * @static - * @param {proto.BizAccountPayload} message BizAccountPayload - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - BizAccountPayload.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.vnameCert = null; - if (options.bytes === String) - object.bizAcctLinkInfo = ""; - else { - object.bizAcctLinkInfo = []; - if (options.bytes !== Array) - object.bizAcctLinkInfo = $util.newBuffer(object.bizAcctLinkInfo); - } - } - if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) - object.vnameCert = $root.proto.VerifiedNameCertificate.toObject(message.vnameCert, options); - if (message.bizAcctLinkInfo != null && message.hasOwnProperty("bizAcctLinkInfo")) - object.bizAcctLinkInfo = options.bytes === String ? $util.base64.encode(message.bizAcctLinkInfo, 0, message.bizAcctLinkInfo.length) : options.bytes === Array ? Array.prototype.slice.call(message.bizAcctLinkInfo) : message.bizAcctLinkInfo; - return object; - }; - - /** - * Converts this BizAccountPayload to JSON. - * @function toJSON - * @memberof proto.BizAccountPayload - * @instance - * @returns {Object.} JSON object - */ - BizAccountPayload.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return BizAccountPayload; - })(); - - proto.VerifiedNameCertificate = (function() { - - /** - * Properties of a VerifiedNameCertificate. - * @memberof proto - * @interface IVerifiedNameCertificate - * @property {Uint8Array|null} [details] VerifiedNameCertificate details - * @property {Uint8Array|null} [signature] VerifiedNameCertificate signature - * @property {Uint8Array|null} [serverSignature] VerifiedNameCertificate serverSignature - */ - - /** - * Constructs a new VerifiedNameCertificate. - * @memberof proto - * @classdesc Represents a VerifiedNameCertificate. - * @implements IVerifiedNameCertificate - * @constructor - * @param {proto.IVerifiedNameCertificate=} [properties] Properties to set - */ - function VerifiedNameCertificate(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * VerifiedNameCertificate details. - * @member {Uint8Array} details - * @memberof proto.VerifiedNameCertificate - * @instance - */ - VerifiedNameCertificate.prototype.details = $util.newBuffer([]); - - /** - * VerifiedNameCertificate signature. - * @member {Uint8Array} signature - * @memberof proto.VerifiedNameCertificate - * @instance - */ - VerifiedNameCertificate.prototype.signature = $util.newBuffer([]); - - /** - * VerifiedNameCertificate serverSignature. - * @member {Uint8Array} serverSignature - * @memberof proto.VerifiedNameCertificate - * @instance - */ - VerifiedNameCertificate.prototype.serverSignature = $util.newBuffer([]); - - /** - * Creates a new VerifiedNameCertificate instance using the specified properties. - * @function create - * @memberof proto.VerifiedNameCertificate - * @static - * @param {proto.IVerifiedNameCertificate=} [properties] Properties to set - * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate instance - */ - VerifiedNameCertificate.create = function create(properties) { - return new VerifiedNameCertificate(properties); - }; - - /** - * Encodes the specified VerifiedNameCertificate message. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages. - * @function encode - * @memberof proto.VerifiedNameCertificate - * @static - * @param {proto.IVerifiedNameCertificate} message VerifiedNameCertificate message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - VerifiedNameCertificate.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.details != null && Object.hasOwnProperty.call(message, "details")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); - if (message.signature != null && Object.hasOwnProperty.call(message, "signature")) - writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.signature); - if (message.serverSignature != null && Object.hasOwnProperty.call(message, "serverSignature")) - writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.serverSignature); - return writer; - }; - - /** - * Encodes the specified VerifiedNameCertificate message, length delimited. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.VerifiedNameCertificate - * @static - * @param {proto.IVerifiedNameCertificate} message VerifiedNameCertificate message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - VerifiedNameCertificate.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a VerifiedNameCertificate message from the specified reader or buffer. - * @function decode - * @memberof proto.VerifiedNameCertificate - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - VerifiedNameCertificate.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.VerifiedNameCertificate(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.details = reader.bytes(); - break; - case 2: - message.signature = reader.bytes(); - break; - case 3: - message.serverSignature = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a VerifiedNameCertificate message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.VerifiedNameCertificate - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - VerifiedNameCertificate.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a VerifiedNameCertificate message. - * @function verify - * @memberof proto.VerifiedNameCertificate - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - VerifiedNameCertificate.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.details != null && message.hasOwnProperty("details")) - if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) - return "details: buffer expected"; - if (message.signature != null && message.hasOwnProperty("signature")) - if (!(message.signature && typeof message.signature.length === "number" || $util.isString(message.signature))) - return "signature: buffer expected"; - if (message.serverSignature != null && message.hasOwnProperty("serverSignature")) - if (!(message.serverSignature && typeof message.serverSignature.length === "number" || $util.isString(message.serverSignature))) - return "serverSignature: buffer expected"; - return null; - }; - - /** - * Creates a VerifiedNameCertificate message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.VerifiedNameCertificate - * @static - * @param {Object.} object Plain object - * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate - */ - VerifiedNameCertificate.fromObject = function fromObject(object) { - if (object instanceof $root.proto.VerifiedNameCertificate) - return object; - var message = new $root.proto.VerifiedNameCertificate(); - if (object.details != null) - if (typeof object.details === "string") - $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); - else if (object.details.length) - message.details = object.details; - if (object.signature != null) - if (typeof object.signature === "string") - $util.base64.decode(object.signature, message.signature = $util.newBuffer($util.base64.length(object.signature)), 0); - else if (object.signature.length) - message.signature = object.signature; - if (object.serverSignature != null) - if (typeof object.serverSignature === "string") - $util.base64.decode(object.serverSignature, message.serverSignature = $util.newBuffer($util.base64.length(object.serverSignature)), 0); - else if (object.serverSignature.length) - message.serverSignature = object.serverSignature; - return message; - }; - - /** - * Creates a plain object from a VerifiedNameCertificate message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.VerifiedNameCertificate - * @static - * @param {proto.VerifiedNameCertificate} message VerifiedNameCertificate - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - VerifiedNameCertificate.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if (options.bytes === String) - object.details = ""; - else { - object.details = []; - if (options.bytes !== Array) - object.details = $util.newBuffer(object.details); - } - if (options.bytes === String) - object.signature = ""; - else { - object.signature = []; - if (options.bytes !== Array) - object.signature = $util.newBuffer(object.signature); - } - if (options.bytes === String) - object.serverSignature = ""; - else { - object.serverSignature = []; - if (options.bytes !== Array) - object.serverSignature = $util.newBuffer(object.serverSignature); - } - } - if (message.details != null && message.hasOwnProperty("details")) - object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; - if (message.signature != null && message.hasOwnProperty("signature")) - object.signature = options.bytes === String ? $util.base64.encode(message.signature, 0, message.signature.length) : options.bytes === Array ? Array.prototype.slice.call(message.signature) : message.signature; - if (message.serverSignature != null && message.hasOwnProperty("serverSignature")) - object.serverSignature = options.bytes === String ? $util.base64.encode(message.serverSignature, 0, message.serverSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.serverSignature) : message.serverSignature; - return object; - }; - - /** - * Converts this VerifiedNameCertificate to JSON. - * @function toJSON - * @memberof proto.VerifiedNameCertificate - * @instance - * @returns {Object.} JSON object - */ - VerifiedNameCertificate.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return VerifiedNameCertificate; - })(); - - proto.LocalizedName = (function() { - - /** - * Properties of a LocalizedName. - * @memberof proto - * @interface ILocalizedName - * @property {string|null} [lg] LocalizedName lg - * @property {string|null} [lc] LocalizedName lc - * @property {string|null} [verifiedName] LocalizedName verifiedName - */ - - /** - * Constructs a new LocalizedName. - * @memberof proto - * @classdesc Represents a LocalizedName. - * @implements ILocalizedName - * @constructor - * @param {proto.ILocalizedName=} [properties] Properties to set - */ - function LocalizedName(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * LocalizedName lg. - * @member {string} lg - * @memberof proto.LocalizedName - * @instance - */ - LocalizedName.prototype.lg = ""; - - /** - * LocalizedName lc. - * @member {string} lc - * @memberof proto.LocalizedName - * @instance - */ - LocalizedName.prototype.lc = ""; - - /** - * LocalizedName verifiedName. - * @member {string} verifiedName - * @memberof proto.LocalizedName - * @instance - */ - LocalizedName.prototype.verifiedName = ""; - - /** - * Creates a new LocalizedName instance using the specified properties. - * @function create - * @memberof proto.LocalizedName - * @static - * @param {proto.ILocalizedName=} [properties] Properties to set - * @returns {proto.LocalizedName} LocalizedName instance - */ - LocalizedName.create = function create(properties) { - return new LocalizedName(properties); - }; - - /** - * Encodes the specified LocalizedName message. Does not implicitly {@link proto.LocalizedName.verify|verify} messages. - * @function encode - * @memberof proto.LocalizedName - * @static - * @param {proto.ILocalizedName} message LocalizedName message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - LocalizedName.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.lg != null && Object.hasOwnProperty.call(message, "lg")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.lg); - if (message.lc != null && Object.hasOwnProperty.call(message, "lc")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.lc); - if (message.verifiedName != null && Object.hasOwnProperty.call(message, "verifiedName")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.verifiedName); - return writer; - }; - - /** - * Encodes the specified LocalizedName message, length delimited. Does not implicitly {@link proto.LocalizedName.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.LocalizedName - * @static - * @param {proto.ILocalizedName} message LocalizedName message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - LocalizedName.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a LocalizedName message from the specified reader or buffer. - * @function decode - * @memberof proto.LocalizedName - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.LocalizedName} LocalizedName - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - LocalizedName.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LocalizedName(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.lg = reader.string(); - break; - case 2: - message.lc = reader.string(); - break; - case 3: - message.verifiedName = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a LocalizedName message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.LocalizedName - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.LocalizedName} LocalizedName - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - LocalizedName.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a LocalizedName message. - * @function verify - * @memberof proto.LocalizedName - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - LocalizedName.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.lg != null && message.hasOwnProperty("lg")) - if (!$util.isString(message.lg)) - return "lg: string expected"; - if (message.lc != null && message.hasOwnProperty("lc")) - if (!$util.isString(message.lc)) - return "lc: string expected"; - if (message.verifiedName != null && message.hasOwnProperty("verifiedName")) - if (!$util.isString(message.verifiedName)) - return "verifiedName: string expected"; - return null; - }; - - /** - * Creates a LocalizedName message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.LocalizedName - * @static - * @param {Object.} object Plain object - * @returns {proto.LocalizedName} LocalizedName - */ - LocalizedName.fromObject = function fromObject(object) { - if (object instanceof $root.proto.LocalizedName) - return object; - var message = new $root.proto.LocalizedName(); - if (object.lg != null) - message.lg = String(object.lg); - if (object.lc != null) - message.lc = String(object.lc); - if (object.verifiedName != null) - message.verifiedName = String(object.verifiedName); - return message; - }; - - /** - * Creates a plain object from a LocalizedName message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.LocalizedName - * @static - * @param {proto.LocalizedName} message LocalizedName - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - LocalizedName.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.lg = ""; - object.lc = ""; - object.verifiedName = ""; - } - if (message.lg != null && message.hasOwnProperty("lg")) - object.lg = message.lg; - if (message.lc != null && message.hasOwnProperty("lc")) - object.lc = message.lc; - if (message.verifiedName != null && message.hasOwnProperty("verifiedName")) - object.verifiedName = message.verifiedName; - return object; - }; - - /** - * Converts this LocalizedName to JSON. - * @function toJSON - * @memberof proto.LocalizedName - * @instance - * @returns {Object.} JSON object - */ - LocalizedName.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return LocalizedName; - })(); - - proto.SyncActionData = (function() { - - /** - * Properties of a SyncActionData. - * @memberof proto - * @interface ISyncActionData - * @property {Uint8Array|null} [index] SyncActionData index - * @property {proto.ISyncActionValue|null} [value] SyncActionData value - * @property {Uint8Array|null} [padding] SyncActionData padding - * @property {number|null} [version] SyncActionData version - */ - - /** - * Constructs a new SyncActionData. - * @memberof proto - * @classdesc Represents a SyncActionData. - * @implements ISyncActionData - * @constructor - * @param {proto.ISyncActionData=} [properties] Properties to set - */ - function SyncActionData(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SyncActionData index. - * @member {Uint8Array} index - * @memberof proto.SyncActionData - * @instance - */ - SyncActionData.prototype.index = $util.newBuffer([]); - - /** - * SyncActionData value. - * @member {proto.ISyncActionValue|null|undefined} value - * @memberof proto.SyncActionData - * @instance - */ - SyncActionData.prototype.value = null; - - /** - * SyncActionData padding. - * @member {Uint8Array} padding - * @memberof proto.SyncActionData - * @instance - */ - SyncActionData.prototype.padding = $util.newBuffer([]); - - /** - * SyncActionData version. - * @member {number} version - * @memberof proto.SyncActionData - * @instance - */ - SyncActionData.prototype.version = 0; - - /** - * Creates a new SyncActionData instance using the specified properties. - * @function create - * @memberof proto.SyncActionData - * @static - * @param {proto.ISyncActionData=} [properties] Properties to set - * @returns {proto.SyncActionData} SyncActionData instance - */ - SyncActionData.create = function create(properties) { - return new SyncActionData(properties); - }; - - /** - * Encodes the specified SyncActionData message. Does not implicitly {@link proto.SyncActionData.verify|verify} messages. - * @function encode - * @memberof proto.SyncActionData - * @static - * @param {proto.ISyncActionData} message SyncActionData message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncActionData.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.index != null && Object.hasOwnProperty.call(message, "index")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.index); - if (message.value != null && Object.hasOwnProperty.call(message, "value")) - $root.proto.SyncActionValue.encode(message.value, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.padding != null && Object.hasOwnProperty.call(message, "padding")) - writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.padding); - if (message.version != null && Object.hasOwnProperty.call(message, "version")) - writer.uint32(/* id 4, wireType 0 =*/32).int32(message.version); - return writer; - }; - - /** - * Encodes the specified SyncActionData message, length delimited. Does not implicitly {@link proto.SyncActionData.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SyncActionData - * @static - * @param {proto.ISyncActionData} message SyncActionData message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncActionData.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SyncActionData message from the specified reader or buffer. - * @function decode - * @memberof proto.SyncActionData - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SyncActionData} SyncActionData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncActionData.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionData(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.index = reader.bytes(); - break; - case 2: - message.value = $root.proto.SyncActionValue.decode(reader, reader.uint32()); - break; - case 3: - message.padding = reader.bytes(); - break; - case 4: - message.version = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SyncActionData message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SyncActionData - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SyncActionData} SyncActionData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncActionData.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SyncActionData message. - * @function verify - * @memberof proto.SyncActionData - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SyncActionData.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.index != null && message.hasOwnProperty("index")) - if (!(message.index && typeof message.index.length === "number" || $util.isString(message.index))) - return "index: buffer expected"; - if (message.value != null && message.hasOwnProperty("value")) { - var error = $root.proto.SyncActionValue.verify(message.value); - if (error) - return "value." + error; - } - if (message.padding != null && message.hasOwnProperty("padding")) - if (!(message.padding && typeof message.padding.length === "number" || $util.isString(message.padding))) - return "padding: buffer expected"; - if (message.version != null && message.hasOwnProperty("version")) - if (!$util.isInteger(message.version)) - return "version: integer expected"; - return null; - }; - - /** - * Creates a SyncActionData message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SyncActionData - * @static - * @param {Object.} object Plain object - * @returns {proto.SyncActionData} SyncActionData - */ - SyncActionData.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SyncActionData) - return object; - var message = new $root.proto.SyncActionData(); - if (object.index != null) - if (typeof object.index === "string") - $util.base64.decode(object.index, message.index = $util.newBuffer($util.base64.length(object.index)), 0); - else if (object.index.length) - message.index = object.index; - if (object.value != null) { - if (typeof object.value !== "object") - throw TypeError(".proto.SyncActionData.value: object expected"); - message.value = $root.proto.SyncActionValue.fromObject(object.value); - } - if (object.padding != null) - if (typeof object.padding === "string") - $util.base64.decode(object.padding, message.padding = $util.newBuffer($util.base64.length(object.padding)), 0); - else if (object.padding.length) - message.padding = object.padding; - if (object.version != null) - message.version = object.version | 0; - return message; - }; - - /** - * Creates a plain object from a SyncActionData message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SyncActionData - * @static - * @param {proto.SyncActionData} message SyncActionData - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SyncActionData.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if (options.bytes === String) - object.index = ""; - else { - object.index = []; - if (options.bytes !== Array) - object.index = $util.newBuffer(object.index); - } - object.value = null; - if (options.bytes === String) - object.padding = ""; - else { - object.padding = []; - if (options.bytes !== Array) - object.padding = $util.newBuffer(object.padding); - } - object.version = 0; - } - if (message.index != null && message.hasOwnProperty("index")) - object.index = options.bytes === String ? $util.base64.encode(message.index, 0, message.index.length) : options.bytes === Array ? Array.prototype.slice.call(message.index) : message.index; - if (message.value != null && message.hasOwnProperty("value")) - object.value = $root.proto.SyncActionValue.toObject(message.value, options); - if (message.padding != null && message.hasOwnProperty("padding")) - object.padding = options.bytes === String ? $util.base64.encode(message.padding, 0, message.padding.length) : options.bytes === Array ? Array.prototype.slice.call(message.padding) : message.padding; - if (message.version != null && message.hasOwnProperty("version")) - object.version = message.version; - return object; - }; - - /** - * Converts this SyncActionData to JSON. - * @function toJSON - * @memberof proto.SyncActionData - * @instance - * @returns {Object.} JSON object - */ - SyncActionData.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SyncActionData; - })(); - - proto.StarAction = (function() { - - /** - * Properties of a StarAction. - * @memberof proto - * @interface IStarAction - * @property {boolean|null} [starred] StarAction starred - */ - - /** - * Constructs a new StarAction. - * @memberof proto - * @classdesc Represents a StarAction. - * @implements IStarAction - * @constructor - * @param {proto.IStarAction=} [properties] Properties to set - */ - function StarAction(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * StarAction starred. - * @member {boolean} starred - * @memberof proto.StarAction - * @instance - */ - StarAction.prototype.starred = false; - - /** - * Creates a new StarAction instance using the specified properties. - * @function create - * @memberof proto.StarAction - * @static - * @param {proto.IStarAction=} [properties] Properties to set - * @returns {proto.StarAction} StarAction instance - */ - StarAction.create = function create(properties) { - return new StarAction(properties); - }; - - /** - * Encodes the specified StarAction message. Does not implicitly {@link proto.StarAction.verify|verify} messages. - * @function encode - * @memberof proto.StarAction - * @static - * @param {proto.IStarAction} message StarAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - StarAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.starred != null && Object.hasOwnProperty.call(message, "starred")) - writer.uint32(/* id 1, wireType 0 =*/8).bool(message.starred); - return writer; - }; - - /** - * Encodes the specified StarAction message, length delimited. Does not implicitly {@link proto.StarAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.StarAction - * @static - * @param {proto.IStarAction} message StarAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - StarAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a StarAction message from the specified reader or buffer. - * @function decode - * @memberof proto.StarAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.StarAction} StarAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - StarAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.StarAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.starred = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a StarAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.StarAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.StarAction} StarAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - StarAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a StarAction message. - * @function verify - * @memberof proto.StarAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - StarAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.starred != null && message.hasOwnProperty("starred")) - if (typeof message.starred !== "boolean") - return "starred: boolean expected"; - return null; - }; - - /** - * Creates a StarAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.StarAction - * @static - * @param {Object.} object Plain object - * @returns {proto.StarAction} StarAction - */ - StarAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.StarAction) - return object; - var message = new $root.proto.StarAction(); - if (object.starred != null) - message.starred = Boolean(object.starred); - return message; - }; - - /** - * Creates a plain object from a StarAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.StarAction - * @static - * @param {proto.StarAction} message StarAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - StarAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.starred = false; - if (message.starred != null && message.hasOwnProperty("starred")) - object.starred = message.starred; - return object; - }; - - /** - * Converts this StarAction to JSON. - * @function toJSON - * @memberof proto.StarAction - * @instance - * @returns {Object.} JSON object - */ - StarAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return StarAction; - })(); - - proto.ContactAction = (function() { - - /** - * Properties of a ContactAction. - * @memberof proto - * @interface IContactAction - * @property {string|null} [fullName] ContactAction fullName - * @property {string|null} [firstName] ContactAction firstName - */ - - /** - * Constructs a new ContactAction. - * @memberof proto - * @classdesc Represents a ContactAction. - * @implements IContactAction - * @constructor - * @param {proto.IContactAction=} [properties] Properties to set - */ - function ContactAction(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ContactAction fullName. - * @member {string} fullName - * @memberof proto.ContactAction - * @instance - */ - ContactAction.prototype.fullName = ""; - - /** - * ContactAction firstName. - * @member {string} firstName - * @memberof proto.ContactAction - * @instance - */ - ContactAction.prototype.firstName = ""; - - /** - * Creates a new ContactAction instance using the specified properties. - * @function create - * @memberof proto.ContactAction - * @static - * @param {proto.IContactAction=} [properties] Properties to set - * @returns {proto.ContactAction} ContactAction instance - */ - ContactAction.create = function create(properties) { - return new ContactAction(properties); - }; - - /** - * Encodes the specified ContactAction message. Does not implicitly {@link proto.ContactAction.verify|verify} messages. - * @function encode - * @memberof proto.ContactAction - * @static - * @param {proto.IContactAction} message ContactAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ContactAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.fullName != null && Object.hasOwnProperty.call(message, "fullName")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.fullName); - if (message.firstName != null && Object.hasOwnProperty.call(message, "firstName")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.firstName); - return writer; - }; - - /** - * Encodes the specified ContactAction message, length delimited. Does not implicitly {@link proto.ContactAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ContactAction - * @static - * @param {proto.IContactAction} message ContactAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ContactAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ContactAction message from the specified reader or buffer. - * @function decode - * @memberof proto.ContactAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ContactAction} ContactAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ContactAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ContactAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.fullName = reader.string(); - break; - case 2: - message.firstName = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ContactAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ContactAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ContactAction} ContactAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ContactAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ContactAction message. - * @function verify - * @memberof proto.ContactAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ContactAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.fullName != null && message.hasOwnProperty("fullName")) - if (!$util.isString(message.fullName)) - return "fullName: string expected"; - if (message.firstName != null && message.hasOwnProperty("firstName")) - if (!$util.isString(message.firstName)) - return "firstName: string expected"; - return null; - }; - - /** - * Creates a ContactAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ContactAction - * @static - * @param {Object.} object Plain object - * @returns {proto.ContactAction} ContactAction - */ - ContactAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ContactAction) - return object; - var message = new $root.proto.ContactAction(); - if (object.fullName != null) - message.fullName = String(object.fullName); - if (object.firstName != null) - message.firstName = String(object.firstName); - return message; - }; - - /** - * Creates a plain object from a ContactAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ContactAction - * @static - * @param {proto.ContactAction} message ContactAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ContactAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.fullName = ""; - object.firstName = ""; - } - if (message.fullName != null && message.hasOwnProperty("fullName")) - object.fullName = message.fullName; - if (message.firstName != null && message.hasOwnProperty("firstName")) - object.firstName = message.firstName; - return object; - }; - - /** - * Converts this ContactAction to JSON. - * @function toJSON - * @memberof proto.ContactAction - * @instance - * @returns {Object.} JSON object - */ - ContactAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ContactAction; - })(); - - proto.MuteAction = (function() { - - /** - * Properties of a MuteAction. - * @memberof proto - * @interface IMuteAction - * @property {boolean|null} [muted] MuteAction muted - * @property {number|Long|null} [muteEndTimestamp] MuteAction muteEndTimestamp - */ - - /** - * Constructs a new MuteAction. - * @memberof proto - * @classdesc Represents a MuteAction. - * @implements IMuteAction - * @constructor - * @param {proto.IMuteAction=} [properties] Properties to set - */ - function MuteAction(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * MuteAction muted. - * @member {boolean} muted - * @memberof proto.MuteAction - * @instance - */ - MuteAction.prototype.muted = false; - - /** - * MuteAction muteEndTimestamp. - * @member {number|Long} muteEndTimestamp - * @memberof proto.MuteAction - * @instance - */ - MuteAction.prototype.muteEndTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * Creates a new MuteAction instance using the specified properties. - * @function create - * @memberof proto.MuteAction - * @static - * @param {proto.IMuteAction=} [properties] Properties to set - * @returns {proto.MuteAction} MuteAction instance - */ - MuteAction.create = function create(properties) { - return new MuteAction(properties); - }; - - /** - * Encodes the specified MuteAction message. Does not implicitly {@link proto.MuteAction.verify|verify} messages. - * @function encode - * @memberof proto.MuteAction - * @static - * @param {proto.IMuteAction} message MuteAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - MuteAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.muted != null && Object.hasOwnProperty.call(message, "muted")) - writer.uint32(/* id 1, wireType 0 =*/8).bool(message.muted); - if (message.muteEndTimestamp != null && Object.hasOwnProperty.call(message, "muteEndTimestamp")) - writer.uint32(/* id 2, wireType 0 =*/16).int64(message.muteEndTimestamp); - return writer; - }; - - /** - * Encodes the specified MuteAction message, length delimited. Does not implicitly {@link proto.MuteAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.MuteAction - * @static - * @param {proto.IMuteAction} message MuteAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - MuteAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a MuteAction message from the specified reader or buffer. - * @function decode - * @memberof proto.MuteAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.MuteAction} MuteAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - MuteAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MuteAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.muted = reader.bool(); - break; - case 2: - message.muteEndTimestamp = reader.int64(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a MuteAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.MuteAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.MuteAction} MuteAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - MuteAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a MuteAction message. - * @function verify - * @memberof proto.MuteAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - MuteAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.muted != null && message.hasOwnProperty("muted")) - if (typeof message.muted !== "boolean") - return "muted: boolean expected"; - if (message.muteEndTimestamp != null && message.hasOwnProperty("muteEndTimestamp")) - if (!$util.isInteger(message.muteEndTimestamp) && !(message.muteEndTimestamp && $util.isInteger(message.muteEndTimestamp.low) && $util.isInteger(message.muteEndTimestamp.high))) - return "muteEndTimestamp: integer|Long expected"; - return null; - }; - - /** - * Creates a MuteAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.MuteAction - * @static - * @param {Object.} object Plain object - * @returns {proto.MuteAction} MuteAction - */ - MuteAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.MuteAction) - return object; - var message = new $root.proto.MuteAction(); - if (object.muted != null) - message.muted = Boolean(object.muted); - if (object.muteEndTimestamp != null) - if ($util.Long) - (message.muteEndTimestamp = $util.Long.fromValue(object.muteEndTimestamp)).unsigned = false; - else if (typeof object.muteEndTimestamp === "string") - message.muteEndTimestamp = parseInt(object.muteEndTimestamp, 10); - else if (typeof object.muteEndTimestamp === "number") - message.muteEndTimestamp = object.muteEndTimestamp; - else if (typeof object.muteEndTimestamp === "object") - message.muteEndTimestamp = new $util.LongBits(object.muteEndTimestamp.low >>> 0, object.muteEndTimestamp.high >>> 0).toNumber(); - return message; - }; - - /** - * Creates a plain object from a MuteAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.MuteAction - * @static - * @param {proto.MuteAction} message MuteAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - MuteAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.muted = false; - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.muteEndTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.muteEndTimestamp = options.longs === String ? "0" : 0; - } - if (message.muted != null && message.hasOwnProperty("muted")) - object.muted = message.muted; - if (message.muteEndTimestamp != null && message.hasOwnProperty("muteEndTimestamp")) - if (typeof message.muteEndTimestamp === "number") - object.muteEndTimestamp = options.longs === String ? String(message.muteEndTimestamp) : message.muteEndTimestamp; - else - object.muteEndTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.muteEndTimestamp) : options.longs === Number ? new $util.LongBits(message.muteEndTimestamp.low >>> 0, message.muteEndTimestamp.high >>> 0).toNumber() : message.muteEndTimestamp; - return object; - }; - - /** - * Converts this MuteAction to JSON. - * @function toJSON - * @memberof proto.MuteAction - * @instance - * @returns {Object.} JSON object - */ - MuteAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return MuteAction; - })(); - - proto.PinAction = (function() { - - /** - * Properties of a PinAction. - * @memberof proto - * @interface IPinAction - * @property {boolean|null} [pinned] PinAction pinned - */ - - /** - * Constructs a new PinAction. - * @memberof proto - * @classdesc Represents a PinAction. - * @implements IPinAction - * @constructor - * @param {proto.IPinAction=} [properties] Properties to set - */ - function PinAction(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * PinAction pinned. - * @member {boolean} pinned - * @memberof proto.PinAction - * @instance - */ - PinAction.prototype.pinned = false; - - /** - * Creates a new PinAction instance using the specified properties. - * @function create - * @memberof proto.PinAction - * @static - * @param {proto.IPinAction=} [properties] Properties to set - * @returns {proto.PinAction} PinAction instance - */ - PinAction.create = function create(properties) { - return new PinAction(properties); - }; - - /** - * Encodes the specified PinAction message. Does not implicitly {@link proto.PinAction.verify|verify} messages. - * @function encode - * @memberof proto.PinAction - * @static - * @param {proto.IPinAction} message PinAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - PinAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.pinned != null && Object.hasOwnProperty.call(message, "pinned")) - writer.uint32(/* id 1, wireType 0 =*/8).bool(message.pinned); - return writer; - }; - - /** - * Encodes the specified PinAction message, length delimited. Does not implicitly {@link proto.PinAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.PinAction - * @static - * @param {proto.IPinAction} message PinAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - PinAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a PinAction message from the specified reader or buffer. - * @function decode - * @memberof proto.PinAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.PinAction} PinAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - PinAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PinAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.pinned = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a PinAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.PinAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.PinAction} PinAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - PinAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a PinAction message. - * @function verify - * @memberof proto.PinAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - PinAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.pinned != null && message.hasOwnProperty("pinned")) - if (typeof message.pinned !== "boolean") - return "pinned: boolean expected"; - return null; - }; - - /** - * Creates a PinAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.PinAction - * @static - * @param {Object.} object Plain object - * @returns {proto.PinAction} PinAction - */ - PinAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.PinAction) - return object; - var message = new $root.proto.PinAction(); - if (object.pinned != null) - message.pinned = Boolean(object.pinned); - return message; - }; - - /** - * Creates a plain object from a PinAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.PinAction - * @static - * @param {proto.PinAction} message PinAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - PinAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.pinned = false; - if (message.pinned != null && message.hasOwnProperty("pinned")) - object.pinned = message.pinned; - return object; - }; - - /** - * Converts this PinAction to JSON. - * @function toJSON - * @memberof proto.PinAction - * @instance - * @returns {Object.} JSON object - */ - PinAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return PinAction; - })(); - - proto.SecurityNotificationSetting = (function() { - - /** - * Properties of a SecurityNotificationSetting. - * @memberof proto - * @interface ISecurityNotificationSetting - * @property {boolean|null} [showNotification] SecurityNotificationSetting showNotification - */ - - /** - * Constructs a new SecurityNotificationSetting. - * @memberof proto - * @classdesc Represents a SecurityNotificationSetting. - * @implements ISecurityNotificationSetting - * @constructor - * @param {proto.ISecurityNotificationSetting=} [properties] Properties to set - */ - function SecurityNotificationSetting(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SecurityNotificationSetting showNotification. - * @member {boolean} showNotification - * @memberof proto.SecurityNotificationSetting - * @instance - */ - SecurityNotificationSetting.prototype.showNotification = false; - - /** - * Creates a new SecurityNotificationSetting instance using the specified properties. - * @function create - * @memberof proto.SecurityNotificationSetting - * @static - * @param {proto.ISecurityNotificationSetting=} [properties] Properties to set - * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting instance - */ - SecurityNotificationSetting.create = function create(properties) { - return new SecurityNotificationSetting(properties); - }; - - /** - * Encodes the specified SecurityNotificationSetting message. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages. - * @function encode - * @memberof proto.SecurityNotificationSetting - * @static - * @param {proto.ISecurityNotificationSetting} message SecurityNotificationSetting message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SecurityNotificationSetting.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.showNotification != null && Object.hasOwnProperty.call(message, "showNotification")) - writer.uint32(/* id 1, wireType 0 =*/8).bool(message.showNotification); - return writer; - }; - - /** - * Encodes the specified SecurityNotificationSetting message, length delimited. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SecurityNotificationSetting - * @static - * @param {proto.ISecurityNotificationSetting} message SecurityNotificationSetting message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SecurityNotificationSetting.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SecurityNotificationSetting message from the specified reader or buffer. - * @function decode - * @memberof proto.SecurityNotificationSetting - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SecurityNotificationSetting.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SecurityNotificationSetting(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.showNotification = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SecurityNotificationSetting message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SecurityNotificationSetting - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SecurityNotificationSetting.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SecurityNotificationSetting message. - * @function verify - * @memberof proto.SecurityNotificationSetting - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SecurityNotificationSetting.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.showNotification != null && message.hasOwnProperty("showNotification")) - if (typeof message.showNotification !== "boolean") - return "showNotification: boolean expected"; - return null; - }; - - /** - * Creates a SecurityNotificationSetting message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SecurityNotificationSetting - * @static - * @param {Object.} object Plain object - * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting - */ - SecurityNotificationSetting.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SecurityNotificationSetting) - return object; - var message = new $root.proto.SecurityNotificationSetting(); - if (object.showNotification != null) - message.showNotification = Boolean(object.showNotification); - return message; - }; - - /** - * Creates a plain object from a SecurityNotificationSetting message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SecurityNotificationSetting - * @static - * @param {proto.SecurityNotificationSetting} message SecurityNotificationSetting - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SecurityNotificationSetting.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.showNotification = false; - if (message.showNotification != null && message.hasOwnProperty("showNotification")) - object.showNotification = message.showNotification; - return object; - }; - - /** - * Converts this SecurityNotificationSetting to JSON. - * @function toJSON - * @memberof proto.SecurityNotificationSetting - * @instance - * @returns {Object.} JSON object - */ - SecurityNotificationSetting.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SecurityNotificationSetting; - })(); - - proto.PushNameSetting = (function() { - - /** - * Properties of a PushNameSetting. - * @memberof proto - * @interface IPushNameSetting - * @property {string|null} [name] PushNameSetting name - */ - - /** - * Constructs a new PushNameSetting. - * @memberof proto - * @classdesc Represents a PushNameSetting. - * @implements IPushNameSetting - * @constructor - * @param {proto.IPushNameSetting=} [properties] Properties to set - */ - function PushNameSetting(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * PushNameSetting name. - * @member {string} name - * @memberof proto.PushNameSetting - * @instance - */ - PushNameSetting.prototype.name = ""; - - /** - * Creates a new PushNameSetting instance using the specified properties. - * @function create - * @memberof proto.PushNameSetting - * @static - * @param {proto.IPushNameSetting=} [properties] Properties to set - * @returns {proto.PushNameSetting} PushNameSetting instance - */ - PushNameSetting.create = function create(properties) { - return new PushNameSetting(properties); - }; - - /** - * Encodes the specified PushNameSetting message. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages. - * @function encode - * @memberof proto.PushNameSetting - * @static - * @param {proto.IPushNameSetting} message PushNameSetting message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - PushNameSetting.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.name != null && Object.hasOwnProperty.call(message, "name")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.name); - return writer; - }; - - /** - * Encodes the specified PushNameSetting message, length delimited. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.PushNameSetting - * @static - * @param {proto.IPushNameSetting} message PushNameSetting message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - PushNameSetting.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a PushNameSetting message from the specified reader or buffer. - * @function decode - * @memberof proto.PushNameSetting - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.PushNameSetting} PushNameSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - PushNameSetting.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PushNameSetting(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.name = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a PushNameSetting message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.PushNameSetting - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.PushNameSetting} PushNameSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - PushNameSetting.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a PushNameSetting message. - * @function verify - * @memberof proto.PushNameSetting - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - PushNameSetting.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.name != null && message.hasOwnProperty("name")) - if (!$util.isString(message.name)) - return "name: string expected"; - return null; - }; - - /** - * Creates a PushNameSetting message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.PushNameSetting - * @static - * @param {Object.} object Plain object - * @returns {proto.PushNameSetting} PushNameSetting - */ - PushNameSetting.fromObject = function fromObject(object) { - if (object instanceof $root.proto.PushNameSetting) - return object; - var message = new $root.proto.PushNameSetting(); - if (object.name != null) - message.name = String(object.name); - return message; - }; - - /** - * Creates a plain object from a PushNameSetting message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.PushNameSetting - * @static - * @param {proto.PushNameSetting} message PushNameSetting - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - PushNameSetting.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.name = ""; - if (message.name != null && message.hasOwnProperty("name")) - object.name = message.name; - return object; - }; - - /** - * Converts this PushNameSetting to JSON. - * @function toJSON - * @memberof proto.PushNameSetting - * @instance - * @returns {Object.} JSON object - */ - PushNameSetting.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return PushNameSetting; - })(); - - proto.LocaleSetting = (function() { - - /** - * Properties of a LocaleSetting. - * @memberof proto - * @interface ILocaleSetting - * @property {string|null} [locale] LocaleSetting locale - */ - - /** - * Constructs a new LocaleSetting. - * @memberof proto - * @classdesc Represents a LocaleSetting. - * @implements ILocaleSetting - * @constructor - * @param {proto.ILocaleSetting=} [properties] Properties to set - */ - function LocaleSetting(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * LocaleSetting locale. - * @member {string} locale - * @memberof proto.LocaleSetting - * @instance - */ - LocaleSetting.prototype.locale = ""; - - /** - * Creates a new LocaleSetting instance using the specified properties. - * @function create - * @memberof proto.LocaleSetting - * @static - * @param {proto.ILocaleSetting=} [properties] Properties to set - * @returns {proto.LocaleSetting} LocaleSetting instance - */ - LocaleSetting.create = function create(properties) { - return new LocaleSetting(properties); - }; - - /** - * Encodes the specified LocaleSetting message. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages. - * @function encode - * @memberof proto.LocaleSetting - * @static - * @param {proto.ILocaleSetting} message LocaleSetting message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - LocaleSetting.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.locale != null && Object.hasOwnProperty.call(message, "locale")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.locale); - return writer; - }; - - /** - * Encodes the specified LocaleSetting message, length delimited. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.LocaleSetting - * @static - * @param {proto.ILocaleSetting} message LocaleSetting message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - LocaleSetting.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a LocaleSetting message from the specified reader or buffer. - * @function decode - * @memberof proto.LocaleSetting - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.LocaleSetting} LocaleSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - LocaleSetting.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LocaleSetting(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.locale = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a LocaleSetting message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.LocaleSetting - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.LocaleSetting} LocaleSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - LocaleSetting.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a LocaleSetting message. - * @function verify - * @memberof proto.LocaleSetting - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - LocaleSetting.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.locale != null && message.hasOwnProperty("locale")) - if (!$util.isString(message.locale)) - return "locale: string expected"; - return null; - }; - - /** - * Creates a LocaleSetting message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.LocaleSetting - * @static - * @param {Object.} object Plain object - * @returns {proto.LocaleSetting} LocaleSetting - */ - LocaleSetting.fromObject = function fromObject(object) { - if (object instanceof $root.proto.LocaleSetting) - return object; - var message = new $root.proto.LocaleSetting(); - if (object.locale != null) - message.locale = String(object.locale); - return message; - }; - - /** - * Creates a plain object from a LocaleSetting message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.LocaleSetting - * @static - * @param {proto.LocaleSetting} message LocaleSetting - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - LocaleSetting.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.locale = ""; - if (message.locale != null && message.hasOwnProperty("locale")) - object.locale = message.locale; - return object; - }; - - /** - * Converts this LocaleSetting to JSON. - * @function toJSON - * @memberof proto.LocaleSetting - * @instance - * @returns {Object.} JSON object - */ - LocaleSetting.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return LocaleSetting; - })(); - - proto.QuickReplyAction = (function() { - - /** - * Properties of a QuickReplyAction. - * @memberof proto - * @interface IQuickReplyAction - * @property {string|null} [shortcut] QuickReplyAction shortcut - * @property {string|null} [message] QuickReplyAction message - * @property {Array.|null} [keywords] QuickReplyAction keywords - * @property {number|null} [count] QuickReplyAction count - * @property {boolean|null} [deleted] QuickReplyAction deleted - */ - - /** - * Constructs a new QuickReplyAction. - * @memberof proto - * @classdesc Represents a QuickReplyAction. - * @implements IQuickReplyAction - * @constructor - * @param {proto.IQuickReplyAction=} [properties] Properties to set - */ - function QuickReplyAction(properties) { - this.keywords = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * QuickReplyAction shortcut. - * @member {string} shortcut - * @memberof proto.QuickReplyAction - * @instance - */ - QuickReplyAction.prototype.shortcut = ""; - - /** - * QuickReplyAction message. - * @member {string} message - * @memberof proto.QuickReplyAction - * @instance - */ - QuickReplyAction.prototype.message = ""; - - /** - * QuickReplyAction keywords. - * @member {Array.} keywords - * @memberof proto.QuickReplyAction - * @instance - */ - QuickReplyAction.prototype.keywords = $util.emptyArray; - - /** - * QuickReplyAction count. - * @member {number} count - * @memberof proto.QuickReplyAction - * @instance - */ - QuickReplyAction.prototype.count = 0; - - /** - * QuickReplyAction deleted. - * @member {boolean} deleted - * @memberof proto.QuickReplyAction - * @instance - */ - QuickReplyAction.prototype.deleted = false; - - /** - * Creates a new QuickReplyAction instance using the specified properties. - * @function create - * @memberof proto.QuickReplyAction - * @static - * @param {proto.IQuickReplyAction=} [properties] Properties to set - * @returns {proto.QuickReplyAction} QuickReplyAction instance - */ - QuickReplyAction.create = function create(properties) { - return new QuickReplyAction(properties); - }; - - /** - * Encodes the specified QuickReplyAction message. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages. - * @function encode - * @memberof proto.QuickReplyAction - * @static - * @param {proto.IQuickReplyAction} message QuickReplyAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - QuickReplyAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.shortcut != null && Object.hasOwnProperty.call(message, "shortcut")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.shortcut); - if (message.message != null && Object.hasOwnProperty.call(message, "message")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.message); - if (message.keywords != null && message.keywords.length) - for (var i = 0; i < message.keywords.length; ++i) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.keywords[i]); - if (message.count != null && Object.hasOwnProperty.call(message, "count")) - writer.uint32(/* id 4, wireType 0 =*/32).int32(message.count); - if (message.deleted != null && Object.hasOwnProperty.call(message, "deleted")) - writer.uint32(/* id 5, wireType 0 =*/40).bool(message.deleted); - return writer; - }; - - /** - * Encodes the specified QuickReplyAction message, length delimited. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.QuickReplyAction - * @static - * @param {proto.IQuickReplyAction} message QuickReplyAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - QuickReplyAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a QuickReplyAction message from the specified reader or buffer. - * @function decode - * @memberof proto.QuickReplyAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.QuickReplyAction} QuickReplyAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - QuickReplyAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.QuickReplyAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.shortcut = reader.string(); - break; - case 2: - message.message = reader.string(); - break; - case 3: - if (!(message.keywords && message.keywords.length)) - message.keywords = []; - message.keywords.push(reader.string()); - break; - case 4: - message.count = reader.int32(); - break; - case 5: - message.deleted = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a QuickReplyAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.QuickReplyAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.QuickReplyAction} QuickReplyAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - QuickReplyAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a QuickReplyAction message. - * @function verify - * @memberof proto.QuickReplyAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - QuickReplyAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.shortcut != null && message.hasOwnProperty("shortcut")) - if (!$util.isString(message.shortcut)) - return "shortcut: string expected"; - if (message.message != null && message.hasOwnProperty("message")) - if (!$util.isString(message.message)) - return "message: string expected"; - if (message.keywords != null && message.hasOwnProperty("keywords")) { - if (!Array.isArray(message.keywords)) - return "keywords: array expected"; - for (var i = 0; i < message.keywords.length; ++i) - if (!$util.isString(message.keywords[i])) - return "keywords: string[] expected"; - } - if (message.count != null && message.hasOwnProperty("count")) - if (!$util.isInteger(message.count)) - return "count: integer expected"; - if (message.deleted != null && message.hasOwnProperty("deleted")) - if (typeof message.deleted !== "boolean") - return "deleted: boolean expected"; - return null; - }; - - /** - * Creates a QuickReplyAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.QuickReplyAction - * @static - * @param {Object.} object Plain object - * @returns {proto.QuickReplyAction} QuickReplyAction - */ - QuickReplyAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.QuickReplyAction) - return object; - var message = new $root.proto.QuickReplyAction(); - if (object.shortcut != null) - message.shortcut = String(object.shortcut); - if (object.message != null) - message.message = String(object.message); - if (object.keywords) { - if (!Array.isArray(object.keywords)) - throw TypeError(".proto.QuickReplyAction.keywords: array expected"); - message.keywords = []; - for (var i = 0; i < object.keywords.length; ++i) - message.keywords[i] = String(object.keywords[i]); - } - if (object.count != null) - message.count = object.count | 0; - if (object.deleted != null) - message.deleted = Boolean(object.deleted); - return message; - }; - - /** - * Creates a plain object from a QuickReplyAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.QuickReplyAction - * @static - * @param {proto.QuickReplyAction} message QuickReplyAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - QuickReplyAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.keywords = []; - if (options.defaults) { - object.shortcut = ""; - object.message = ""; - object.count = 0; - object.deleted = false; - } - if (message.shortcut != null && message.hasOwnProperty("shortcut")) - object.shortcut = message.shortcut; - if (message.message != null && message.hasOwnProperty("message")) - object.message = message.message; - if (message.keywords && message.keywords.length) { - object.keywords = []; - for (var j = 0; j < message.keywords.length; ++j) - object.keywords[j] = message.keywords[j]; - } - if (message.count != null && message.hasOwnProperty("count")) - object.count = message.count; - if (message.deleted != null && message.hasOwnProperty("deleted")) - object.deleted = message.deleted; - return object; - }; - - /** - * Converts this QuickReplyAction to JSON. - * @function toJSON - * @memberof proto.QuickReplyAction - * @instance - * @returns {Object.} JSON object - */ - QuickReplyAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return QuickReplyAction; - })(); - - proto.LabelAssociationAction = (function() { - - /** - * Properties of a LabelAssociationAction. - * @memberof proto - * @interface ILabelAssociationAction - * @property {boolean|null} [labeled] LabelAssociationAction labeled - */ - - /** - * Constructs a new LabelAssociationAction. - * @memberof proto - * @classdesc Represents a LabelAssociationAction. - * @implements ILabelAssociationAction - * @constructor - * @param {proto.ILabelAssociationAction=} [properties] Properties to set - */ - function LabelAssociationAction(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * LabelAssociationAction labeled. - * @member {boolean} labeled - * @memberof proto.LabelAssociationAction - * @instance - */ - LabelAssociationAction.prototype.labeled = false; - - /** - * Creates a new LabelAssociationAction instance using the specified properties. - * @function create - * @memberof proto.LabelAssociationAction - * @static - * @param {proto.ILabelAssociationAction=} [properties] Properties to set - * @returns {proto.LabelAssociationAction} LabelAssociationAction instance - */ - LabelAssociationAction.create = function create(properties) { - return new LabelAssociationAction(properties); - }; - - /** - * Encodes the specified LabelAssociationAction message. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages. - * @function encode - * @memberof proto.LabelAssociationAction - * @static - * @param {proto.ILabelAssociationAction} message LabelAssociationAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - LabelAssociationAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.labeled != null && Object.hasOwnProperty.call(message, "labeled")) - writer.uint32(/* id 1, wireType 0 =*/8).bool(message.labeled); - return writer; - }; - - /** - * Encodes the specified LabelAssociationAction message, length delimited. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.LabelAssociationAction - * @static - * @param {proto.ILabelAssociationAction} message LabelAssociationAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - LabelAssociationAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a LabelAssociationAction message from the specified reader or buffer. - * @function decode - * @memberof proto.LabelAssociationAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.LabelAssociationAction} LabelAssociationAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - LabelAssociationAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LabelAssociationAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.labeled = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a LabelAssociationAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.LabelAssociationAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.LabelAssociationAction} LabelAssociationAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - LabelAssociationAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a LabelAssociationAction message. - * @function verify - * @memberof proto.LabelAssociationAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - LabelAssociationAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.labeled != null && message.hasOwnProperty("labeled")) - if (typeof message.labeled !== "boolean") - return "labeled: boolean expected"; - return null; - }; - - /** - * Creates a LabelAssociationAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.LabelAssociationAction - * @static - * @param {Object.} object Plain object - * @returns {proto.LabelAssociationAction} LabelAssociationAction - */ - LabelAssociationAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.LabelAssociationAction) - return object; - var message = new $root.proto.LabelAssociationAction(); - if (object.labeled != null) - message.labeled = Boolean(object.labeled); - return message; - }; - - /** - * Creates a plain object from a LabelAssociationAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.LabelAssociationAction - * @static - * @param {proto.LabelAssociationAction} message LabelAssociationAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - LabelAssociationAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.labeled = false; - if (message.labeled != null && message.hasOwnProperty("labeled")) - object.labeled = message.labeled; - return object; - }; - - /** - * Converts this LabelAssociationAction to JSON. - * @function toJSON - * @memberof proto.LabelAssociationAction - * @instance - * @returns {Object.} JSON object - */ - LabelAssociationAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return LabelAssociationAction; - })(); - - proto.LabelEditAction = (function() { - - /** - * Properties of a LabelEditAction. - * @memberof proto - * @interface ILabelEditAction - * @property {string|null} [name] LabelEditAction name - * @property {number|null} [color] LabelEditAction color - * @property {number|null} [predefinedId] LabelEditAction predefinedId - * @property {boolean|null} [deleted] LabelEditAction deleted - */ - - /** - * Constructs a new LabelEditAction. - * @memberof proto - * @classdesc Represents a LabelEditAction. - * @implements ILabelEditAction - * @constructor - * @param {proto.ILabelEditAction=} [properties] Properties to set - */ - function LabelEditAction(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * LabelEditAction name. - * @member {string} name - * @memberof proto.LabelEditAction - * @instance - */ - LabelEditAction.prototype.name = ""; - - /** - * LabelEditAction color. - * @member {number} color - * @memberof proto.LabelEditAction - * @instance - */ - LabelEditAction.prototype.color = 0; - - /** - * LabelEditAction predefinedId. - * @member {number} predefinedId - * @memberof proto.LabelEditAction - * @instance - */ - LabelEditAction.prototype.predefinedId = 0; - - /** - * LabelEditAction deleted. - * @member {boolean} deleted - * @memberof proto.LabelEditAction - * @instance - */ - LabelEditAction.prototype.deleted = false; - - /** - * Creates a new LabelEditAction instance using the specified properties. - * @function create - * @memberof proto.LabelEditAction - * @static - * @param {proto.ILabelEditAction=} [properties] Properties to set - * @returns {proto.LabelEditAction} LabelEditAction instance - */ - LabelEditAction.create = function create(properties) { - return new LabelEditAction(properties); - }; - - /** - * Encodes the specified LabelEditAction message. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages. - * @function encode - * @memberof proto.LabelEditAction - * @static - * @param {proto.ILabelEditAction} message LabelEditAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - LabelEditAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.name != null && Object.hasOwnProperty.call(message, "name")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.name); - if (message.color != null && Object.hasOwnProperty.call(message, "color")) - writer.uint32(/* id 2, wireType 0 =*/16).int32(message.color); - if (message.predefinedId != null && Object.hasOwnProperty.call(message, "predefinedId")) - writer.uint32(/* id 3, wireType 0 =*/24).int32(message.predefinedId); - if (message.deleted != null && Object.hasOwnProperty.call(message, "deleted")) - writer.uint32(/* id 4, wireType 0 =*/32).bool(message.deleted); - return writer; - }; - - /** - * Encodes the specified LabelEditAction message, length delimited. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.LabelEditAction - * @static - * @param {proto.ILabelEditAction} message LabelEditAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - LabelEditAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a LabelEditAction message from the specified reader or buffer. - * @function decode - * @memberof proto.LabelEditAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.LabelEditAction} LabelEditAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - LabelEditAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LabelEditAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.name = reader.string(); - break; - case 2: - message.color = reader.int32(); - break; - case 3: - message.predefinedId = reader.int32(); - break; - case 4: - message.deleted = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a LabelEditAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.LabelEditAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.LabelEditAction} LabelEditAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - LabelEditAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a LabelEditAction message. - * @function verify - * @memberof proto.LabelEditAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - LabelEditAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.name != null && message.hasOwnProperty("name")) - if (!$util.isString(message.name)) - return "name: string expected"; - if (message.color != null && message.hasOwnProperty("color")) - if (!$util.isInteger(message.color)) - return "color: integer expected"; - if (message.predefinedId != null && message.hasOwnProperty("predefinedId")) - if (!$util.isInteger(message.predefinedId)) - return "predefinedId: integer expected"; - if (message.deleted != null && message.hasOwnProperty("deleted")) - if (typeof message.deleted !== "boolean") - return "deleted: boolean expected"; - return null; - }; - - /** - * Creates a LabelEditAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.LabelEditAction - * @static - * @param {Object.} object Plain object - * @returns {proto.LabelEditAction} LabelEditAction - */ - LabelEditAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.LabelEditAction) - return object; - var message = new $root.proto.LabelEditAction(); - if (object.name != null) - message.name = String(object.name); - if (object.color != null) - message.color = object.color | 0; - if (object.predefinedId != null) - message.predefinedId = object.predefinedId | 0; - if (object.deleted != null) - message.deleted = Boolean(object.deleted); - return message; - }; - - /** - * Creates a plain object from a LabelEditAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.LabelEditAction - * @static - * @param {proto.LabelEditAction} message LabelEditAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - LabelEditAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.name = ""; - object.color = 0; - object.predefinedId = 0; - object.deleted = false; - } - if (message.name != null && message.hasOwnProperty("name")) - object.name = message.name; - if (message.color != null && message.hasOwnProperty("color")) - object.color = message.color; - if (message.predefinedId != null && message.hasOwnProperty("predefinedId")) - object.predefinedId = message.predefinedId; - if (message.deleted != null && message.hasOwnProperty("deleted")) - object.deleted = message.deleted; - return object; - }; - - /** - * Converts this LabelEditAction to JSON. - * @function toJSON - * @memberof proto.LabelEditAction - * @instance - * @returns {Object.} JSON object - */ - LabelEditAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return LabelEditAction; - })(); - - proto.RecentStickerWeightsAction = (function() { - - /** - * Properties of a RecentStickerWeightsAction. - * @memberof proto - * @interface IRecentStickerWeightsAction - * @property {Array.|null} [weights] RecentStickerWeightsAction weights - */ - - /** - * Constructs a new RecentStickerWeightsAction. - * @memberof proto - * @classdesc Represents a RecentStickerWeightsAction. - * @implements IRecentStickerWeightsAction - * @constructor - * @param {proto.IRecentStickerWeightsAction=} [properties] Properties to set - */ - function RecentStickerWeightsAction(properties) { - this.weights = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * RecentStickerWeightsAction weights. - * @member {Array.} weights - * @memberof proto.RecentStickerWeightsAction - * @instance - */ - RecentStickerWeightsAction.prototype.weights = $util.emptyArray; - - /** - * Creates a new RecentStickerWeightsAction instance using the specified properties. - * @function create - * @memberof proto.RecentStickerWeightsAction - * @static - * @param {proto.IRecentStickerWeightsAction=} [properties] Properties to set - * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction instance - */ - RecentStickerWeightsAction.create = function create(properties) { - return new RecentStickerWeightsAction(properties); - }; - - /** - * Encodes the specified RecentStickerWeightsAction message. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages. - * @function encode - * @memberof proto.RecentStickerWeightsAction - * @static - * @param {proto.IRecentStickerWeightsAction} message RecentStickerWeightsAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - RecentStickerWeightsAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.weights != null && message.weights.length) - for (var i = 0; i < message.weights.length; ++i) - $root.proto.RecentStickerWeight.encode(message.weights[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified RecentStickerWeightsAction message, length delimited. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.RecentStickerWeightsAction - * @static - * @param {proto.IRecentStickerWeightsAction} message RecentStickerWeightsAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - RecentStickerWeightsAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a RecentStickerWeightsAction message from the specified reader or buffer. - * @function decode - * @memberof proto.RecentStickerWeightsAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - RecentStickerWeightsAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentStickerWeightsAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (!(message.weights && message.weights.length)) - message.weights = []; - message.weights.push($root.proto.RecentStickerWeight.decode(reader, reader.uint32())); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a RecentStickerWeightsAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.RecentStickerWeightsAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - RecentStickerWeightsAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a RecentStickerWeightsAction message. - * @function verify - * @memberof proto.RecentStickerWeightsAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - RecentStickerWeightsAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.weights != null && message.hasOwnProperty("weights")) { - if (!Array.isArray(message.weights)) - return "weights: array expected"; - for (var i = 0; i < message.weights.length; ++i) { - var error = $root.proto.RecentStickerWeight.verify(message.weights[i]); - if (error) - return "weights." + error; - } - } - return null; - }; - - /** - * Creates a RecentStickerWeightsAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.RecentStickerWeightsAction - * @static - * @param {Object.} object Plain object - * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction - */ - RecentStickerWeightsAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.RecentStickerWeightsAction) - return object; - var message = new $root.proto.RecentStickerWeightsAction(); - if (object.weights) { - if (!Array.isArray(object.weights)) - throw TypeError(".proto.RecentStickerWeightsAction.weights: array expected"); - message.weights = []; - for (var i = 0; i < object.weights.length; ++i) { - if (typeof object.weights[i] !== "object") - throw TypeError(".proto.RecentStickerWeightsAction.weights: object expected"); - message.weights[i] = $root.proto.RecentStickerWeight.fromObject(object.weights[i]); - } - } - return message; - }; - - /** - * Creates a plain object from a RecentStickerWeightsAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.RecentStickerWeightsAction - * @static - * @param {proto.RecentStickerWeightsAction} message RecentStickerWeightsAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - RecentStickerWeightsAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.weights = []; - if (message.weights && message.weights.length) { - object.weights = []; - for (var j = 0; j < message.weights.length; ++j) - object.weights[j] = $root.proto.RecentStickerWeight.toObject(message.weights[j], options); - } - return object; - }; - - /** - * Converts this RecentStickerWeightsAction to JSON. - * @function toJSON - * @memberof proto.RecentStickerWeightsAction - * @instance - * @returns {Object.} JSON object - */ - RecentStickerWeightsAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return RecentStickerWeightsAction; - })(); - - proto.RecentStickerMetadata = (function() { - - /** - * Properties of a RecentStickerMetadata. - * @memberof proto - * @interface IRecentStickerMetadata - * @property {string|null} [directPath] RecentStickerMetadata directPath - * @property {string|null} [encFilehash] RecentStickerMetadata encFilehash - * @property {string|null} [mediaKey] RecentStickerMetadata mediaKey - * @property {string|null} [stanzaId] RecentStickerMetadata stanzaId - * @property {string|null} [chatJid] RecentStickerMetadata chatJid - * @property {string|null} [participant] RecentStickerMetadata participant - * @property {boolean|null} [isSentByMe] RecentStickerMetadata isSentByMe - */ - - /** - * Constructs a new RecentStickerMetadata. - * @memberof proto - * @classdesc Represents a RecentStickerMetadata. - * @implements IRecentStickerMetadata - * @constructor - * @param {proto.IRecentStickerMetadata=} [properties] Properties to set - */ - function RecentStickerMetadata(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * RecentStickerMetadata directPath. - * @member {string} directPath - * @memberof proto.RecentStickerMetadata - * @instance - */ - RecentStickerMetadata.prototype.directPath = ""; - - /** - * RecentStickerMetadata encFilehash. - * @member {string} encFilehash - * @memberof proto.RecentStickerMetadata - * @instance - */ - RecentStickerMetadata.prototype.encFilehash = ""; - - /** - * RecentStickerMetadata mediaKey. - * @member {string} mediaKey - * @memberof proto.RecentStickerMetadata - * @instance - */ - RecentStickerMetadata.prototype.mediaKey = ""; - - /** - * RecentStickerMetadata stanzaId. - * @member {string} stanzaId - * @memberof proto.RecentStickerMetadata - * @instance - */ - RecentStickerMetadata.prototype.stanzaId = ""; - - /** - * RecentStickerMetadata chatJid. - * @member {string} chatJid - * @memberof proto.RecentStickerMetadata - * @instance - */ - RecentStickerMetadata.prototype.chatJid = ""; - - /** - * RecentStickerMetadata participant. + * MessageKey participant. * @member {string} participant - * @memberof proto.RecentStickerMetadata + * @memberof proto.MessageKey * @instance */ - RecentStickerMetadata.prototype.participant = ""; + MessageKey.prototype.participant = ""; /** - * RecentStickerMetadata isSentByMe. - * @member {boolean} isSentByMe - * @memberof proto.RecentStickerMetadata - * @instance - */ - RecentStickerMetadata.prototype.isSentByMe = false; - - /** - * Creates a new RecentStickerMetadata instance using the specified properties. + * Creates a new MessageKey instance using the specified properties. * @function create - * @memberof proto.RecentStickerMetadata + * @memberof proto.MessageKey * @static - * @param {proto.IRecentStickerMetadata=} [properties] Properties to set - * @returns {proto.RecentStickerMetadata} RecentStickerMetadata instance + * @param {proto.IMessageKey=} [properties] Properties to set + * @returns {proto.MessageKey} MessageKey instance */ - RecentStickerMetadata.create = function create(properties) { - return new RecentStickerMetadata(properties); + MessageKey.create = function create(properties) { + return new MessageKey(properties); }; /** - * Encodes the specified RecentStickerMetadata message. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages. + * Encodes the specified MessageKey message. Does not implicitly {@link proto.MessageKey.verify|verify} messages. * @function encode - * @memberof proto.RecentStickerMetadata + * @memberof proto.MessageKey * @static - * @param {proto.IRecentStickerMetadata} message RecentStickerMetadata message or plain object to encode + * @param {proto.IMessageKey} message MessageKey message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - RecentStickerMetadata.encode = function encode(message, writer) { + MessageKey.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.directPath); - if (message.encFilehash != null && Object.hasOwnProperty.call(message, "encFilehash")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.encFilehash); - if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.mediaKey); - if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId")) - writer.uint32(/* id 4, wireType 2 =*/34).string(message.stanzaId); - if (message.chatJid != null && Object.hasOwnProperty.call(message, "chatJid")) - writer.uint32(/* id 5, wireType 2 =*/42).string(message.chatJid); + if (message.remoteJid != null && Object.hasOwnProperty.call(message, "remoteJid")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.remoteJid); + if (message.fromMe != null && Object.hasOwnProperty.call(message, "fromMe")) + writer.uint32(/* id 2, wireType 0 =*/16).bool(message.fromMe); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.id); if (message.participant != null && Object.hasOwnProperty.call(message, "participant")) - writer.uint32(/* id 6, wireType 2 =*/50).string(message.participant); - if (message.isSentByMe != null && Object.hasOwnProperty.call(message, "isSentByMe")) - writer.uint32(/* id 7, wireType 0 =*/56).bool(message.isSentByMe); + writer.uint32(/* id 4, wireType 2 =*/34).string(message.participant); return writer; }; /** - * Encodes the specified RecentStickerMetadata message, length delimited. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages. + * Encodes the specified MessageKey message, length delimited. Does not implicitly {@link proto.MessageKey.verify|verify} messages. * @function encodeDelimited - * @memberof proto.RecentStickerMetadata + * @memberof proto.MessageKey * @static - * @param {proto.IRecentStickerMetadata} message RecentStickerMetadata message or plain object to encode + * @param {proto.IMessageKey} message MessageKey message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - RecentStickerMetadata.encodeDelimited = function encodeDelimited(message, writer) { + MessageKey.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; /** - * Decodes a RecentStickerMetadata message from the specified reader or buffer. + * Decodes a MessageKey message from the specified reader or buffer. * @function decode - * @memberof proto.RecentStickerMetadata + * @memberof proto.MessageKey * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from * @param {number} [length] Message length if known beforehand - * @returns {proto.RecentStickerMetadata} RecentStickerMetadata + * @returns {proto.MessageKey} MessageKey * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - RecentStickerMetadata.decode = function decode(reader, length) { + MessageKey.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentStickerMetadata(); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MessageKey(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.directPath = reader.string(); + message.remoteJid = reader.string(); break; case 2: - message.encFilehash = reader.string(); + message.fromMe = reader.bool(); break; case 3: - message.mediaKey = reader.string(); + message.id = reader.string(); break; case 4: - message.stanzaId = reader.string(); - break; - case 5: - message.chatJid = reader.string(); - break; - case 6: message.participant = reader.string(); break; - case 7: - message.isSentByMe = reader.bool(); - break; default: reader.skipType(tag & 7); break; @@ -8860,10444 +164,112 @@ $root.proto = (function() { }; /** - * Decodes a RecentStickerMetadata message from the specified reader or buffer, length delimited. + * Decodes a MessageKey message from the specified reader or buffer, length delimited. * @function decodeDelimited - * @memberof proto.RecentStickerMetadata + * @memberof proto.MessageKey * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.RecentStickerMetadata} RecentStickerMetadata + * @returns {proto.MessageKey} MessageKey * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - RecentStickerMetadata.decodeDelimited = function decodeDelimited(reader) { + MessageKey.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; /** - * Verifies a RecentStickerMetadata message. + * Verifies a MessageKey message. * @function verify - * @memberof proto.RecentStickerMetadata + * @memberof proto.MessageKey * @static * @param {Object.} message Plain object to verify * @returns {string|null} `null` if valid, otherwise the reason why it is not */ - RecentStickerMetadata.verify = function verify(message) { + MessageKey.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.directPath != null && message.hasOwnProperty("directPath")) - if (!$util.isString(message.directPath)) - return "directPath: string expected"; - if (message.encFilehash != null && message.hasOwnProperty("encFilehash")) - if (!$util.isString(message.encFilehash)) - return "encFilehash: string expected"; - if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) - if (!$util.isString(message.mediaKey)) - return "mediaKey: string expected"; - if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) - if (!$util.isString(message.stanzaId)) - return "stanzaId: string expected"; - if (message.chatJid != null && message.hasOwnProperty("chatJid")) - if (!$util.isString(message.chatJid)) - return "chatJid: string expected"; + if (message.remoteJid != null && message.hasOwnProperty("remoteJid")) + if (!$util.isString(message.remoteJid)) + return "remoteJid: string expected"; + if (message.fromMe != null && message.hasOwnProperty("fromMe")) + if (typeof message.fromMe !== "boolean") + return "fromMe: boolean expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; if (message.participant != null && message.hasOwnProperty("participant")) if (!$util.isString(message.participant)) return "participant: string expected"; - if (message.isSentByMe != null && message.hasOwnProperty("isSentByMe")) - if (typeof message.isSentByMe !== "boolean") - return "isSentByMe: boolean expected"; return null; }; /** - * Creates a RecentStickerMetadata message from a plain object. Also converts values to their respective internal types. + * Creates a MessageKey message from a plain object. Also converts values to their respective internal types. * @function fromObject - * @memberof proto.RecentStickerMetadata + * @memberof proto.MessageKey * @static * @param {Object.} object Plain object - * @returns {proto.RecentStickerMetadata} RecentStickerMetadata + * @returns {proto.MessageKey} MessageKey */ - RecentStickerMetadata.fromObject = function fromObject(object) { - if (object instanceof $root.proto.RecentStickerMetadata) + MessageKey.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MessageKey) return object; - var message = new $root.proto.RecentStickerMetadata(); - if (object.directPath != null) - message.directPath = String(object.directPath); - if (object.encFilehash != null) - message.encFilehash = String(object.encFilehash); - if (object.mediaKey != null) - message.mediaKey = String(object.mediaKey); - if (object.stanzaId != null) - message.stanzaId = String(object.stanzaId); - if (object.chatJid != null) - message.chatJid = String(object.chatJid); + var message = new $root.proto.MessageKey(); + if (object.remoteJid != null) + message.remoteJid = String(object.remoteJid); + if (object.fromMe != null) + message.fromMe = Boolean(object.fromMe); + if (object.id != null) + message.id = String(object.id); if (object.participant != null) message.participant = String(object.participant); - if (object.isSentByMe != null) - message.isSentByMe = Boolean(object.isSentByMe); return message; }; /** - * Creates a plain object from a RecentStickerMetadata message. Also converts values to other types if specified. + * Creates a plain object from a MessageKey message. Also converts values to other types if specified. * @function toObject - * @memberof proto.RecentStickerMetadata + * @memberof proto.MessageKey * @static - * @param {proto.RecentStickerMetadata} message RecentStickerMetadata + * @param {proto.MessageKey} message MessageKey * @param {$protobuf.IConversionOptions} [options] Conversion options * @returns {Object.} Plain object */ - RecentStickerMetadata.toObject = function toObject(message, options) { + MessageKey.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { - object.directPath = ""; - object.encFilehash = ""; - object.mediaKey = ""; - object.stanzaId = ""; - object.chatJid = ""; + object.remoteJid = ""; + object.fromMe = false; + object.id = ""; object.participant = ""; - object.isSentByMe = false; } - if (message.directPath != null && message.hasOwnProperty("directPath")) - object.directPath = message.directPath; - if (message.encFilehash != null && message.hasOwnProperty("encFilehash")) - object.encFilehash = message.encFilehash; - if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) - object.mediaKey = message.mediaKey; - if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) - object.stanzaId = message.stanzaId; - if (message.chatJid != null && message.hasOwnProperty("chatJid")) - object.chatJid = message.chatJid; + if (message.remoteJid != null && message.hasOwnProperty("remoteJid")) + object.remoteJid = message.remoteJid; + if (message.fromMe != null && message.hasOwnProperty("fromMe")) + object.fromMe = message.fromMe; + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; if (message.participant != null && message.hasOwnProperty("participant")) object.participant = message.participant; - if (message.isSentByMe != null && message.hasOwnProperty("isSentByMe")) - object.isSentByMe = message.isSentByMe; return object; }; /** - * Converts this RecentStickerMetadata to JSON. + * Converts this MessageKey to JSON. * @function toJSON - * @memberof proto.RecentStickerMetadata + * @memberof proto.MessageKey * @instance * @returns {Object.} JSON object */ - RecentStickerMetadata.prototype.toJSON = function toJSON() { + MessageKey.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - return RecentStickerMetadata; - })(); - - proto.RecentEmojiWeightsAction = (function() { - - /** - * Properties of a RecentEmojiWeightsAction. - * @memberof proto - * @interface IRecentEmojiWeightsAction - * @property {Array.|null} [weights] RecentEmojiWeightsAction weights - */ - - /** - * Constructs a new RecentEmojiWeightsAction. - * @memberof proto - * @classdesc Represents a RecentEmojiWeightsAction. - * @implements IRecentEmojiWeightsAction - * @constructor - * @param {proto.IRecentEmojiWeightsAction=} [properties] Properties to set - */ - function RecentEmojiWeightsAction(properties) { - this.weights = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * RecentEmojiWeightsAction weights. - * @member {Array.} weights - * @memberof proto.RecentEmojiWeightsAction - * @instance - */ - RecentEmojiWeightsAction.prototype.weights = $util.emptyArray; - - /** - * Creates a new RecentEmojiWeightsAction instance using the specified properties. - * @function create - * @memberof proto.RecentEmojiWeightsAction - * @static - * @param {proto.IRecentEmojiWeightsAction=} [properties] Properties to set - * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction instance - */ - RecentEmojiWeightsAction.create = function create(properties) { - return new RecentEmojiWeightsAction(properties); - }; - - /** - * Encodes the specified RecentEmojiWeightsAction message. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages. - * @function encode - * @memberof proto.RecentEmojiWeightsAction - * @static - * @param {proto.IRecentEmojiWeightsAction} message RecentEmojiWeightsAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - RecentEmojiWeightsAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.weights != null && message.weights.length) - for (var i = 0; i < message.weights.length; ++i) - $root.proto.RecentEmojiWeight.encode(message.weights[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified RecentEmojiWeightsAction message, length delimited. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.RecentEmojiWeightsAction - * @static - * @param {proto.IRecentEmojiWeightsAction} message RecentEmojiWeightsAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - RecentEmojiWeightsAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer. - * @function decode - * @memberof proto.RecentEmojiWeightsAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - RecentEmojiWeightsAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentEmojiWeightsAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (!(message.weights && message.weights.length)) - message.weights = []; - message.weights.push($root.proto.RecentEmojiWeight.decode(reader, reader.uint32())); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.RecentEmojiWeightsAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - RecentEmojiWeightsAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a RecentEmojiWeightsAction message. - * @function verify - * @memberof proto.RecentEmojiWeightsAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - RecentEmojiWeightsAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.weights != null && message.hasOwnProperty("weights")) { - if (!Array.isArray(message.weights)) - return "weights: array expected"; - for (var i = 0; i < message.weights.length; ++i) { - var error = $root.proto.RecentEmojiWeight.verify(message.weights[i]); - if (error) - return "weights." + error; - } - } - return null; - }; - - /** - * Creates a RecentEmojiWeightsAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.RecentEmojiWeightsAction - * @static - * @param {Object.} object Plain object - * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction - */ - RecentEmojiWeightsAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.RecentEmojiWeightsAction) - return object; - var message = new $root.proto.RecentEmojiWeightsAction(); - if (object.weights) { - if (!Array.isArray(object.weights)) - throw TypeError(".proto.RecentEmojiWeightsAction.weights: array expected"); - message.weights = []; - for (var i = 0; i < object.weights.length; ++i) { - if (typeof object.weights[i] !== "object") - throw TypeError(".proto.RecentEmojiWeightsAction.weights: object expected"); - message.weights[i] = $root.proto.RecentEmojiWeight.fromObject(object.weights[i]); - } - } - return message; - }; - - /** - * Creates a plain object from a RecentEmojiWeightsAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.RecentEmojiWeightsAction - * @static - * @param {proto.RecentEmojiWeightsAction} message RecentEmojiWeightsAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - RecentEmojiWeightsAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.weights = []; - if (message.weights && message.weights.length) { - object.weights = []; - for (var j = 0; j < message.weights.length; ++j) - object.weights[j] = $root.proto.RecentEmojiWeight.toObject(message.weights[j], options); - } - return object; - }; - - /** - * Converts this RecentEmojiWeightsAction to JSON. - * @function toJSON - * @memberof proto.RecentEmojiWeightsAction - * @instance - * @returns {Object.} JSON object - */ - RecentEmojiWeightsAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return RecentEmojiWeightsAction; - })(); - - proto.ArchiveChatAction = (function() { - - /** - * Properties of an ArchiveChatAction. - * @memberof proto - * @interface IArchiveChatAction - * @property {boolean|null} [archived] ArchiveChatAction archived - * @property {proto.ISyncActionMessageRange|null} [messageRange] ArchiveChatAction messageRange - */ - - /** - * Constructs a new ArchiveChatAction. - * @memberof proto - * @classdesc Represents an ArchiveChatAction. - * @implements IArchiveChatAction - * @constructor - * @param {proto.IArchiveChatAction=} [properties] Properties to set - */ - function ArchiveChatAction(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ArchiveChatAction archived. - * @member {boolean} archived - * @memberof proto.ArchiveChatAction - * @instance - */ - ArchiveChatAction.prototype.archived = false; - - /** - * ArchiveChatAction messageRange. - * @member {proto.ISyncActionMessageRange|null|undefined} messageRange - * @memberof proto.ArchiveChatAction - * @instance - */ - ArchiveChatAction.prototype.messageRange = null; - - /** - * Creates a new ArchiveChatAction instance using the specified properties. - * @function create - * @memberof proto.ArchiveChatAction - * @static - * @param {proto.IArchiveChatAction=} [properties] Properties to set - * @returns {proto.ArchiveChatAction} ArchiveChatAction instance - */ - ArchiveChatAction.create = function create(properties) { - return new ArchiveChatAction(properties); - }; - - /** - * Encodes the specified ArchiveChatAction message. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages. - * @function encode - * @memberof proto.ArchiveChatAction - * @static - * @param {proto.IArchiveChatAction} message ArchiveChatAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ArchiveChatAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.archived != null && Object.hasOwnProperty.call(message, "archived")) - writer.uint32(/* id 1, wireType 0 =*/8).bool(message.archived); - if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange")) - $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified ArchiveChatAction message, length delimited. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ArchiveChatAction - * @static - * @param {proto.IArchiveChatAction} message ArchiveChatAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ArchiveChatAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes an ArchiveChatAction message from the specified reader or buffer. - * @function decode - * @memberof proto.ArchiveChatAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ArchiveChatAction} ArchiveChatAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ArchiveChatAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ArchiveChatAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.archived = reader.bool(); - break; - case 2: - message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes an ArchiveChatAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ArchiveChatAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ArchiveChatAction} ArchiveChatAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ArchiveChatAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies an ArchiveChatAction message. - * @function verify - * @memberof proto.ArchiveChatAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ArchiveChatAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.archived != null && message.hasOwnProperty("archived")) - if (typeof message.archived !== "boolean") - return "archived: boolean expected"; - if (message.messageRange != null && message.hasOwnProperty("messageRange")) { - var error = $root.proto.SyncActionMessageRange.verify(message.messageRange); - if (error) - return "messageRange." + error; - } - return null; - }; - - /** - * Creates an ArchiveChatAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ArchiveChatAction - * @static - * @param {Object.} object Plain object - * @returns {proto.ArchiveChatAction} ArchiveChatAction - */ - ArchiveChatAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ArchiveChatAction) - return object; - var message = new $root.proto.ArchiveChatAction(); - if (object.archived != null) - message.archived = Boolean(object.archived); - if (object.messageRange != null) { - if (typeof object.messageRange !== "object") - throw TypeError(".proto.ArchiveChatAction.messageRange: object expected"); - message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange); - } - return message; - }; - - /** - * Creates a plain object from an ArchiveChatAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ArchiveChatAction - * @static - * @param {proto.ArchiveChatAction} message ArchiveChatAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ArchiveChatAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.archived = false; - object.messageRange = null; - } - if (message.archived != null && message.hasOwnProperty("archived")) - object.archived = message.archived; - if (message.messageRange != null && message.hasOwnProperty("messageRange")) - object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options); - return object; - }; - - /** - * Converts this ArchiveChatAction to JSON. - * @function toJSON - * @memberof proto.ArchiveChatAction - * @instance - * @returns {Object.} JSON object - */ - ArchiveChatAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ArchiveChatAction; - })(); - - proto.DeleteMessageForMeAction = (function() { - - /** - * Properties of a DeleteMessageForMeAction. - * @memberof proto - * @interface IDeleteMessageForMeAction - * @property {boolean|null} [deleteMedia] DeleteMessageForMeAction deleteMedia - * @property {number|Long|null} [messageTimestamp] DeleteMessageForMeAction messageTimestamp - */ - - /** - * Constructs a new DeleteMessageForMeAction. - * @memberof proto - * @classdesc Represents a DeleteMessageForMeAction. - * @implements IDeleteMessageForMeAction - * @constructor - * @param {proto.IDeleteMessageForMeAction=} [properties] Properties to set - */ - function DeleteMessageForMeAction(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * DeleteMessageForMeAction deleteMedia. - * @member {boolean} deleteMedia - * @memberof proto.DeleteMessageForMeAction - * @instance - */ - DeleteMessageForMeAction.prototype.deleteMedia = false; - - /** - * DeleteMessageForMeAction messageTimestamp. - * @member {number|Long} messageTimestamp - * @memberof proto.DeleteMessageForMeAction - * @instance - */ - DeleteMessageForMeAction.prototype.messageTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * Creates a new DeleteMessageForMeAction instance using the specified properties. - * @function create - * @memberof proto.DeleteMessageForMeAction - * @static - * @param {proto.IDeleteMessageForMeAction=} [properties] Properties to set - * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction instance - */ - DeleteMessageForMeAction.create = function create(properties) { - return new DeleteMessageForMeAction(properties); - }; - - /** - * Encodes the specified DeleteMessageForMeAction message. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages. - * @function encode - * @memberof proto.DeleteMessageForMeAction - * @static - * @param {proto.IDeleteMessageForMeAction} message DeleteMessageForMeAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - DeleteMessageForMeAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.deleteMedia != null && Object.hasOwnProperty.call(message, "deleteMedia")) - writer.uint32(/* id 1, wireType 0 =*/8).bool(message.deleteMedia); - if (message.messageTimestamp != null && Object.hasOwnProperty.call(message, "messageTimestamp")) - writer.uint32(/* id 2, wireType 0 =*/16).int64(message.messageTimestamp); - return writer; - }; - - /** - * Encodes the specified DeleteMessageForMeAction message, length delimited. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.DeleteMessageForMeAction - * @static - * @param {proto.IDeleteMessageForMeAction} message DeleteMessageForMeAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - DeleteMessageForMeAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a DeleteMessageForMeAction message from the specified reader or buffer. - * @function decode - * @memberof proto.DeleteMessageForMeAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - DeleteMessageForMeAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DeleteMessageForMeAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.deleteMedia = reader.bool(); - break; - case 2: - message.messageTimestamp = reader.int64(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a DeleteMessageForMeAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.DeleteMessageForMeAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - DeleteMessageForMeAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a DeleteMessageForMeAction message. - * @function verify - * @memberof proto.DeleteMessageForMeAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - DeleteMessageForMeAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.deleteMedia != null && message.hasOwnProperty("deleteMedia")) - if (typeof message.deleteMedia !== "boolean") - return "deleteMedia: boolean expected"; - if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) - if (!$util.isInteger(message.messageTimestamp) && !(message.messageTimestamp && $util.isInteger(message.messageTimestamp.low) && $util.isInteger(message.messageTimestamp.high))) - return "messageTimestamp: integer|Long expected"; - return null; - }; - - /** - * Creates a DeleteMessageForMeAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.DeleteMessageForMeAction - * @static - * @param {Object.} object Plain object - * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction - */ - DeleteMessageForMeAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.DeleteMessageForMeAction) - return object; - var message = new $root.proto.DeleteMessageForMeAction(); - if (object.deleteMedia != null) - message.deleteMedia = Boolean(object.deleteMedia); - if (object.messageTimestamp != null) - if ($util.Long) - (message.messageTimestamp = $util.Long.fromValue(object.messageTimestamp)).unsigned = false; - else if (typeof object.messageTimestamp === "string") - message.messageTimestamp = parseInt(object.messageTimestamp, 10); - else if (typeof object.messageTimestamp === "number") - message.messageTimestamp = object.messageTimestamp; - else if (typeof object.messageTimestamp === "object") - message.messageTimestamp = new $util.LongBits(object.messageTimestamp.low >>> 0, object.messageTimestamp.high >>> 0).toNumber(); - return message; - }; - - /** - * Creates a plain object from a DeleteMessageForMeAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.DeleteMessageForMeAction - * @static - * @param {proto.DeleteMessageForMeAction} message DeleteMessageForMeAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - DeleteMessageForMeAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.deleteMedia = false; - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.messageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.messageTimestamp = options.longs === String ? "0" : 0; - } - if (message.deleteMedia != null && message.hasOwnProperty("deleteMedia")) - object.deleteMedia = message.deleteMedia; - if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) - if (typeof message.messageTimestamp === "number") - object.messageTimestamp = options.longs === String ? String(message.messageTimestamp) : message.messageTimestamp; - else - object.messageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.messageTimestamp) : options.longs === Number ? new $util.LongBits(message.messageTimestamp.low >>> 0, message.messageTimestamp.high >>> 0).toNumber() : message.messageTimestamp; - return object; - }; - - /** - * Converts this DeleteMessageForMeAction to JSON. - * @function toJSON - * @memberof proto.DeleteMessageForMeAction - * @instance - * @returns {Object.} JSON object - */ - DeleteMessageForMeAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return DeleteMessageForMeAction; - })(); - - proto.MarkChatAsReadAction = (function() { - - /** - * Properties of a MarkChatAsReadAction. - * @memberof proto - * @interface IMarkChatAsReadAction - * @property {boolean|null} [read] MarkChatAsReadAction read - * @property {proto.ISyncActionMessageRange|null} [messageRange] MarkChatAsReadAction messageRange - */ - - /** - * Constructs a new MarkChatAsReadAction. - * @memberof proto - * @classdesc Represents a MarkChatAsReadAction. - * @implements IMarkChatAsReadAction - * @constructor - * @param {proto.IMarkChatAsReadAction=} [properties] Properties to set - */ - function MarkChatAsReadAction(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * MarkChatAsReadAction read. - * @member {boolean} read - * @memberof proto.MarkChatAsReadAction - * @instance - */ - MarkChatAsReadAction.prototype.read = false; - - /** - * MarkChatAsReadAction messageRange. - * @member {proto.ISyncActionMessageRange|null|undefined} messageRange - * @memberof proto.MarkChatAsReadAction - * @instance - */ - MarkChatAsReadAction.prototype.messageRange = null; - - /** - * Creates a new MarkChatAsReadAction instance using the specified properties. - * @function create - * @memberof proto.MarkChatAsReadAction - * @static - * @param {proto.IMarkChatAsReadAction=} [properties] Properties to set - * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction instance - */ - MarkChatAsReadAction.create = function create(properties) { - return new MarkChatAsReadAction(properties); - }; - - /** - * Encodes the specified MarkChatAsReadAction message. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages. - * @function encode - * @memberof proto.MarkChatAsReadAction - * @static - * @param {proto.IMarkChatAsReadAction} message MarkChatAsReadAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - MarkChatAsReadAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.read != null && Object.hasOwnProperty.call(message, "read")) - writer.uint32(/* id 1, wireType 0 =*/8).bool(message.read); - if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange")) - $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified MarkChatAsReadAction message, length delimited. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.MarkChatAsReadAction - * @static - * @param {proto.IMarkChatAsReadAction} message MarkChatAsReadAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - MarkChatAsReadAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a MarkChatAsReadAction message from the specified reader or buffer. - * @function decode - * @memberof proto.MarkChatAsReadAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - MarkChatAsReadAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MarkChatAsReadAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.read = reader.bool(); - break; - case 2: - message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a MarkChatAsReadAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.MarkChatAsReadAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - MarkChatAsReadAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a MarkChatAsReadAction message. - * @function verify - * @memberof proto.MarkChatAsReadAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - MarkChatAsReadAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.read != null && message.hasOwnProperty("read")) - if (typeof message.read !== "boolean") - return "read: boolean expected"; - if (message.messageRange != null && message.hasOwnProperty("messageRange")) { - var error = $root.proto.SyncActionMessageRange.verify(message.messageRange); - if (error) - return "messageRange." + error; - } - return null; - }; - - /** - * Creates a MarkChatAsReadAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.MarkChatAsReadAction - * @static - * @param {Object.} object Plain object - * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction - */ - MarkChatAsReadAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.MarkChatAsReadAction) - return object; - var message = new $root.proto.MarkChatAsReadAction(); - if (object.read != null) - message.read = Boolean(object.read); - if (object.messageRange != null) { - if (typeof object.messageRange !== "object") - throw TypeError(".proto.MarkChatAsReadAction.messageRange: object expected"); - message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange); - } - return message; - }; - - /** - * Creates a plain object from a MarkChatAsReadAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.MarkChatAsReadAction - * @static - * @param {proto.MarkChatAsReadAction} message MarkChatAsReadAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - MarkChatAsReadAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.read = false; - object.messageRange = null; - } - if (message.read != null && message.hasOwnProperty("read")) - object.read = message.read; - if (message.messageRange != null && message.hasOwnProperty("messageRange")) - object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options); - return object; - }; - - /** - * Converts this MarkChatAsReadAction to JSON. - * @function toJSON - * @memberof proto.MarkChatAsReadAction - * @instance - * @returns {Object.} JSON object - */ - MarkChatAsReadAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return MarkChatAsReadAction; - })(); - - proto.ClearChatAction = (function() { - - /** - * Properties of a ClearChatAction. - * @memberof proto - * @interface IClearChatAction - * @property {proto.ISyncActionMessageRange|null} [messageRange] ClearChatAction messageRange - */ - - /** - * Constructs a new ClearChatAction. - * @memberof proto - * @classdesc Represents a ClearChatAction. - * @implements IClearChatAction - * @constructor - * @param {proto.IClearChatAction=} [properties] Properties to set - */ - function ClearChatAction(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ClearChatAction messageRange. - * @member {proto.ISyncActionMessageRange|null|undefined} messageRange - * @memberof proto.ClearChatAction - * @instance - */ - ClearChatAction.prototype.messageRange = null; - - /** - * Creates a new ClearChatAction instance using the specified properties. - * @function create - * @memberof proto.ClearChatAction - * @static - * @param {proto.IClearChatAction=} [properties] Properties to set - * @returns {proto.ClearChatAction} ClearChatAction instance - */ - ClearChatAction.create = function create(properties) { - return new ClearChatAction(properties); - }; - - /** - * Encodes the specified ClearChatAction message. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages. - * @function encode - * @memberof proto.ClearChatAction - * @static - * @param {proto.IClearChatAction} message ClearChatAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ClearChatAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange")) - $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified ClearChatAction message, length delimited. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ClearChatAction - * @static - * @param {proto.IClearChatAction} message ClearChatAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ClearChatAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ClearChatAction message from the specified reader or buffer. - * @function decode - * @memberof proto.ClearChatAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ClearChatAction} ClearChatAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ClearChatAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClearChatAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ClearChatAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ClearChatAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ClearChatAction} ClearChatAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ClearChatAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ClearChatAction message. - * @function verify - * @memberof proto.ClearChatAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ClearChatAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.messageRange != null && message.hasOwnProperty("messageRange")) { - var error = $root.proto.SyncActionMessageRange.verify(message.messageRange); - if (error) - return "messageRange." + error; - } - return null; - }; - - /** - * Creates a ClearChatAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ClearChatAction - * @static - * @param {Object.} object Plain object - * @returns {proto.ClearChatAction} ClearChatAction - */ - ClearChatAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ClearChatAction) - return object; - var message = new $root.proto.ClearChatAction(); - if (object.messageRange != null) { - if (typeof object.messageRange !== "object") - throw TypeError(".proto.ClearChatAction.messageRange: object expected"); - message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange); - } - return message; - }; - - /** - * Creates a plain object from a ClearChatAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ClearChatAction - * @static - * @param {proto.ClearChatAction} message ClearChatAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ClearChatAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.messageRange = null; - if (message.messageRange != null && message.hasOwnProperty("messageRange")) - object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options); - return object; - }; - - /** - * Converts this ClearChatAction to JSON. - * @function toJSON - * @memberof proto.ClearChatAction - * @instance - * @returns {Object.} JSON object - */ - ClearChatAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ClearChatAction; - })(); - - proto.DeleteChatAction = (function() { - - /** - * Properties of a DeleteChatAction. - * @memberof proto - * @interface IDeleteChatAction - * @property {proto.ISyncActionMessageRange|null} [messageRange] DeleteChatAction messageRange - */ - - /** - * Constructs a new DeleteChatAction. - * @memberof proto - * @classdesc Represents a DeleteChatAction. - * @implements IDeleteChatAction - * @constructor - * @param {proto.IDeleteChatAction=} [properties] Properties to set - */ - function DeleteChatAction(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * DeleteChatAction messageRange. - * @member {proto.ISyncActionMessageRange|null|undefined} messageRange - * @memberof proto.DeleteChatAction - * @instance - */ - DeleteChatAction.prototype.messageRange = null; - - /** - * Creates a new DeleteChatAction instance using the specified properties. - * @function create - * @memberof proto.DeleteChatAction - * @static - * @param {proto.IDeleteChatAction=} [properties] Properties to set - * @returns {proto.DeleteChatAction} DeleteChatAction instance - */ - DeleteChatAction.create = function create(properties) { - return new DeleteChatAction(properties); - }; - - /** - * Encodes the specified DeleteChatAction message. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages. - * @function encode - * @memberof proto.DeleteChatAction - * @static - * @param {proto.IDeleteChatAction} message DeleteChatAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - DeleteChatAction.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange")) - $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified DeleteChatAction message, length delimited. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.DeleteChatAction - * @static - * @param {proto.IDeleteChatAction} message DeleteChatAction message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - DeleteChatAction.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a DeleteChatAction message from the specified reader or buffer. - * @function decode - * @memberof proto.DeleteChatAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.DeleteChatAction} DeleteChatAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - DeleteChatAction.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DeleteChatAction(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a DeleteChatAction message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.DeleteChatAction - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.DeleteChatAction} DeleteChatAction - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - DeleteChatAction.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a DeleteChatAction message. - * @function verify - * @memberof proto.DeleteChatAction - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - DeleteChatAction.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.messageRange != null && message.hasOwnProperty("messageRange")) { - var error = $root.proto.SyncActionMessageRange.verify(message.messageRange); - if (error) - return "messageRange." + error; - } - return null; - }; - - /** - * Creates a DeleteChatAction message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.DeleteChatAction - * @static - * @param {Object.} object Plain object - * @returns {proto.DeleteChatAction} DeleteChatAction - */ - DeleteChatAction.fromObject = function fromObject(object) { - if (object instanceof $root.proto.DeleteChatAction) - return object; - var message = new $root.proto.DeleteChatAction(); - if (object.messageRange != null) { - if (typeof object.messageRange !== "object") - throw TypeError(".proto.DeleteChatAction.messageRange: object expected"); - message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange); - } - return message; - }; - - /** - * Creates a plain object from a DeleteChatAction message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.DeleteChatAction - * @static - * @param {proto.DeleteChatAction} message DeleteChatAction - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - DeleteChatAction.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.messageRange = null; - if (message.messageRange != null && message.hasOwnProperty("messageRange")) - object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options); - return object; - }; - - /** - * Converts this DeleteChatAction to JSON. - * @function toJSON - * @memberof proto.DeleteChatAction - * @instance - * @returns {Object.} JSON object - */ - DeleteChatAction.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return DeleteChatAction; - })(); - - proto.UnarchiveChatsSetting = (function() { - - /** - * Properties of an UnarchiveChatsSetting. - * @memberof proto - * @interface IUnarchiveChatsSetting - * @property {boolean|null} [unarchiveChats] UnarchiveChatsSetting unarchiveChats - */ - - /** - * Constructs a new UnarchiveChatsSetting. - * @memberof proto - * @classdesc Represents an UnarchiveChatsSetting. - * @implements IUnarchiveChatsSetting - * @constructor - * @param {proto.IUnarchiveChatsSetting=} [properties] Properties to set - */ - function UnarchiveChatsSetting(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * UnarchiveChatsSetting unarchiveChats. - * @member {boolean} unarchiveChats - * @memberof proto.UnarchiveChatsSetting - * @instance - */ - UnarchiveChatsSetting.prototype.unarchiveChats = false; - - /** - * Creates a new UnarchiveChatsSetting instance using the specified properties. - * @function create - * @memberof proto.UnarchiveChatsSetting - * @static - * @param {proto.IUnarchiveChatsSetting=} [properties] Properties to set - * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting instance - */ - UnarchiveChatsSetting.create = function create(properties) { - return new UnarchiveChatsSetting(properties); - }; - - /** - * Encodes the specified UnarchiveChatsSetting message. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages. - * @function encode - * @memberof proto.UnarchiveChatsSetting - * @static - * @param {proto.IUnarchiveChatsSetting} message UnarchiveChatsSetting message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - UnarchiveChatsSetting.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.unarchiveChats != null && Object.hasOwnProperty.call(message, "unarchiveChats")) - writer.uint32(/* id 1, wireType 0 =*/8).bool(message.unarchiveChats); - return writer; - }; - - /** - * Encodes the specified UnarchiveChatsSetting message, length delimited. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.UnarchiveChatsSetting - * @static - * @param {proto.IUnarchiveChatsSetting} message UnarchiveChatsSetting message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - UnarchiveChatsSetting.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes an UnarchiveChatsSetting message from the specified reader or buffer. - * @function decode - * @memberof proto.UnarchiveChatsSetting - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - UnarchiveChatsSetting.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.UnarchiveChatsSetting(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.unarchiveChats = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes an UnarchiveChatsSetting message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.UnarchiveChatsSetting - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - UnarchiveChatsSetting.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies an UnarchiveChatsSetting message. - * @function verify - * @memberof proto.UnarchiveChatsSetting - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - UnarchiveChatsSetting.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.unarchiveChats != null && message.hasOwnProperty("unarchiveChats")) - if (typeof message.unarchiveChats !== "boolean") - return "unarchiveChats: boolean expected"; - return null; - }; - - /** - * Creates an UnarchiveChatsSetting message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.UnarchiveChatsSetting - * @static - * @param {Object.} object Plain object - * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting - */ - UnarchiveChatsSetting.fromObject = function fromObject(object) { - if (object instanceof $root.proto.UnarchiveChatsSetting) - return object; - var message = new $root.proto.UnarchiveChatsSetting(); - if (object.unarchiveChats != null) - message.unarchiveChats = Boolean(object.unarchiveChats); - return message; - }; - - /** - * Creates a plain object from an UnarchiveChatsSetting message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.UnarchiveChatsSetting - * @static - * @param {proto.UnarchiveChatsSetting} message UnarchiveChatsSetting - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - UnarchiveChatsSetting.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.unarchiveChats = false; - if (message.unarchiveChats != null && message.hasOwnProperty("unarchiveChats")) - object.unarchiveChats = message.unarchiveChats; - return object; - }; - - /** - * Converts this UnarchiveChatsSetting to JSON. - * @function toJSON - * @memberof proto.UnarchiveChatsSetting - * @instance - * @returns {Object.} JSON object - */ - UnarchiveChatsSetting.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return UnarchiveChatsSetting; - })(); - - proto.SyncActionMessageRange = (function() { - - /** - * Properties of a SyncActionMessageRange. - * @memberof proto - * @interface ISyncActionMessageRange - * @property {number|Long|null} [lastMessageTimestamp] SyncActionMessageRange lastMessageTimestamp - * @property {number|Long|null} [lastSystemMessageTimestamp] SyncActionMessageRange lastSystemMessageTimestamp - * @property {Array.|null} [messages] SyncActionMessageRange messages - */ - - /** - * Constructs a new SyncActionMessageRange. - * @memberof proto - * @classdesc Represents a SyncActionMessageRange. - * @implements ISyncActionMessageRange - * @constructor - * @param {proto.ISyncActionMessageRange=} [properties] Properties to set - */ - function SyncActionMessageRange(properties) { - this.messages = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SyncActionMessageRange lastMessageTimestamp. - * @member {number|Long} lastMessageTimestamp - * @memberof proto.SyncActionMessageRange - * @instance - */ - SyncActionMessageRange.prototype.lastMessageTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * SyncActionMessageRange lastSystemMessageTimestamp. - * @member {number|Long} lastSystemMessageTimestamp - * @memberof proto.SyncActionMessageRange - * @instance - */ - SyncActionMessageRange.prototype.lastSystemMessageTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * SyncActionMessageRange messages. - * @member {Array.} messages - * @memberof proto.SyncActionMessageRange - * @instance - */ - SyncActionMessageRange.prototype.messages = $util.emptyArray; - - /** - * Creates a new SyncActionMessageRange instance using the specified properties. - * @function create - * @memberof proto.SyncActionMessageRange - * @static - * @param {proto.ISyncActionMessageRange=} [properties] Properties to set - * @returns {proto.SyncActionMessageRange} SyncActionMessageRange instance - */ - SyncActionMessageRange.create = function create(properties) { - return new SyncActionMessageRange(properties); - }; - - /** - * Encodes the specified SyncActionMessageRange message. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages. - * @function encode - * @memberof proto.SyncActionMessageRange - * @static - * @param {proto.ISyncActionMessageRange} message SyncActionMessageRange message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncActionMessageRange.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.lastMessageTimestamp != null && Object.hasOwnProperty.call(message, "lastMessageTimestamp")) - writer.uint32(/* id 1, wireType 0 =*/8).int64(message.lastMessageTimestamp); - if (message.lastSystemMessageTimestamp != null && Object.hasOwnProperty.call(message, "lastSystemMessageTimestamp")) - writer.uint32(/* id 2, wireType 0 =*/16).int64(message.lastSystemMessageTimestamp); - if (message.messages != null && message.messages.length) - for (var i = 0; i < message.messages.length; ++i) - $root.proto.SyncActionMessage.encode(message.messages[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified SyncActionMessageRange message, length delimited. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SyncActionMessageRange - * @static - * @param {proto.ISyncActionMessageRange} message SyncActionMessageRange message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncActionMessageRange.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SyncActionMessageRange message from the specified reader or buffer. - * @function decode - * @memberof proto.SyncActionMessageRange - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SyncActionMessageRange} SyncActionMessageRange - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncActionMessageRange.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionMessageRange(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.lastMessageTimestamp = reader.int64(); - break; - case 2: - message.lastSystemMessageTimestamp = reader.int64(); - break; - case 3: - if (!(message.messages && message.messages.length)) - message.messages = []; - message.messages.push($root.proto.SyncActionMessage.decode(reader, reader.uint32())); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SyncActionMessageRange message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SyncActionMessageRange - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SyncActionMessageRange} SyncActionMessageRange - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncActionMessageRange.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SyncActionMessageRange message. - * @function verify - * @memberof proto.SyncActionMessageRange - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SyncActionMessageRange.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.lastMessageTimestamp != null && message.hasOwnProperty("lastMessageTimestamp")) - if (!$util.isInteger(message.lastMessageTimestamp) && !(message.lastMessageTimestamp && $util.isInteger(message.lastMessageTimestamp.low) && $util.isInteger(message.lastMessageTimestamp.high))) - return "lastMessageTimestamp: integer|Long expected"; - if (message.lastSystemMessageTimestamp != null && message.hasOwnProperty("lastSystemMessageTimestamp")) - if (!$util.isInteger(message.lastSystemMessageTimestamp) && !(message.lastSystemMessageTimestamp && $util.isInteger(message.lastSystemMessageTimestamp.low) && $util.isInteger(message.lastSystemMessageTimestamp.high))) - return "lastSystemMessageTimestamp: integer|Long expected"; - if (message.messages != null && message.hasOwnProperty("messages")) { - if (!Array.isArray(message.messages)) - return "messages: array expected"; - for (var i = 0; i < message.messages.length; ++i) { - var error = $root.proto.SyncActionMessage.verify(message.messages[i]); - if (error) - return "messages." + error; - } - } - return null; - }; - - /** - * Creates a SyncActionMessageRange message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SyncActionMessageRange - * @static - * @param {Object.} object Plain object - * @returns {proto.SyncActionMessageRange} SyncActionMessageRange - */ - SyncActionMessageRange.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SyncActionMessageRange) - return object; - var message = new $root.proto.SyncActionMessageRange(); - if (object.lastMessageTimestamp != null) - if ($util.Long) - (message.lastMessageTimestamp = $util.Long.fromValue(object.lastMessageTimestamp)).unsigned = false; - else if (typeof object.lastMessageTimestamp === "string") - message.lastMessageTimestamp = parseInt(object.lastMessageTimestamp, 10); - else if (typeof object.lastMessageTimestamp === "number") - message.lastMessageTimestamp = object.lastMessageTimestamp; - else if (typeof object.lastMessageTimestamp === "object") - message.lastMessageTimestamp = new $util.LongBits(object.lastMessageTimestamp.low >>> 0, object.lastMessageTimestamp.high >>> 0).toNumber(); - if (object.lastSystemMessageTimestamp != null) - if ($util.Long) - (message.lastSystemMessageTimestamp = $util.Long.fromValue(object.lastSystemMessageTimestamp)).unsigned = false; - else if (typeof object.lastSystemMessageTimestamp === "string") - message.lastSystemMessageTimestamp = parseInt(object.lastSystemMessageTimestamp, 10); - else if (typeof object.lastSystemMessageTimestamp === "number") - message.lastSystemMessageTimestamp = object.lastSystemMessageTimestamp; - else if (typeof object.lastSystemMessageTimestamp === "object") - message.lastSystemMessageTimestamp = new $util.LongBits(object.lastSystemMessageTimestamp.low >>> 0, object.lastSystemMessageTimestamp.high >>> 0).toNumber(); - if (object.messages) { - if (!Array.isArray(object.messages)) - throw TypeError(".proto.SyncActionMessageRange.messages: array expected"); - message.messages = []; - for (var i = 0; i < object.messages.length; ++i) { - if (typeof object.messages[i] !== "object") - throw TypeError(".proto.SyncActionMessageRange.messages: object expected"); - message.messages[i] = $root.proto.SyncActionMessage.fromObject(object.messages[i]); - } - } - return message; - }; - - /** - * Creates a plain object from a SyncActionMessageRange message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SyncActionMessageRange - * @static - * @param {proto.SyncActionMessageRange} message SyncActionMessageRange - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SyncActionMessageRange.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.messages = []; - if (options.defaults) { - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.lastMessageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.lastMessageTimestamp = options.longs === String ? "0" : 0; - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.lastSystemMessageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.lastSystemMessageTimestamp = options.longs === String ? "0" : 0; - } - if (message.lastMessageTimestamp != null && message.hasOwnProperty("lastMessageTimestamp")) - if (typeof message.lastMessageTimestamp === "number") - object.lastMessageTimestamp = options.longs === String ? String(message.lastMessageTimestamp) : message.lastMessageTimestamp; - else - object.lastMessageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.lastMessageTimestamp) : options.longs === Number ? new $util.LongBits(message.lastMessageTimestamp.low >>> 0, message.lastMessageTimestamp.high >>> 0).toNumber() : message.lastMessageTimestamp; - if (message.lastSystemMessageTimestamp != null && message.hasOwnProperty("lastSystemMessageTimestamp")) - if (typeof message.lastSystemMessageTimestamp === "number") - object.lastSystemMessageTimestamp = options.longs === String ? String(message.lastSystemMessageTimestamp) : message.lastSystemMessageTimestamp; - else - object.lastSystemMessageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.lastSystemMessageTimestamp) : options.longs === Number ? new $util.LongBits(message.lastSystemMessageTimestamp.low >>> 0, message.lastSystemMessageTimestamp.high >>> 0).toNumber() : message.lastSystemMessageTimestamp; - if (message.messages && message.messages.length) { - object.messages = []; - for (var j = 0; j < message.messages.length; ++j) - object.messages[j] = $root.proto.SyncActionMessage.toObject(message.messages[j], options); - } - return object; - }; - - /** - * Converts this SyncActionMessageRange to JSON. - * @function toJSON - * @memberof proto.SyncActionMessageRange - * @instance - * @returns {Object.} JSON object - */ - SyncActionMessageRange.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SyncActionMessageRange; - })(); - - proto.SyncActionMessage = (function() { - - /** - * Properties of a SyncActionMessage. - * @memberof proto - * @interface ISyncActionMessage - * @property {proto.IMessageKey|null} [key] SyncActionMessage key - * @property {number|Long|null} [timestamp] SyncActionMessage timestamp - */ - - /** - * Constructs a new SyncActionMessage. - * @memberof proto - * @classdesc Represents a SyncActionMessage. - * @implements ISyncActionMessage - * @constructor - * @param {proto.ISyncActionMessage=} [properties] Properties to set - */ - function SyncActionMessage(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SyncActionMessage key. - * @member {proto.IMessageKey|null|undefined} key - * @memberof proto.SyncActionMessage - * @instance - */ - SyncActionMessage.prototype.key = null; - - /** - * SyncActionMessage timestamp. - * @member {number|Long} timestamp - * @memberof proto.SyncActionMessage - * @instance - */ - SyncActionMessage.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * Creates a new SyncActionMessage instance using the specified properties. - * @function create - * @memberof proto.SyncActionMessage - * @static - * @param {proto.ISyncActionMessage=} [properties] Properties to set - * @returns {proto.SyncActionMessage} SyncActionMessage instance - */ - SyncActionMessage.create = function create(properties) { - return new SyncActionMessage(properties); - }; - - /** - * Encodes the specified SyncActionMessage message. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages. - * @function encode - * @memberof proto.SyncActionMessage - * @static - * @param {proto.ISyncActionMessage} message SyncActionMessage message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncActionMessage.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.key != null && Object.hasOwnProperty.call(message, "key")) - $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) - writer.uint32(/* id 2, wireType 0 =*/16).int64(message.timestamp); - return writer; - }; - - /** - * Encodes the specified SyncActionMessage message, length delimited. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SyncActionMessage - * @static - * @param {proto.ISyncActionMessage} message SyncActionMessage message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncActionMessage.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SyncActionMessage message from the specified reader or buffer. - * @function decode - * @memberof proto.SyncActionMessage - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SyncActionMessage} SyncActionMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncActionMessage.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionMessage(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.key = $root.proto.MessageKey.decode(reader, reader.uint32()); - break; - case 2: - message.timestamp = reader.int64(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SyncActionMessage message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SyncActionMessage - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SyncActionMessage} SyncActionMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncActionMessage.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SyncActionMessage message. - * @function verify - * @memberof proto.SyncActionMessage - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SyncActionMessage.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.key != null && message.hasOwnProperty("key")) { - var error = $root.proto.MessageKey.verify(message.key); - if (error) - return "key." + error; - } - if (message.timestamp != null && message.hasOwnProperty("timestamp")) - if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) - return "timestamp: integer|Long expected"; - return null; - }; - - /** - * Creates a SyncActionMessage message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SyncActionMessage - * @static - * @param {Object.} object Plain object - * @returns {proto.SyncActionMessage} SyncActionMessage - */ - SyncActionMessage.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SyncActionMessage) - return object; - var message = new $root.proto.SyncActionMessage(); - if (object.key != null) { - if (typeof object.key !== "object") - throw TypeError(".proto.SyncActionMessage.key: object expected"); - message.key = $root.proto.MessageKey.fromObject(object.key); - } - if (object.timestamp != null) - if ($util.Long) - (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false; - else if (typeof object.timestamp === "string") - message.timestamp = parseInt(object.timestamp, 10); - else if (typeof object.timestamp === "number") - message.timestamp = object.timestamp; - else if (typeof object.timestamp === "object") - message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(); - return message; - }; - - /** - * Creates a plain object from a SyncActionMessage message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SyncActionMessage - * @static - * @param {proto.SyncActionMessage} message SyncActionMessage - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SyncActionMessage.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.key = null; - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.timestamp = options.longs === String ? "0" : 0; - } - if (message.key != null && message.hasOwnProperty("key")) - object.key = $root.proto.MessageKey.toObject(message.key, options); - if (message.timestamp != null && message.hasOwnProperty("timestamp")) - if (typeof message.timestamp === "number") - object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; - else - object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp; - return object; - }; - - /** - * Converts this SyncActionMessage to JSON. - * @function toJSON - * @memberof proto.SyncActionMessage - * @instance - * @returns {Object.} JSON object - */ - SyncActionMessage.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SyncActionMessage; - })(); - - proto.KeyExpiration = (function() { - - /** - * Properties of a KeyExpiration. - * @memberof proto - * @interface IKeyExpiration - * @property {number|null} [expiredKeyEpoch] KeyExpiration expiredKeyEpoch - */ - - /** - * Constructs a new KeyExpiration. - * @memberof proto - * @classdesc Represents a KeyExpiration. - * @implements IKeyExpiration - * @constructor - * @param {proto.IKeyExpiration=} [properties] Properties to set - */ - function KeyExpiration(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * KeyExpiration expiredKeyEpoch. - * @member {number} expiredKeyEpoch - * @memberof proto.KeyExpiration - * @instance - */ - KeyExpiration.prototype.expiredKeyEpoch = 0; - - /** - * Creates a new KeyExpiration instance using the specified properties. - * @function create - * @memberof proto.KeyExpiration - * @static - * @param {proto.IKeyExpiration=} [properties] Properties to set - * @returns {proto.KeyExpiration} KeyExpiration instance - */ - KeyExpiration.create = function create(properties) { - return new KeyExpiration(properties); - }; - - /** - * Encodes the specified KeyExpiration message. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages. - * @function encode - * @memberof proto.KeyExpiration - * @static - * @param {proto.IKeyExpiration} message KeyExpiration message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - KeyExpiration.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.expiredKeyEpoch != null && Object.hasOwnProperty.call(message, "expiredKeyEpoch")) - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.expiredKeyEpoch); - return writer; - }; - - /** - * Encodes the specified KeyExpiration message, length delimited. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.KeyExpiration - * @static - * @param {proto.IKeyExpiration} message KeyExpiration message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - KeyExpiration.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a KeyExpiration message from the specified reader or buffer. - * @function decode - * @memberof proto.KeyExpiration - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.KeyExpiration} KeyExpiration - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - KeyExpiration.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.KeyExpiration(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.expiredKeyEpoch = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a KeyExpiration message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.KeyExpiration - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.KeyExpiration} KeyExpiration - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - KeyExpiration.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a KeyExpiration message. - * @function verify - * @memberof proto.KeyExpiration - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - KeyExpiration.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.expiredKeyEpoch != null && message.hasOwnProperty("expiredKeyEpoch")) - if (!$util.isInteger(message.expiredKeyEpoch)) - return "expiredKeyEpoch: integer expected"; - return null; - }; - - /** - * Creates a KeyExpiration message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.KeyExpiration - * @static - * @param {Object.} object Plain object - * @returns {proto.KeyExpiration} KeyExpiration - */ - KeyExpiration.fromObject = function fromObject(object) { - if (object instanceof $root.proto.KeyExpiration) - return object; - var message = new $root.proto.KeyExpiration(); - if (object.expiredKeyEpoch != null) - message.expiredKeyEpoch = object.expiredKeyEpoch | 0; - return message; - }; - - /** - * Creates a plain object from a KeyExpiration message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.KeyExpiration - * @static - * @param {proto.KeyExpiration} message KeyExpiration - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - KeyExpiration.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.expiredKeyEpoch = 0; - if (message.expiredKeyEpoch != null && message.hasOwnProperty("expiredKeyEpoch")) - object.expiredKeyEpoch = message.expiredKeyEpoch; - return object; - }; - - /** - * Converts this KeyExpiration to JSON. - * @function toJSON - * @memberof proto.KeyExpiration - * @instance - * @returns {Object.} JSON object - */ - KeyExpiration.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return KeyExpiration; - })(); - - proto.SyncActionValue = (function() { - - /** - * Properties of a SyncActionValue. - * @memberof proto - * @interface ISyncActionValue - * @property {number|Long|null} [timestamp] SyncActionValue timestamp - * @property {proto.IStarAction|null} [starAction] SyncActionValue starAction - * @property {proto.IContactAction|null} [contactAction] SyncActionValue contactAction - * @property {proto.IMuteAction|null} [muteAction] SyncActionValue muteAction - * @property {proto.IPinAction|null} [pinAction] SyncActionValue pinAction - * @property {proto.ISecurityNotificationSetting|null} [securityNotificationSetting] SyncActionValue securityNotificationSetting - * @property {proto.IPushNameSetting|null} [pushNameSetting] SyncActionValue pushNameSetting - * @property {proto.IQuickReplyAction|null} [quickReplyAction] SyncActionValue quickReplyAction - * @property {proto.IRecentStickerWeightsAction|null} [recentStickerWeightsAction] SyncActionValue recentStickerWeightsAction - * @property {proto.IRecentStickerMetadata|null} [recentStickerMetadata] SyncActionValue recentStickerMetadata - * @property {proto.IRecentEmojiWeightsAction|null} [recentEmojiWeightsAction] SyncActionValue recentEmojiWeightsAction - * @property {proto.ILabelEditAction|null} [labelEditAction] SyncActionValue labelEditAction - * @property {proto.ILabelAssociationAction|null} [labelAssociationAction] SyncActionValue labelAssociationAction - * @property {proto.ILocaleSetting|null} [localeSetting] SyncActionValue localeSetting - * @property {proto.IArchiveChatAction|null} [archiveChatAction] SyncActionValue archiveChatAction - * @property {proto.IDeleteMessageForMeAction|null} [deleteMessageForMeAction] SyncActionValue deleteMessageForMeAction - * @property {proto.IKeyExpiration|null} [keyExpiration] SyncActionValue keyExpiration - * @property {proto.IMarkChatAsReadAction|null} [markChatAsReadAction] SyncActionValue markChatAsReadAction - * @property {proto.IClearChatAction|null} [clearChatAction] SyncActionValue clearChatAction - * @property {proto.IDeleteChatAction|null} [deleteChatAction] SyncActionValue deleteChatAction - * @property {proto.IUnarchiveChatsSetting|null} [unarchiveChatsSetting] SyncActionValue unarchiveChatsSetting - */ - - /** - * Constructs a new SyncActionValue. - * @memberof proto - * @classdesc Represents a SyncActionValue. - * @implements ISyncActionValue - * @constructor - * @param {proto.ISyncActionValue=} [properties] Properties to set - */ - function SyncActionValue(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SyncActionValue timestamp. - * @member {number|Long} timestamp - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * SyncActionValue starAction. - * @member {proto.IStarAction|null|undefined} starAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.starAction = null; - - /** - * SyncActionValue contactAction. - * @member {proto.IContactAction|null|undefined} contactAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.contactAction = null; - - /** - * SyncActionValue muteAction. - * @member {proto.IMuteAction|null|undefined} muteAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.muteAction = null; - - /** - * SyncActionValue pinAction. - * @member {proto.IPinAction|null|undefined} pinAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.pinAction = null; - - /** - * SyncActionValue securityNotificationSetting. - * @member {proto.ISecurityNotificationSetting|null|undefined} securityNotificationSetting - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.securityNotificationSetting = null; - - /** - * SyncActionValue pushNameSetting. - * @member {proto.IPushNameSetting|null|undefined} pushNameSetting - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.pushNameSetting = null; - - /** - * SyncActionValue quickReplyAction. - * @member {proto.IQuickReplyAction|null|undefined} quickReplyAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.quickReplyAction = null; - - /** - * SyncActionValue recentStickerWeightsAction. - * @member {proto.IRecentStickerWeightsAction|null|undefined} recentStickerWeightsAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.recentStickerWeightsAction = null; - - /** - * SyncActionValue recentStickerMetadata. - * @member {proto.IRecentStickerMetadata|null|undefined} recentStickerMetadata - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.recentStickerMetadata = null; - - /** - * SyncActionValue recentEmojiWeightsAction. - * @member {proto.IRecentEmojiWeightsAction|null|undefined} recentEmojiWeightsAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.recentEmojiWeightsAction = null; - - /** - * SyncActionValue labelEditAction. - * @member {proto.ILabelEditAction|null|undefined} labelEditAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.labelEditAction = null; - - /** - * SyncActionValue labelAssociationAction. - * @member {proto.ILabelAssociationAction|null|undefined} labelAssociationAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.labelAssociationAction = null; - - /** - * SyncActionValue localeSetting. - * @member {proto.ILocaleSetting|null|undefined} localeSetting - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.localeSetting = null; - - /** - * SyncActionValue archiveChatAction. - * @member {proto.IArchiveChatAction|null|undefined} archiveChatAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.archiveChatAction = null; - - /** - * SyncActionValue deleteMessageForMeAction. - * @member {proto.IDeleteMessageForMeAction|null|undefined} deleteMessageForMeAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.deleteMessageForMeAction = null; - - /** - * SyncActionValue keyExpiration. - * @member {proto.IKeyExpiration|null|undefined} keyExpiration - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.keyExpiration = null; - - /** - * SyncActionValue markChatAsReadAction. - * @member {proto.IMarkChatAsReadAction|null|undefined} markChatAsReadAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.markChatAsReadAction = null; - - /** - * SyncActionValue clearChatAction. - * @member {proto.IClearChatAction|null|undefined} clearChatAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.clearChatAction = null; - - /** - * SyncActionValue deleteChatAction. - * @member {proto.IDeleteChatAction|null|undefined} deleteChatAction - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.deleteChatAction = null; - - /** - * SyncActionValue unarchiveChatsSetting. - * @member {proto.IUnarchiveChatsSetting|null|undefined} unarchiveChatsSetting - * @memberof proto.SyncActionValue - * @instance - */ - SyncActionValue.prototype.unarchiveChatsSetting = null; - - /** - * Creates a new SyncActionValue instance using the specified properties. - * @function create - * @memberof proto.SyncActionValue - * @static - * @param {proto.ISyncActionValue=} [properties] Properties to set - * @returns {proto.SyncActionValue} SyncActionValue instance - */ - SyncActionValue.create = function create(properties) { - return new SyncActionValue(properties); - }; - - /** - * Encodes the specified SyncActionValue message. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages. - * @function encode - * @memberof proto.SyncActionValue - * @static - * @param {proto.ISyncActionValue} message SyncActionValue message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncActionValue.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) - writer.uint32(/* id 1, wireType 0 =*/8).int64(message.timestamp); - if (message.starAction != null && Object.hasOwnProperty.call(message, "starAction")) - $root.proto.StarAction.encode(message.starAction, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.contactAction != null && Object.hasOwnProperty.call(message, "contactAction")) - $root.proto.ContactAction.encode(message.contactAction, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - if (message.muteAction != null && Object.hasOwnProperty.call(message, "muteAction")) - $root.proto.MuteAction.encode(message.muteAction, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); - if (message.pinAction != null && Object.hasOwnProperty.call(message, "pinAction")) - $root.proto.PinAction.encode(message.pinAction, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); - if (message.securityNotificationSetting != null && Object.hasOwnProperty.call(message, "securityNotificationSetting")) - $root.proto.SecurityNotificationSetting.encode(message.securityNotificationSetting, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); - if (message.pushNameSetting != null && Object.hasOwnProperty.call(message, "pushNameSetting")) - $root.proto.PushNameSetting.encode(message.pushNameSetting, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); - if (message.quickReplyAction != null && Object.hasOwnProperty.call(message, "quickReplyAction")) - $root.proto.QuickReplyAction.encode(message.quickReplyAction, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim(); - if (message.recentStickerWeightsAction != null && Object.hasOwnProperty.call(message, "recentStickerWeightsAction")) - $root.proto.RecentStickerWeightsAction.encode(message.recentStickerWeightsAction, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim(); - if (message.recentStickerMetadata != null && Object.hasOwnProperty.call(message, "recentStickerMetadata")) - $root.proto.RecentStickerMetadata.encode(message.recentStickerMetadata, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim(); - if (message.recentEmojiWeightsAction != null && Object.hasOwnProperty.call(message, "recentEmojiWeightsAction")) - $root.proto.RecentEmojiWeightsAction.encode(message.recentEmojiWeightsAction, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim(); - if (message.labelEditAction != null && Object.hasOwnProperty.call(message, "labelEditAction")) - $root.proto.LabelEditAction.encode(message.labelEditAction, writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim(); - if (message.labelAssociationAction != null && Object.hasOwnProperty.call(message, "labelAssociationAction")) - $root.proto.LabelAssociationAction.encode(message.labelAssociationAction, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim(); - if (message.localeSetting != null && Object.hasOwnProperty.call(message, "localeSetting")) - $root.proto.LocaleSetting.encode(message.localeSetting, writer.uint32(/* id 16, wireType 2 =*/130).fork()).ldelim(); - if (message.archiveChatAction != null && Object.hasOwnProperty.call(message, "archiveChatAction")) - $root.proto.ArchiveChatAction.encode(message.archiveChatAction, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim(); - if (message.deleteMessageForMeAction != null && Object.hasOwnProperty.call(message, "deleteMessageForMeAction")) - $root.proto.DeleteMessageForMeAction.encode(message.deleteMessageForMeAction, writer.uint32(/* id 18, wireType 2 =*/146).fork()).ldelim(); - if (message.keyExpiration != null && Object.hasOwnProperty.call(message, "keyExpiration")) - $root.proto.KeyExpiration.encode(message.keyExpiration, writer.uint32(/* id 19, wireType 2 =*/154).fork()).ldelim(); - if (message.markChatAsReadAction != null && Object.hasOwnProperty.call(message, "markChatAsReadAction")) - $root.proto.MarkChatAsReadAction.encode(message.markChatAsReadAction, writer.uint32(/* id 20, wireType 2 =*/162).fork()).ldelim(); - if (message.clearChatAction != null && Object.hasOwnProperty.call(message, "clearChatAction")) - $root.proto.ClearChatAction.encode(message.clearChatAction, writer.uint32(/* id 21, wireType 2 =*/170).fork()).ldelim(); - if (message.deleteChatAction != null && Object.hasOwnProperty.call(message, "deleteChatAction")) - $root.proto.DeleteChatAction.encode(message.deleteChatAction, writer.uint32(/* id 22, wireType 2 =*/178).fork()).ldelim(); - if (message.unarchiveChatsSetting != null && Object.hasOwnProperty.call(message, "unarchiveChatsSetting")) - $root.proto.UnarchiveChatsSetting.encode(message.unarchiveChatsSetting, writer.uint32(/* id 23, wireType 2 =*/186).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified SyncActionValue message, length delimited. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SyncActionValue - * @static - * @param {proto.ISyncActionValue} message SyncActionValue message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncActionValue.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SyncActionValue message from the specified reader or buffer. - * @function decode - * @memberof proto.SyncActionValue - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SyncActionValue} SyncActionValue - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncActionValue.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionValue(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.timestamp = reader.int64(); - break; - case 2: - message.starAction = $root.proto.StarAction.decode(reader, reader.uint32()); - break; - case 3: - message.contactAction = $root.proto.ContactAction.decode(reader, reader.uint32()); - break; - case 4: - message.muteAction = $root.proto.MuteAction.decode(reader, reader.uint32()); - break; - case 5: - message.pinAction = $root.proto.PinAction.decode(reader, reader.uint32()); - break; - case 6: - message.securityNotificationSetting = $root.proto.SecurityNotificationSetting.decode(reader, reader.uint32()); - break; - case 7: - message.pushNameSetting = $root.proto.PushNameSetting.decode(reader, reader.uint32()); - break; - case 8: - message.quickReplyAction = $root.proto.QuickReplyAction.decode(reader, reader.uint32()); - break; - case 9: - message.recentStickerWeightsAction = $root.proto.RecentStickerWeightsAction.decode(reader, reader.uint32()); - break; - case 10: - message.recentStickerMetadata = $root.proto.RecentStickerMetadata.decode(reader, reader.uint32()); - break; - case 11: - message.recentEmojiWeightsAction = $root.proto.RecentEmojiWeightsAction.decode(reader, reader.uint32()); - break; - case 14: - message.labelEditAction = $root.proto.LabelEditAction.decode(reader, reader.uint32()); - break; - case 15: - message.labelAssociationAction = $root.proto.LabelAssociationAction.decode(reader, reader.uint32()); - break; - case 16: - message.localeSetting = $root.proto.LocaleSetting.decode(reader, reader.uint32()); - break; - case 17: - message.archiveChatAction = $root.proto.ArchiveChatAction.decode(reader, reader.uint32()); - break; - case 18: - message.deleteMessageForMeAction = $root.proto.DeleteMessageForMeAction.decode(reader, reader.uint32()); - break; - case 19: - message.keyExpiration = $root.proto.KeyExpiration.decode(reader, reader.uint32()); - break; - case 20: - message.markChatAsReadAction = $root.proto.MarkChatAsReadAction.decode(reader, reader.uint32()); - break; - case 21: - message.clearChatAction = $root.proto.ClearChatAction.decode(reader, reader.uint32()); - break; - case 22: - message.deleteChatAction = $root.proto.DeleteChatAction.decode(reader, reader.uint32()); - break; - case 23: - message.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SyncActionValue message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SyncActionValue - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SyncActionValue} SyncActionValue - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncActionValue.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SyncActionValue message. - * @function verify - * @memberof proto.SyncActionValue - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SyncActionValue.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.timestamp != null && message.hasOwnProperty("timestamp")) - if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) - return "timestamp: integer|Long expected"; - if (message.starAction != null && message.hasOwnProperty("starAction")) { - var error = $root.proto.StarAction.verify(message.starAction); - if (error) - return "starAction." + error; - } - if (message.contactAction != null && message.hasOwnProperty("contactAction")) { - var error = $root.proto.ContactAction.verify(message.contactAction); - if (error) - return "contactAction." + error; - } - if (message.muteAction != null && message.hasOwnProperty("muteAction")) { - var error = $root.proto.MuteAction.verify(message.muteAction); - if (error) - return "muteAction." + error; - } - if (message.pinAction != null && message.hasOwnProperty("pinAction")) { - var error = $root.proto.PinAction.verify(message.pinAction); - if (error) - return "pinAction." + error; - } - if (message.securityNotificationSetting != null && message.hasOwnProperty("securityNotificationSetting")) { - var error = $root.proto.SecurityNotificationSetting.verify(message.securityNotificationSetting); - if (error) - return "securityNotificationSetting." + error; - } - if (message.pushNameSetting != null && message.hasOwnProperty("pushNameSetting")) { - var error = $root.proto.PushNameSetting.verify(message.pushNameSetting); - if (error) - return "pushNameSetting." + error; - } - if (message.quickReplyAction != null && message.hasOwnProperty("quickReplyAction")) { - var error = $root.proto.QuickReplyAction.verify(message.quickReplyAction); - if (error) - return "quickReplyAction." + error; - } - if (message.recentStickerWeightsAction != null && message.hasOwnProperty("recentStickerWeightsAction")) { - var error = $root.proto.RecentStickerWeightsAction.verify(message.recentStickerWeightsAction); - if (error) - return "recentStickerWeightsAction." + error; - } - if (message.recentStickerMetadata != null && message.hasOwnProperty("recentStickerMetadata")) { - var error = $root.proto.RecentStickerMetadata.verify(message.recentStickerMetadata); - if (error) - return "recentStickerMetadata." + error; - } - if (message.recentEmojiWeightsAction != null && message.hasOwnProperty("recentEmojiWeightsAction")) { - var error = $root.proto.RecentEmojiWeightsAction.verify(message.recentEmojiWeightsAction); - if (error) - return "recentEmojiWeightsAction." + error; - } - if (message.labelEditAction != null && message.hasOwnProperty("labelEditAction")) { - var error = $root.proto.LabelEditAction.verify(message.labelEditAction); - if (error) - return "labelEditAction." + error; - } - if (message.labelAssociationAction != null && message.hasOwnProperty("labelAssociationAction")) { - var error = $root.proto.LabelAssociationAction.verify(message.labelAssociationAction); - if (error) - return "labelAssociationAction." + error; - } - if (message.localeSetting != null && message.hasOwnProperty("localeSetting")) { - var error = $root.proto.LocaleSetting.verify(message.localeSetting); - if (error) - return "localeSetting." + error; - } - if (message.archiveChatAction != null && message.hasOwnProperty("archiveChatAction")) { - var error = $root.proto.ArchiveChatAction.verify(message.archiveChatAction); - if (error) - return "archiveChatAction." + error; - } - if (message.deleteMessageForMeAction != null && message.hasOwnProperty("deleteMessageForMeAction")) { - var error = $root.proto.DeleteMessageForMeAction.verify(message.deleteMessageForMeAction); - if (error) - return "deleteMessageForMeAction." + error; - } - if (message.keyExpiration != null && message.hasOwnProperty("keyExpiration")) { - var error = $root.proto.KeyExpiration.verify(message.keyExpiration); - if (error) - return "keyExpiration." + error; - } - if (message.markChatAsReadAction != null && message.hasOwnProperty("markChatAsReadAction")) { - var error = $root.proto.MarkChatAsReadAction.verify(message.markChatAsReadAction); - if (error) - return "markChatAsReadAction." + error; - } - if (message.clearChatAction != null && message.hasOwnProperty("clearChatAction")) { - var error = $root.proto.ClearChatAction.verify(message.clearChatAction); - if (error) - return "clearChatAction." + error; - } - if (message.deleteChatAction != null && message.hasOwnProperty("deleteChatAction")) { - var error = $root.proto.DeleteChatAction.verify(message.deleteChatAction); - if (error) - return "deleteChatAction." + error; - } - if (message.unarchiveChatsSetting != null && message.hasOwnProperty("unarchiveChatsSetting")) { - var error = $root.proto.UnarchiveChatsSetting.verify(message.unarchiveChatsSetting); - if (error) - return "unarchiveChatsSetting." + error; - } - return null; - }; - - /** - * Creates a SyncActionValue message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SyncActionValue - * @static - * @param {Object.} object Plain object - * @returns {proto.SyncActionValue} SyncActionValue - */ - SyncActionValue.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SyncActionValue) - return object; - var message = new $root.proto.SyncActionValue(); - if (object.timestamp != null) - if ($util.Long) - (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false; - else if (typeof object.timestamp === "string") - message.timestamp = parseInt(object.timestamp, 10); - else if (typeof object.timestamp === "number") - message.timestamp = object.timestamp; - else if (typeof object.timestamp === "object") - message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(); - if (object.starAction != null) { - if (typeof object.starAction !== "object") - throw TypeError(".proto.SyncActionValue.starAction: object expected"); - message.starAction = $root.proto.StarAction.fromObject(object.starAction); - } - if (object.contactAction != null) { - if (typeof object.contactAction !== "object") - throw TypeError(".proto.SyncActionValue.contactAction: object expected"); - message.contactAction = $root.proto.ContactAction.fromObject(object.contactAction); - } - if (object.muteAction != null) { - if (typeof object.muteAction !== "object") - throw TypeError(".proto.SyncActionValue.muteAction: object expected"); - message.muteAction = $root.proto.MuteAction.fromObject(object.muteAction); - } - if (object.pinAction != null) { - if (typeof object.pinAction !== "object") - throw TypeError(".proto.SyncActionValue.pinAction: object expected"); - message.pinAction = $root.proto.PinAction.fromObject(object.pinAction); - } - if (object.securityNotificationSetting != null) { - if (typeof object.securityNotificationSetting !== "object") - throw TypeError(".proto.SyncActionValue.securityNotificationSetting: object expected"); - message.securityNotificationSetting = $root.proto.SecurityNotificationSetting.fromObject(object.securityNotificationSetting); - } - if (object.pushNameSetting != null) { - if (typeof object.pushNameSetting !== "object") - throw TypeError(".proto.SyncActionValue.pushNameSetting: object expected"); - message.pushNameSetting = $root.proto.PushNameSetting.fromObject(object.pushNameSetting); - } - if (object.quickReplyAction != null) { - if (typeof object.quickReplyAction !== "object") - throw TypeError(".proto.SyncActionValue.quickReplyAction: object expected"); - message.quickReplyAction = $root.proto.QuickReplyAction.fromObject(object.quickReplyAction); - } - if (object.recentStickerWeightsAction != null) { - if (typeof object.recentStickerWeightsAction !== "object") - throw TypeError(".proto.SyncActionValue.recentStickerWeightsAction: object expected"); - message.recentStickerWeightsAction = $root.proto.RecentStickerWeightsAction.fromObject(object.recentStickerWeightsAction); - } - if (object.recentStickerMetadata != null) { - if (typeof object.recentStickerMetadata !== "object") - throw TypeError(".proto.SyncActionValue.recentStickerMetadata: object expected"); - message.recentStickerMetadata = $root.proto.RecentStickerMetadata.fromObject(object.recentStickerMetadata); - } - if (object.recentEmojiWeightsAction != null) { - if (typeof object.recentEmojiWeightsAction !== "object") - throw TypeError(".proto.SyncActionValue.recentEmojiWeightsAction: object expected"); - message.recentEmojiWeightsAction = $root.proto.RecentEmojiWeightsAction.fromObject(object.recentEmojiWeightsAction); - } - if (object.labelEditAction != null) { - if (typeof object.labelEditAction !== "object") - throw TypeError(".proto.SyncActionValue.labelEditAction: object expected"); - message.labelEditAction = $root.proto.LabelEditAction.fromObject(object.labelEditAction); - } - if (object.labelAssociationAction != null) { - if (typeof object.labelAssociationAction !== "object") - throw TypeError(".proto.SyncActionValue.labelAssociationAction: object expected"); - message.labelAssociationAction = $root.proto.LabelAssociationAction.fromObject(object.labelAssociationAction); - } - if (object.localeSetting != null) { - if (typeof object.localeSetting !== "object") - throw TypeError(".proto.SyncActionValue.localeSetting: object expected"); - message.localeSetting = $root.proto.LocaleSetting.fromObject(object.localeSetting); - } - if (object.archiveChatAction != null) { - if (typeof object.archiveChatAction !== "object") - throw TypeError(".proto.SyncActionValue.archiveChatAction: object expected"); - message.archiveChatAction = $root.proto.ArchiveChatAction.fromObject(object.archiveChatAction); - } - if (object.deleteMessageForMeAction != null) { - if (typeof object.deleteMessageForMeAction !== "object") - throw TypeError(".proto.SyncActionValue.deleteMessageForMeAction: object expected"); - message.deleteMessageForMeAction = $root.proto.DeleteMessageForMeAction.fromObject(object.deleteMessageForMeAction); - } - if (object.keyExpiration != null) { - if (typeof object.keyExpiration !== "object") - throw TypeError(".proto.SyncActionValue.keyExpiration: object expected"); - message.keyExpiration = $root.proto.KeyExpiration.fromObject(object.keyExpiration); - } - if (object.markChatAsReadAction != null) { - if (typeof object.markChatAsReadAction !== "object") - throw TypeError(".proto.SyncActionValue.markChatAsReadAction: object expected"); - message.markChatAsReadAction = $root.proto.MarkChatAsReadAction.fromObject(object.markChatAsReadAction); - } - if (object.clearChatAction != null) { - if (typeof object.clearChatAction !== "object") - throw TypeError(".proto.SyncActionValue.clearChatAction: object expected"); - message.clearChatAction = $root.proto.ClearChatAction.fromObject(object.clearChatAction); - } - if (object.deleteChatAction != null) { - if (typeof object.deleteChatAction !== "object") - throw TypeError(".proto.SyncActionValue.deleteChatAction: object expected"); - message.deleteChatAction = $root.proto.DeleteChatAction.fromObject(object.deleteChatAction); - } - if (object.unarchiveChatsSetting != null) { - if (typeof object.unarchiveChatsSetting !== "object") - throw TypeError(".proto.SyncActionValue.unarchiveChatsSetting: object expected"); - message.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.fromObject(object.unarchiveChatsSetting); - } - return message; - }; - - /** - * Creates a plain object from a SyncActionValue message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SyncActionValue - * @static - * @param {proto.SyncActionValue} message SyncActionValue - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SyncActionValue.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.timestamp = options.longs === String ? "0" : 0; - object.starAction = null; - object.contactAction = null; - object.muteAction = null; - object.pinAction = null; - object.securityNotificationSetting = null; - object.pushNameSetting = null; - object.quickReplyAction = null; - object.recentStickerWeightsAction = null; - object.recentStickerMetadata = null; - object.recentEmojiWeightsAction = null; - object.labelEditAction = null; - object.labelAssociationAction = null; - object.localeSetting = null; - object.archiveChatAction = null; - object.deleteMessageForMeAction = null; - object.keyExpiration = null; - object.markChatAsReadAction = null; - object.clearChatAction = null; - object.deleteChatAction = null; - object.unarchiveChatsSetting = null; - } - if (message.timestamp != null && message.hasOwnProperty("timestamp")) - if (typeof message.timestamp === "number") - object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; - else - object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp; - if (message.starAction != null && message.hasOwnProperty("starAction")) - object.starAction = $root.proto.StarAction.toObject(message.starAction, options); - if (message.contactAction != null && message.hasOwnProperty("contactAction")) - object.contactAction = $root.proto.ContactAction.toObject(message.contactAction, options); - if (message.muteAction != null && message.hasOwnProperty("muteAction")) - object.muteAction = $root.proto.MuteAction.toObject(message.muteAction, options); - if (message.pinAction != null && message.hasOwnProperty("pinAction")) - object.pinAction = $root.proto.PinAction.toObject(message.pinAction, options); - if (message.securityNotificationSetting != null && message.hasOwnProperty("securityNotificationSetting")) - object.securityNotificationSetting = $root.proto.SecurityNotificationSetting.toObject(message.securityNotificationSetting, options); - if (message.pushNameSetting != null && message.hasOwnProperty("pushNameSetting")) - object.pushNameSetting = $root.proto.PushNameSetting.toObject(message.pushNameSetting, options); - if (message.quickReplyAction != null && message.hasOwnProperty("quickReplyAction")) - object.quickReplyAction = $root.proto.QuickReplyAction.toObject(message.quickReplyAction, options); - if (message.recentStickerWeightsAction != null && message.hasOwnProperty("recentStickerWeightsAction")) - object.recentStickerWeightsAction = $root.proto.RecentStickerWeightsAction.toObject(message.recentStickerWeightsAction, options); - if (message.recentStickerMetadata != null && message.hasOwnProperty("recentStickerMetadata")) - object.recentStickerMetadata = $root.proto.RecentStickerMetadata.toObject(message.recentStickerMetadata, options); - if (message.recentEmojiWeightsAction != null && message.hasOwnProperty("recentEmojiWeightsAction")) - object.recentEmojiWeightsAction = $root.proto.RecentEmojiWeightsAction.toObject(message.recentEmojiWeightsAction, options); - if (message.labelEditAction != null && message.hasOwnProperty("labelEditAction")) - object.labelEditAction = $root.proto.LabelEditAction.toObject(message.labelEditAction, options); - if (message.labelAssociationAction != null && message.hasOwnProperty("labelAssociationAction")) - object.labelAssociationAction = $root.proto.LabelAssociationAction.toObject(message.labelAssociationAction, options); - if (message.localeSetting != null && message.hasOwnProperty("localeSetting")) - object.localeSetting = $root.proto.LocaleSetting.toObject(message.localeSetting, options); - if (message.archiveChatAction != null && message.hasOwnProperty("archiveChatAction")) - object.archiveChatAction = $root.proto.ArchiveChatAction.toObject(message.archiveChatAction, options); - if (message.deleteMessageForMeAction != null && message.hasOwnProperty("deleteMessageForMeAction")) - object.deleteMessageForMeAction = $root.proto.DeleteMessageForMeAction.toObject(message.deleteMessageForMeAction, options); - if (message.keyExpiration != null && message.hasOwnProperty("keyExpiration")) - object.keyExpiration = $root.proto.KeyExpiration.toObject(message.keyExpiration, options); - if (message.markChatAsReadAction != null && message.hasOwnProperty("markChatAsReadAction")) - object.markChatAsReadAction = $root.proto.MarkChatAsReadAction.toObject(message.markChatAsReadAction, options); - if (message.clearChatAction != null && message.hasOwnProperty("clearChatAction")) - object.clearChatAction = $root.proto.ClearChatAction.toObject(message.clearChatAction, options); - if (message.deleteChatAction != null && message.hasOwnProperty("deleteChatAction")) - object.deleteChatAction = $root.proto.DeleteChatAction.toObject(message.deleteChatAction, options); - if (message.unarchiveChatsSetting != null && message.hasOwnProperty("unarchiveChatsSetting")) - object.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.toObject(message.unarchiveChatsSetting, options); - return object; - }; - - /** - * Converts this SyncActionValue to JSON. - * @function toJSON - * @memberof proto.SyncActionValue - * @instance - * @returns {Object.} JSON object - */ - SyncActionValue.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SyncActionValue; - })(); - - proto.RecentEmojiWeight = (function() { - - /** - * Properties of a RecentEmojiWeight. - * @memberof proto - * @interface IRecentEmojiWeight - * @property {string|null} [emoji] RecentEmojiWeight emoji - * @property {number|null} [weight] RecentEmojiWeight weight - */ - - /** - * Constructs a new RecentEmojiWeight. - * @memberof proto - * @classdesc Represents a RecentEmojiWeight. - * @implements IRecentEmojiWeight - * @constructor - * @param {proto.IRecentEmojiWeight=} [properties] Properties to set - */ - function RecentEmojiWeight(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * RecentEmojiWeight emoji. - * @member {string} emoji - * @memberof proto.RecentEmojiWeight - * @instance - */ - RecentEmojiWeight.prototype.emoji = ""; - - /** - * RecentEmojiWeight weight. - * @member {number} weight - * @memberof proto.RecentEmojiWeight - * @instance - */ - RecentEmojiWeight.prototype.weight = 0; - - /** - * Creates a new RecentEmojiWeight instance using the specified properties. - * @function create - * @memberof proto.RecentEmojiWeight - * @static - * @param {proto.IRecentEmojiWeight=} [properties] Properties to set - * @returns {proto.RecentEmojiWeight} RecentEmojiWeight instance - */ - RecentEmojiWeight.create = function create(properties) { - return new RecentEmojiWeight(properties); - }; - - /** - * Encodes the specified RecentEmojiWeight message. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages. - * @function encode - * @memberof proto.RecentEmojiWeight - * @static - * @param {proto.IRecentEmojiWeight} message RecentEmojiWeight message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - RecentEmojiWeight.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.emoji != null && Object.hasOwnProperty.call(message, "emoji")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.emoji); - if (message.weight != null && Object.hasOwnProperty.call(message, "weight")) - writer.uint32(/* id 2, wireType 5 =*/21).float(message.weight); - return writer; - }; - - /** - * Encodes the specified RecentEmojiWeight message, length delimited. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.RecentEmojiWeight - * @static - * @param {proto.IRecentEmojiWeight} message RecentEmojiWeight message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - RecentEmojiWeight.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a RecentEmojiWeight message from the specified reader or buffer. - * @function decode - * @memberof proto.RecentEmojiWeight - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.RecentEmojiWeight} RecentEmojiWeight - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - RecentEmojiWeight.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentEmojiWeight(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.emoji = reader.string(); - break; - case 2: - message.weight = reader.float(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a RecentEmojiWeight message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.RecentEmojiWeight - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.RecentEmojiWeight} RecentEmojiWeight - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - RecentEmojiWeight.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a RecentEmojiWeight message. - * @function verify - * @memberof proto.RecentEmojiWeight - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - RecentEmojiWeight.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.emoji != null && message.hasOwnProperty("emoji")) - if (!$util.isString(message.emoji)) - return "emoji: string expected"; - if (message.weight != null && message.hasOwnProperty("weight")) - if (typeof message.weight !== "number") - return "weight: number expected"; - return null; - }; - - /** - * Creates a RecentEmojiWeight message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.RecentEmojiWeight - * @static - * @param {Object.} object Plain object - * @returns {proto.RecentEmojiWeight} RecentEmojiWeight - */ - RecentEmojiWeight.fromObject = function fromObject(object) { - if (object instanceof $root.proto.RecentEmojiWeight) - return object; - var message = new $root.proto.RecentEmojiWeight(); - if (object.emoji != null) - message.emoji = String(object.emoji); - if (object.weight != null) - message.weight = Number(object.weight); - return message; - }; - - /** - * Creates a plain object from a RecentEmojiWeight message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.RecentEmojiWeight - * @static - * @param {proto.RecentEmojiWeight} message RecentEmojiWeight - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - RecentEmojiWeight.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.emoji = ""; - object.weight = 0; - } - if (message.emoji != null && message.hasOwnProperty("emoji")) - object.emoji = message.emoji; - if (message.weight != null && message.hasOwnProperty("weight")) - object.weight = options.json && !isFinite(message.weight) ? String(message.weight) : message.weight; - return object; - }; - - /** - * Converts this RecentEmojiWeight to JSON. - * @function toJSON - * @memberof proto.RecentEmojiWeight - * @instance - * @returns {Object.} JSON object - */ - RecentEmojiWeight.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return RecentEmojiWeight; - })(); - - proto.RecentStickerWeight = (function() { - - /** - * Properties of a RecentStickerWeight. - * @memberof proto - * @interface IRecentStickerWeight - * @property {string|null} [filehash] RecentStickerWeight filehash - * @property {number|null} [weight] RecentStickerWeight weight - */ - - /** - * Constructs a new RecentStickerWeight. - * @memberof proto - * @classdesc Represents a RecentStickerWeight. - * @implements IRecentStickerWeight - * @constructor - * @param {proto.IRecentStickerWeight=} [properties] Properties to set - */ - function RecentStickerWeight(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * RecentStickerWeight filehash. - * @member {string} filehash - * @memberof proto.RecentStickerWeight - * @instance - */ - RecentStickerWeight.prototype.filehash = ""; - - /** - * RecentStickerWeight weight. - * @member {number} weight - * @memberof proto.RecentStickerWeight - * @instance - */ - RecentStickerWeight.prototype.weight = 0; - - /** - * Creates a new RecentStickerWeight instance using the specified properties. - * @function create - * @memberof proto.RecentStickerWeight - * @static - * @param {proto.IRecentStickerWeight=} [properties] Properties to set - * @returns {proto.RecentStickerWeight} RecentStickerWeight instance - */ - RecentStickerWeight.create = function create(properties) { - return new RecentStickerWeight(properties); - }; - - /** - * Encodes the specified RecentStickerWeight message. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages. - * @function encode - * @memberof proto.RecentStickerWeight - * @static - * @param {proto.IRecentStickerWeight} message RecentStickerWeight message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - RecentStickerWeight.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.filehash != null && Object.hasOwnProperty.call(message, "filehash")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.filehash); - if (message.weight != null && Object.hasOwnProperty.call(message, "weight")) - writer.uint32(/* id 2, wireType 5 =*/21).float(message.weight); - return writer; - }; - - /** - * Encodes the specified RecentStickerWeight message, length delimited. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.RecentStickerWeight - * @static - * @param {proto.IRecentStickerWeight} message RecentStickerWeight message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - RecentStickerWeight.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a RecentStickerWeight message from the specified reader or buffer. - * @function decode - * @memberof proto.RecentStickerWeight - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.RecentStickerWeight} RecentStickerWeight - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - RecentStickerWeight.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentStickerWeight(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.filehash = reader.string(); - break; - case 2: - message.weight = reader.float(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a RecentStickerWeight message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.RecentStickerWeight - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.RecentStickerWeight} RecentStickerWeight - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - RecentStickerWeight.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a RecentStickerWeight message. - * @function verify - * @memberof proto.RecentStickerWeight - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - RecentStickerWeight.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.filehash != null && message.hasOwnProperty("filehash")) - if (!$util.isString(message.filehash)) - return "filehash: string expected"; - if (message.weight != null && message.hasOwnProperty("weight")) - if (typeof message.weight !== "number") - return "weight: number expected"; - return null; - }; - - /** - * Creates a RecentStickerWeight message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.RecentStickerWeight - * @static - * @param {Object.} object Plain object - * @returns {proto.RecentStickerWeight} RecentStickerWeight - */ - RecentStickerWeight.fromObject = function fromObject(object) { - if (object instanceof $root.proto.RecentStickerWeight) - return object; - var message = new $root.proto.RecentStickerWeight(); - if (object.filehash != null) - message.filehash = String(object.filehash); - if (object.weight != null) - message.weight = Number(object.weight); - return message; - }; - - /** - * Creates a plain object from a RecentStickerWeight message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.RecentStickerWeight - * @static - * @param {proto.RecentStickerWeight} message RecentStickerWeight - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - RecentStickerWeight.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.filehash = ""; - object.weight = 0; - } - if (message.filehash != null && message.hasOwnProperty("filehash")) - object.filehash = message.filehash; - if (message.weight != null && message.hasOwnProperty("weight")) - object.weight = options.json && !isFinite(message.weight) ? String(message.weight) : message.weight; - return object; - }; - - /** - * Converts this RecentStickerWeight to JSON. - * @function toJSON - * @memberof proto.RecentStickerWeight - * @instance - * @returns {Object.} JSON object - */ - RecentStickerWeight.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return RecentStickerWeight; - })(); - - proto.SyncdPatch = (function() { - - /** - * Properties of a SyncdPatch. - * @memberof proto - * @interface ISyncdPatch - * @property {proto.ISyncdVersion|null} [version] SyncdPatch version - * @property {Array.|null} [mutations] SyncdPatch mutations - * @property {proto.IExternalBlobReference|null} [externalMutations] SyncdPatch externalMutations - * @property {Uint8Array|null} [snapshotMac] SyncdPatch snapshotMac - * @property {Uint8Array|null} [patchMac] SyncdPatch patchMac - * @property {proto.IKeyId|null} [keyId] SyncdPatch keyId - * @property {proto.IExitCode|null} [exitCode] SyncdPatch exitCode - * @property {number|null} [deviceIndex] SyncdPatch deviceIndex - */ - - /** - * Constructs a new SyncdPatch. - * @memberof proto - * @classdesc Represents a SyncdPatch. - * @implements ISyncdPatch - * @constructor - * @param {proto.ISyncdPatch=} [properties] Properties to set - */ - function SyncdPatch(properties) { - this.mutations = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SyncdPatch version. - * @member {proto.ISyncdVersion|null|undefined} version - * @memberof proto.SyncdPatch - * @instance - */ - SyncdPatch.prototype.version = null; - - /** - * SyncdPatch mutations. - * @member {Array.} mutations - * @memberof proto.SyncdPatch - * @instance - */ - SyncdPatch.prototype.mutations = $util.emptyArray; - - /** - * SyncdPatch externalMutations. - * @member {proto.IExternalBlobReference|null|undefined} externalMutations - * @memberof proto.SyncdPatch - * @instance - */ - SyncdPatch.prototype.externalMutations = null; - - /** - * SyncdPatch snapshotMac. - * @member {Uint8Array} snapshotMac - * @memberof proto.SyncdPatch - * @instance - */ - SyncdPatch.prototype.snapshotMac = $util.newBuffer([]); - - /** - * SyncdPatch patchMac. - * @member {Uint8Array} patchMac - * @memberof proto.SyncdPatch - * @instance - */ - SyncdPatch.prototype.patchMac = $util.newBuffer([]); - - /** - * SyncdPatch keyId. - * @member {proto.IKeyId|null|undefined} keyId - * @memberof proto.SyncdPatch - * @instance - */ - SyncdPatch.prototype.keyId = null; - - /** - * SyncdPatch exitCode. - * @member {proto.IExitCode|null|undefined} exitCode - * @memberof proto.SyncdPatch - * @instance - */ - SyncdPatch.prototype.exitCode = null; - - /** - * SyncdPatch deviceIndex. - * @member {number} deviceIndex - * @memberof proto.SyncdPatch - * @instance - */ - SyncdPatch.prototype.deviceIndex = 0; - - /** - * Creates a new SyncdPatch instance using the specified properties. - * @function create - * @memberof proto.SyncdPatch - * @static - * @param {proto.ISyncdPatch=} [properties] Properties to set - * @returns {proto.SyncdPatch} SyncdPatch instance - */ - SyncdPatch.create = function create(properties) { - return new SyncdPatch(properties); - }; - - /** - * Encodes the specified SyncdPatch message. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages. - * @function encode - * @memberof proto.SyncdPatch - * @static - * @param {proto.ISyncdPatch} message SyncdPatch message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdPatch.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.version != null && Object.hasOwnProperty.call(message, "version")) - $root.proto.SyncdVersion.encode(message.version, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.mutations != null && message.mutations.length) - for (var i = 0; i < message.mutations.length; ++i) - $root.proto.SyncdMutation.encode(message.mutations[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.externalMutations != null && Object.hasOwnProperty.call(message, "externalMutations")) - $root.proto.ExternalBlobReference.encode(message.externalMutations, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - if (message.snapshotMac != null && Object.hasOwnProperty.call(message, "snapshotMac")) - writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.snapshotMac); - if (message.patchMac != null && Object.hasOwnProperty.call(message, "patchMac")) - writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.patchMac); - if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId")) - $root.proto.KeyId.encode(message.keyId, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); - if (message.exitCode != null && Object.hasOwnProperty.call(message, "exitCode")) - $root.proto.ExitCode.encode(message.exitCode, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); - if (message.deviceIndex != null && Object.hasOwnProperty.call(message, "deviceIndex")) - writer.uint32(/* id 8, wireType 0 =*/64).uint32(message.deviceIndex); - return writer; - }; - - /** - * Encodes the specified SyncdPatch message, length delimited. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SyncdPatch - * @static - * @param {proto.ISyncdPatch} message SyncdPatch message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdPatch.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SyncdPatch message from the specified reader or buffer. - * @function decode - * @memberof proto.SyncdPatch - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SyncdPatch} SyncdPatch - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdPatch.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdPatch(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.version = $root.proto.SyncdVersion.decode(reader, reader.uint32()); - break; - case 2: - if (!(message.mutations && message.mutations.length)) - message.mutations = []; - message.mutations.push($root.proto.SyncdMutation.decode(reader, reader.uint32())); - break; - case 3: - message.externalMutations = $root.proto.ExternalBlobReference.decode(reader, reader.uint32()); - break; - case 4: - message.snapshotMac = reader.bytes(); - break; - case 5: - message.patchMac = reader.bytes(); - break; - case 6: - message.keyId = $root.proto.KeyId.decode(reader, reader.uint32()); - break; - case 7: - message.exitCode = $root.proto.ExitCode.decode(reader, reader.uint32()); - break; - case 8: - message.deviceIndex = reader.uint32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SyncdPatch message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SyncdPatch - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SyncdPatch} SyncdPatch - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdPatch.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SyncdPatch message. - * @function verify - * @memberof proto.SyncdPatch - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SyncdPatch.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.version != null && message.hasOwnProperty("version")) { - var error = $root.proto.SyncdVersion.verify(message.version); - if (error) - return "version." + error; - } - if (message.mutations != null && message.hasOwnProperty("mutations")) { - if (!Array.isArray(message.mutations)) - return "mutations: array expected"; - for (var i = 0; i < message.mutations.length; ++i) { - var error = $root.proto.SyncdMutation.verify(message.mutations[i]); - if (error) - return "mutations." + error; - } - } - if (message.externalMutations != null && message.hasOwnProperty("externalMutations")) { - var error = $root.proto.ExternalBlobReference.verify(message.externalMutations); - if (error) - return "externalMutations." + error; - } - if (message.snapshotMac != null && message.hasOwnProperty("snapshotMac")) - if (!(message.snapshotMac && typeof message.snapshotMac.length === "number" || $util.isString(message.snapshotMac))) - return "snapshotMac: buffer expected"; - if (message.patchMac != null && message.hasOwnProperty("patchMac")) - if (!(message.patchMac && typeof message.patchMac.length === "number" || $util.isString(message.patchMac))) - return "patchMac: buffer expected"; - if (message.keyId != null && message.hasOwnProperty("keyId")) { - var error = $root.proto.KeyId.verify(message.keyId); - if (error) - return "keyId." + error; - } - if (message.exitCode != null && message.hasOwnProperty("exitCode")) { - var error = $root.proto.ExitCode.verify(message.exitCode); - if (error) - return "exitCode." + error; - } - if (message.deviceIndex != null && message.hasOwnProperty("deviceIndex")) - if (!$util.isInteger(message.deviceIndex)) - return "deviceIndex: integer expected"; - return null; - }; - - /** - * Creates a SyncdPatch message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SyncdPatch - * @static - * @param {Object.} object Plain object - * @returns {proto.SyncdPatch} SyncdPatch - */ - SyncdPatch.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SyncdPatch) - return object; - var message = new $root.proto.SyncdPatch(); - if (object.version != null) { - if (typeof object.version !== "object") - throw TypeError(".proto.SyncdPatch.version: object expected"); - message.version = $root.proto.SyncdVersion.fromObject(object.version); - } - if (object.mutations) { - if (!Array.isArray(object.mutations)) - throw TypeError(".proto.SyncdPatch.mutations: array expected"); - message.mutations = []; - for (var i = 0; i < object.mutations.length; ++i) { - if (typeof object.mutations[i] !== "object") - throw TypeError(".proto.SyncdPatch.mutations: object expected"); - message.mutations[i] = $root.proto.SyncdMutation.fromObject(object.mutations[i]); - } - } - if (object.externalMutations != null) { - if (typeof object.externalMutations !== "object") - throw TypeError(".proto.SyncdPatch.externalMutations: object expected"); - message.externalMutations = $root.proto.ExternalBlobReference.fromObject(object.externalMutations); - } - if (object.snapshotMac != null) - if (typeof object.snapshotMac === "string") - $util.base64.decode(object.snapshotMac, message.snapshotMac = $util.newBuffer($util.base64.length(object.snapshotMac)), 0); - else if (object.snapshotMac.length) - message.snapshotMac = object.snapshotMac; - if (object.patchMac != null) - if (typeof object.patchMac === "string") - $util.base64.decode(object.patchMac, message.patchMac = $util.newBuffer($util.base64.length(object.patchMac)), 0); - else if (object.patchMac.length) - message.patchMac = object.patchMac; - if (object.keyId != null) { - if (typeof object.keyId !== "object") - throw TypeError(".proto.SyncdPatch.keyId: object expected"); - message.keyId = $root.proto.KeyId.fromObject(object.keyId); - } - if (object.exitCode != null) { - if (typeof object.exitCode !== "object") - throw TypeError(".proto.SyncdPatch.exitCode: object expected"); - message.exitCode = $root.proto.ExitCode.fromObject(object.exitCode); - } - if (object.deviceIndex != null) - message.deviceIndex = object.deviceIndex >>> 0; - return message; - }; - - /** - * Creates a plain object from a SyncdPatch message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SyncdPatch - * @static - * @param {proto.SyncdPatch} message SyncdPatch - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SyncdPatch.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.mutations = []; - if (options.defaults) { - object.version = null; - object.externalMutations = null; - if (options.bytes === String) - object.snapshotMac = ""; - else { - object.snapshotMac = []; - if (options.bytes !== Array) - object.snapshotMac = $util.newBuffer(object.snapshotMac); - } - if (options.bytes === String) - object.patchMac = ""; - else { - object.patchMac = []; - if (options.bytes !== Array) - object.patchMac = $util.newBuffer(object.patchMac); - } - object.keyId = null; - object.exitCode = null; - object.deviceIndex = 0; - } - if (message.version != null && message.hasOwnProperty("version")) - object.version = $root.proto.SyncdVersion.toObject(message.version, options); - if (message.mutations && message.mutations.length) { - object.mutations = []; - for (var j = 0; j < message.mutations.length; ++j) - object.mutations[j] = $root.proto.SyncdMutation.toObject(message.mutations[j], options); - } - if (message.externalMutations != null && message.hasOwnProperty("externalMutations")) - object.externalMutations = $root.proto.ExternalBlobReference.toObject(message.externalMutations, options); - if (message.snapshotMac != null && message.hasOwnProperty("snapshotMac")) - object.snapshotMac = options.bytes === String ? $util.base64.encode(message.snapshotMac, 0, message.snapshotMac.length) : options.bytes === Array ? Array.prototype.slice.call(message.snapshotMac) : message.snapshotMac; - if (message.patchMac != null && message.hasOwnProperty("patchMac")) - object.patchMac = options.bytes === String ? $util.base64.encode(message.patchMac, 0, message.patchMac.length) : options.bytes === Array ? Array.prototype.slice.call(message.patchMac) : message.patchMac; - if (message.keyId != null && message.hasOwnProperty("keyId")) - object.keyId = $root.proto.KeyId.toObject(message.keyId, options); - if (message.exitCode != null && message.hasOwnProperty("exitCode")) - object.exitCode = $root.proto.ExitCode.toObject(message.exitCode, options); - if (message.deviceIndex != null && message.hasOwnProperty("deviceIndex")) - object.deviceIndex = message.deviceIndex; - return object; - }; - - /** - * Converts this SyncdPatch to JSON. - * @function toJSON - * @memberof proto.SyncdPatch - * @instance - * @returns {Object.} JSON object - */ - SyncdPatch.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SyncdPatch; - })(); - - proto.SyncdMutation = (function() { - - /** - * Properties of a SyncdMutation. - * @memberof proto - * @interface ISyncdMutation - * @property {proto.SyncdMutation.SyncdMutationSyncdOperation|null} [operation] SyncdMutation operation - * @property {proto.ISyncdRecord|null} [record] SyncdMutation record - */ - - /** - * Constructs a new SyncdMutation. - * @memberof proto - * @classdesc Represents a SyncdMutation. - * @implements ISyncdMutation - * @constructor - * @param {proto.ISyncdMutation=} [properties] Properties to set - */ - function SyncdMutation(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SyncdMutation operation. - * @member {proto.SyncdMutation.SyncdMutationSyncdOperation} operation - * @memberof proto.SyncdMutation - * @instance - */ - SyncdMutation.prototype.operation = 0; - - /** - * SyncdMutation record. - * @member {proto.ISyncdRecord|null|undefined} record - * @memberof proto.SyncdMutation - * @instance - */ - SyncdMutation.prototype.record = null; - - /** - * Creates a new SyncdMutation instance using the specified properties. - * @function create - * @memberof proto.SyncdMutation - * @static - * @param {proto.ISyncdMutation=} [properties] Properties to set - * @returns {proto.SyncdMutation} SyncdMutation instance - */ - SyncdMutation.create = function create(properties) { - return new SyncdMutation(properties); - }; - - /** - * Encodes the specified SyncdMutation message. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages. - * @function encode - * @memberof proto.SyncdMutation - * @static - * @param {proto.ISyncdMutation} message SyncdMutation message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdMutation.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.operation != null && Object.hasOwnProperty.call(message, "operation")) - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.operation); - if (message.record != null && Object.hasOwnProperty.call(message, "record")) - $root.proto.SyncdRecord.encode(message.record, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified SyncdMutation message, length delimited. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SyncdMutation - * @static - * @param {proto.ISyncdMutation} message SyncdMutation message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdMutation.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SyncdMutation message from the specified reader or buffer. - * @function decode - * @memberof proto.SyncdMutation - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SyncdMutation} SyncdMutation - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdMutation.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdMutation(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.operation = reader.int32(); - break; - case 2: - message.record = $root.proto.SyncdRecord.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SyncdMutation message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SyncdMutation - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SyncdMutation} SyncdMutation - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdMutation.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SyncdMutation message. - * @function verify - * @memberof proto.SyncdMutation - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SyncdMutation.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.operation != null && message.hasOwnProperty("operation")) - switch (message.operation) { - default: - return "operation: enum value expected"; - case 0: - case 1: - break; - } - if (message.record != null && message.hasOwnProperty("record")) { - var error = $root.proto.SyncdRecord.verify(message.record); - if (error) - return "record." + error; - } - return null; - }; - - /** - * Creates a SyncdMutation message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SyncdMutation - * @static - * @param {Object.} object Plain object - * @returns {proto.SyncdMutation} SyncdMutation - */ - SyncdMutation.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SyncdMutation) - return object; - var message = new $root.proto.SyncdMutation(); - switch (object.operation) { - case "SET": - case 0: - message.operation = 0; - break; - case "REMOVE": - case 1: - message.operation = 1; - break; - } - if (object.record != null) { - if (typeof object.record !== "object") - throw TypeError(".proto.SyncdMutation.record: object expected"); - message.record = $root.proto.SyncdRecord.fromObject(object.record); - } - return message; - }; - - /** - * Creates a plain object from a SyncdMutation message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SyncdMutation - * @static - * @param {proto.SyncdMutation} message SyncdMutation - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SyncdMutation.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.operation = options.enums === String ? "SET" : 0; - object.record = null; - } - if (message.operation != null && message.hasOwnProperty("operation")) - object.operation = options.enums === String ? $root.proto.SyncdMutation.SyncdMutationSyncdOperation[message.operation] : message.operation; - if (message.record != null && message.hasOwnProperty("record")) - object.record = $root.proto.SyncdRecord.toObject(message.record, options); - return object; - }; - - /** - * Converts this SyncdMutation to JSON. - * @function toJSON - * @memberof proto.SyncdMutation - * @instance - * @returns {Object.} JSON object - */ - SyncdMutation.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * SyncdMutationSyncdOperation enum. - * @name proto.SyncdMutation.SyncdMutationSyncdOperation - * @enum {number} - * @property {number} SET=0 SET value - * @property {number} REMOVE=1 REMOVE value - */ - SyncdMutation.SyncdMutationSyncdOperation = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "SET"] = 0; - values[valuesById[1] = "REMOVE"] = 1; - return values; - })(); - - return SyncdMutation; - })(); - - proto.SyncdMutations = (function() { - - /** - * Properties of a SyncdMutations. - * @memberof proto - * @interface ISyncdMutations - * @property {Array.|null} [mutations] SyncdMutations mutations - */ - - /** - * Constructs a new SyncdMutations. - * @memberof proto - * @classdesc Represents a SyncdMutations. - * @implements ISyncdMutations - * @constructor - * @param {proto.ISyncdMutations=} [properties] Properties to set - */ - function SyncdMutations(properties) { - this.mutations = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SyncdMutations mutations. - * @member {Array.} mutations - * @memberof proto.SyncdMutations - * @instance - */ - SyncdMutations.prototype.mutations = $util.emptyArray; - - /** - * Creates a new SyncdMutations instance using the specified properties. - * @function create - * @memberof proto.SyncdMutations - * @static - * @param {proto.ISyncdMutations=} [properties] Properties to set - * @returns {proto.SyncdMutations} SyncdMutations instance - */ - SyncdMutations.create = function create(properties) { - return new SyncdMutations(properties); - }; - - /** - * Encodes the specified SyncdMutations message. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages. - * @function encode - * @memberof proto.SyncdMutations - * @static - * @param {proto.ISyncdMutations} message SyncdMutations message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdMutations.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.mutations != null && message.mutations.length) - for (var i = 0; i < message.mutations.length; ++i) - $root.proto.SyncdMutation.encode(message.mutations[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified SyncdMutations message, length delimited. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SyncdMutations - * @static - * @param {proto.ISyncdMutations} message SyncdMutations message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdMutations.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SyncdMutations message from the specified reader or buffer. - * @function decode - * @memberof proto.SyncdMutations - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SyncdMutations} SyncdMutations - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdMutations.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdMutations(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (!(message.mutations && message.mutations.length)) - message.mutations = []; - message.mutations.push($root.proto.SyncdMutation.decode(reader, reader.uint32())); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SyncdMutations message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SyncdMutations - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SyncdMutations} SyncdMutations - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdMutations.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SyncdMutations message. - * @function verify - * @memberof proto.SyncdMutations - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SyncdMutations.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.mutations != null && message.hasOwnProperty("mutations")) { - if (!Array.isArray(message.mutations)) - return "mutations: array expected"; - for (var i = 0; i < message.mutations.length; ++i) { - var error = $root.proto.SyncdMutation.verify(message.mutations[i]); - if (error) - return "mutations." + error; - } - } - return null; - }; - - /** - * Creates a SyncdMutations message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SyncdMutations - * @static - * @param {Object.} object Plain object - * @returns {proto.SyncdMutations} SyncdMutations - */ - SyncdMutations.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SyncdMutations) - return object; - var message = new $root.proto.SyncdMutations(); - if (object.mutations) { - if (!Array.isArray(object.mutations)) - throw TypeError(".proto.SyncdMutations.mutations: array expected"); - message.mutations = []; - for (var i = 0; i < object.mutations.length; ++i) { - if (typeof object.mutations[i] !== "object") - throw TypeError(".proto.SyncdMutations.mutations: object expected"); - message.mutations[i] = $root.proto.SyncdMutation.fromObject(object.mutations[i]); - } - } - return message; - }; - - /** - * Creates a plain object from a SyncdMutations message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SyncdMutations - * @static - * @param {proto.SyncdMutations} message SyncdMutations - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SyncdMutations.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.mutations = []; - if (message.mutations && message.mutations.length) { - object.mutations = []; - for (var j = 0; j < message.mutations.length; ++j) - object.mutations[j] = $root.proto.SyncdMutation.toObject(message.mutations[j], options); - } - return object; - }; - - /** - * Converts this SyncdMutations to JSON. - * @function toJSON - * @memberof proto.SyncdMutations - * @instance - * @returns {Object.} JSON object - */ - SyncdMutations.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SyncdMutations; - })(); - - proto.SyncdSnapshot = (function() { - - /** - * Properties of a SyncdSnapshot. - * @memberof proto - * @interface ISyncdSnapshot - * @property {proto.ISyncdVersion|null} [version] SyncdSnapshot version - * @property {Array.|null} [records] SyncdSnapshot records - * @property {Uint8Array|null} [mac] SyncdSnapshot mac - * @property {proto.IKeyId|null} [keyId] SyncdSnapshot keyId - */ - - /** - * Constructs a new SyncdSnapshot. - * @memberof proto - * @classdesc Represents a SyncdSnapshot. - * @implements ISyncdSnapshot - * @constructor - * @param {proto.ISyncdSnapshot=} [properties] Properties to set - */ - function SyncdSnapshot(properties) { - this.records = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SyncdSnapshot version. - * @member {proto.ISyncdVersion|null|undefined} version - * @memberof proto.SyncdSnapshot - * @instance - */ - SyncdSnapshot.prototype.version = null; - - /** - * SyncdSnapshot records. - * @member {Array.} records - * @memberof proto.SyncdSnapshot - * @instance - */ - SyncdSnapshot.prototype.records = $util.emptyArray; - - /** - * SyncdSnapshot mac. - * @member {Uint8Array} mac - * @memberof proto.SyncdSnapshot - * @instance - */ - SyncdSnapshot.prototype.mac = $util.newBuffer([]); - - /** - * SyncdSnapshot keyId. - * @member {proto.IKeyId|null|undefined} keyId - * @memberof proto.SyncdSnapshot - * @instance - */ - SyncdSnapshot.prototype.keyId = null; - - /** - * Creates a new SyncdSnapshot instance using the specified properties. - * @function create - * @memberof proto.SyncdSnapshot - * @static - * @param {proto.ISyncdSnapshot=} [properties] Properties to set - * @returns {proto.SyncdSnapshot} SyncdSnapshot instance - */ - SyncdSnapshot.create = function create(properties) { - return new SyncdSnapshot(properties); - }; - - /** - * Encodes the specified SyncdSnapshot message. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages. - * @function encode - * @memberof proto.SyncdSnapshot - * @static - * @param {proto.ISyncdSnapshot} message SyncdSnapshot message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdSnapshot.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.version != null && Object.hasOwnProperty.call(message, "version")) - $root.proto.SyncdVersion.encode(message.version, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.records != null && message.records.length) - for (var i = 0; i < message.records.length; ++i) - $root.proto.SyncdRecord.encode(message.records[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.mac != null && Object.hasOwnProperty.call(message, "mac")) - writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.mac); - if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId")) - $root.proto.KeyId.encode(message.keyId, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified SyncdSnapshot message, length delimited. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SyncdSnapshot - * @static - * @param {proto.ISyncdSnapshot} message SyncdSnapshot message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdSnapshot.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SyncdSnapshot message from the specified reader or buffer. - * @function decode - * @memberof proto.SyncdSnapshot - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SyncdSnapshot} SyncdSnapshot - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdSnapshot.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdSnapshot(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.version = $root.proto.SyncdVersion.decode(reader, reader.uint32()); - break; - case 2: - if (!(message.records && message.records.length)) - message.records = []; - message.records.push($root.proto.SyncdRecord.decode(reader, reader.uint32())); - break; - case 3: - message.mac = reader.bytes(); - break; - case 4: - message.keyId = $root.proto.KeyId.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SyncdSnapshot message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SyncdSnapshot - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SyncdSnapshot} SyncdSnapshot - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdSnapshot.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SyncdSnapshot message. - * @function verify - * @memberof proto.SyncdSnapshot - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SyncdSnapshot.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.version != null && message.hasOwnProperty("version")) { - var error = $root.proto.SyncdVersion.verify(message.version); - if (error) - return "version." + error; - } - if (message.records != null && message.hasOwnProperty("records")) { - if (!Array.isArray(message.records)) - return "records: array expected"; - for (var i = 0; i < message.records.length; ++i) { - var error = $root.proto.SyncdRecord.verify(message.records[i]); - if (error) - return "records." + error; - } - } - if (message.mac != null && message.hasOwnProperty("mac")) - if (!(message.mac && typeof message.mac.length === "number" || $util.isString(message.mac))) - return "mac: buffer expected"; - if (message.keyId != null && message.hasOwnProperty("keyId")) { - var error = $root.proto.KeyId.verify(message.keyId); - if (error) - return "keyId." + error; - } - return null; - }; - - /** - * Creates a SyncdSnapshot message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SyncdSnapshot - * @static - * @param {Object.} object Plain object - * @returns {proto.SyncdSnapshot} SyncdSnapshot - */ - SyncdSnapshot.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SyncdSnapshot) - return object; - var message = new $root.proto.SyncdSnapshot(); - if (object.version != null) { - if (typeof object.version !== "object") - throw TypeError(".proto.SyncdSnapshot.version: object expected"); - message.version = $root.proto.SyncdVersion.fromObject(object.version); - } - if (object.records) { - if (!Array.isArray(object.records)) - throw TypeError(".proto.SyncdSnapshot.records: array expected"); - message.records = []; - for (var i = 0; i < object.records.length; ++i) { - if (typeof object.records[i] !== "object") - throw TypeError(".proto.SyncdSnapshot.records: object expected"); - message.records[i] = $root.proto.SyncdRecord.fromObject(object.records[i]); - } - } - if (object.mac != null) - if (typeof object.mac === "string") - $util.base64.decode(object.mac, message.mac = $util.newBuffer($util.base64.length(object.mac)), 0); - else if (object.mac.length) - message.mac = object.mac; - if (object.keyId != null) { - if (typeof object.keyId !== "object") - throw TypeError(".proto.SyncdSnapshot.keyId: object expected"); - message.keyId = $root.proto.KeyId.fromObject(object.keyId); - } - return message; - }; - - /** - * Creates a plain object from a SyncdSnapshot message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SyncdSnapshot - * @static - * @param {proto.SyncdSnapshot} message SyncdSnapshot - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SyncdSnapshot.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.records = []; - if (options.defaults) { - object.version = null; - if (options.bytes === String) - object.mac = ""; - else { - object.mac = []; - if (options.bytes !== Array) - object.mac = $util.newBuffer(object.mac); - } - object.keyId = null; - } - if (message.version != null && message.hasOwnProperty("version")) - object.version = $root.proto.SyncdVersion.toObject(message.version, options); - if (message.records && message.records.length) { - object.records = []; - for (var j = 0; j < message.records.length; ++j) - object.records[j] = $root.proto.SyncdRecord.toObject(message.records[j], options); - } - if (message.mac != null && message.hasOwnProperty("mac")) - object.mac = options.bytes === String ? $util.base64.encode(message.mac, 0, message.mac.length) : options.bytes === Array ? Array.prototype.slice.call(message.mac) : message.mac; - if (message.keyId != null && message.hasOwnProperty("keyId")) - object.keyId = $root.proto.KeyId.toObject(message.keyId, options); - return object; - }; - - /** - * Converts this SyncdSnapshot to JSON. - * @function toJSON - * @memberof proto.SyncdSnapshot - * @instance - * @returns {Object.} JSON object - */ - SyncdSnapshot.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SyncdSnapshot; - })(); - - proto.ExternalBlobReference = (function() { - - /** - * Properties of an ExternalBlobReference. - * @memberof proto - * @interface IExternalBlobReference - * @property {Uint8Array|null} [mediaKey] ExternalBlobReference mediaKey - * @property {string|null} [directPath] ExternalBlobReference directPath - * @property {string|null} [handle] ExternalBlobReference handle - * @property {number|Long|null} [fileSizeBytes] ExternalBlobReference fileSizeBytes - * @property {Uint8Array|null} [fileSha256] ExternalBlobReference fileSha256 - * @property {Uint8Array|null} [fileEncSha256] ExternalBlobReference fileEncSha256 - */ - - /** - * Constructs a new ExternalBlobReference. - * @memberof proto - * @classdesc Represents an ExternalBlobReference. - * @implements IExternalBlobReference - * @constructor - * @param {proto.IExternalBlobReference=} [properties] Properties to set - */ - function ExternalBlobReference(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ExternalBlobReference mediaKey. - * @member {Uint8Array} mediaKey - * @memberof proto.ExternalBlobReference - * @instance - */ - ExternalBlobReference.prototype.mediaKey = $util.newBuffer([]); - - /** - * ExternalBlobReference directPath. - * @member {string} directPath - * @memberof proto.ExternalBlobReference - * @instance - */ - ExternalBlobReference.prototype.directPath = ""; - - /** - * ExternalBlobReference handle. - * @member {string} handle - * @memberof proto.ExternalBlobReference - * @instance - */ - ExternalBlobReference.prototype.handle = ""; - - /** - * ExternalBlobReference fileSizeBytes. - * @member {number|Long} fileSizeBytes - * @memberof proto.ExternalBlobReference - * @instance - */ - ExternalBlobReference.prototype.fileSizeBytes = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * ExternalBlobReference fileSha256. - * @member {Uint8Array} fileSha256 - * @memberof proto.ExternalBlobReference - * @instance - */ - ExternalBlobReference.prototype.fileSha256 = $util.newBuffer([]); - - /** - * ExternalBlobReference fileEncSha256. - * @member {Uint8Array} fileEncSha256 - * @memberof proto.ExternalBlobReference - * @instance - */ - ExternalBlobReference.prototype.fileEncSha256 = $util.newBuffer([]); - - /** - * Creates a new ExternalBlobReference instance using the specified properties. - * @function create - * @memberof proto.ExternalBlobReference - * @static - * @param {proto.IExternalBlobReference=} [properties] Properties to set - * @returns {proto.ExternalBlobReference} ExternalBlobReference instance - */ - ExternalBlobReference.create = function create(properties) { - return new ExternalBlobReference(properties); - }; - - /** - * Encodes the specified ExternalBlobReference message. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages. - * @function encode - * @memberof proto.ExternalBlobReference - * @static - * @param {proto.IExternalBlobReference} message ExternalBlobReference message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ExternalBlobReference.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.mediaKey); - if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.directPath); - if (message.handle != null && Object.hasOwnProperty.call(message, "handle")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.handle); - if (message.fileSizeBytes != null && Object.hasOwnProperty.call(message, "fileSizeBytes")) - writer.uint32(/* id 4, wireType 0 =*/32).uint64(message.fileSizeBytes); - if (message.fileSha256 != null && Object.hasOwnProperty.call(message, "fileSha256")) - writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.fileSha256); - if (message.fileEncSha256 != null && Object.hasOwnProperty.call(message, "fileEncSha256")) - writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.fileEncSha256); - return writer; - }; - - /** - * Encodes the specified ExternalBlobReference message, length delimited. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ExternalBlobReference - * @static - * @param {proto.IExternalBlobReference} message ExternalBlobReference message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ExternalBlobReference.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes an ExternalBlobReference message from the specified reader or buffer. - * @function decode - * @memberof proto.ExternalBlobReference - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ExternalBlobReference} ExternalBlobReference - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ExternalBlobReference.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ExternalBlobReference(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.mediaKey = reader.bytes(); - break; - case 2: - message.directPath = reader.string(); - break; - case 3: - message.handle = reader.string(); - break; - case 4: - message.fileSizeBytes = reader.uint64(); - break; - case 5: - message.fileSha256 = reader.bytes(); - break; - case 6: - message.fileEncSha256 = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes an ExternalBlobReference message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ExternalBlobReference - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ExternalBlobReference} ExternalBlobReference - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ExternalBlobReference.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies an ExternalBlobReference message. - * @function verify - * @memberof proto.ExternalBlobReference - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ExternalBlobReference.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) - if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey))) - return "mediaKey: buffer expected"; - if (message.directPath != null && message.hasOwnProperty("directPath")) - if (!$util.isString(message.directPath)) - return "directPath: string expected"; - if (message.handle != null && message.hasOwnProperty("handle")) - if (!$util.isString(message.handle)) - return "handle: string expected"; - if (message.fileSizeBytes != null && message.hasOwnProperty("fileSizeBytes")) - if (!$util.isInteger(message.fileSizeBytes) && !(message.fileSizeBytes && $util.isInteger(message.fileSizeBytes.low) && $util.isInteger(message.fileSizeBytes.high))) - return "fileSizeBytes: integer|Long expected"; - if (message.fileSha256 != null && message.hasOwnProperty("fileSha256")) - if (!(message.fileSha256 && typeof message.fileSha256.length === "number" || $util.isString(message.fileSha256))) - return "fileSha256: buffer expected"; - if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256")) - if (!(message.fileEncSha256 && typeof message.fileEncSha256.length === "number" || $util.isString(message.fileEncSha256))) - return "fileEncSha256: buffer expected"; - return null; - }; - - /** - * Creates an ExternalBlobReference message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ExternalBlobReference - * @static - * @param {Object.} object Plain object - * @returns {proto.ExternalBlobReference} ExternalBlobReference - */ - ExternalBlobReference.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ExternalBlobReference) - return object; - var message = new $root.proto.ExternalBlobReference(); - if (object.mediaKey != null) - if (typeof object.mediaKey === "string") - $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0); - else if (object.mediaKey.length) - message.mediaKey = object.mediaKey; - if (object.directPath != null) - message.directPath = String(object.directPath); - if (object.handle != null) - message.handle = String(object.handle); - if (object.fileSizeBytes != null) - if ($util.Long) - (message.fileSizeBytes = $util.Long.fromValue(object.fileSizeBytes)).unsigned = true; - else if (typeof object.fileSizeBytes === "string") - message.fileSizeBytes = parseInt(object.fileSizeBytes, 10); - else if (typeof object.fileSizeBytes === "number") - message.fileSizeBytes = object.fileSizeBytes; - else if (typeof object.fileSizeBytes === "object") - message.fileSizeBytes = new $util.LongBits(object.fileSizeBytes.low >>> 0, object.fileSizeBytes.high >>> 0).toNumber(true); - if (object.fileSha256 != null) - if (typeof object.fileSha256 === "string") - $util.base64.decode(object.fileSha256, message.fileSha256 = $util.newBuffer($util.base64.length(object.fileSha256)), 0); - else if (object.fileSha256.length) - message.fileSha256 = object.fileSha256; - if (object.fileEncSha256 != null) - if (typeof object.fileEncSha256 === "string") - $util.base64.decode(object.fileEncSha256, message.fileEncSha256 = $util.newBuffer($util.base64.length(object.fileEncSha256)), 0); - else if (object.fileEncSha256.length) - message.fileEncSha256 = object.fileEncSha256; - return message; - }; - - /** - * Creates a plain object from an ExternalBlobReference message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ExternalBlobReference - * @static - * @param {proto.ExternalBlobReference} message ExternalBlobReference - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ExternalBlobReference.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if (options.bytes === String) - object.mediaKey = ""; - else { - object.mediaKey = []; - if (options.bytes !== Array) - object.mediaKey = $util.newBuffer(object.mediaKey); - } - object.directPath = ""; - object.handle = ""; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.fileSizeBytes = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.fileSizeBytes = options.longs === String ? "0" : 0; - if (options.bytes === String) - object.fileSha256 = ""; - else { - object.fileSha256 = []; - if (options.bytes !== Array) - object.fileSha256 = $util.newBuffer(object.fileSha256); - } - if (options.bytes === String) - object.fileEncSha256 = ""; - else { - object.fileEncSha256 = []; - if (options.bytes !== Array) - object.fileEncSha256 = $util.newBuffer(object.fileEncSha256); - } - } - if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) - object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey; - if (message.directPath != null && message.hasOwnProperty("directPath")) - object.directPath = message.directPath; - if (message.handle != null && message.hasOwnProperty("handle")) - object.handle = message.handle; - if (message.fileSizeBytes != null && message.hasOwnProperty("fileSizeBytes")) - if (typeof message.fileSizeBytes === "number") - object.fileSizeBytes = options.longs === String ? String(message.fileSizeBytes) : message.fileSizeBytes; - else - object.fileSizeBytes = options.longs === String ? $util.Long.prototype.toString.call(message.fileSizeBytes) : options.longs === Number ? new $util.LongBits(message.fileSizeBytes.low >>> 0, message.fileSizeBytes.high >>> 0).toNumber(true) : message.fileSizeBytes; - if (message.fileSha256 != null && message.hasOwnProperty("fileSha256")) - object.fileSha256 = options.bytes === String ? $util.base64.encode(message.fileSha256, 0, message.fileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileSha256) : message.fileSha256; - if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256")) - object.fileEncSha256 = options.bytes === String ? $util.base64.encode(message.fileEncSha256, 0, message.fileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileEncSha256) : message.fileEncSha256; - return object; - }; - - /** - * Converts this ExternalBlobReference to JSON. - * @function toJSON - * @memberof proto.ExternalBlobReference - * @instance - * @returns {Object.} JSON object - */ - ExternalBlobReference.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ExternalBlobReference; - })(); - - proto.SyncdRecord = (function() { - - /** - * Properties of a SyncdRecord. - * @memberof proto - * @interface ISyncdRecord - * @property {proto.ISyncdIndex|null} [index] SyncdRecord index - * @property {proto.ISyncdValue|null} [value] SyncdRecord value - * @property {proto.IKeyId|null} [keyId] SyncdRecord keyId - */ - - /** - * Constructs a new SyncdRecord. - * @memberof proto - * @classdesc Represents a SyncdRecord. - * @implements ISyncdRecord - * @constructor - * @param {proto.ISyncdRecord=} [properties] Properties to set - */ - function SyncdRecord(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SyncdRecord index. - * @member {proto.ISyncdIndex|null|undefined} index - * @memberof proto.SyncdRecord - * @instance - */ - SyncdRecord.prototype.index = null; - - /** - * SyncdRecord value. - * @member {proto.ISyncdValue|null|undefined} value - * @memberof proto.SyncdRecord - * @instance - */ - SyncdRecord.prototype.value = null; - - /** - * SyncdRecord keyId. - * @member {proto.IKeyId|null|undefined} keyId - * @memberof proto.SyncdRecord - * @instance - */ - SyncdRecord.prototype.keyId = null; - - /** - * Creates a new SyncdRecord instance using the specified properties. - * @function create - * @memberof proto.SyncdRecord - * @static - * @param {proto.ISyncdRecord=} [properties] Properties to set - * @returns {proto.SyncdRecord} SyncdRecord instance - */ - SyncdRecord.create = function create(properties) { - return new SyncdRecord(properties); - }; - - /** - * Encodes the specified SyncdRecord message. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages. - * @function encode - * @memberof proto.SyncdRecord - * @static - * @param {proto.ISyncdRecord} message SyncdRecord message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdRecord.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.index != null && Object.hasOwnProperty.call(message, "index")) - $root.proto.SyncdIndex.encode(message.index, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.value != null && Object.hasOwnProperty.call(message, "value")) - $root.proto.SyncdValue.encode(message.value, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId")) - $root.proto.KeyId.encode(message.keyId, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified SyncdRecord message, length delimited. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SyncdRecord - * @static - * @param {proto.ISyncdRecord} message SyncdRecord message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdRecord.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SyncdRecord message from the specified reader or buffer. - * @function decode - * @memberof proto.SyncdRecord - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SyncdRecord} SyncdRecord - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdRecord.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdRecord(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.index = $root.proto.SyncdIndex.decode(reader, reader.uint32()); - break; - case 2: - message.value = $root.proto.SyncdValue.decode(reader, reader.uint32()); - break; - case 3: - message.keyId = $root.proto.KeyId.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SyncdRecord message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SyncdRecord - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SyncdRecord} SyncdRecord - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdRecord.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SyncdRecord message. - * @function verify - * @memberof proto.SyncdRecord - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SyncdRecord.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.index != null && message.hasOwnProperty("index")) { - var error = $root.proto.SyncdIndex.verify(message.index); - if (error) - return "index." + error; - } - if (message.value != null && message.hasOwnProperty("value")) { - var error = $root.proto.SyncdValue.verify(message.value); - if (error) - return "value." + error; - } - if (message.keyId != null && message.hasOwnProperty("keyId")) { - var error = $root.proto.KeyId.verify(message.keyId); - if (error) - return "keyId." + error; - } - return null; - }; - - /** - * Creates a SyncdRecord message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SyncdRecord - * @static - * @param {Object.} object Plain object - * @returns {proto.SyncdRecord} SyncdRecord - */ - SyncdRecord.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SyncdRecord) - return object; - var message = new $root.proto.SyncdRecord(); - if (object.index != null) { - if (typeof object.index !== "object") - throw TypeError(".proto.SyncdRecord.index: object expected"); - message.index = $root.proto.SyncdIndex.fromObject(object.index); - } - if (object.value != null) { - if (typeof object.value !== "object") - throw TypeError(".proto.SyncdRecord.value: object expected"); - message.value = $root.proto.SyncdValue.fromObject(object.value); - } - if (object.keyId != null) { - if (typeof object.keyId !== "object") - throw TypeError(".proto.SyncdRecord.keyId: object expected"); - message.keyId = $root.proto.KeyId.fromObject(object.keyId); - } - return message; - }; - - /** - * Creates a plain object from a SyncdRecord message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SyncdRecord - * @static - * @param {proto.SyncdRecord} message SyncdRecord - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SyncdRecord.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.index = null; - object.value = null; - object.keyId = null; - } - if (message.index != null && message.hasOwnProperty("index")) - object.index = $root.proto.SyncdIndex.toObject(message.index, options); - if (message.value != null && message.hasOwnProperty("value")) - object.value = $root.proto.SyncdValue.toObject(message.value, options); - if (message.keyId != null && message.hasOwnProperty("keyId")) - object.keyId = $root.proto.KeyId.toObject(message.keyId, options); - return object; - }; - - /** - * Converts this SyncdRecord to JSON. - * @function toJSON - * @memberof proto.SyncdRecord - * @instance - * @returns {Object.} JSON object - */ - SyncdRecord.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SyncdRecord; - })(); - - proto.KeyId = (function() { - - /** - * Properties of a KeyId. - * @memberof proto - * @interface IKeyId - * @property {Uint8Array|null} [id] KeyId id - */ - - /** - * Constructs a new KeyId. - * @memberof proto - * @classdesc Represents a KeyId. - * @implements IKeyId - * @constructor - * @param {proto.IKeyId=} [properties] Properties to set - */ - function KeyId(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * KeyId id. - * @member {Uint8Array} id - * @memberof proto.KeyId - * @instance - */ - KeyId.prototype.id = $util.newBuffer([]); - - /** - * Creates a new KeyId instance using the specified properties. - * @function create - * @memberof proto.KeyId - * @static - * @param {proto.IKeyId=} [properties] Properties to set - * @returns {proto.KeyId} KeyId instance - */ - KeyId.create = function create(properties) { - return new KeyId(properties); - }; - - /** - * Encodes the specified KeyId message. Does not implicitly {@link proto.KeyId.verify|verify} messages. - * @function encode - * @memberof proto.KeyId - * @static - * @param {proto.IKeyId} message KeyId message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - KeyId.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.id); - return writer; - }; - - /** - * Encodes the specified KeyId message, length delimited. Does not implicitly {@link proto.KeyId.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.KeyId - * @static - * @param {proto.IKeyId} message KeyId message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - KeyId.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a KeyId message from the specified reader or buffer. - * @function decode - * @memberof proto.KeyId - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.KeyId} KeyId - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - KeyId.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.KeyId(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.id = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a KeyId message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.KeyId - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.KeyId} KeyId - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - KeyId.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a KeyId message. - * @function verify - * @memberof proto.KeyId - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - KeyId.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.id != null && message.hasOwnProperty("id")) - if (!(message.id && typeof message.id.length === "number" || $util.isString(message.id))) - return "id: buffer expected"; - return null; - }; - - /** - * Creates a KeyId message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.KeyId - * @static - * @param {Object.} object Plain object - * @returns {proto.KeyId} KeyId - */ - KeyId.fromObject = function fromObject(object) { - if (object instanceof $root.proto.KeyId) - return object; - var message = new $root.proto.KeyId(); - if (object.id != null) - if (typeof object.id === "string") - $util.base64.decode(object.id, message.id = $util.newBuffer($util.base64.length(object.id)), 0); - else if (object.id.length) - message.id = object.id; - return message; - }; - - /** - * Creates a plain object from a KeyId message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.KeyId - * @static - * @param {proto.KeyId} message KeyId - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - KeyId.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - if (options.bytes === String) - object.id = ""; - else { - object.id = []; - if (options.bytes !== Array) - object.id = $util.newBuffer(object.id); - } - if (message.id != null && message.hasOwnProperty("id")) - object.id = options.bytes === String ? $util.base64.encode(message.id, 0, message.id.length) : options.bytes === Array ? Array.prototype.slice.call(message.id) : message.id; - return object; - }; - - /** - * Converts this KeyId to JSON. - * @function toJSON - * @memberof proto.KeyId - * @instance - * @returns {Object.} JSON object - */ - KeyId.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return KeyId; - })(); - - proto.SyncdValue = (function() { - - /** - * Properties of a SyncdValue. - * @memberof proto - * @interface ISyncdValue - * @property {Uint8Array|null} [blob] SyncdValue blob - */ - - /** - * Constructs a new SyncdValue. - * @memberof proto - * @classdesc Represents a SyncdValue. - * @implements ISyncdValue - * @constructor - * @param {proto.ISyncdValue=} [properties] Properties to set - */ - function SyncdValue(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SyncdValue blob. - * @member {Uint8Array} blob - * @memberof proto.SyncdValue - * @instance - */ - SyncdValue.prototype.blob = $util.newBuffer([]); - - /** - * Creates a new SyncdValue instance using the specified properties. - * @function create - * @memberof proto.SyncdValue - * @static - * @param {proto.ISyncdValue=} [properties] Properties to set - * @returns {proto.SyncdValue} SyncdValue instance - */ - SyncdValue.create = function create(properties) { - return new SyncdValue(properties); - }; - - /** - * Encodes the specified SyncdValue message. Does not implicitly {@link proto.SyncdValue.verify|verify} messages. - * @function encode - * @memberof proto.SyncdValue - * @static - * @param {proto.ISyncdValue} message SyncdValue message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdValue.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.blob != null && Object.hasOwnProperty.call(message, "blob")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.blob); - return writer; - }; - - /** - * Encodes the specified SyncdValue message, length delimited. Does not implicitly {@link proto.SyncdValue.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SyncdValue - * @static - * @param {proto.ISyncdValue} message SyncdValue message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdValue.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SyncdValue message from the specified reader or buffer. - * @function decode - * @memberof proto.SyncdValue - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SyncdValue} SyncdValue - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdValue.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdValue(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.blob = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SyncdValue message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SyncdValue - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SyncdValue} SyncdValue - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdValue.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SyncdValue message. - * @function verify - * @memberof proto.SyncdValue - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SyncdValue.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.blob != null && message.hasOwnProperty("blob")) - if (!(message.blob && typeof message.blob.length === "number" || $util.isString(message.blob))) - return "blob: buffer expected"; - return null; - }; - - /** - * Creates a SyncdValue message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SyncdValue - * @static - * @param {Object.} object Plain object - * @returns {proto.SyncdValue} SyncdValue - */ - SyncdValue.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SyncdValue) - return object; - var message = new $root.proto.SyncdValue(); - if (object.blob != null) - if (typeof object.blob === "string") - $util.base64.decode(object.blob, message.blob = $util.newBuffer($util.base64.length(object.blob)), 0); - else if (object.blob.length) - message.blob = object.blob; - return message; - }; - - /** - * Creates a plain object from a SyncdValue message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SyncdValue - * @static - * @param {proto.SyncdValue} message SyncdValue - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SyncdValue.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - if (options.bytes === String) - object.blob = ""; - else { - object.blob = []; - if (options.bytes !== Array) - object.blob = $util.newBuffer(object.blob); - } - if (message.blob != null && message.hasOwnProperty("blob")) - object.blob = options.bytes === String ? $util.base64.encode(message.blob, 0, message.blob.length) : options.bytes === Array ? Array.prototype.slice.call(message.blob) : message.blob; - return object; - }; - - /** - * Converts this SyncdValue to JSON. - * @function toJSON - * @memberof proto.SyncdValue - * @instance - * @returns {Object.} JSON object - */ - SyncdValue.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SyncdValue; - })(); - - proto.SyncdIndex = (function() { - - /** - * Properties of a SyncdIndex. - * @memberof proto - * @interface ISyncdIndex - * @property {Uint8Array|null} [blob] SyncdIndex blob - */ - - /** - * Constructs a new SyncdIndex. - * @memberof proto - * @classdesc Represents a SyncdIndex. - * @implements ISyncdIndex - * @constructor - * @param {proto.ISyncdIndex=} [properties] Properties to set - */ - function SyncdIndex(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SyncdIndex blob. - * @member {Uint8Array} blob - * @memberof proto.SyncdIndex - * @instance - */ - SyncdIndex.prototype.blob = $util.newBuffer([]); - - /** - * Creates a new SyncdIndex instance using the specified properties. - * @function create - * @memberof proto.SyncdIndex - * @static - * @param {proto.ISyncdIndex=} [properties] Properties to set - * @returns {proto.SyncdIndex} SyncdIndex instance - */ - SyncdIndex.create = function create(properties) { - return new SyncdIndex(properties); - }; - - /** - * Encodes the specified SyncdIndex message. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages. - * @function encode - * @memberof proto.SyncdIndex - * @static - * @param {proto.ISyncdIndex} message SyncdIndex message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdIndex.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.blob != null && Object.hasOwnProperty.call(message, "blob")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.blob); - return writer; - }; - - /** - * Encodes the specified SyncdIndex message, length delimited. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SyncdIndex - * @static - * @param {proto.ISyncdIndex} message SyncdIndex message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdIndex.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SyncdIndex message from the specified reader or buffer. - * @function decode - * @memberof proto.SyncdIndex - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SyncdIndex} SyncdIndex - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdIndex.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdIndex(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.blob = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SyncdIndex message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SyncdIndex - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SyncdIndex} SyncdIndex - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdIndex.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SyncdIndex message. - * @function verify - * @memberof proto.SyncdIndex - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SyncdIndex.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.blob != null && message.hasOwnProperty("blob")) - if (!(message.blob && typeof message.blob.length === "number" || $util.isString(message.blob))) - return "blob: buffer expected"; - return null; - }; - - /** - * Creates a SyncdIndex message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SyncdIndex - * @static - * @param {Object.} object Plain object - * @returns {proto.SyncdIndex} SyncdIndex - */ - SyncdIndex.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SyncdIndex) - return object; - var message = new $root.proto.SyncdIndex(); - if (object.blob != null) - if (typeof object.blob === "string") - $util.base64.decode(object.blob, message.blob = $util.newBuffer($util.base64.length(object.blob)), 0); - else if (object.blob.length) - message.blob = object.blob; - return message; - }; - - /** - * Creates a plain object from a SyncdIndex message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SyncdIndex - * @static - * @param {proto.SyncdIndex} message SyncdIndex - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SyncdIndex.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - if (options.bytes === String) - object.blob = ""; - else { - object.blob = []; - if (options.bytes !== Array) - object.blob = $util.newBuffer(object.blob); - } - if (message.blob != null && message.hasOwnProperty("blob")) - object.blob = options.bytes === String ? $util.base64.encode(message.blob, 0, message.blob.length) : options.bytes === Array ? Array.prototype.slice.call(message.blob) : message.blob; - return object; - }; - - /** - * Converts this SyncdIndex to JSON. - * @function toJSON - * @memberof proto.SyncdIndex - * @instance - * @returns {Object.} JSON object - */ - SyncdIndex.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SyncdIndex; - })(); - - proto.ExitCode = (function() { - - /** - * Properties of an ExitCode. - * @memberof proto - * @interface IExitCode - * @property {number|Long|null} [code] ExitCode code - * @property {string|null} [text] ExitCode text - */ - - /** - * Constructs a new ExitCode. - * @memberof proto - * @classdesc Represents an ExitCode. - * @implements IExitCode - * @constructor - * @param {proto.IExitCode=} [properties] Properties to set - */ - function ExitCode(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ExitCode code. - * @member {number|Long} code - * @memberof proto.ExitCode - * @instance - */ - ExitCode.prototype.code = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * ExitCode text. - * @member {string} text - * @memberof proto.ExitCode - * @instance - */ - ExitCode.prototype.text = ""; - - /** - * Creates a new ExitCode instance using the specified properties. - * @function create - * @memberof proto.ExitCode - * @static - * @param {proto.IExitCode=} [properties] Properties to set - * @returns {proto.ExitCode} ExitCode instance - */ - ExitCode.create = function create(properties) { - return new ExitCode(properties); - }; - - /** - * Encodes the specified ExitCode message. Does not implicitly {@link proto.ExitCode.verify|verify} messages. - * @function encode - * @memberof proto.ExitCode - * @static - * @param {proto.IExitCode} message ExitCode message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ExitCode.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.code != null && Object.hasOwnProperty.call(message, "code")) - writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.code); - if (message.text != null && Object.hasOwnProperty.call(message, "text")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.text); - return writer; - }; - - /** - * Encodes the specified ExitCode message, length delimited. Does not implicitly {@link proto.ExitCode.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ExitCode - * @static - * @param {proto.IExitCode} message ExitCode message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ExitCode.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes an ExitCode message from the specified reader or buffer. - * @function decode - * @memberof proto.ExitCode - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ExitCode} ExitCode - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ExitCode.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ExitCode(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.code = reader.uint64(); - break; - case 2: - message.text = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes an ExitCode message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ExitCode - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ExitCode} ExitCode - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ExitCode.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies an ExitCode message. - * @function verify - * @memberof proto.ExitCode - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ExitCode.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.code != null && message.hasOwnProperty("code")) - if (!$util.isInteger(message.code) && !(message.code && $util.isInteger(message.code.low) && $util.isInteger(message.code.high))) - return "code: integer|Long expected"; - if (message.text != null && message.hasOwnProperty("text")) - if (!$util.isString(message.text)) - return "text: string expected"; - return null; - }; - - /** - * Creates an ExitCode message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ExitCode - * @static - * @param {Object.} object Plain object - * @returns {proto.ExitCode} ExitCode - */ - ExitCode.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ExitCode) - return object; - var message = new $root.proto.ExitCode(); - if (object.code != null) - if ($util.Long) - (message.code = $util.Long.fromValue(object.code)).unsigned = true; - else if (typeof object.code === "string") - message.code = parseInt(object.code, 10); - else if (typeof object.code === "number") - message.code = object.code; - else if (typeof object.code === "object") - message.code = new $util.LongBits(object.code.low >>> 0, object.code.high >>> 0).toNumber(true); - if (object.text != null) - message.text = String(object.text); - return message; - }; - - /** - * Creates a plain object from an ExitCode message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ExitCode - * @static - * @param {proto.ExitCode} message ExitCode - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ExitCode.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.code = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.code = options.longs === String ? "0" : 0; - object.text = ""; - } - if (message.code != null && message.hasOwnProperty("code")) - if (typeof message.code === "number") - object.code = options.longs === String ? String(message.code) : message.code; - else - object.code = options.longs === String ? $util.Long.prototype.toString.call(message.code) : options.longs === Number ? new $util.LongBits(message.code.low >>> 0, message.code.high >>> 0).toNumber(true) : message.code; - if (message.text != null && message.hasOwnProperty("text")) - object.text = message.text; - return object; - }; - - /** - * Converts this ExitCode to JSON. - * @function toJSON - * @memberof proto.ExitCode - * @instance - * @returns {Object.} JSON object - */ - ExitCode.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ExitCode; - })(); - - proto.SyncdVersion = (function() { - - /** - * Properties of a SyncdVersion. - * @memberof proto - * @interface ISyncdVersion - * @property {number|Long|null} [version] SyncdVersion version - */ - - /** - * Constructs a new SyncdVersion. - * @memberof proto - * @classdesc Represents a SyncdVersion. - * @implements ISyncdVersion - * @constructor - * @param {proto.ISyncdVersion=} [properties] Properties to set - */ - function SyncdVersion(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * SyncdVersion version. - * @member {number|Long} version - * @memberof proto.SyncdVersion - * @instance - */ - SyncdVersion.prototype.version = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * Creates a new SyncdVersion instance using the specified properties. - * @function create - * @memberof proto.SyncdVersion - * @static - * @param {proto.ISyncdVersion=} [properties] Properties to set - * @returns {proto.SyncdVersion} SyncdVersion instance - */ - SyncdVersion.create = function create(properties) { - return new SyncdVersion(properties); - }; - - /** - * Encodes the specified SyncdVersion message. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages. - * @function encode - * @memberof proto.SyncdVersion - * @static - * @param {proto.ISyncdVersion} message SyncdVersion message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdVersion.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.version != null && Object.hasOwnProperty.call(message, "version")) - writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.version); - return writer; - }; - - /** - * Encodes the specified SyncdVersion message, length delimited. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.SyncdVersion - * @static - * @param {proto.ISyncdVersion} message SyncdVersion message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - SyncdVersion.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a SyncdVersion message from the specified reader or buffer. - * @function decode - * @memberof proto.SyncdVersion - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.SyncdVersion} SyncdVersion - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdVersion.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdVersion(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.version = reader.uint64(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a SyncdVersion message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.SyncdVersion - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.SyncdVersion} SyncdVersion - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - SyncdVersion.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a SyncdVersion message. - * @function verify - * @memberof proto.SyncdVersion - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - SyncdVersion.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.version != null && message.hasOwnProperty("version")) - if (!$util.isInteger(message.version) && !(message.version && $util.isInteger(message.version.low) && $util.isInteger(message.version.high))) - return "version: integer|Long expected"; - return null; - }; - - /** - * Creates a SyncdVersion message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.SyncdVersion - * @static - * @param {Object.} object Plain object - * @returns {proto.SyncdVersion} SyncdVersion - */ - SyncdVersion.fromObject = function fromObject(object) { - if (object instanceof $root.proto.SyncdVersion) - return object; - var message = new $root.proto.SyncdVersion(); - if (object.version != null) - if ($util.Long) - (message.version = $util.Long.fromValue(object.version)).unsigned = true; - else if (typeof object.version === "string") - message.version = parseInt(object.version, 10); - else if (typeof object.version === "number") - message.version = object.version; - else if (typeof object.version === "object") - message.version = new $util.LongBits(object.version.low >>> 0, object.version.high >>> 0).toNumber(true); - return message; - }; - - /** - * Creates a plain object from a SyncdVersion message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.SyncdVersion - * @static - * @param {proto.SyncdVersion} message SyncdVersion - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - SyncdVersion.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.version = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.version = options.longs === String ? "0" : 0; - if (message.version != null && message.hasOwnProperty("version")) - if (typeof message.version === "number") - object.version = options.longs === String ? String(message.version) : message.version; - else - object.version = options.longs === String ? $util.Long.prototype.toString.call(message.version) : options.longs === Number ? new $util.LongBits(message.version.low >>> 0, message.version.high >>> 0).toNumber(true) : message.version; - return object; - }; - - /** - * Converts this SyncdVersion to JSON. - * @function toJSON - * @memberof proto.SyncdVersion - * @instance - * @returns {Object.} JSON object - */ - SyncdVersion.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return SyncdVersion; - })(); - - proto.ServerErrorReceipt = (function() { - - /** - * Properties of a ServerErrorReceipt. - * @memberof proto - * @interface IServerErrorReceipt - * @property {string|null} [stanzaId] ServerErrorReceipt stanzaId - */ - - /** - * Constructs a new ServerErrorReceipt. - * @memberof proto - * @classdesc Represents a ServerErrorReceipt. - * @implements IServerErrorReceipt - * @constructor - * @param {proto.IServerErrorReceipt=} [properties] Properties to set - */ - function ServerErrorReceipt(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ServerErrorReceipt stanzaId. - * @member {string} stanzaId - * @memberof proto.ServerErrorReceipt - * @instance - */ - ServerErrorReceipt.prototype.stanzaId = ""; - - /** - * Creates a new ServerErrorReceipt instance using the specified properties. - * @function create - * @memberof proto.ServerErrorReceipt - * @static - * @param {proto.IServerErrorReceipt=} [properties] Properties to set - * @returns {proto.ServerErrorReceipt} ServerErrorReceipt instance - */ - ServerErrorReceipt.create = function create(properties) { - return new ServerErrorReceipt(properties); - }; - - /** - * Encodes the specified ServerErrorReceipt message. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages. - * @function encode - * @memberof proto.ServerErrorReceipt - * @static - * @param {proto.IServerErrorReceipt} message ServerErrorReceipt message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ServerErrorReceipt.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.stanzaId); - return writer; - }; - - /** - * Encodes the specified ServerErrorReceipt message, length delimited. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ServerErrorReceipt - * @static - * @param {proto.IServerErrorReceipt} message ServerErrorReceipt message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ServerErrorReceipt.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ServerErrorReceipt message from the specified reader or buffer. - * @function decode - * @memberof proto.ServerErrorReceipt - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ServerErrorReceipt} ServerErrorReceipt - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ServerErrorReceipt.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ServerErrorReceipt(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.stanzaId = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ServerErrorReceipt message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ServerErrorReceipt - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ServerErrorReceipt} ServerErrorReceipt - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ServerErrorReceipt.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ServerErrorReceipt message. - * @function verify - * @memberof proto.ServerErrorReceipt - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ServerErrorReceipt.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) - if (!$util.isString(message.stanzaId)) - return "stanzaId: string expected"; - return null; - }; - - /** - * Creates a ServerErrorReceipt message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ServerErrorReceipt - * @static - * @param {Object.} object Plain object - * @returns {proto.ServerErrorReceipt} ServerErrorReceipt - */ - ServerErrorReceipt.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ServerErrorReceipt) - return object; - var message = new $root.proto.ServerErrorReceipt(); - if (object.stanzaId != null) - message.stanzaId = String(object.stanzaId); - return message; - }; - - /** - * Creates a plain object from a ServerErrorReceipt message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ServerErrorReceipt - * @static - * @param {proto.ServerErrorReceipt} message ServerErrorReceipt - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ServerErrorReceipt.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.stanzaId = ""; - if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) - object.stanzaId = message.stanzaId; - return object; - }; - - /** - * Converts this ServerErrorReceipt to JSON. - * @function toJSON - * @memberof proto.ServerErrorReceipt - * @instance - * @returns {Object.} JSON object - */ - ServerErrorReceipt.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ServerErrorReceipt; - })(); - - proto.MediaRetryNotification = (function() { - - /** - * Properties of a MediaRetryNotification. - * @memberof proto - * @interface IMediaRetryNotification - * @property {string|null} [stanzaId] MediaRetryNotification stanzaId - * @property {string|null} [directPath] MediaRetryNotification directPath - * @property {proto.MediaRetryNotification.MediaRetryNotificationResultType|null} [result] MediaRetryNotification result - */ - - /** - * Constructs a new MediaRetryNotification. - * @memberof proto - * @classdesc Represents a MediaRetryNotification. - * @implements IMediaRetryNotification - * @constructor - * @param {proto.IMediaRetryNotification=} [properties] Properties to set - */ - function MediaRetryNotification(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * MediaRetryNotification stanzaId. - * @member {string} stanzaId - * @memberof proto.MediaRetryNotification - * @instance - */ - MediaRetryNotification.prototype.stanzaId = ""; - - /** - * MediaRetryNotification directPath. - * @member {string} directPath - * @memberof proto.MediaRetryNotification - * @instance - */ - MediaRetryNotification.prototype.directPath = ""; - - /** - * MediaRetryNotification result. - * @member {proto.MediaRetryNotification.MediaRetryNotificationResultType} result - * @memberof proto.MediaRetryNotification - * @instance - */ - MediaRetryNotification.prototype.result = 0; - - /** - * Creates a new MediaRetryNotification instance using the specified properties. - * @function create - * @memberof proto.MediaRetryNotification - * @static - * @param {proto.IMediaRetryNotification=} [properties] Properties to set - * @returns {proto.MediaRetryNotification} MediaRetryNotification instance - */ - MediaRetryNotification.create = function create(properties) { - return new MediaRetryNotification(properties); - }; - - /** - * Encodes the specified MediaRetryNotification message. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages. - * @function encode - * @memberof proto.MediaRetryNotification - * @static - * @param {proto.IMediaRetryNotification} message MediaRetryNotification message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - MediaRetryNotification.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.stanzaId); - if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.directPath); - if (message.result != null && Object.hasOwnProperty.call(message, "result")) - writer.uint32(/* id 3, wireType 0 =*/24).int32(message.result); - return writer; - }; - - /** - * Encodes the specified MediaRetryNotification message, length delimited. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.MediaRetryNotification - * @static - * @param {proto.IMediaRetryNotification} message MediaRetryNotification message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - MediaRetryNotification.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a MediaRetryNotification message from the specified reader or buffer. - * @function decode - * @memberof proto.MediaRetryNotification - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.MediaRetryNotification} MediaRetryNotification - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - MediaRetryNotification.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MediaRetryNotification(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.stanzaId = reader.string(); - break; - case 2: - message.directPath = reader.string(); - break; - case 3: - message.result = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a MediaRetryNotification message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.MediaRetryNotification - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.MediaRetryNotification} MediaRetryNotification - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - MediaRetryNotification.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a MediaRetryNotification message. - * @function verify - * @memberof proto.MediaRetryNotification - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - MediaRetryNotification.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) - if (!$util.isString(message.stanzaId)) - return "stanzaId: string expected"; - if (message.directPath != null && message.hasOwnProperty("directPath")) - if (!$util.isString(message.directPath)) - return "directPath: string expected"; - if (message.result != null && message.hasOwnProperty("result")) - switch (message.result) { - default: - return "result: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - return null; - }; - - /** - * Creates a MediaRetryNotification message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.MediaRetryNotification - * @static - * @param {Object.} object Plain object - * @returns {proto.MediaRetryNotification} MediaRetryNotification - */ - MediaRetryNotification.fromObject = function fromObject(object) { - if (object instanceof $root.proto.MediaRetryNotification) - return object; - var message = new $root.proto.MediaRetryNotification(); - if (object.stanzaId != null) - message.stanzaId = String(object.stanzaId); - if (object.directPath != null) - message.directPath = String(object.directPath); - switch (object.result) { - case "GENERAL_ERROR": - case 0: - message.result = 0; - break; - case "SUCCESS": - case 1: - message.result = 1; - break; - case "NOT_FOUND": - case 2: - message.result = 2; - break; - case "DECRYPTION_ERROR": - case 3: - message.result = 3; - break; - } - return message; - }; - - /** - * Creates a plain object from a MediaRetryNotification message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.MediaRetryNotification - * @static - * @param {proto.MediaRetryNotification} message MediaRetryNotification - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - MediaRetryNotification.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.stanzaId = ""; - object.directPath = ""; - object.result = options.enums === String ? "GENERAL_ERROR" : 0; - } - if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) - object.stanzaId = message.stanzaId; - if (message.directPath != null && message.hasOwnProperty("directPath")) - object.directPath = message.directPath; - if (message.result != null && message.hasOwnProperty("result")) - object.result = options.enums === String ? $root.proto.MediaRetryNotification.MediaRetryNotificationResultType[message.result] : message.result; - return object; - }; - - /** - * Converts this MediaRetryNotification to JSON. - * @function toJSON - * @memberof proto.MediaRetryNotification - * @instance - * @returns {Object.} JSON object - */ - MediaRetryNotification.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * MediaRetryNotificationResultType enum. - * @name proto.MediaRetryNotification.MediaRetryNotificationResultType - * @enum {number} - * @property {number} GENERAL_ERROR=0 GENERAL_ERROR value - * @property {number} SUCCESS=1 SUCCESS value - * @property {number} NOT_FOUND=2 NOT_FOUND value - * @property {number} DECRYPTION_ERROR=3 DECRYPTION_ERROR value - */ - MediaRetryNotification.MediaRetryNotificationResultType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "GENERAL_ERROR"] = 0; - values[valuesById[1] = "SUCCESS"] = 1; - values[valuesById[2] = "NOT_FOUND"] = 2; - values[valuesById[3] = "DECRYPTION_ERROR"] = 3; - return values; - })(); - - return MediaRetryNotification; - })(); - - proto.MsgOpaqueData = (function() { - - /** - * Properties of a MsgOpaqueData. - * @memberof proto - * @interface IMsgOpaqueData - * @property {string|null} [body] MsgOpaqueData body - * @property {string|null} [caption] MsgOpaqueData caption - * @property {string|null} [clientUrl] MsgOpaqueData clientUrl - * @property {number|null} [lng] MsgOpaqueData lng - * @property {number|null} [lat] MsgOpaqueData lat - * @property {number|null} [paymentAmount1000] MsgOpaqueData paymentAmount1000 - * @property {string|null} [paymentNoteMsgBody] MsgOpaqueData paymentNoteMsgBody - * @property {string|null} [canonicalUrl] MsgOpaqueData canonicalUrl - * @property {string|null} [matchedText] MsgOpaqueData matchedText - * @property {string|null} [title] MsgOpaqueData title - * @property {string|null} [description] MsgOpaqueData description - */ - - /** - * Constructs a new MsgOpaqueData. - * @memberof proto - * @classdesc Represents a MsgOpaqueData. - * @implements IMsgOpaqueData - * @constructor - * @param {proto.IMsgOpaqueData=} [properties] Properties to set - */ - function MsgOpaqueData(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * MsgOpaqueData body. - * @member {string} body - * @memberof proto.MsgOpaqueData - * @instance - */ - MsgOpaqueData.prototype.body = ""; - - /** - * MsgOpaqueData caption. - * @member {string} caption - * @memberof proto.MsgOpaqueData - * @instance - */ - MsgOpaqueData.prototype.caption = ""; - - /** - * MsgOpaqueData clientUrl. - * @member {string} clientUrl - * @memberof proto.MsgOpaqueData - * @instance - */ - MsgOpaqueData.prototype.clientUrl = ""; - - /** - * MsgOpaqueData lng. - * @member {number} lng - * @memberof proto.MsgOpaqueData - * @instance - */ - MsgOpaqueData.prototype.lng = 0; - - /** - * MsgOpaqueData lat. - * @member {number} lat - * @memberof proto.MsgOpaqueData - * @instance - */ - MsgOpaqueData.prototype.lat = 0; - - /** - * MsgOpaqueData paymentAmount1000. - * @member {number} paymentAmount1000 - * @memberof proto.MsgOpaqueData - * @instance - */ - MsgOpaqueData.prototype.paymentAmount1000 = 0; - - /** - * MsgOpaqueData paymentNoteMsgBody. - * @member {string} paymentNoteMsgBody - * @memberof proto.MsgOpaqueData - * @instance - */ - MsgOpaqueData.prototype.paymentNoteMsgBody = ""; - - /** - * MsgOpaqueData canonicalUrl. - * @member {string} canonicalUrl - * @memberof proto.MsgOpaqueData - * @instance - */ - MsgOpaqueData.prototype.canonicalUrl = ""; - - /** - * MsgOpaqueData matchedText. - * @member {string} matchedText - * @memberof proto.MsgOpaqueData - * @instance - */ - MsgOpaqueData.prototype.matchedText = ""; - - /** - * MsgOpaqueData title. - * @member {string} title - * @memberof proto.MsgOpaqueData - * @instance - */ - MsgOpaqueData.prototype.title = ""; - - /** - * MsgOpaqueData description. - * @member {string} description - * @memberof proto.MsgOpaqueData - * @instance - */ - MsgOpaqueData.prototype.description = ""; - - /** - * Creates a new MsgOpaqueData instance using the specified properties. - * @function create - * @memberof proto.MsgOpaqueData - * @static - * @param {proto.IMsgOpaqueData=} [properties] Properties to set - * @returns {proto.MsgOpaqueData} MsgOpaqueData instance - */ - MsgOpaqueData.create = function create(properties) { - return new MsgOpaqueData(properties); - }; - - /** - * Encodes the specified MsgOpaqueData message. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages. - * @function encode - * @memberof proto.MsgOpaqueData - * @static - * @param {proto.IMsgOpaqueData} message MsgOpaqueData message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - MsgOpaqueData.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.body != null && Object.hasOwnProperty.call(message, "body")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.body); - if (message.caption != null && Object.hasOwnProperty.call(message, "caption")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.caption); - if (message.clientUrl != null && Object.hasOwnProperty.call(message, "clientUrl")) - writer.uint32(/* id 4, wireType 2 =*/34).string(message.clientUrl); - if (message.lng != null && Object.hasOwnProperty.call(message, "lng")) - writer.uint32(/* id 5, wireType 1 =*/41).double(message.lng); - if (message.lat != null && Object.hasOwnProperty.call(message, "lat")) - writer.uint32(/* id 7, wireType 1 =*/57).double(message.lat); - if (message.paymentAmount1000 != null && Object.hasOwnProperty.call(message, "paymentAmount1000")) - writer.uint32(/* id 8, wireType 0 =*/64).int32(message.paymentAmount1000); - if (message.paymentNoteMsgBody != null && Object.hasOwnProperty.call(message, "paymentNoteMsgBody")) - writer.uint32(/* id 9, wireType 2 =*/74).string(message.paymentNoteMsgBody); - if (message.canonicalUrl != null && Object.hasOwnProperty.call(message, "canonicalUrl")) - writer.uint32(/* id 10, wireType 2 =*/82).string(message.canonicalUrl); - if (message.matchedText != null && Object.hasOwnProperty.call(message, "matchedText")) - writer.uint32(/* id 11, wireType 2 =*/90).string(message.matchedText); - if (message.title != null && Object.hasOwnProperty.call(message, "title")) - writer.uint32(/* id 12, wireType 2 =*/98).string(message.title); - if (message.description != null && Object.hasOwnProperty.call(message, "description")) - writer.uint32(/* id 13, wireType 2 =*/106).string(message.description); - return writer; - }; - - /** - * Encodes the specified MsgOpaqueData message, length delimited. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.MsgOpaqueData - * @static - * @param {proto.IMsgOpaqueData} message MsgOpaqueData message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - MsgOpaqueData.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a MsgOpaqueData message from the specified reader or buffer. - * @function decode - * @memberof proto.MsgOpaqueData - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.MsgOpaqueData} MsgOpaqueData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - MsgOpaqueData.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MsgOpaqueData(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.body = reader.string(); - break; - case 3: - message.caption = reader.string(); - break; - case 4: - message.clientUrl = reader.string(); - break; - case 5: - message.lng = reader.double(); - break; - case 7: - message.lat = reader.double(); - break; - case 8: - message.paymentAmount1000 = reader.int32(); - break; - case 9: - message.paymentNoteMsgBody = reader.string(); - break; - case 10: - message.canonicalUrl = reader.string(); - break; - case 11: - message.matchedText = reader.string(); - break; - case 12: - message.title = reader.string(); - break; - case 13: - message.description = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a MsgOpaqueData message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.MsgOpaqueData - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.MsgOpaqueData} MsgOpaqueData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - MsgOpaqueData.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a MsgOpaqueData message. - * @function verify - * @memberof proto.MsgOpaqueData - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - MsgOpaqueData.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.body != null && message.hasOwnProperty("body")) - if (!$util.isString(message.body)) - return "body: string expected"; - if (message.caption != null && message.hasOwnProperty("caption")) - if (!$util.isString(message.caption)) - return "caption: string expected"; - if (message.clientUrl != null && message.hasOwnProperty("clientUrl")) - if (!$util.isString(message.clientUrl)) - return "clientUrl: string expected"; - if (message.lng != null && message.hasOwnProperty("lng")) - if (typeof message.lng !== "number") - return "lng: number expected"; - if (message.lat != null && message.hasOwnProperty("lat")) - if (typeof message.lat !== "number") - return "lat: number expected"; - if (message.paymentAmount1000 != null && message.hasOwnProperty("paymentAmount1000")) - if (!$util.isInteger(message.paymentAmount1000)) - return "paymentAmount1000: integer expected"; - if (message.paymentNoteMsgBody != null && message.hasOwnProperty("paymentNoteMsgBody")) - if (!$util.isString(message.paymentNoteMsgBody)) - return "paymentNoteMsgBody: string expected"; - if (message.canonicalUrl != null && message.hasOwnProperty("canonicalUrl")) - if (!$util.isString(message.canonicalUrl)) - return "canonicalUrl: string expected"; - if (message.matchedText != null && message.hasOwnProperty("matchedText")) - if (!$util.isString(message.matchedText)) - return "matchedText: string expected"; - if (message.title != null && message.hasOwnProperty("title")) - if (!$util.isString(message.title)) - return "title: string expected"; - if (message.description != null && message.hasOwnProperty("description")) - if (!$util.isString(message.description)) - return "description: string expected"; - return null; - }; - - /** - * Creates a MsgOpaqueData message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.MsgOpaqueData - * @static - * @param {Object.} object Plain object - * @returns {proto.MsgOpaqueData} MsgOpaqueData - */ - MsgOpaqueData.fromObject = function fromObject(object) { - if (object instanceof $root.proto.MsgOpaqueData) - return object; - var message = new $root.proto.MsgOpaqueData(); - if (object.body != null) - message.body = String(object.body); - if (object.caption != null) - message.caption = String(object.caption); - if (object.clientUrl != null) - message.clientUrl = String(object.clientUrl); - if (object.lng != null) - message.lng = Number(object.lng); - if (object.lat != null) - message.lat = Number(object.lat); - if (object.paymentAmount1000 != null) - message.paymentAmount1000 = object.paymentAmount1000 | 0; - if (object.paymentNoteMsgBody != null) - message.paymentNoteMsgBody = String(object.paymentNoteMsgBody); - if (object.canonicalUrl != null) - message.canonicalUrl = String(object.canonicalUrl); - if (object.matchedText != null) - message.matchedText = String(object.matchedText); - if (object.title != null) - message.title = String(object.title); - if (object.description != null) - message.description = String(object.description); - return message; - }; - - /** - * Creates a plain object from a MsgOpaqueData message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.MsgOpaqueData - * @static - * @param {proto.MsgOpaqueData} message MsgOpaqueData - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - MsgOpaqueData.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.body = ""; - object.caption = ""; - object.clientUrl = ""; - object.lng = 0; - object.lat = 0; - object.paymentAmount1000 = 0; - object.paymentNoteMsgBody = ""; - object.canonicalUrl = ""; - object.matchedText = ""; - object.title = ""; - object.description = ""; - } - if (message.body != null && message.hasOwnProperty("body")) - object.body = message.body; - if (message.caption != null && message.hasOwnProperty("caption")) - object.caption = message.caption; - if (message.clientUrl != null && message.hasOwnProperty("clientUrl")) - object.clientUrl = message.clientUrl; - if (message.lng != null && message.hasOwnProperty("lng")) - object.lng = options.json && !isFinite(message.lng) ? String(message.lng) : message.lng; - if (message.lat != null && message.hasOwnProperty("lat")) - object.lat = options.json && !isFinite(message.lat) ? String(message.lat) : message.lat; - if (message.paymentAmount1000 != null && message.hasOwnProperty("paymentAmount1000")) - object.paymentAmount1000 = message.paymentAmount1000; - if (message.paymentNoteMsgBody != null && message.hasOwnProperty("paymentNoteMsgBody")) - object.paymentNoteMsgBody = message.paymentNoteMsgBody; - if (message.canonicalUrl != null && message.hasOwnProperty("canonicalUrl")) - object.canonicalUrl = message.canonicalUrl; - if (message.matchedText != null && message.hasOwnProperty("matchedText")) - object.matchedText = message.matchedText; - if (message.title != null && message.hasOwnProperty("title")) - object.title = message.title; - if (message.description != null && message.hasOwnProperty("description")) - object.description = message.description; - return object; - }; - - /** - * Converts this MsgOpaqueData to JSON. - * @function toJSON - * @memberof proto.MsgOpaqueData - * @instance - * @returns {Object.} JSON object - */ - MsgOpaqueData.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return MsgOpaqueData; - })(); - - proto.MsgRowOpaqueData = (function() { - - /** - * Properties of a MsgRowOpaqueData. - * @memberof proto - * @interface IMsgRowOpaqueData - * @property {proto.IMsgOpaqueData|null} [currentMsg] MsgRowOpaqueData currentMsg - * @property {proto.IMsgOpaqueData|null} [quotedMsg] MsgRowOpaqueData quotedMsg - */ - - /** - * Constructs a new MsgRowOpaqueData. - * @memberof proto - * @classdesc Represents a MsgRowOpaqueData. - * @implements IMsgRowOpaqueData - * @constructor - * @param {proto.IMsgRowOpaqueData=} [properties] Properties to set - */ - function MsgRowOpaqueData(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * MsgRowOpaqueData currentMsg. - * @member {proto.IMsgOpaqueData|null|undefined} currentMsg - * @memberof proto.MsgRowOpaqueData - * @instance - */ - MsgRowOpaqueData.prototype.currentMsg = null; - - /** - * MsgRowOpaqueData quotedMsg. - * @member {proto.IMsgOpaqueData|null|undefined} quotedMsg - * @memberof proto.MsgRowOpaqueData - * @instance - */ - MsgRowOpaqueData.prototype.quotedMsg = null; - - /** - * Creates a new MsgRowOpaqueData instance using the specified properties. - * @function create - * @memberof proto.MsgRowOpaqueData - * @static - * @param {proto.IMsgRowOpaqueData=} [properties] Properties to set - * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData instance - */ - MsgRowOpaqueData.create = function create(properties) { - return new MsgRowOpaqueData(properties); - }; - - /** - * Encodes the specified MsgRowOpaqueData message. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages. - * @function encode - * @memberof proto.MsgRowOpaqueData - * @static - * @param {proto.IMsgRowOpaqueData} message MsgRowOpaqueData message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - MsgRowOpaqueData.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.currentMsg != null && Object.hasOwnProperty.call(message, "currentMsg")) - $root.proto.MsgOpaqueData.encode(message.currentMsg, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.quotedMsg != null && Object.hasOwnProperty.call(message, "quotedMsg")) - $root.proto.MsgOpaqueData.encode(message.quotedMsg, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified MsgRowOpaqueData message, length delimited. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.MsgRowOpaqueData - * @static - * @param {proto.IMsgRowOpaqueData} message MsgRowOpaqueData message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - MsgRowOpaqueData.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a MsgRowOpaqueData message from the specified reader or buffer. - * @function decode - * @memberof proto.MsgRowOpaqueData - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - MsgRowOpaqueData.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MsgRowOpaqueData(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.currentMsg = $root.proto.MsgOpaqueData.decode(reader, reader.uint32()); - break; - case 2: - message.quotedMsg = $root.proto.MsgOpaqueData.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a MsgRowOpaqueData message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.MsgRowOpaqueData - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - MsgRowOpaqueData.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a MsgRowOpaqueData message. - * @function verify - * @memberof proto.MsgRowOpaqueData - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - MsgRowOpaqueData.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.currentMsg != null && message.hasOwnProperty("currentMsg")) { - var error = $root.proto.MsgOpaqueData.verify(message.currentMsg); - if (error) - return "currentMsg." + error; - } - if (message.quotedMsg != null && message.hasOwnProperty("quotedMsg")) { - var error = $root.proto.MsgOpaqueData.verify(message.quotedMsg); - if (error) - return "quotedMsg." + error; - } - return null; - }; - - /** - * Creates a MsgRowOpaqueData message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.MsgRowOpaqueData - * @static - * @param {Object.} object Plain object - * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData - */ - MsgRowOpaqueData.fromObject = function fromObject(object) { - if (object instanceof $root.proto.MsgRowOpaqueData) - return object; - var message = new $root.proto.MsgRowOpaqueData(); - if (object.currentMsg != null) { - if (typeof object.currentMsg !== "object") - throw TypeError(".proto.MsgRowOpaqueData.currentMsg: object expected"); - message.currentMsg = $root.proto.MsgOpaqueData.fromObject(object.currentMsg); - } - if (object.quotedMsg != null) { - if (typeof object.quotedMsg !== "object") - throw TypeError(".proto.MsgRowOpaqueData.quotedMsg: object expected"); - message.quotedMsg = $root.proto.MsgOpaqueData.fromObject(object.quotedMsg); - } - return message; - }; - - /** - * Creates a plain object from a MsgRowOpaqueData message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.MsgRowOpaqueData - * @static - * @param {proto.MsgRowOpaqueData} message MsgRowOpaqueData - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - MsgRowOpaqueData.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.currentMsg = null; - object.quotedMsg = null; - } - if (message.currentMsg != null && message.hasOwnProperty("currentMsg")) - object.currentMsg = $root.proto.MsgOpaqueData.toObject(message.currentMsg, options); - if (message.quotedMsg != null && message.hasOwnProperty("quotedMsg")) - object.quotedMsg = $root.proto.MsgOpaqueData.toObject(message.quotedMsg, options); - return object; - }; - - /** - * Converts this MsgRowOpaqueData to JSON. - * @function toJSON - * @memberof proto.MsgRowOpaqueData - * @instance - * @returns {Object.} JSON object - */ - MsgRowOpaqueData.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return MsgRowOpaqueData; - })(); - - proto.Pushname = (function() { - - /** - * Properties of a Pushname. - * @memberof proto - * @interface IPushname - * @property {string|null} [id] Pushname id - * @property {string|null} [pushname] Pushname pushname - */ - - /** - * Constructs a new Pushname. - * @memberof proto - * @classdesc Represents a Pushname. - * @implements IPushname - * @constructor - * @param {proto.IPushname=} [properties] Properties to set - */ - function Pushname(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * Pushname id. - * @member {string} id - * @memberof proto.Pushname - * @instance - */ - Pushname.prototype.id = ""; - - /** - * Pushname pushname. - * @member {string} pushname - * @memberof proto.Pushname - * @instance - */ - Pushname.prototype.pushname = ""; - - /** - * Creates a new Pushname instance using the specified properties. - * @function create - * @memberof proto.Pushname - * @static - * @param {proto.IPushname=} [properties] Properties to set - * @returns {proto.Pushname} Pushname instance - */ - Pushname.create = function create(properties) { - return new Pushname(properties); - }; - - /** - * Encodes the specified Pushname message. Does not implicitly {@link proto.Pushname.verify|verify} messages. - * @function encode - * @memberof proto.Pushname - * @static - * @param {proto.IPushname} message Pushname message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Pushname.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); - if (message.pushname != null && Object.hasOwnProperty.call(message, "pushname")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.pushname); - return writer; - }; - - /** - * Encodes the specified Pushname message, length delimited. Does not implicitly {@link proto.Pushname.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.Pushname - * @static - * @param {proto.IPushname} message Pushname message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Pushname.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a Pushname message from the specified reader or buffer. - * @function decode - * @memberof proto.Pushname - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.Pushname} Pushname - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Pushname.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Pushname(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.id = reader.string(); - break; - case 2: - message.pushname = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a Pushname message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.Pushname - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.Pushname} Pushname - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Pushname.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a Pushname message. - * @function verify - * @memberof proto.Pushname - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - Pushname.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.id != null && message.hasOwnProperty("id")) - if (!$util.isString(message.id)) - return "id: string expected"; - if (message.pushname != null && message.hasOwnProperty("pushname")) - if (!$util.isString(message.pushname)) - return "pushname: string expected"; - return null; - }; - - /** - * Creates a Pushname message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.Pushname - * @static - * @param {Object.} object Plain object - * @returns {proto.Pushname} Pushname - */ - Pushname.fromObject = function fromObject(object) { - if (object instanceof $root.proto.Pushname) - return object; - var message = new $root.proto.Pushname(); - if (object.id != null) - message.id = String(object.id); - if (object.pushname != null) - message.pushname = String(object.pushname); - return message; - }; - - /** - * Creates a plain object from a Pushname message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.Pushname - * @static - * @param {proto.Pushname} message Pushname - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - Pushname.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.id = ""; - object.pushname = ""; - } - if (message.id != null && message.hasOwnProperty("id")) - object.id = message.id; - if (message.pushname != null && message.hasOwnProperty("pushname")) - object.pushname = message.pushname; - return object; - }; - - /** - * Converts this Pushname to JSON. - * @function toJSON - * @memberof proto.Pushname - * @instance - * @returns {Object.} JSON object - */ - Pushname.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return Pushname; - })(); - - proto.HistorySyncMsg = (function() { - - /** - * Properties of a HistorySyncMsg. - * @memberof proto - * @interface IHistorySyncMsg - * @property {proto.IWebMessageInfo|null} [message] HistorySyncMsg message - * @property {number|Long|null} [msgOrderId] HistorySyncMsg msgOrderId - */ - - /** - * Constructs a new HistorySyncMsg. - * @memberof proto - * @classdesc Represents a HistorySyncMsg. - * @implements IHistorySyncMsg - * @constructor - * @param {proto.IHistorySyncMsg=} [properties] Properties to set - */ - function HistorySyncMsg(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HistorySyncMsg message. - * @member {proto.IWebMessageInfo|null|undefined} message - * @memberof proto.HistorySyncMsg - * @instance - */ - HistorySyncMsg.prototype.message = null; - - /** - * HistorySyncMsg msgOrderId. - * @member {number|Long} msgOrderId - * @memberof proto.HistorySyncMsg - * @instance - */ - HistorySyncMsg.prototype.msgOrderId = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * Creates a new HistorySyncMsg instance using the specified properties. - * @function create - * @memberof proto.HistorySyncMsg - * @static - * @param {proto.IHistorySyncMsg=} [properties] Properties to set - * @returns {proto.HistorySyncMsg} HistorySyncMsg instance - */ - HistorySyncMsg.create = function create(properties) { - return new HistorySyncMsg(properties); - }; - - /** - * Encodes the specified HistorySyncMsg message. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages. - * @function encode - * @memberof proto.HistorySyncMsg - * @static - * @param {proto.IHistorySyncMsg} message HistorySyncMsg message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HistorySyncMsg.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.message != null && Object.hasOwnProperty.call(message, "message")) - $root.proto.WebMessageInfo.encode(message.message, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.msgOrderId != null && Object.hasOwnProperty.call(message, "msgOrderId")) - writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.msgOrderId); - return writer; - }; - - /** - * Encodes the specified HistorySyncMsg message, length delimited. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HistorySyncMsg - * @static - * @param {proto.IHistorySyncMsg} message HistorySyncMsg message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HistorySyncMsg.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HistorySyncMsg message from the specified reader or buffer. - * @function decode - * @memberof proto.HistorySyncMsg - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HistorySyncMsg} HistorySyncMsg - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HistorySyncMsg.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HistorySyncMsg(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.message = $root.proto.WebMessageInfo.decode(reader, reader.uint32()); - break; - case 2: - message.msgOrderId = reader.uint64(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HistorySyncMsg message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HistorySyncMsg - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HistorySyncMsg} HistorySyncMsg - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HistorySyncMsg.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HistorySyncMsg message. - * @function verify - * @memberof proto.HistorySyncMsg - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HistorySyncMsg.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.message != null && message.hasOwnProperty("message")) { - var error = $root.proto.WebMessageInfo.verify(message.message); - if (error) - return "message." + error; - } - if (message.msgOrderId != null && message.hasOwnProperty("msgOrderId")) - if (!$util.isInteger(message.msgOrderId) && !(message.msgOrderId && $util.isInteger(message.msgOrderId.low) && $util.isInteger(message.msgOrderId.high))) - return "msgOrderId: integer|Long expected"; - return null; - }; - - /** - * Creates a HistorySyncMsg message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HistorySyncMsg - * @static - * @param {Object.} object Plain object - * @returns {proto.HistorySyncMsg} HistorySyncMsg - */ - HistorySyncMsg.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HistorySyncMsg) - return object; - var message = new $root.proto.HistorySyncMsg(); - if (object.message != null) { - if (typeof object.message !== "object") - throw TypeError(".proto.HistorySyncMsg.message: object expected"); - message.message = $root.proto.WebMessageInfo.fromObject(object.message); - } - if (object.msgOrderId != null) - if ($util.Long) - (message.msgOrderId = $util.Long.fromValue(object.msgOrderId)).unsigned = true; - else if (typeof object.msgOrderId === "string") - message.msgOrderId = parseInt(object.msgOrderId, 10); - else if (typeof object.msgOrderId === "number") - message.msgOrderId = object.msgOrderId; - else if (typeof object.msgOrderId === "object") - message.msgOrderId = new $util.LongBits(object.msgOrderId.low >>> 0, object.msgOrderId.high >>> 0).toNumber(true); - return message; - }; - - /** - * Creates a plain object from a HistorySyncMsg message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HistorySyncMsg - * @static - * @param {proto.HistorySyncMsg} message HistorySyncMsg - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HistorySyncMsg.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.message = null; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.msgOrderId = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.msgOrderId = options.longs === String ? "0" : 0; - } - if (message.message != null && message.hasOwnProperty("message")) - object.message = $root.proto.WebMessageInfo.toObject(message.message, options); - if (message.msgOrderId != null && message.hasOwnProperty("msgOrderId")) - if (typeof message.msgOrderId === "number") - object.msgOrderId = options.longs === String ? String(message.msgOrderId) : message.msgOrderId; - else - object.msgOrderId = options.longs === String ? $util.Long.prototype.toString.call(message.msgOrderId) : options.longs === Number ? new $util.LongBits(message.msgOrderId.low >>> 0, message.msgOrderId.high >>> 0).toNumber(true) : message.msgOrderId; - return object; - }; - - /** - * Converts this HistorySyncMsg to JSON. - * @function toJSON - * @memberof proto.HistorySyncMsg - * @instance - * @returns {Object.} JSON object - */ - HistorySyncMsg.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HistorySyncMsg; - })(); - - proto.Conversation = (function() { - - /** - * Properties of a Conversation. - * @memberof proto - * @interface IConversation - * @property {string} id Conversation id - * @property {Array.|null} [messages] Conversation messages - * @property {string|null} [newJid] Conversation newJid - * @property {string|null} [oldJid] Conversation oldJid - * @property {number|Long|null} [lastMsgTimestamp] Conversation lastMsgTimestamp - * @property {number|null} [unreadCount] Conversation unreadCount - * @property {boolean|null} [readOnly] Conversation readOnly - * @property {boolean|null} [endOfHistoryTransfer] Conversation endOfHistoryTransfer - * @property {number|null} [ephemeralExpiration] Conversation ephemeralExpiration - * @property {number|Long|null} [ephemeralSettingTimestamp] Conversation ephemeralSettingTimestamp - * @property {proto.Conversation.ConversationEndOfHistoryTransferType|null} [endOfHistoryTransferType] Conversation endOfHistoryTransferType - * @property {number|Long|null} [conversationTimestamp] Conversation conversationTimestamp - * @property {string|null} [name] Conversation name - * @property {string|null} [pHash] Conversation pHash - * @property {boolean|null} [notSpam] Conversation notSpam - */ - - /** - * Constructs a new Conversation. - * @memberof proto - * @classdesc Represents a Conversation. - * @implements IConversation - * @constructor - * @param {proto.IConversation=} [properties] Properties to set - */ - function Conversation(properties) { - this.messages = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * Conversation id. - * @member {string} id - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.id = ""; - - /** - * Conversation messages. - * @member {Array.} messages - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.messages = $util.emptyArray; - - /** - * Conversation newJid. - * @member {string} newJid - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.newJid = ""; - - /** - * Conversation oldJid. - * @member {string} oldJid - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.oldJid = ""; - - /** - * Conversation lastMsgTimestamp. - * @member {number|Long} lastMsgTimestamp - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.lastMsgTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * Conversation unreadCount. - * @member {number} unreadCount - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.unreadCount = 0; - - /** - * Conversation readOnly. - * @member {boolean} readOnly - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.readOnly = false; - - /** - * Conversation endOfHistoryTransfer. - * @member {boolean} endOfHistoryTransfer - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.endOfHistoryTransfer = false; - - /** - * Conversation ephemeralExpiration. - * @member {number} ephemeralExpiration - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.ephemeralExpiration = 0; - - /** - * Conversation ephemeralSettingTimestamp. - * @member {number|Long} ephemeralSettingTimestamp - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.ephemeralSettingTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * Conversation endOfHistoryTransferType. - * @member {proto.Conversation.ConversationEndOfHistoryTransferType} endOfHistoryTransferType - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.endOfHistoryTransferType = 0; - - /** - * Conversation conversationTimestamp. - * @member {number|Long} conversationTimestamp - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.conversationTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * Conversation name. - * @member {string} name - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.name = ""; - - /** - * Conversation pHash. - * @member {string} pHash - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.pHash = ""; - - /** - * Conversation notSpam. - * @member {boolean} notSpam - * @memberof proto.Conversation - * @instance - */ - Conversation.prototype.notSpam = false; - - /** - * Creates a new Conversation instance using the specified properties. - * @function create - * @memberof proto.Conversation - * @static - * @param {proto.IConversation=} [properties] Properties to set - * @returns {proto.Conversation} Conversation instance - */ - Conversation.create = function create(properties) { - return new Conversation(properties); - }; - - /** - * Encodes the specified Conversation message. Does not implicitly {@link proto.Conversation.verify|verify} messages. - * @function encode - * @memberof proto.Conversation - * @static - * @param {proto.IConversation} message Conversation message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Conversation.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); - if (message.messages != null && message.messages.length) - for (var i = 0; i < message.messages.length; ++i) - $root.proto.HistorySyncMsg.encode(message.messages[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.newJid != null && Object.hasOwnProperty.call(message, "newJid")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.newJid); - if (message.oldJid != null && Object.hasOwnProperty.call(message, "oldJid")) - writer.uint32(/* id 4, wireType 2 =*/34).string(message.oldJid); - if (message.lastMsgTimestamp != null && Object.hasOwnProperty.call(message, "lastMsgTimestamp")) - writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.lastMsgTimestamp); - if (message.unreadCount != null && Object.hasOwnProperty.call(message, "unreadCount")) - writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.unreadCount); - if (message.readOnly != null && Object.hasOwnProperty.call(message, "readOnly")) - writer.uint32(/* id 7, wireType 0 =*/56).bool(message.readOnly); - if (message.endOfHistoryTransfer != null && Object.hasOwnProperty.call(message, "endOfHistoryTransfer")) - writer.uint32(/* id 8, wireType 0 =*/64).bool(message.endOfHistoryTransfer); - if (message.ephemeralExpiration != null && Object.hasOwnProperty.call(message, "ephemeralExpiration")) - writer.uint32(/* id 9, wireType 0 =*/72).uint32(message.ephemeralExpiration); - if (message.ephemeralSettingTimestamp != null && Object.hasOwnProperty.call(message, "ephemeralSettingTimestamp")) - writer.uint32(/* id 10, wireType 0 =*/80).int64(message.ephemeralSettingTimestamp); - if (message.endOfHistoryTransferType != null && Object.hasOwnProperty.call(message, "endOfHistoryTransferType")) - writer.uint32(/* id 11, wireType 0 =*/88).int32(message.endOfHistoryTransferType); - if (message.conversationTimestamp != null && Object.hasOwnProperty.call(message, "conversationTimestamp")) - writer.uint32(/* id 12, wireType 0 =*/96).uint64(message.conversationTimestamp); - if (message.name != null && Object.hasOwnProperty.call(message, "name")) - writer.uint32(/* id 13, wireType 2 =*/106).string(message.name); - if (message.pHash != null && Object.hasOwnProperty.call(message, "pHash")) - writer.uint32(/* id 14, wireType 2 =*/114).string(message.pHash); - if (message.notSpam != null && Object.hasOwnProperty.call(message, "notSpam")) - writer.uint32(/* id 15, wireType 0 =*/120).bool(message.notSpam); - return writer; - }; - - /** - * Encodes the specified Conversation message, length delimited. Does not implicitly {@link proto.Conversation.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.Conversation - * @static - * @param {proto.IConversation} message Conversation message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Conversation.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a Conversation message from the specified reader or buffer. - * @function decode - * @memberof proto.Conversation - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.Conversation} Conversation - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Conversation.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Conversation(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.id = reader.string(); - break; - case 2: - if (!(message.messages && message.messages.length)) - message.messages = []; - message.messages.push($root.proto.HistorySyncMsg.decode(reader, reader.uint32())); - break; - case 3: - message.newJid = reader.string(); - break; - case 4: - message.oldJid = reader.string(); - break; - case 5: - message.lastMsgTimestamp = reader.uint64(); - break; - case 6: - message.unreadCount = reader.uint32(); - break; - case 7: - message.readOnly = reader.bool(); - break; - case 8: - message.endOfHistoryTransfer = reader.bool(); - break; - case 9: - message.ephemeralExpiration = reader.uint32(); - break; - case 10: - message.ephemeralSettingTimestamp = reader.int64(); - break; - case 11: - message.endOfHistoryTransferType = reader.int32(); - break; - case 12: - message.conversationTimestamp = reader.uint64(); - break; - case 13: - message.name = reader.string(); - break; - case 14: - message.pHash = reader.string(); - break; - case 15: - message.notSpam = reader.bool(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - if (!message.hasOwnProperty("id")) - throw $util.ProtocolError("missing required 'id'", { instance: message }); - return message; - }; - - /** - * Decodes a Conversation message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.Conversation - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.Conversation} Conversation - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Conversation.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a Conversation message. - * @function verify - * @memberof proto.Conversation - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - Conversation.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (!$util.isString(message.id)) - return "id: string expected"; - if (message.messages != null && message.hasOwnProperty("messages")) { - if (!Array.isArray(message.messages)) - return "messages: array expected"; - for (var i = 0; i < message.messages.length; ++i) { - var error = $root.proto.HistorySyncMsg.verify(message.messages[i]); - if (error) - return "messages." + error; - } - } - if (message.newJid != null && message.hasOwnProperty("newJid")) - if (!$util.isString(message.newJid)) - return "newJid: string expected"; - if (message.oldJid != null && message.hasOwnProperty("oldJid")) - if (!$util.isString(message.oldJid)) - return "oldJid: string expected"; - if (message.lastMsgTimestamp != null && message.hasOwnProperty("lastMsgTimestamp")) - if (!$util.isInteger(message.lastMsgTimestamp) && !(message.lastMsgTimestamp && $util.isInteger(message.lastMsgTimestamp.low) && $util.isInteger(message.lastMsgTimestamp.high))) - return "lastMsgTimestamp: integer|Long expected"; - if (message.unreadCount != null && message.hasOwnProperty("unreadCount")) - if (!$util.isInteger(message.unreadCount)) - return "unreadCount: integer expected"; - if (message.readOnly != null && message.hasOwnProperty("readOnly")) - if (typeof message.readOnly !== "boolean") - return "readOnly: boolean expected"; - if (message.endOfHistoryTransfer != null && message.hasOwnProperty("endOfHistoryTransfer")) - if (typeof message.endOfHistoryTransfer !== "boolean") - return "endOfHistoryTransfer: boolean expected"; - if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration")) - if (!$util.isInteger(message.ephemeralExpiration)) - return "ephemeralExpiration: integer expected"; - if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp")) - if (!$util.isInteger(message.ephemeralSettingTimestamp) && !(message.ephemeralSettingTimestamp && $util.isInteger(message.ephemeralSettingTimestamp.low) && $util.isInteger(message.ephemeralSettingTimestamp.high))) - return "ephemeralSettingTimestamp: integer|Long expected"; - if (message.endOfHistoryTransferType != null && message.hasOwnProperty("endOfHistoryTransferType")) - switch (message.endOfHistoryTransferType) { - default: - return "endOfHistoryTransferType: enum value expected"; - case 0: - case 1: - break; - } - if (message.conversationTimestamp != null && message.hasOwnProperty("conversationTimestamp")) - if (!$util.isInteger(message.conversationTimestamp) && !(message.conversationTimestamp && $util.isInteger(message.conversationTimestamp.low) && $util.isInteger(message.conversationTimestamp.high))) - return "conversationTimestamp: integer|Long expected"; - if (message.name != null && message.hasOwnProperty("name")) - if (!$util.isString(message.name)) - return "name: string expected"; - if (message.pHash != null && message.hasOwnProperty("pHash")) - if (!$util.isString(message.pHash)) - return "pHash: string expected"; - if (message.notSpam != null && message.hasOwnProperty("notSpam")) - if (typeof message.notSpam !== "boolean") - return "notSpam: boolean expected"; - return null; - }; - - /** - * Creates a Conversation message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.Conversation - * @static - * @param {Object.} object Plain object - * @returns {proto.Conversation} Conversation - */ - Conversation.fromObject = function fromObject(object) { - if (object instanceof $root.proto.Conversation) - return object; - var message = new $root.proto.Conversation(); - if (object.id != null) - message.id = String(object.id); - if (object.messages) { - if (!Array.isArray(object.messages)) - throw TypeError(".proto.Conversation.messages: array expected"); - message.messages = []; - for (var i = 0; i < object.messages.length; ++i) { - if (typeof object.messages[i] !== "object") - throw TypeError(".proto.Conversation.messages: object expected"); - message.messages[i] = $root.proto.HistorySyncMsg.fromObject(object.messages[i]); - } - } - if (object.newJid != null) - message.newJid = String(object.newJid); - if (object.oldJid != null) - message.oldJid = String(object.oldJid); - if (object.lastMsgTimestamp != null) - if ($util.Long) - (message.lastMsgTimestamp = $util.Long.fromValue(object.lastMsgTimestamp)).unsigned = true; - else if (typeof object.lastMsgTimestamp === "string") - message.lastMsgTimestamp = parseInt(object.lastMsgTimestamp, 10); - else if (typeof object.lastMsgTimestamp === "number") - message.lastMsgTimestamp = object.lastMsgTimestamp; - else if (typeof object.lastMsgTimestamp === "object") - message.lastMsgTimestamp = new $util.LongBits(object.lastMsgTimestamp.low >>> 0, object.lastMsgTimestamp.high >>> 0).toNumber(true); - if (object.unreadCount != null) - message.unreadCount = object.unreadCount >>> 0; - if (object.readOnly != null) - message.readOnly = Boolean(object.readOnly); - if (object.endOfHistoryTransfer != null) - message.endOfHistoryTransfer = Boolean(object.endOfHistoryTransfer); - if (object.ephemeralExpiration != null) - message.ephemeralExpiration = object.ephemeralExpiration >>> 0; - if (object.ephemeralSettingTimestamp != null) - if ($util.Long) - (message.ephemeralSettingTimestamp = $util.Long.fromValue(object.ephemeralSettingTimestamp)).unsigned = false; - else if (typeof object.ephemeralSettingTimestamp === "string") - message.ephemeralSettingTimestamp = parseInt(object.ephemeralSettingTimestamp, 10); - else if (typeof object.ephemeralSettingTimestamp === "number") - message.ephemeralSettingTimestamp = object.ephemeralSettingTimestamp; - else if (typeof object.ephemeralSettingTimestamp === "object") - message.ephemeralSettingTimestamp = new $util.LongBits(object.ephemeralSettingTimestamp.low >>> 0, object.ephemeralSettingTimestamp.high >>> 0).toNumber(); - switch (object.endOfHistoryTransferType) { - case "COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY": - case 0: - message.endOfHistoryTransferType = 0; - break; - case "COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY": - case 1: - message.endOfHistoryTransferType = 1; - break; - } - if (object.conversationTimestamp != null) - if ($util.Long) - (message.conversationTimestamp = $util.Long.fromValue(object.conversationTimestamp)).unsigned = true; - else if (typeof object.conversationTimestamp === "string") - message.conversationTimestamp = parseInt(object.conversationTimestamp, 10); - else if (typeof object.conversationTimestamp === "number") - message.conversationTimestamp = object.conversationTimestamp; - else if (typeof object.conversationTimestamp === "object") - message.conversationTimestamp = new $util.LongBits(object.conversationTimestamp.low >>> 0, object.conversationTimestamp.high >>> 0).toNumber(true); - if (object.name != null) - message.name = String(object.name); - if (object.pHash != null) - message.pHash = String(object.pHash); - if (object.notSpam != null) - message.notSpam = Boolean(object.notSpam); - return message; - }; - - /** - * Creates a plain object from a Conversation message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.Conversation - * @static - * @param {proto.Conversation} message Conversation - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - Conversation.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.messages = []; - if (options.defaults) { - object.id = ""; - object.newJid = ""; - object.oldJid = ""; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.lastMsgTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.lastMsgTimestamp = options.longs === String ? "0" : 0; - object.unreadCount = 0; - object.readOnly = false; - object.endOfHistoryTransfer = false; - object.ephemeralExpiration = 0; - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.ephemeralSettingTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.ephemeralSettingTimestamp = options.longs === String ? "0" : 0; - object.endOfHistoryTransferType = options.enums === String ? "COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY" : 0; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.conversationTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.conversationTimestamp = options.longs === String ? "0" : 0; - object.name = ""; - object.pHash = ""; - object.notSpam = false; - } - if (message.id != null && message.hasOwnProperty("id")) - object.id = message.id; - if (message.messages && message.messages.length) { - object.messages = []; - for (var j = 0; j < message.messages.length; ++j) - object.messages[j] = $root.proto.HistorySyncMsg.toObject(message.messages[j], options); - } - if (message.newJid != null && message.hasOwnProperty("newJid")) - object.newJid = message.newJid; - if (message.oldJid != null && message.hasOwnProperty("oldJid")) - object.oldJid = message.oldJid; - if (message.lastMsgTimestamp != null && message.hasOwnProperty("lastMsgTimestamp")) - if (typeof message.lastMsgTimestamp === "number") - object.lastMsgTimestamp = options.longs === String ? String(message.lastMsgTimestamp) : message.lastMsgTimestamp; - else - object.lastMsgTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.lastMsgTimestamp) : options.longs === Number ? new $util.LongBits(message.lastMsgTimestamp.low >>> 0, message.lastMsgTimestamp.high >>> 0).toNumber(true) : message.lastMsgTimestamp; - if (message.unreadCount != null && message.hasOwnProperty("unreadCount")) - object.unreadCount = message.unreadCount; - if (message.readOnly != null && message.hasOwnProperty("readOnly")) - object.readOnly = message.readOnly; - if (message.endOfHistoryTransfer != null && message.hasOwnProperty("endOfHistoryTransfer")) - object.endOfHistoryTransfer = message.endOfHistoryTransfer; - if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration")) - object.ephemeralExpiration = message.ephemeralExpiration; - if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp")) - if (typeof message.ephemeralSettingTimestamp === "number") - object.ephemeralSettingTimestamp = options.longs === String ? String(message.ephemeralSettingTimestamp) : message.ephemeralSettingTimestamp; - else - object.ephemeralSettingTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.ephemeralSettingTimestamp) : options.longs === Number ? new $util.LongBits(message.ephemeralSettingTimestamp.low >>> 0, message.ephemeralSettingTimestamp.high >>> 0).toNumber() : message.ephemeralSettingTimestamp; - if (message.endOfHistoryTransferType != null && message.hasOwnProperty("endOfHistoryTransferType")) - object.endOfHistoryTransferType = options.enums === String ? $root.proto.Conversation.ConversationEndOfHistoryTransferType[message.endOfHistoryTransferType] : message.endOfHistoryTransferType; - if (message.conversationTimestamp != null && message.hasOwnProperty("conversationTimestamp")) - if (typeof message.conversationTimestamp === "number") - object.conversationTimestamp = options.longs === String ? String(message.conversationTimestamp) : message.conversationTimestamp; - else - object.conversationTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.conversationTimestamp) : options.longs === Number ? new $util.LongBits(message.conversationTimestamp.low >>> 0, message.conversationTimestamp.high >>> 0).toNumber(true) : message.conversationTimestamp; - if (message.name != null && message.hasOwnProperty("name")) - object.name = message.name; - if (message.pHash != null && message.hasOwnProperty("pHash")) - object.pHash = message.pHash; - if (message.notSpam != null && message.hasOwnProperty("notSpam")) - object.notSpam = message.notSpam; - return object; - }; - - /** - * Converts this Conversation to JSON. - * @function toJSON - * @memberof proto.Conversation - * @instance - * @returns {Object.} JSON object - */ - Conversation.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * ConversationEndOfHistoryTransferType enum. - * @name proto.Conversation.ConversationEndOfHistoryTransferType - * @enum {number} - * @property {number} COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY=0 COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY value - * @property {number} COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY=1 COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY value - */ - Conversation.ConversationEndOfHistoryTransferType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY"] = 0; - values[valuesById[1] = "COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY"] = 1; - return values; - })(); - - return Conversation; - })(); - - proto.HistorySync = (function() { - - /** - * Properties of a HistorySync. - * @memberof proto - * @interface IHistorySync - * @property {proto.HistorySync.HistorySyncHistorySyncType} syncType HistorySync syncType - * @property {Array.|null} [conversations] HistorySync conversations - * @property {Array.|null} [statusV3Messages] HistorySync statusV3Messages - * @property {number|null} [chunkOrder] HistorySync chunkOrder - * @property {number|null} [progress] HistorySync progress - * @property {Array.|null} [pushnames] HistorySync pushnames - */ - - /** - * Constructs a new HistorySync. - * @memberof proto - * @classdesc Represents a HistorySync. - * @implements IHistorySync - * @constructor - * @param {proto.IHistorySync=} [properties] Properties to set - */ - function HistorySync(properties) { - this.conversations = []; - this.statusV3Messages = []; - this.pushnames = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HistorySync syncType. - * @member {proto.HistorySync.HistorySyncHistorySyncType} syncType - * @memberof proto.HistorySync - * @instance - */ - HistorySync.prototype.syncType = 0; - - /** - * HistorySync conversations. - * @member {Array.} conversations - * @memberof proto.HistorySync - * @instance - */ - HistorySync.prototype.conversations = $util.emptyArray; - - /** - * HistorySync statusV3Messages. - * @member {Array.} statusV3Messages - * @memberof proto.HistorySync - * @instance - */ - HistorySync.prototype.statusV3Messages = $util.emptyArray; - - /** - * HistorySync chunkOrder. - * @member {number} chunkOrder - * @memberof proto.HistorySync - * @instance - */ - HistorySync.prototype.chunkOrder = 0; - - /** - * HistorySync progress. - * @member {number} progress - * @memberof proto.HistorySync - * @instance - */ - HistorySync.prototype.progress = 0; - - /** - * HistorySync pushnames. - * @member {Array.} pushnames - * @memberof proto.HistorySync - * @instance - */ - HistorySync.prototype.pushnames = $util.emptyArray; - - /** - * Creates a new HistorySync instance using the specified properties. - * @function create - * @memberof proto.HistorySync - * @static - * @param {proto.IHistorySync=} [properties] Properties to set - * @returns {proto.HistorySync} HistorySync instance - */ - HistorySync.create = function create(properties) { - return new HistorySync(properties); - }; - - /** - * Encodes the specified HistorySync message. Does not implicitly {@link proto.HistorySync.verify|verify} messages. - * @function encode - * @memberof proto.HistorySync - * @static - * @param {proto.IHistorySync} message HistorySync message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HistorySync.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.syncType); - if (message.conversations != null && message.conversations.length) - for (var i = 0; i < message.conversations.length; ++i) - $root.proto.Conversation.encode(message.conversations[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.statusV3Messages != null && message.statusV3Messages.length) - for (var i = 0; i < message.statusV3Messages.length; ++i) - $root.proto.WebMessageInfo.encode(message.statusV3Messages[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - if (message.chunkOrder != null && Object.hasOwnProperty.call(message, "chunkOrder")) - writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.chunkOrder); - if (message.progress != null && Object.hasOwnProperty.call(message, "progress")) - writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.progress); - if (message.pushnames != null && message.pushnames.length) - for (var i = 0; i < message.pushnames.length; ++i) - $root.proto.Pushname.encode(message.pushnames[i], writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified HistorySync message, length delimited. Does not implicitly {@link proto.HistorySync.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HistorySync - * @static - * @param {proto.IHistorySync} message HistorySync message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HistorySync.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HistorySync message from the specified reader or buffer. - * @function decode - * @memberof proto.HistorySync - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HistorySync} HistorySync - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HistorySync.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HistorySync(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.syncType = reader.int32(); - break; - case 2: - if (!(message.conversations && message.conversations.length)) - message.conversations = []; - message.conversations.push($root.proto.Conversation.decode(reader, reader.uint32())); - break; - case 3: - if (!(message.statusV3Messages && message.statusV3Messages.length)) - message.statusV3Messages = []; - message.statusV3Messages.push($root.proto.WebMessageInfo.decode(reader, reader.uint32())); - break; - case 5: - message.chunkOrder = reader.uint32(); - break; - case 6: - message.progress = reader.uint32(); - break; - case 7: - if (!(message.pushnames && message.pushnames.length)) - message.pushnames = []; - message.pushnames.push($root.proto.Pushname.decode(reader, reader.uint32())); - break; - default: - reader.skipType(tag & 7); - break; - } - } - if (!message.hasOwnProperty("syncType")) - throw $util.ProtocolError("missing required 'syncType'", { instance: message }); - return message; - }; - - /** - * Decodes a HistorySync message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HistorySync - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HistorySync} HistorySync - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HistorySync.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HistorySync message. - * @function verify - * @memberof proto.HistorySync - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HistorySync.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - switch (message.syncType) { - default: - return "syncType: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - break; - } - if (message.conversations != null && message.hasOwnProperty("conversations")) { - if (!Array.isArray(message.conversations)) - return "conversations: array expected"; - for (var i = 0; i < message.conversations.length; ++i) { - var error = $root.proto.Conversation.verify(message.conversations[i]); - if (error) - return "conversations." + error; - } - } - if (message.statusV3Messages != null && message.hasOwnProperty("statusV3Messages")) { - if (!Array.isArray(message.statusV3Messages)) - return "statusV3Messages: array expected"; - for (var i = 0; i < message.statusV3Messages.length; ++i) { - var error = $root.proto.WebMessageInfo.verify(message.statusV3Messages[i]); - if (error) - return "statusV3Messages." + error; - } - } - if (message.chunkOrder != null && message.hasOwnProperty("chunkOrder")) - if (!$util.isInteger(message.chunkOrder)) - return "chunkOrder: integer expected"; - if (message.progress != null && message.hasOwnProperty("progress")) - if (!$util.isInteger(message.progress)) - return "progress: integer expected"; - if (message.pushnames != null && message.hasOwnProperty("pushnames")) { - if (!Array.isArray(message.pushnames)) - return "pushnames: array expected"; - for (var i = 0; i < message.pushnames.length; ++i) { - var error = $root.proto.Pushname.verify(message.pushnames[i]); - if (error) - return "pushnames." + error; - } - } - return null; - }; - - /** - * Creates a HistorySync message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HistorySync - * @static - * @param {Object.} object Plain object - * @returns {proto.HistorySync} HistorySync - */ - HistorySync.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HistorySync) - return object; - var message = new $root.proto.HistorySync(); - switch (object.syncType) { - case "INITIAL_BOOTSTRAP": - case 0: - message.syncType = 0; - break; - case "INITIAL_STATUS_V3": - case 1: - message.syncType = 1; - break; - case "FULL": - case 2: - message.syncType = 2; - break; - case "RECENT": - case 3: - message.syncType = 3; - break; - case "PUSH_NAME": - case 4: - message.syncType = 4; - break; - } - if (object.conversations) { - if (!Array.isArray(object.conversations)) - throw TypeError(".proto.HistorySync.conversations: array expected"); - message.conversations = []; - for (var i = 0; i < object.conversations.length; ++i) { - if (typeof object.conversations[i] !== "object") - throw TypeError(".proto.HistorySync.conversations: object expected"); - message.conversations[i] = $root.proto.Conversation.fromObject(object.conversations[i]); - } - } - if (object.statusV3Messages) { - if (!Array.isArray(object.statusV3Messages)) - throw TypeError(".proto.HistorySync.statusV3Messages: array expected"); - message.statusV3Messages = []; - for (var i = 0; i < object.statusV3Messages.length; ++i) { - if (typeof object.statusV3Messages[i] !== "object") - throw TypeError(".proto.HistorySync.statusV3Messages: object expected"); - message.statusV3Messages[i] = $root.proto.WebMessageInfo.fromObject(object.statusV3Messages[i]); - } - } - if (object.chunkOrder != null) - message.chunkOrder = object.chunkOrder >>> 0; - if (object.progress != null) - message.progress = object.progress >>> 0; - if (object.pushnames) { - if (!Array.isArray(object.pushnames)) - throw TypeError(".proto.HistorySync.pushnames: array expected"); - message.pushnames = []; - for (var i = 0; i < object.pushnames.length; ++i) { - if (typeof object.pushnames[i] !== "object") - throw TypeError(".proto.HistorySync.pushnames: object expected"); - message.pushnames[i] = $root.proto.Pushname.fromObject(object.pushnames[i]); - } - } - return message; - }; - - /** - * Creates a plain object from a HistorySync message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HistorySync - * @static - * @param {proto.HistorySync} message HistorySync - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HistorySync.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) { - object.conversations = []; - object.statusV3Messages = []; - object.pushnames = []; - } - if (options.defaults) { - object.syncType = options.enums === String ? "INITIAL_BOOTSTRAP" : 0; - object.chunkOrder = 0; - object.progress = 0; - } - if (message.syncType != null && message.hasOwnProperty("syncType")) - object.syncType = options.enums === String ? $root.proto.HistorySync.HistorySyncHistorySyncType[message.syncType] : message.syncType; - if (message.conversations && message.conversations.length) { - object.conversations = []; - for (var j = 0; j < message.conversations.length; ++j) - object.conversations[j] = $root.proto.Conversation.toObject(message.conversations[j], options); - } - if (message.statusV3Messages && message.statusV3Messages.length) { - object.statusV3Messages = []; - for (var j = 0; j < message.statusV3Messages.length; ++j) - object.statusV3Messages[j] = $root.proto.WebMessageInfo.toObject(message.statusV3Messages[j], options); - } - if (message.chunkOrder != null && message.hasOwnProperty("chunkOrder")) - object.chunkOrder = message.chunkOrder; - if (message.progress != null && message.hasOwnProperty("progress")) - object.progress = message.progress; - if (message.pushnames && message.pushnames.length) { - object.pushnames = []; - for (var j = 0; j < message.pushnames.length; ++j) - object.pushnames[j] = $root.proto.Pushname.toObject(message.pushnames[j], options); - } - return object; - }; - - /** - * Converts this HistorySync to JSON. - * @function toJSON - * @memberof proto.HistorySync - * @instance - * @returns {Object.} JSON object - */ - HistorySync.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * HistorySyncHistorySyncType enum. - * @name proto.HistorySync.HistorySyncHistorySyncType - * @enum {number} - * @property {number} INITIAL_BOOTSTRAP=0 INITIAL_BOOTSTRAP value - * @property {number} INITIAL_STATUS_V3=1 INITIAL_STATUS_V3 value - * @property {number} FULL=2 FULL value - * @property {number} RECENT=3 RECENT value - * @property {number} PUSH_NAME=4 PUSH_NAME value - */ - HistorySync.HistorySyncHistorySyncType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "INITIAL_BOOTSTRAP"] = 0; - values[valuesById[1] = "INITIAL_STATUS_V3"] = 1; - values[valuesById[2] = "FULL"] = 2; - values[valuesById[3] = "RECENT"] = 3; - values[valuesById[4] = "PUSH_NAME"] = 4; - return values; - })(); - - return HistorySync; - })(); - - proto.EphemeralSetting = (function() { - - /** - * Properties of an EphemeralSetting. - * @memberof proto - * @interface IEphemeralSetting - * @property {number|null} [duration] EphemeralSetting duration - * @property {number|Long|null} [timestamp] EphemeralSetting timestamp - */ - - /** - * Constructs a new EphemeralSetting. - * @memberof proto - * @classdesc Represents an EphemeralSetting. - * @implements IEphemeralSetting - * @constructor - * @param {proto.IEphemeralSetting=} [properties] Properties to set - */ - function EphemeralSetting(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * EphemeralSetting duration. - * @member {number} duration - * @memberof proto.EphemeralSetting - * @instance - */ - EphemeralSetting.prototype.duration = 0; - - /** - * EphemeralSetting timestamp. - * @member {number|Long} timestamp - * @memberof proto.EphemeralSetting - * @instance - */ - EphemeralSetting.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * Creates a new EphemeralSetting instance using the specified properties. - * @function create - * @memberof proto.EphemeralSetting - * @static - * @param {proto.IEphemeralSetting=} [properties] Properties to set - * @returns {proto.EphemeralSetting} EphemeralSetting instance - */ - EphemeralSetting.create = function create(properties) { - return new EphemeralSetting(properties); - }; - - /** - * Encodes the specified EphemeralSetting message. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. - * @function encode - * @memberof proto.EphemeralSetting - * @static - * @param {proto.IEphemeralSetting} message EphemeralSetting message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - EphemeralSetting.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.duration != null && Object.hasOwnProperty.call(message, "duration")) - writer.uint32(/* id 1, wireType 5 =*/13).sfixed32(message.duration); - if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) - writer.uint32(/* id 2, wireType 1 =*/17).sfixed64(message.timestamp); - return writer; - }; - - /** - * Encodes the specified EphemeralSetting message, length delimited. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.EphemeralSetting - * @static - * @param {proto.IEphemeralSetting} message EphemeralSetting message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - EphemeralSetting.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes an EphemeralSetting message from the specified reader or buffer. - * @function decode - * @memberof proto.EphemeralSetting - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.EphemeralSetting} EphemeralSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - EphemeralSetting.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.EphemeralSetting(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.duration = reader.sfixed32(); - break; - case 2: - message.timestamp = reader.sfixed64(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes an EphemeralSetting message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.EphemeralSetting - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.EphemeralSetting} EphemeralSetting - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - EphemeralSetting.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies an EphemeralSetting message. - * @function verify - * @memberof proto.EphemeralSetting - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - EphemeralSetting.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.duration != null && message.hasOwnProperty("duration")) - if (!$util.isInteger(message.duration)) - return "duration: integer expected"; - if (message.timestamp != null && message.hasOwnProperty("timestamp")) - if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) - return "timestamp: integer|Long expected"; - return null; - }; - - /** - * Creates an EphemeralSetting message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.EphemeralSetting - * @static - * @param {Object.} object Plain object - * @returns {proto.EphemeralSetting} EphemeralSetting - */ - EphemeralSetting.fromObject = function fromObject(object) { - if (object instanceof $root.proto.EphemeralSetting) - return object; - var message = new $root.proto.EphemeralSetting(); - if (object.duration != null) - message.duration = object.duration | 0; - if (object.timestamp != null) - if ($util.Long) - (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false; - else if (typeof object.timestamp === "string") - message.timestamp = parseInt(object.timestamp, 10); - else if (typeof object.timestamp === "number") - message.timestamp = object.timestamp; - else if (typeof object.timestamp === "object") - message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(); - return message; - }; - - /** - * Creates a plain object from an EphemeralSetting message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.EphemeralSetting - * @static - * @param {proto.EphemeralSetting} message EphemeralSetting - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - EphemeralSetting.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.duration = 0; - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.timestamp = options.longs === String ? "0" : 0; - } - if (message.duration != null && message.hasOwnProperty("duration")) - object.duration = message.duration; - if (message.timestamp != null && message.hasOwnProperty("timestamp")) - if (typeof message.timestamp === "number") - object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; - else - object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp; - return object; - }; - - /** - * Converts this EphemeralSetting to JSON. - * @function toJSON - * @memberof proto.EphemeralSetting - * @instance - * @returns {Object.} JSON object - */ - EphemeralSetting.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return EphemeralSetting; - })(); - - proto.PaymentBackground = (function() { - - /** - * Properties of a PaymentBackground. - * @memberof proto - * @interface IPaymentBackground - * @property {string|null} [id] PaymentBackground id - * @property {string|null} [fileLength] PaymentBackground fileLength - * @property {number|null} [width] PaymentBackground width - * @property {number|null} [height] PaymentBackground height - * @property {string|null} [mimetype] PaymentBackground mimetype - * @property {number|null} [placeholderArgb] PaymentBackground placeholderArgb - * @property {number|null} [textArgb] PaymentBackground textArgb - * @property {number|null} [subtextArgb] PaymentBackground subtextArgb - */ - - /** - * Constructs a new PaymentBackground. - * @memberof proto - * @classdesc Represents a PaymentBackground. - * @implements IPaymentBackground - * @constructor - * @param {proto.IPaymentBackground=} [properties] Properties to set - */ - function PaymentBackground(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * PaymentBackground id. - * @member {string} id - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.id = ""; - - /** - * PaymentBackground fileLength. - * @member {string} fileLength - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.fileLength = ""; - - /** - * PaymentBackground width. - * @member {number} width - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.width = 0; - - /** - * PaymentBackground height. - * @member {number} height - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.height = 0; - - /** - * PaymentBackground mimetype. - * @member {string} mimetype - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.mimetype = ""; - - /** - * PaymentBackground placeholderArgb. - * @member {number} placeholderArgb - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.placeholderArgb = 0; - - /** - * PaymentBackground textArgb. - * @member {number} textArgb - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.textArgb = 0; - - /** - * PaymentBackground subtextArgb. - * @member {number} subtextArgb - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.subtextArgb = 0; - - /** - * Creates a new PaymentBackground instance using the specified properties. - * @function create - * @memberof proto.PaymentBackground - * @static - * @param {proto.IPaymentBackground=} [properties] Properties to set - * @returns {proto.PaymentBackground} PaymentBackground instance - */ - PaymentBackground.create = function create(properties) { - return new PaymentBackground(properties); - }; - - /** - * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. - * @function encode - * @memberof proto.PaymentBackground - * @static - * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - PaymentBackground.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); - if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.fileLength); - if (message.width != null && Object.hasOwnProperty.call(message, "width")) - writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.width); - if (message.height != null && Object.hasOwnProperty.call(message, "height")) - writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.height); - if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype")) - writer.uint32(/* id 5, wireType 2 =*/42).string(message.mimetype); - if (message.placeholderArgb != null && Object.hasOwnProperty.call(message, "placeholderArgb")) - writer.uint32(/* id 6, wireType 5 =*/53).fixed32(message.placeholderArgb); - if (message.textArgb != null && Object.hasOwnProperty.call(message, "textArgb")) - writer.uint32(/* id 7, wireType 5 =*/61).fixed32(message.textArgb); - if (message.subtextArgb != null && Object.hasOwnProperty.call(message, "subtextArgb")) - writer.uint32(/* id 8, wireType 5 =*/69).fixed32(message.subtextArgb); - return writer; - }; - - /** - * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.PaymentBackground - * @static - * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - PaymentBackground.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a PaymentBackground message from the specified reader or buffer. - * @function decode - * @memberof proto.PaymentBackground - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.PaymentBackground} PaymentBackground - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - PaymentBackground.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentBackground(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.id = reader.string(); - break; - case 2: - message.fileLength = reader.string(); - break; - case 3: - message.width = reader.uint32(); - break; - case 4: - message.height = reader.uint32(); - break; - case 5: - message.mimetype = reader.string(); - break; - case 6: - message.placeholderArgb = reader.fixed32(); - break; - case 7: - message.textArgb = reader.fixed32(); - break; - case 8: - message.subtextArgb = reader.fixed32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.PaymentBackground - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.PaymentBackground} PaymentBackground - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - PaymentBackground.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a PaymentBackground message. - * @function verify - * @memberof proto.PaymentBackground - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - PaymentBackground.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.id != null && message.hasOwnProperty("id")) - if (!$util.isString(message.id)) - return "id: string expected"; - if (message.fileLength != null && message.hasOwnProperty("fileLength")) - if (!$util.isString(message.fileLength)) - return "fileLength: string expected"; - if (message.width != null && message.hasOwnProperty("width")) - if (!$util.isInteger(message.width)) - return "width: integer expected"; - if (message.height != null && message.hasOwnProperty("height")) - if (!$util.isInteger(message.height)) - return "height: integer expected"; - if (message.mimetype != null && message.hasOwnProperty("mimetype")) - if (!$util.isString(message.mimetype)) - return "mimetype: string expected"; - if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) - if (!$util.isInteger(message.placeholderArgb)) - return "placeholderArgb: integer expected"; - if (message.textArgb != null && message.hasOwnProperty("textArgb")) - if (!$util.isInteger(message.textArgb)) - return "textArgb: integer expected"; - if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) - if (!$util.isInteger(message.subtextArgb)) - return "subtextArgb: integer expected"; - return null; - }; - - /** - * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.PaymentBackground - * @static - * @param {Object.} object Plain object - * @returns {proto.PaymentBackground} PaymentBackground - */ - PaymentBackground.fromObject = function fromObject(object) { - if (object instanceof $root.proto.PaymentBackground) - return object; - var message = new $root.proto.PaymentBackground(); - if (object.id != null) - message.id = String(object.id); - if (object.fileLength != null) - message.fileLength = String(object.fileLength); - if (object.width != null) - message.width = object.width >>> 0; - if (object.height != null) - message.height = object.height >>> 0; - if (object.mimetype != null) - message.mimetype = String(object.mimetype); - if (object.placeholderArgb != null) - message.placeholderArgb = object.placeholderArgb >>> 0; - if (object.textArgb != null) - message.textArgb = object.textArgb >>> 0; - if (object.subtextArgb != null) - message.subtextArgb = object.subtextArgb >>> 0; - return message; - }; - - /** - * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.PaymentBackground - * @static - * @param {proto.PaymentBackground} message PaymentBackground - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - PaymentBackground.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.id = ""; - object.fileLength = ""; - object.width = 0; - object.height = 0; - object.mimetype = ""; - object.placeholderArgb = 0; - object.textArgb = 0; - object.subtextArgb = 0; - } - if (message.id != null && message.hasOwnProperty("id")) - object.id = message.id; - if (message.fileLength != null && message.hasOwnProperty("fileLength")) - object.fileLength = message.fileLength; - if (message.width != null && message.hasOwnProperty("width")) - object.width = message.width; - if (message.height != null && message.hasOwnProperty("height")) - object.height = message.height; - if (message.mimetype != null && message.hasOwnProperty("mimetype")) - object.mimetype = message.mimetype; - if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) - object.placeholderArgb = message.placeholderArgb; - if (message.textArgb != null && message.hasOwnProperty("textArgb")) - object.textArgb = message.textArgb; - if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) - object.subtextArgb = message.subtextArgb; - return object; - }; - - /** - * Converts this PaymentBackground to JSON. - * @function toJSON - * @memberof proto.PaymentBackground - * @instance - * @returns {Object.} JSON object - */ - PaymentBackground.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return PaymentBackground; - })(); - - proto.Money = (function() { - - /** - * Properties of a Money. - * @memberof proto - * @interface IMoney - * @property {number|Long|null} [value] Money value - * @property {number|null} [offset] Money offset - * @property {string|null} [currencyCode] Money currencyCode - */ - - /** - * Constructs a new Money. - * @memberof proto - * @classdesc Represents a Money. - * @implements IMoney - * @constructor - * @param {proto.IMoney=} [properties] Properties to set - */ - function Money(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * Money value. - * @member {number|Long} value - * @memberof proto.Money - * @instance - */ - Money.prototype.value = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * Money offset. - * @member {number} offset - * @memberof proto.Money - * @instance - */ - Money.prototype.offset = 0; - - /** - * Money currencyCode. - * @member {string} currencyCode - * @memberof proto.Money - * @instance - */ - Money.prototype.currencyCode = ""; - - /** - * Creates a new Money instance using the specified properties. - * @function create - * @memberof proto.Money - * @static - * @param {proto.IMoney=} [properties] Properties to set - * @returns {proto.Money} Money instance - */ - Money.create = function create(properties) { - return new Money(properties); - }; - - /** - * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. - * @function encode - * @memberof proto.Money - * @static - * @param {proto.IMoney} message Money message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Money.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.value != null && Object.hasOwnProperty.call(message, "value")) - writer.uint32(/* id 1, wireType 0 =*/8).int64(message.value); - if (message.offset != null && Object.hasOwnProperty.call(message, "offset")) - writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.offset); - if (message.currencyCode != null && Object.hasOwnProperty.call(message, "currencyCode")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.currencyCode); - return writer; - }; - - /** - * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.Money - * @static - * @param {proto.IMoney} message Money message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Money.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a Money message from the specified reader or buffer. - * @function decode - * @memberof proto.Money - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.Money} Money - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Money.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Money(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.value = reader.int64(); - break; - case 2: - message.offset = reader.uint32(); - break; - case 3: - message.currencyCode = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a Money message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.Money - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.Money} Money - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Money.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a Money message. - * @function verify - * @memberof proto.Money - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - Money.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.value != null && message.hasOwnProperty("value")) - if (!$util.isInteger(message.value) && !(message.value && $util.isInteger(message.value.low) && $util.isInteger(message.value.high))) - return "value: integer|Long expected"; - if (message.offset != null && message.hasOwnProperty("offset")) - if (!$util.isInteger(message.offset)) - return "offset: integer expected"; - if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) - if (!$util.isString(message.currencyCode)) - return "currencyCode: string expected"; - return null; - }; - - /** - * Creates a Money message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.Money - * @static - * @param {Object.} object Plain object - * @returns {proto.Money} Money - */ - Money.fromObject = function fromObject(object) { - if (object instanceof $root.proto.Money) - return object; - var message = new $root.proto.Money(); - if (object.value != null) - if ($util.Long) - (message.value = $util.Long.fromValue(object.value)).unsigned = false; - else if (typeof object.value === "string") - message.value = parseInt(object.value, 10); - else if (typeof object.value === "number") - message.value = object.value; - else if (typeof object.value === "object") - message.value = new $util.LongBits(object.value.low >>> 0, object.value.high >>> 0).toNumber(); - if (object.offset != null) - message.offset = object.offset >>> 0; - if (object.currencyCode != null) - message.currencyCode = String(object.currencyCode); - return message; - }; - - /** - * Creates a plain object from a Money message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.Money - * @static - * @param {proto.Money} message Money - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - Money.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.value = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.value = options.longs === String ? "0" : 0; - object.offset = 0; - object.currencyCode = ""; - } - if (message.value != null && message.hasOwnProperty("value")) - if (typeof message.value === "number") - object.value = options.longs === String ? String(message.value) : message.value; - else - object.value = options.longs === String ? $util.Long.prototype.toString.call(message.value) : options.longs === Number ? new $util.LongBits(message.value.low >>> 0, message.value.high >>> 0).toNumber() : message.value; - if (message.offset != null && message.hasOwnProperty("offset")) - object.offset = message.offset; - if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) - object.currencyCode = message.currencyCode; - return object; - }; - - /** - * Converts this Money to JSON. - * @function toJSON - * @memberof proto.Money - * @instance - * @returns {Object.} JSON object - */ - Money.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return Money; - })(); - - proto.HydratedQuickReplyButton = (function() { - - /** - * Properties of a HydratedQuickReplyButton. - * @memberof proto - * @interface IHydratedQuickReplyButton - * @property {string|null} [displayText] HydratedQuickReplyButton displayText - * @property {string|null} [id] HydratedQuickReplyButton id - */ - - /** - * Constructs a new HydratedQuickReplyButton. - * @memberof proto - * @classdesc Represents a HydratedQuickReplyButton. - * @implements IHydratedQuickReplyButton - * @constructor - * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set - */ - function HydratedQuickReplyButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HydratedQuickReplyButton displayText. - * @member {string} displayText - * @memberof proto.HydratedQuickReplyButton - * @instance - */ - HydratedQuickReplyButton.prototype.displayText = ""; - - /** - * HydratedQuickReplyButton id. - * @member {string} id - * @memberof proto.HydratedQuickReplyButton - * @instance - */ - HydratedQuickReplyButton.prototype.id = ""; - - /** - * Creates a new HydratedQuickReplyButton instance using the specified properties. - * @function create - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set - * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton instance - */ - HydratedQuickReplyButton.create = function create(properties) { - return new HydratedQuickReplyButton(properties); - }; - - /** - * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. - * @function encode - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedQuickReplyButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.id); - return writer; - }; - - /** - * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedQuickReplyButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HydratedQuickReplyButton message from the specified reader or buffer. - * @function decode - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedQuickReplyButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedQuickReplyButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.displayText = reader.string(); - break; - case 2: - message.id = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedQuickReplyButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HydratedQuickReplyButton message. - * @function verify - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HydratedQuickReplyButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.displayText != null && message.hasOwnProperty("displayText")) - if (!$util.isString(message.displayText)) - return "displayText: string expected"; - if (message.id != null && message.hasOwnProperty("id")) - if (!$util.isString(message.id)) - return "id: string expected"; - return null; - }; - - /** - * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {Object.} object Plain object - * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton - */ - HydratedQuickReplyButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HydratedQuickReplyButton) - return object; - var message = new $root.proto.HydratedQuickReplyButton(); - if (object.displayText != null) - message.displayText = String(object.displayText); - if (object.id != null) - message.id = String(object.id); - return message; - }; - - /** - * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {proto.HydratedQuickReplyButton} message HydratedQuickReplyButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HydratedQuickReplyButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.displayText = ""; - object.id = ""; - } - if (message.displayText != null && message.hasOwnProperty("displayText")) - object.displayText = message.displayText; - if (message.id != null && message.hasOwnProperty("id")) - object.id = message.id; - return object; - }; - - /** - * Converts this HydratedQuickReplyButton to JSON. - * @function toJSON - * @memberof proto.HydratedQuickReplyButton - * @instance - * @returns {Object.} JSON object - */ - HydratedQuickReplyButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HydratedQuickReplyButton; - })(); - - proto.HydratedURLButton = (function() { - - /** - * Properties of a HydratedURLButton. - * @memberof proto - * @interface IHydratedURLButton - * @property {string|null} [displayText] HydratedURLButton displayText - * @property {string|null} [url] HydratedURLButton url - */ - - /** - * Constructs a new HydratedURLButton. - * @memberof proto - * @classdesc Represents a HydratedURLButton. - * @implements IHydratedURLButton - * @constructor - * @param {proto.IHydratedURLButton=} [properties] Properties to set - */ - function HydratedURLButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HydratedURLButton displayText. - * @member {string} displayText - * @memberof proto.HydratedURLButton - * @instance - */ - HydratedURLButton.prototype.displayText = ""; - - /** - * HydratedURLButton url. - * @member {string} url - * @memberof proto.HydratedURLButton - * @instance - */ - HydratedURLButton.prototype.url = ""; - - /** - * Creates a new HydratedURLButton instance using the specified properties. - * @function create - * @memberof proto.HydratedURLButton - * @static - * @param {proto.IHydratedURLButton=} [properties] Properties to set - * @returns {proto.HydratedURLButton} HydratedURLButton instance - */ - HydratedURLButton.create = function create(properties) { - return new HydratedURLButton(properties); - }; - - /** - * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. - * @function encode - * @memberof proto.HydratedURLButton - * @static - * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedURLButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); - if (message.url != null && Object.hasOwnProperty.call(message, "url")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.url); - return writer; - }; - - /** - * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HydratedURLButton - * @static - * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedURLButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HydratedURLButton message from the specified reader or buffer. - * @function decode - * @memberof proto.HydratedURLButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HydratedURLButton} HydratedURLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedURLButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedURLButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.displayText = reader.string(); - break; - case 2: - message.url = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HydratedURLButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HydratedURLButton} HydratedURLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedURLButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HydratedURLButton message. - * @function verify - * @memberof proto.HydratedURLButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HydratedURLButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.displayText != null && message.hasOwnProperty("displayText")) - if (!$util.isString(message.displayText)) - return "displayText: string expected"; - if (message.url != null && message.hasOwnProperty("url")) - if (!$util.isString(message.url)) - return "url: string expected"; - return null; - }; - - /** - * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HydratedURLButton - * @static - * @param {Object.} object Plain object - * @returns {proto.HydratedURLButton} HydratedURLButton - */ - HydratedURLButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HydratedURLButton) - return object; - var message = new $root.proto.HydratedURLButton(); - if (object.displayText != null) - message.displayText = String(object.displayText); - if (object.url != null) - message.url = String(object.url); - return message; - }; - - /** - * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HydratedURLButton - * @static - * @param {proto.HydratedURLButton} message HydratedURLButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HydratedURLButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.displayText = ""; - object.url = ""; - } - if (message.displayText != null && message.hasOwnProperty("displayText")) - object.displayText = message.displayText; - if (message.url != null && message.hasOwnProperty("url")) - object.url = message.url; - return object; - }; - - /** - * Converts this HydratedURLButton to JSON. - * @function toJSON - * @memberof proto.HydratedURLButton - * @instance - * @returns {Object.} JSON object - */ - HydratedURLButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HydratedURLButton; - })(); - - proto.HydratedCallButton = (function() { - - /** - * Properties of a HydratedCallButton. - * @memberof proto - * @interface IHydratedCallButton - * @property {string|null} [displayText] HydratedCallButton displayText - * @property {string|null} [phoneNumber] HydratedCallButton phoneNumber - */ - - /** - * Constructs a new HydratedCallButton. - * @memberof proto - * @classdesc Represents a HydratedCallButton. - * @implements IHydratedCallButton - * @constructor - * @param {proto.IHydratedCallButton=} [properties] Properties to set - */ - function HydratedCallButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HydratedCallButton displayText. - * @member {string} displayText - * @memberof proto.HydratedCallButton - * @instance - */ - HydratedCallButton.prototype.displayText = ""; - - /** - * HydratedCallButton phoneNumber. - * @member {string} phoneNumber - * @memberof proto.HydratedCallButton - * @instance - */ - HydratedCallButton.prototype.phoneNumber = ""; - - /** - * Creates a new HydratedCallButton instance using the specified properties. - * @function create - * @memberof proto.HydratedCallButton - * @static - * @param {proto.IHydratedCallButton=} [properties] Properties to set - * @returns {proto.HydratedCallButton} HydratedCallButton instance - */ - HydratedCallButton.create = function create(properties) { - return new HydratedCallButton(properties); - }; - - /** - * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. - * @function encode - * @memberof proto.HydratedCallButton - * @static - * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedCallButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); - if (message.phoneNumber != null && Object.hasOwnProperty.call(message, "phoneNumber")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.phoneNumber); - return writer; - }; - - /** - * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HydratedCallButton - * @static - * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedCallButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HydratedCallButton message from the specified reader or buffer. - * @function decode - * @memberof proto.HydratedCallButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HydratedCallButton} HydratedCallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedCallButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedCallButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.displayText = reader.string(); - break; - case 2: - message.phoneNumber = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HydratedCallButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HydratedCallButton} HydratedCallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedCallButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HydratedCallButton message. - * @function verify - * @memberof proto.HydratedCallButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HydratedCallButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.displayText != null && message.hasOwnProperty("displayText")) - if (!$util.isString(message.displayText)) - return "displayText: string expected"; - if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) - if (!$util.isString(message.phoneNumber)) - return "phoneNumber: string expected"; - return null; - }; - - /** - * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HydratedCallButton - * @static - * @param {Object.} object Plain object - * @returns {proto.HydratedCallButton} HydratedCallButton - */ - HydratedCallButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HydratedCallButton) - return object; - var message = new $root.proto.HydratedCallButton(); - if (object.displayText != null) - message.displayText = String(object.displayText); - if (object.phoneNumber != null) - message.phoneNumber = String(object.phoneNumber); - return message; - }; - - /** - * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HydratedCallButton - * @static - * @param {proto.HydratedCallButton} message HydratedCallButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HydratedCallButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.displayText = ""; - object.phoneNumber = ""; - } - if (message.displayText != null && message.hasOwnProperty("displayText")) - object.displayText = message.displayText; - if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) - object.phoneNumber = message.phoneNumber; - return object; - }; - - /** - * Converts this HydratedCallButton to JSON. - * @function toJSON - * @memberof proto.HydratedCallButton - * @instance - * @returns {Object.} JSON object - */ - HydratedCallButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HydratedCallButton; - })(); - - proto.HydratedTemplateButton = (function() { - - /** - * Properties of a HydratedTemplateButton. - * @memberof proto - * @interface IHydratedTemplateButton - * @property {number|null} [index] HydratedTemplateButton index - * @property {proto.IHydratedQuickReplyButton|null} [quickReplyButton] HydratedTemplateButton quickReplyButton - * @property {proto.IHydratedURLButton|null} [urlButton] HydratedTemplateButton urlButton - * @property {proto.IHydratedCallButton|null} [callButton] HydratedTemplateButton callButton - */ - - /** - * Constructs a new HydratedTemplateButton. - * @memberof proto - * @classdesc Represents a HydratedTemplateButton. - * @implements IHydratedTemplateButton - * @constructor - * @param {proto.IHydratedTemplateButton=} [properties] Properties to set - */ - function HydratedTemplateButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HydratedTemplateButton index. - * @member {number} index - * @memberof proto.HydratedTemplateButton - * @instance - */ - HydratedTemplateButton.prototype.index = 0; - - /** - * HydratedTemplateButton quickReplyButton. - * @member {proto.IHydratedQuickReplyButton|null|undefined} quickReplyButton - * @memberof proto.HydratedTemplateButton - * @instance - */ - HydratedTemplateButton.prototype.quickReplyButton = null; - - /** - * HydratedTemplateButton urlButton. - * @member {proto.IHydratedURLButton|null|undefined} urlButton - * @memberof proto.HydratedTemplateButton - * @instance - */ - HydratedTemplateButton.prototype.urlButton = null; - - /** - * HydratedTemplateButton callButton. - * @member {proto.IHydratedCallButton|null|undefined} callButton - * @memberof proto.HydratedTemplateButton - * @instance - */ - HydratedTemplateButton.prototype.callButton = null; - - // OneOf field names bound to virtual getters and setters - var $oneOfFields; - - /** - * HydratedTemplateButton hydratedButton. - * @member {"quickReplyButton"|"urlButton"|"callButton"|undefined} hydratedButton - * @memberof proto.HydratedTemplateButton - * @instance - */ - Object.defineProperty(HydratedTemplateButton.prototype, "hydratedButton", { - get: $util.oneOfGetter($oneOfFields = ["quickReplyButton", "urlButton", "callButton"]), - set: $util.oneOfSetter($oneOfFields) - }); - - /** - * Creates a new HydratedTemplateButton instance using the specified properties. - * @function create - * @memberof proto.HydratedTemplateButton - * @static - * @param {proto.IHydratedTemplateButton=} [properties] Properties to set - * @returns {proto.HydratedTemplateButton} HydratedTemplateButton instance - */ - HydratedTemplateButton.create = function create(properties) { - return new HydratedTemplateButton(properties); - }; - - /** - * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. - * @function encode - * @memberof proto.HydratedTemplateButton - * @static - * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedTemplateButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.quickReplyButton != null && Object.hasOwnProperty.call(message, "quickReplyButton")) - $root.proto.HydratedQuickReplyButton.encode(message.quickReplyButton, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.urlButton != null && Object.hasOwnProperty.call(message, "urlButton")) - $root.proto.HydratedURLButton.encode(message.urlButton, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.callButton != null && Object.hasOwnProperty.call(message, "callButton")) - $root.proto.HydratedCallButton.encode(message.callButton, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - if (message.index != null && Object.hasOwnProperty.call(message, "index")) - writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.index); - return writer; - }; - - /** - * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HydratedTemplateButton - * @static - * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedTemplateButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HydratedTemplateButton message from the specified reader or buffer. - * @function decode - * @memberof proto.HydratedTemplateButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HydratedTemplateButton} HydratedTemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedTemplateButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedTemplateButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 4: - message.index = reader.uint32(); - break; - case 1: - message.quickReplyButton = $root.proto.HydratedQuickReplyButton.decode(reader, reader.uint32()); - break; - case 2: - message.urlButton = $root.proto.HydratedURLButton.decode(reader, reader.uint32()); - break; - case 3: - message.callButton = $root.proto.HydratedCallButton.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HydratedTemplateButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HydratedTemplateButton} HydratedTemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedTemplateButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HydratedTemplateButton message. - * @function verify - * @memberof proto.HydratedTemplateButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HydratedTemplateButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - var properties = {}; - if (message.index != null && message.hasOwnProperty("index")) - if (!$util.isInteger(message.index)) - return "index: integer expected"; - if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { - properties.hydratedButton = 1; - { - var error = $root.proto.HydratedQuickReplyButton.verify(message.quickReplyButton); - if (error) - return "quickReplyButton." + error; - } - } - if (message.urlButton != null && message.hasOwnProperty("urlButton")) { - if (properties.hydratedButton === 1) - return "hydratedButton: multiple values"; - properties.hydratedButton = 1; - { - var error = $root.proto.HydratedURLButton.verify(message.urlButton); - if (error) - return "urlButton." + error; - } - } - if (message.callButton != null && message.hasOwnProperty("callButton")) { - if (properties.hydratedButton === 1) - return "hydratedButton: multiple values"; - properties.hydratedButton = 1; - { - var error = $root.proto.HydratedCallButton.verify(message.callButton); - if (error) - return "callButton." + error; - } - } - return null; - }; - - /** - * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HydratedTemplateButton - * @static - * @param {Object.} object Plain object - * @returns {proto.HydratedTemplateButton} HydratedTemplateButton - */ - HydratedTemplateButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HydratedTemplateButton) - return object; - var message = new $root.proto.HydratedTemplateButton(); - if (object.index != null) - message.index = object.index >>> 0; - if (object.quickReplyButton != null) { - if (typeof object.quickReplyButton !== "object") - throw TypeError(".proto.HydratedTemplateButton.quickReplyButton: object expected"); - message.quickReplyButton = $root.proto.HydratedQuickReplyButton.fromObject(object.quickReplyButton); - } - if (object.urlButton != null) { - if (typeof object.urlButton !== "object") - throw TypeError(".proto.HydratedTemplateButton.urlButton: object expected"); - message.urlButton = $root.proto.HydratedURLButton.fromObject(object.urlButton); - } - if (object.callButton != null) { - if (typeof object.callButton !== "object") - throw TypeError(".proto.HydratedTemplateButton.callButton: object expected"); - message.callButton = $root.proto.HydratedCallButton.fromObject(object.callButton); - } - return message; - }; - - /** - * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HydratedTemplateButton - * @static - * @param {proto.HydratedTemplateButton} message HydratedTemplateButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HydratedTemplateButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.index = 0; - if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { - object.quickReplyButton = $root.proto.HydratedQuickReplyButton.toObject(message.quickReplyButton, options); - if (options.oneofs) - object.hydratedButton = "quickReplyButton"; - } - if (message.urlButton != null && message.hasOwnProperty("urlButton")) { - object.urlButton = $root.proto.HydratedURLButton.toObject(message.urlButton, options); - if (options.oneofs) - object.hydratedButton = "urlButton"; - } - if (message.callButton != null && message.hasOwnProperty("callButton")) { - object.callButton = $root.proto.HydratedCallButton.toObject(message.callButton, options); - if (options.oneofs) - object.hydratedButton = "callButton"; - } - if (message.index != null && message.hasOwnProperty("index")) - object.index = message.index; - return object; - }; - - /** - * Converts this HydratedTemplateButton to JSON. - * @function toJSON - * @memberof proto.HydratedTemplateButton - * @instance - * @returns {Object.} JSON object - */ - HydratedTemplateButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HydratedTemplateButton; + return MessageKey; })(); proto.QuickReplyButton = (function() { @@ -22336,6 +3308,7 @@ $root.proto = (function() { * @property {string|null} [entryPointConversionSource] ContextInfo entryPointConversionSource * @property {string|null} [entryPointConversionApp] ContextInfo entryPointConversionApp * @property {number|null} [entryPointConversionDelaySeconds] ContextInfo entryPointConversionDelaySeconds + * @property {proto.IDisappearingMode|null} [disappearingMode] ContextInfo disappearingMode */ /** @@ -22506,6 +3479,14 @@ $root.proto = (function() { */ ContextInfo.prototype.entryPointConversionDelaySeconds = 0; + /** + * ContextInfo disappearingMode. + * @member {proto.IDisappearingMode|null|undefined} disappearingMode + * @memberof proto.ContextInfo + * @instance + */ + ContextInfo.prototype.disappearingMode = null; + /** * Creates a new ContextInfo instance using the specified properties. * @function create @@ -22569,6 +3550,8 @@ $root.proto = (function() { writer.uint32(/* id 30, wireType 2 =*/242).string(message.entryPointConversionApp); if (message.entryPointConversionDelaySeconds != null && Object.hasOwnProperty.call(message, "entryPointConversionDelaySeconds")) writer.uint32(/* id 31, wireType 0 =*/248).uint32(message.entryPointConversionDelaySeconds); + if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode")) + $root.proto.DisappearingMode.encode(message.disappearingMode, writer.uint32(/* id 32, wireType 2 =*/258).fork()).ldelim(); return writer; }; @@ -22662,6 +3645,9 @@ $root.proto = (function() { case 31: message.entryPointConversionDelaySeconds = reader.uint32(); break; + case 32: + message.disappearingMode = $root.proto.DisappearingMode.decode(reader, reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -22766,6 +3752,11 @@ $root.proto = (function() { if (message.entryPointConversionDelaySeconds != null && message.hasOwnProperty("entryPointConversionDelaySeconds")) if (!$util.isInteger(message.entryPointConversionDelaySeconds)) return "entryPointConversionDelaySeconds: integer expected"; + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) { + var error = $root.proto.DisappearingMode.verify(message.disappearingMode); + if (error) + return "disappearingMode." + error; + } return null; }; @@ -22849,6 +3840,11 @@ $root.proto = (function() { message.entryPointConversionApp = String(object.entryPointConversionApp); if (object.entryPointConversionDelaySeconds != null) message.entryPointConversionDelaySeconds = object.entryPointConversionDelaySeconds >>> 0; + if (object.disappearingMode != null) { + if (typeof object.disappearingMode !== "object") + throw TypeError(".proto.ContextInfo.disappearingMode: object expected"); + message.disappearingMode = $root.proto.DisappearingMode.fromObject(object.disappearingMode); + } return message; }; @@ -22902,6 +3898,7 @@ $root.proto = (function() { object.entryPointConversionSource = ""; object.entryPointConversionApp = ""; object.entryPointConversionDelaySeconds = 0; + object.disappearingMode = null; } if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) object.stanzaId = message.stanzaId; @@ -22947,6 +3944,8 @@ $root.proto = (function() { object.entryPointConversionApp = message.entryPointConversionApp; if (message.entryPointConversionDelaySeconds != null && message.hasOwnProperty("entryPointConversionDelaySeconds")) object.entryPointConversionDelaySeconds = message.entryPointConversionDelaySeconds; + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) + object.disappearingMode = $root.proto.DisappearingMode.toObject(message.disappearingMode, options); return object; }; @@ -23214,6 +4213,7 @@ $root.proto = (function() { * @property {string|null} [thumbnailDirectPath] ImageMessage thumbnailDirectPath * @property {Uint8Array|null} [thumbnailSha256] ImageMessage thumbnailSha256 * @property {Uint8Array|null} [thumbnailEncSha256] ImageMessage thumbnailEncSha256 + * @property {string|null} [staticUrl] ImageMessage staticUrl */ /** @@ -23433,6 +4433,14 @@ $root.proto = (function() { */ ImageMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]); + /** + * ImageMessage staticUrl. + * @member {string} staticUrl + * @memberof proto.ImageMessage + * @instance + */ + ImageMessage.prototype.staticUrl = ""; + /** * Creates a new ImageMessage instance using the specified properties. * @function create @@ -23509,6 +4517,8 @@ $root.proto = (function() { writer.uint32(/* id 27, wireType 2 =*/218).bytes(message.thumbnailSha256); if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256")) writer.uint32(/* id 28, wireType 2 =*/226).bytes(message.thumbnailEncSha256); + if (message.staticUrl != null && Object.hasOwnProperty.call(message, "staticUrl")) + writer.uint32(/* id 29, wireType 2 =*/234).string(message.staticUrl); return writer; }; @@ -23627,6 +4637,9 @@ $root.proto = (function() { case 28: message.thumbnailEncSha256 = reader.bytes(); break; + case 29: + message.staticUrl = reader.string(); + break; default: reader.skipType(tag & 7); break; @@ -23749,6 +4762,9 @@ $root.proto = (function() { if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256))) return "thumbnailEncSha256: buffer expected"; + if (message.staticUrl != null && message.hasOwnProperty("staticUrl")) + if (!$util.isString(message.staticUrl)) + return "staticUrl: string expected"; return null; }; @@ -23874,6 +4890,8 @@ $root.proto = (function() { $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0); else if (object.thumbnailEncSha256.length) message.thumbnailEncSha256 = object.thumbnailEncSha256; + if (object.staticUrl != null) + message.staticUrl = String(object.staticUrl); return message; }; @@ -23986,6 +5004,7 @@ $root.proto = (function() { if (options.bytes !== Array) object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256); } + object.staticUrl = ""; } if (message.url != null && message.hasOwnProperty("url")) object.url = message.url; @@ -24049,6 +5068,8 @@ $root.proto = (function() { object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256; if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256; + if (message.staticUrl != null && message.hasOwnProperty("staticUrl")) + object.staticUrl = message.staticUrl; return object; }; @@ -27129,6 +8150,7 @@ $root.proto = (function() { * @property {string|null} [thumbnailDirectPath] VideoMessage thumbnailDirectPath * @property {Uint8Array|null} [thumbnailSha256] VideoMessage thumbnailSha256 * @property {Uint8Array|null} [thumbnailEncSha256] VideoMessage thumbnailEncSha256 + * @property {string|null} [staticUrl] VideoMessage staticUrl */ /** @@ -27323,6 +8345,14 @@ $root.proto = (function() { */ VideoMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]); + /** + * VideoMessage staticUrl. + * @member {string} staticUrl + * @memberof proto.VideoMessage + * @instance + */ + VideoMessage.prototype.staticUrl = ""; + /** * Creates a new VideoMessage instance using the specified properties. * @function create @@ -27392,6 +8422,8 @@ $root.proto = (function() { writer.uint32(/* id 22, wireType 2 =*/178).bytes(message.thumbnailSha256); if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256")) writer.uint32(/* id 23, wireType 2 =*/186).bytes(message.thumbnailEncSha256); + if (message.staticUrl != null && Object.hasOwnProperty.call(message, "staticUrl")) + writer.uint32(/* id 24, wireType 2 =*/194).string(message.staticUrl); return writer; }; @@ -27494,6 +8526,9 @@ $root.proto = (function() { case 23: message.thumbnailEncSha256 = reader.bytes(); break; + case 24: + message.staticUrl = reader.string(); + break; default: reader.skipType(tag & 7); break; @@ -27609,6 +8644,9 @@ $root.proto = (function() { if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256))) return "thumbnailEncSha256: buffer expected"; + if (message.staticUrl != null && message.hasOwnProperty("staticUrl")) + if (!$util.isString(message.staticUrl)) + return "staticUrl: string expected"; return null; }; @@ -27726,6 +8764,8 @@ $root.proto = (function() { $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0); else if (object.thumbnailEncSha256.length) message.thumbnailEncSha256 = object.thumbnailEncSha256; + if (object.staticUrl != null) + message.staticUrl = String(object.staticUrl); return message; }; @@ -27816,6 +8856,7 @@ $root.proto = (function() { if (options.bytes !== Array) object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256); } + object.staticUrl = ""; } if (message.url != null && message.hasOwnProperty("url")) object.url = message.url; @@ -27870,6 +8911,8 @@ $root.proto = (function() { object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256; if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256; + if (message.staticUrl != null && message.hasOwnProperty("staticUrl")) + object.staticUrl = message.staticUrl; return object; }; @@ -28400,6 +9443,7 @@ $root.proto = (function() { * @property {proto.IAppStateSyncKeyRequest|null} [appStateSyncKeyRequest] ProtocolMessage appStateSyncKeyRequest * @property {proto.IInitialSecurityNotificationSettingSync|null} [initialSecurityNotificationSettingSync] ProtocolMessage initialSecurityNotificationSettingSync * @property {proto.IAppStateFatalExceptionNotification|null} [appStateFatalExceptionNotification] ProtocolMessage appStateFatalExceptionNotification + * @property {proto.IDisappearingMode|null} [disappearingMode] ProtocolMessage disappearingMode */ /** @@ -28489,6 +9533,14 @@ $root.proto = (function() { */ ProtocolMessage.prototype.appStateFatalExceptionNotification = null; + /** + * ProtocolMessage disappearingMode. + * @member {proto.IDisappearingMode|null|undefined} disappearingMode + * @memberof proto.ProtocolMessage + * @instance + */ + ProtocolMessage.prototype.disappearingMode = null; + /** * Creates a new ProtocolMessage instance using the specified properties. * @function create @@ -28531,6 +9583,8 @@ $root.proto = (function() { $root.proto.InitialSecurityNotificationSettingSync.encode(message.initialSecurityNotificationSettingSync, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim(); if (message.appStateFatalExceptionNotification != null && Object.hasOwnProperty.call(message, "appStateFatalExceptionNotification")) $root.proto.AppStateFatalExceptionNotification.encode(message.appStateFatalExceptionNotification, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim(); + if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode")) + $root.proto.DisappearingMode.encode(message.disappearingMode, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim(); return writer; }; @@ -28592,6 +9646,9 @@ $root.proto = (function() { case 10: message.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.decode(reader, reader.uint32()); break; + case 11: + message.disappearingMode = $root.proto.DisappearingMode.decode(reader, reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -28678,6 +9735,11 @@ $root.proto = (function() { if (error) return "appStateFatalExceptionNotification." + error; } + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) { + var error = $root.proto.DisappearingMode.verify(message.disappearingMode); + if (error) + return "disappearingMode." + error; + } return null; }; @@ -28772,6 +9834,11 @@ $root.proto = (function() { throw TypeError(".proto.ProtocolMessage.appStateFatalExceptionNotification: object expected"); message.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.fromObject(object.appStateFatalExceptionNotification); } + if (object.disappearingMode != null) { + if (typeof object.disappearingMode !== "object") + throw TypeError(".proto.ProtocolMessage.disappearingMode: object expected"); + message.disappearingMode = $root.proto.DisappearingMode.fromObject(object.disappearingMode); + } return message; }; @@ -28802,6 +9869,7 @@ $root.proto = (function() { object.appStateSyncKeyRequest = null; object.initialSecurityNotificationSettingSync = null; object.appStateFatalExceptionNotification = null; + object.disappearingMode = null; } if (message.key != null && message.hasOwnProperty("key")) object.key = $root.proto.MessageKey.toObject(message.key, options); @@ -28824,6 +9892,8 @@ $root.proto = (function() { object.initialSecurityNotificationSettingSync = $root.proto.InitialSecurityNotificationSettingSync.toObject(message.initialSecurityNotificationSettingSync, options); if (message.appStateFatalExceptionNotification != null && message.hasOwnProperty("appStateFatalExceptionNotification")) object.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.toObject(message.appStateFatalExceptionNotification, options); + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) + object.disappearingMode = $root.proto.DisappearingMode.toObject(message.disappearingMode, options); return object; }; @@ -40509,6 +21579,1594 @@ $root.proto = (function() { return ListResponseMessage; })(); + proto.Header = (function() { + + /** + * Properties of a Header. + * @memberof proto + * @interface IHeader + * @property {string|null} [title] Header title + * @property {string|null} [subtitle] Header subtitle + * @property {proto.IDocumentMessage|null} [documentMessage] Header documentMessage + * @property {proto.IImageMessage|null} [imageMessage] Header imageMessage + */ + + /** + * Constructs a new Header. + * @memberof proto + * @classdesc Represents a Header. + * @implements IHeader + * @constructor + * @param {proto.IHeader=} [properties] Properties to set + */ + function Header(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Header title. + * @member {string} title + * @memberof proto.Header + * @instance + */ + Header.prototype.title = ""; + + /** + * Header subtitle. + * @member {string} subtitle + * @memberof proto.Header + * @instance + */ + Header.prototype.subtitle = ""; + + /** + * Header documentMessage. + * @member {proto.IDocumentMessage|null|undefined} documentMessage + * @memberof proto.Header + * @instance + */ + Header.prototype.documentMessage = null; + + /** + * Header imageMessage. + * @member {proto.IImageMessage|null|undefined} imageMessage + * @memberof proto.Header + * @instance + */ + Header.prototype.imageMessage = null; + + // OneOf field names bound to virtual getters and setters + var $oneOfFields; + + /** + * Header media. + * @member {"documentMessage"|"imageMessage"|undefined} media + * @memberof proto.Header + * @instance + */ + Object.defineProperty(Header.prototype, "media", { + get: $util.oneOfGetter($oneOfFields = ["documentMessage", "imageMessage"]), + set: $util.oneOfSetter($oneOfFields) + }); + + /** + * Creates a new Header instance using the specified properties. + * @function create + * @memberof proto.Header + * @static + * @param {proto.IHeader=} [properties] Properties to set + * @returns {proto.Header} Header instance + */ + Header.create = function create(properties) { + return new Header(properties); + }; + + /** + * Encodes the specified Header message. Does not implicitly {@link proto.Header.verify|verify} messages. + * @function encode + * @memberof proto.Header + * @static + * @param {proto.IHeader} message Header message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Header.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.title != null && Object.hasOwnProperty.call(message, "title")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.title); + if (message.subtitle != null && Object.hasOwnProperty.call(message, "subtitle")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.subtitle); + if (message.documentMessage != null && Object.hasOwnProperty.call(message, "documentMessage")) + $root.proto.DocumentMessage.encode(message.documentMessage, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.imageMessage != null && Object.hasOwnProperty.call(message, "imageMessage")) + $root.proto.ImageMessage.encode(message.imageMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified Header message, length delimited. Does not implicitly {@link proto.Header.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Header + * @static + * @param {proto.IHeader} message Header message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Header.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Header message from the specified reader or buffer. + * @function decode + * @memberof proto.Header + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Header} Header + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Header.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Header(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.title = reader.string(); + break; + case 2: + message.subtitle = reader.string(); + break; + case 3: + message.documentMessage = $root.proto.DocumentMessage.decode(reader, reader.uint32()); + break; + case 4: + message.imageMessage = $root.proto.ImageMessage.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Header message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Header + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Header} Header + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Header.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Header message. + * @function verify + * @memberof proto.Header + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Header.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var properties = {}; + if (message.title != null && message.hasOwnProperty("title")) + if (!$util.isString(message.title)) + return "title: string expected"; + if (message.subtitle != null && message.hasOwnProperty("subtitle")) + if (!$util.isString(message.subtitle)) + return "subtitle: string expected"; + if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) { + properties.media = 1; + { + var error = $root.proto.DocumentMessage.verify(message.documentMessage); + if (error) + return "documentMessage." + error; + } + } + if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) { + if (properties.media === 1) + return "media: multiple values"; + properties.media = 1; + { + var error = $root.proto.ImageMessage.verify(message.imageMessage); + if (error) + return "imageMessage." + error; + } + } + return null; + }; + + /** + * Creates a Header message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Header + * @static + * @param {Object.} object Plain object + * @returns {proto.Header} Header + */ + Header.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Header) + return object; + var message = new $root.proto.Header(); + if (object.title != null) + message.title = String(object.title); + if (object.subtitle != null) + message.subtitle = String(object.subtitle); + if (object.documentMessage != null) { + if (typeof object.documentMessage !== "object") + throw TypeError(".proto.Header.documentMessage: object expected"); + message.documentMessage = $root.proto.DocumentMessage.fromObject(object.documentMessage); + } + if (object.imageMessage != null) { + if (typeof object.imageMessage !== "object") + throw TypeError(".proto.Header.imageMessage: object expected"); + message.imageMessage = $root.proto.ImageMessage.fromObject(object.imageMessage); + } + return message; + }; + + /** + * Creates a plain object from a Header message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Header + * @static + * @param {proto.Header} message Header + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Header.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.title = ""; + object.subtitle = ""; + } + if (message.title != null && message.hasOwnProperty("title")) + object.title = message.title; + if (message.subtitle != null && message.hasOwnProperty("subtitle")) + object.subtitle = message.subtitle; + if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) { + object.documentMessage = $root.proto.DocumentMessage.toObject(message.documentMessage, options); + if (options.oneofs) + object.media = "documentMessage"; + } + if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) { + object.imageMessage = $root.proto.ImageMessage.toObject(message.imageMessage, options); + if (options.oneofs) + object.media = "imageMessage"; + } + return object; + }; + + /** + * Converts this Header to JSON. + * @function toJSON + * @memberof proto.Header + * @instance + * @returns {Object.} JSON object + */ + Header.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Header; + })(); + + proto.Body = (function() { + + /** + * Properties of a Body. + * @memberof proto + * @interface IBody + * @property {string|null} [text] Body text + */ + + /** + * Constructs a new Body. + * @memberof proto + * @classdesc Represents a Body. + * @implements IBody + * @constructor + * @param {proto.IBody=} [properties] Properties to set + */ + function Body(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Body text. + * @member {string} text + * @memberof proto.Body + * @instance + */ + Body.prototype.text = ""; + + /** + * Creates a new Body instance using the specified properties. + * @function create + * @memberof proto.Body + * @static + * @param {proto.IBody=} [properties] Properties to set + * @returns {proto.Body} Body instance + */ + Body.create = function create(properties) { + return new Body(properties); + }; + + /** + * Encodes the specified Body message. Does not implicitly {@link proto.Body.verify|verify} messages. + * @function encode + * @memberof proto.Body + * @static + * @param {proto.IBody} message Body message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Body.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.text != null && Object.hasOwnProperty.call(message, "text")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.text); + return writer; + }; + + /** + * Encodes the specified Body message, length delimited. Does not implicitly {@link proto.Body.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Body + * @static + * @param {proto.IBody} message Body message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Body.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Body message from the specified reader or buffer. + * @function decode + * @memberof proto.Body + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Body} Body + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Body.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Body(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.text = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Body message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Body + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Body} Body + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Body.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Body message. + * @function verify + * @memberof proto.Body + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Body.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.text != null && message.hasOwnProperty("text")) + if (!$util.isString(message.text)) + return "text: string expected"; + return null; + }; + + /** + * Creates a Body message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Body + * @static + * @param {Object.} object Plain object + * @returns {proto.Body} Body + */ + Body.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Body) + return object; + var message = new $root.proto.Body(); + if (object.text != null) + message.text = String(object.text); + return message; + }; + + /** + * Creates a plain object from a Body message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Body + * @static + * @param {proto.Body} message Body + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Body.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.text = ""; + if (message.text != null && message.hasOwnProperty("text")) + object.text = message.text; + return object; + }; + + /** + * Converts this Body to JSON. + * @function toJSON + * @memberof proto.Body + * @instance + * @returns {Object.} JSON object + */ + Body.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Body; + })(); + + proto.Footer = (function() { + + /** + * Properties of a Footer. + * @memberof proto + * @interface IFooter + * @property {string|null} [text] Footer text + */ + + /** + * Constructs a new Footer. + * @memberof proto + * @classdesc Represents a Footer. + * @implements IFooter + * @constructor + * @param {proto.IFooter=} [properties] Properties to set + */ + function Footer(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Footer text. + * @member {string} text + * @memberof proto.Footer + * @instance + */ + Footer.prototype.text = ""; + + /** + * Creates a new Footer instance using the specified properties. + * @function create + * @memberof proto.Footer + * @static + * @param {proto.IFooter=} [properties] Properties to set + * @returns {proto.Footer} Footer instance + */ + Footer.create = function create(properties) { + return new Footer(properties); + }; + + /** + * Encodes the specified Footer message. Does not implicitly {@link proto.Footer.verify|verify} messages. + * @function encode + * @memberof proto.Footer + * @static + * @param {proto.IFooter} message Footer message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Footer.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.text != null && Object.hasOwnProperty.call(message, "text")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.text); + return writer; + }; + + /** + * Encodes the specified Footer message, length delimited. Does not implicitly {@link proto.Footer.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Footer + * @static + * @param {proto.IFooter} message Footer message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Footer.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Footer message from the specified reader or buffer. + * @function decode + * @memberof proto.Footer + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Footer} Footer + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Footer.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Footer(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.text = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Footer message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Footer + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Footer} Footer + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Footer.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Footer message. + * @function verify + * @memberof proto.Footer + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Footer.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.text != null && message.hasOwnProperty("text")) + if (!$util.isString(message.text)) + return "text: string expected"; + return null; + }; + + /** + * Creates a Footer message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Footer + * @static + * @param {Object.} object Plain object + * @returns {proto.Footer} Footer + */ + Footer.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Footer) + return object; + var message = new $root.proto.Footer(); + if (object.text != null) + message.text = String(object.text); + return message; + }; + + /** + * Creates a plain object from a Footer message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Footer + * @static + * @param {proto.Footer} message Footer + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Footer.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.text = ""; + if (message.text != null && message.hasOwnProperty("text")) + object.text = message.text; + return object; + }; + + /** + * Converts this Footer to JSON. + * @function toJSON + * @memberof proto.Footer + * @instance + * @returns {Object.} JSON object + */ + Footer.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Footer; + })(); + + proto.ShopsMessage = (function() { + + /** + * Properties of a ShopsMessage. + * @memberof proto + * @interface IShopsMessage + * @property {string|null} [id] ShopsMessage id + * @property {proto.ShopsMessage.ShopsMessageSurface|null} [surface] ShopsMessage surface + * @property {proto.ShopsMessage.ShopsMessageType|null} [type] ShopsMessage type + * @property {number|null} [messageVersion] ShopsMessage messageVersion + */ + + /** + * Constructs a new ShopsMessage. + * @memberof proto + * @classdesc Represents a ShopsMessage. + * @implements IShopsMessage + * @constructor + * @param {proto.IShopsMessage=} [properties] Properties to set + */ + function ShopsMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ShopsMessage id. + * @member {string} id + * @memberof proto.ShopsMessage + * @instance + */ + ShopsMessage.prototype.id = ""; + + /** + * ShopsMessage surface. + * @member {proto.ShopsMessage.ShopsMessageSurface} surface + * @memberof proto.ShopsMessage + * @instance + */ + ShopsMessage.prototype.surface = 0; + + /** + * ShopsMessage type. + * @member {proto.ShopsMessage.ShopsMessageType} type + * @memberof proto.ShopsMessage + * @instance + */ + ShopsMessage.prototype.type = 0; + + /** + * ShopsMessage messageVersion. + * @member {number} messageVersion + * @memberof proto.ShopsMessage + * @instance + */ + ShopsMessage.prototype.messageVersion = 0; + + /** + * Creates a new ShopsMessage instance using the specified properties. + * @function create + * @memberof proto.ShopsMessage + * @static + * @param {proto.IShopsMessage=} [properties] Properties to set + * @returns {proto.ShopsMessage} ShopsMessage instance + */ + ShopsMessage.create = function create(properties) { + return new ShopsMessage(properties); + }; + + /** + * Encodes the specified ShopsMessage message. Does not implicitly {@link proto.ShopsMessage.verify|verify} messages. + * @function encode + * @memberof proto.ShopsMessage + * @static + * @param {proto.IShopsMessage} message ShopsMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ShopsMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); + if (message.surface != null && Object.hasOwnProperty.call(message, "surface")) + writer.uint32(/* id 2, wireType 0 =*/16).int32(message.surface); + if (message.type != null && Object.hasOwnProperty.call(message, "type")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.type); + if (message.messageVersion != null && Object.hasOwnProperty.call(message, "messageVersion")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.messageVersion); + return writer; + }; + + /** + * Encodes the specified ShopsMessage message, length delimited. Does not implicitly {@link proto.ShopsMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ShopsMessage + * @static + * @param {proto.IShopsMessage} message ShopsMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ShopsMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ShopsMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.ShopsMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ShopsMessage} ShopsMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ShopsMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ShopsMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.surface = reader.int32(); + break; + case 3: + message.type = reader.int32(); + break; + case 4: + message.messageVersion = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ShopsMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ShopsMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ShopsMessage} ShopsMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ShopsMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ShopsMessage message. + * @function verify + * @memberof proto.ShopsMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ShopsMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.surface != null && message.hasOwnProperty("surface")) + switch (message.surface) { + default: + return "surface: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.type != null && message.hasOwnProperty("type")) + switch (message.type) { + default: + return "type: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) + if (!$util.isInteger(message.messageVersion)) + return "messageVersion: integer expected"; + return null; + }; + + /** + * Creates a ShopsMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ShopsMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.ShopsMessage} ShopsMessage + */ + ShopsMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ShopsMessage) + return object; + var message = new $root.proto.ShopsMessage(); + if (object.id != null) + message.id = String(object.id); + switch (object.surface) { + case "UNKNOWN_SURFACE": + case 0: + message.surface = 0; + break; + case "FB": + case 1: + message.surface = 1; + break; + case "IG": + case 2: + message.surface = 2; + break; + case "WA": + case 3: + message.surface = 3; + break; + } + switch (object.type) { + case "UNKNOWN_TYPE": + case 0: + message.type = 0; + break; + case "PRODUCT": + case 1: + message.type = 1; + break; + case "STOREFRONT": + case 2: + message.type = 2; + break; + case "COLLECTION": + case 3: + message.type = 3; + break; + } + if (object.messageVersion != null) + message.messageVersion = object.messageVersion | 0; + return message; + }; + + /** + * Creates a plain object from a ShopsMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ShopsMessage + * @static + * @param {proto.ShopsMessage} message ShopsMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ShopsMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.id = ""; + object.surface = options.enums === String ? "UNKNOWN_SURFACE" : 0; + object.type = options.enums === String ? "UNKNOWN_TYPE" : 0; + object.messageVersion = 0; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.surface != null && message.hasOwnProperty("surface")) + object.surface = options.enums === String ? $root.proto.ShopsMessage.ShopsMessageSurface[message.surface] : message.surface; + if (message.type != null && message.hasOwnProperty("type")) + object.type = options.enums === String ? $root.proto.ShopsMessage.ShopsMessageType[message.type] : message.type; + if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) + object.messageVersion = message.messageVersion; + return object; + }; + + /** + * Converts this ShopsMessage to JSON. + * @function toJSON + * @memberof proto.ShopsMessage + * @instance + * @returns {Object.} JSON object + */ + ShopsMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * ShopsMessageSurface enum. + * @name proto.ShopsMessage.ShopsMessageSurface + * @enum {number} + * @property {number} UNKNOWN_SURFACE=0 UNKNOWN_SURFACE value + * @property {number} FB=1 FB value + * @property {number} IG=2 IG value + * @property {number} WA=3 WA value + */ + ShopsMessage.ShopsMessageSurface = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN_SURFACE"] = 0; + values[valuesById[1] = "FB"] = 1; + values[valuesById[2] = "IG"] = 2; + values[valuesById[3] = "WA"] = 3; + return values; + })(); + + /** + * ShopsMessageType enum. + * @name proto.ShopsMessage.ShopsMessageType + * @enum {number} + * @property {number} UNKNOWN_TYPE=0 UNKNOWN_TYPE value + * @property {number} PRODUCT=1 PRODUCT value + * @property {number} STOREFRONT=2 STOREFRONT value + * @property {number} COLLECTION=3 COLLECTION value + */ + ShopsMessage.ShopsMessageType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN_TYPE"] = 0; + values[valuesById[1] = "PRODUCT"] = 1; + values[valuesById[2] = "STOREFRONT"] = 2; + values[valuesById[3] = "COLLECTION"] = 3; + return values; + })(); + + return ShopsMessage; + })(); + + proto.CollectionMessage = (function() { + + /** + * Properties of a CollectionMessage. + * @memberof proto + * @interface ICollectionMessage + * @property {string|null} [bizJid] CollectionMessage bizJid + * @property {string|null} [id] CollectionMessage id + * @property {number|null} [messageVersion] CollectionMessage messageVersion + */ + + /** + * Constructs a new CollectionMessage. + * @memberof proto + * @classdesc Represents a CollectionMessage. + * @implements ICollectionMessage + * @constructor + * @param {proto.ICollectionMessage=} [properties] Properties to set + */ + function CollectionMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * CollectionMessage bizJid. + * @member {string} bizJid + * @memberof proto.CollectionMessage + * @instance + */ + CollectionMessage.prototype.bizJid = ""; + + /** + * CollectionMessage id. + * @member {string} id + * @memberof proto.CollectionMessage + * @instance + */ + CollectionMessage.prototype.id = ""; + + /** + * CollectionMessage messageVersion. + * @member {number} messageVersion + * @memberof proto.CollectionMessage + * @instance + */ + CollectionMessage.prototype.messageVersion = 0; + + /** + * Creates a new CollectionMessage instance using the specified properties. + * @function create + * @memberof proto.CollectionMessage + * @static + * @param {proto.ICollectionMessage=} [properties] Properties to set + * @returns {proto.CollectionMessage} CollectionMessage instance + */ + CollectionMessage.create = function create(properties) { + return new CollectionMessage(properties); + }; + + /** + * Encodes the specified CollectionMessage message. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages. + * @function encode + * @memberof proto.CollectionMessage + * @static + * @param {proto.ICollectionMessage} message CollectionMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CollectionMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.bizJid != null && Object.hasOwnProperty.call(message, "bizJid")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.bizJid); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.id); + if (message.messageVersion != null && Object.hasOwnProperty.call(message, "messageVersion")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.messageVersion); + return writer; + }; + + /** + * Encodes the specified CollectionMessage message, length delimited. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.CollectionMessage + * @static + * @param {proto.ICollectionMessage} message CollectionMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CollectionMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a CollectionMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.CollectionMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.CollectionMessage} CollectionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CollectionMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CollectionMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.bizJid = reader.string(); + break; + case 2: + message.id = reader.string(); + break; + case 3: + message.messageVersion = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a CollectionMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.CollectionMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.CollectionMessage} CollectionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CollectionMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a CollectionMessage message. + * @function verify + * @memberof proto.CollectionMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + CollectionMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.bizJid != null && message.hasOwnProperty("bizJid")) + if (!$util.isString(message.bizJid)) + return "bizJid: string expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) + if (!$util.isInteger(message.messageVersion)) + return "messageVersion: integer expected"; + return null; + }; + + /** + * Creates a CollectionMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.CollectionMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.CollectionMessage} CollectionMessage + */ + CollectionMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.CollectionMessage) + return object; + var message = new $root.proto.CollectionMessage(); + if (object.bizJid != null) + message.bizJid = String(object.bizJid); + if (object.id != null) + message.id = String(object.id); + if (object.messageVersion != null) + message.messageVersion = object.messageVersion | 0; + return message; + }; + + /** + * Creates a plain object from a CollectionMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.CollectionMessage + * @static + * @param {proto.CollectionMessage} message CollectionMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + CollectionMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.bizJid = ""; + object.id = ""; + object.messageVersion = 0; + } + if (message.bizJid != null && message.hasOwnProperty("bizJid")) + object.bizJid = message.bizJid; + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) + object.messageVersion = message.messageVersion; + return object; + }; + + /** + * Converts this CollectionMessage to JSON. + * @function toJSON + * @memberof proto.CollectionMessage + * @instance + * @returns {Object.} JSON object + */ + CollectionMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return CollectionMessage; + })(); + + proto.InteractiveMessage = (function() { + + /** + * Properties of an InteractiveMessage. + * @memberof proto + * @interface IInteractiveMessage + * @property {proto.IHeader|null} [header] InteractiveMessage header + * @property {proto.IBody|null} [body] InteractiveMessage body + * @property {proto.IFooter|null} [footer] InteractiveMessage footer + * @property {proto.IContextInfo|null} [contextInfo] InteractiveMessage contextInfo + * @property {proto.IShopsMessage|null} [shopsMessage] InteractiveMessage shopsMessage + * @property {proto.ICollectionMessage|null} [collectionMessage] InteractiveMessage collectionMessage + */ + + /** + * Constructs a new InteractiveMessage. + * @memberof proto + * @classdesc Represents an InteractiveMessage. + * @implements IInteractiveMessage + * @constructor + * @param {proto.IInteractiveMessage=} [properties] Properties to set + */ + function InteractiveMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * InteractiveMessage header. + * @member {proto.IHeader|null|undefined} header + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.header = null; + + /** + * InteractiveMessage body. + * @member {proto.IBody|null|undefined} body + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.body = null; + + /** + * InteractiveMessage footer. + * @member {proto.IFooter|null|undefined} footer + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.footer = null; + + /** + * InteractiveMessage contextInfo. + * @member {proto.IContextInfo|null|undefined} contextInfo + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.contextInfo = null; + + /** + * InteractiveMessage shopsMessage. + * @member {proto.IShopsMessage|null|undefined} shopsMessage + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.shopsMessage = null; + + /** + * InteractiveMessage collectionMessage. + * @member {proto.ICollectionMessage|null|undefined} collectionMessage + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.collectionMessage = null; + + // OneOf field names bound to virtual getters and setters + var $oneOfFields; + + /** + * InteractiveMessage interactiveMessage. + * @member {"shopsMessage"|"collectionMessage"|undefined} interactiveMessage + * @memberof proto.InteractiveMessage + * @instance + */ + Object.defineProperty(InteractiveMessage.prototype, "interactiveMessage", { + get: $util.oneOfGetter($oneOfFields = ["shopsMessage", "collectionMessage"]), + set: $util.oneOfSetter($oneOfFields) + }); + + /** + * Creates a new InteractiveMessage instance using the specified properties. + * @function create + * @memberof proto.InteractiveMessage + * @static + * @param {proto.IInteractiveMessage=} [properties] Properties to set + * @returns {proto.InteractiveMessage} InteractiveMessage instance + */ + InteractiveMessage.create = function create(properties) { + return new InteractiveMessage(properties); + }; + + /** + * Encodes the specified InteractiveMessage message. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages. + * @function encode + * @memberof proto.InteractiveMessage + * @static + * @param {proto.IInteractiveMessage} message InteractiveMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + InteractiveMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.header != null && Object.hasOwnProperty.call(message, "header")) + $root.proto.Header.encode(message.header, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.body != null && Object.hasOwnProperty.call(message, "body")) + $root.proto.Body.encode(message.body, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.footer != null && Object.hasOwnProperty.call(message, "footer")) + $root.proto.Footer.encode(message.footer, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.shopsMessage != null && Object.hasOwnProperty.call(message, "shopsMessage")) + $root.proto.ShopsMessage.encode(message.shopsMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + if (message.collectionMessage != null && Object.hasOwnProperty.call(message, "collectionMessage")) + $root.proto.CollectionMessage.encode(message.collectionMessage, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo")) + $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified InteractiveMessage message, length delimited. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.InteractiveMessage + * @static + * @param {proto.IInteractiveMessage} message InteractiveMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + InteractiveMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an InteractiveMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.InteractiveMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.InteractiveMessage} InteractiveMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + InteractiveMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.InteractiveMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.header = $root.proto.Header.decode(reader, reader.uint32()); + break; + case 2: + message.body = $root.proto.Body.decode(reader, reader.uint32()); + break; + case 3: + message.footer = $root.proto.Footer.decode(reader, reader.uint32()); + break; + case 15: + message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32()); + break; + case 4: + message.shopsMessage = $root.proto.ShopsMessage.decode(reader, reader.uint32()); + break; + case 5: + message.collectionMessage = $root.proto.CollectionMessage.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an InteractiveMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.InteractiveMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.InteractiveMessage} InteractiveMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + InteractiveMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an InteractiveMessage message. + * @function verify + * @memberof proto.InteractiveMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + InteractiveMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var properties = {}; + if (message.header != null && message.hasOwnProperty("header")) { + var error = $root.proto.Header.verify(message.header); + if (error) + return "header." + error; + } + if (message.body != null && message.hasOwnProperty("body")) { + var error = $root.proto.Body.verify(message.body); + if (error) + return "body." + error; + } + if (message.footer != null && message.hasOwnProperty("footer")) { + var error = $root.proto.Footer.verify(message.footer); + if (error) + return "footer." + error; + } + if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) { + var error = $root.proto.ContextInfo.verify(message.contextInfo); + if (error) + return "contextInfo." + error; + } + if (message.shopsMessage != null && message.hasOwnProperty("shopsMessage")) { + properties.interactiveMessage = 1; + { + var error = $root.proto.ShopsMessage.verify(message.shopsMessage); + if (error) + return "shopsMessage." + error; + } + } + if (message.collectionMessage != null && message.hasOwnProperty("collectionMessage")) { + if (properties.interactiveMessage === 1) + return "interactiveMessage: multiple values"; + properties.interactiveMessage = 1; + { + var error = $root.proto.CollectionMessage.verify(message.collectionMessage); + if (error) + return "collectionMessage." + error; + } + } + return null; + }; + + /** + * Creates an InteractiveMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.InteractiveMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.InteractiveMessage} InteractiveMessage + */ + InteractiveMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.InteractiveMessage) + return object; + var message = new $root.proto.InteractiveMessage(); + if (object.header != null) { + if (typeof object.header !== "object") + throw TypeError(".proto.InteractiveMessage.header: object expected"); + message.header = $root.proto.Header.fromObject(object.header); + } + if (object.body != null) { + if (typeof object.body !== "object") + throw TypeError(".proto.InteractiveMessage.body: object expected"); + message.body = $root.proto.Body.fromObject(object.body); + } + if (object.footer != null) { + if (typeof object.footer !== "object") + throw TypeError(".proto.InteractiveMessage.footer: object expected"); + message.footer = $root.proto.Footer.fromObject(object.footer); + } + if (object.contextInfo != null) { + if (typeof object.contextInfo !== "object") + throw TypeError(".proto.InteractiveMessage.contextInfo: object expected"); + message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo); + } + if (object.shopsMessage != null) { + if (typeof object.shopsMessage !== "object") + throw TypeError(".proto.InteractiveMessage.shopsMessage: object expected"); + message.shopsMessage = $root.proto.ShopsMessage.fromObject(object.shopsMessage); + } + if (object.collectionMessage != null) { + if (typeof object.collectionMessage !== "object") + throw TypeError(".proto.InteractiveMessage.collectionMessage: object expected"); + message.collectionMessage = $root.proto.CollectionMessage.fromObject(object.collectionMessage); + } + return message; + }; + + /** + * Creates a plain object from an InteractiveMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.InteractiveMessage + * @static + * @param {proto.InteractiveMessage} message InteractiveMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + InteractiveMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.header = null; + object.body = null; + object.footer = null; + object.contextInfo = null; + } + if (message.header != null && message.hasOwnProperty("header")) + object.header = $root.proto.Header.toObject(message.header, options); + if (message.body != null && message.hasOwnProperty("body")) + object.body = $root.proto.Body.toObject(message.body, options); + if (message.footer != null && message.hasOwnProperty("footer")) + object.footer = $root.proto.Footer.toObject(message.footer, options); + if (message.shopsMessage != null && message.hasOwnProperty("shopsMessage")) { + object.shopsMessage = $root.proto.ShopsMessage.toObject(message.shopsMessage, options); + if (options.oneofs) + object.interactiveMessage = "shopsMessage"; + } + if (message.collectionMessage != null && message.hasOwnProperty("collectionMessage")) { + object.collectionMessage = $root.proto.CollectionMessage.toObject(message.collectionMessage, options); + if (options.oneofs) + object.interactiveMessage = "collectionMessage"; + } + if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) + object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options); + return object; + }; + + /** + * Converts this InteractiveMessage to JSON. + * @function toJSON + * @memberof proto.InteractiveMessage + * @instance + * @returns {Object.} JSON object + */ + InteractiveMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return InteractiveMessage; + })(); + proto.GroupInviteMessage = (function() { /** @@ -42870,6 +25528,7 @@ $root.proto = (function() { * @property {proto.IButtonsMessage|null} [buttonsMessage] Message buttonsMessage * @property {proto.IButtonsResponseMessage|null} [buttonsResponseMessage] Message buttonsResponseMessage * @property {proto.IPaymentInviteMessage|null} [paymentInviteMessage] Message paymentInviteMessage + * @property {proto.IInteractiveMessage|null} [interactiveMessage] Message interactiveMessage */ /** @@ -43175,6 +25834,14 @@ $root.proto = (function() { */ Message.prototype.paymentInviteMessage = null; + /** + * Message interactiveMessage. + * @member {proto.IInteractiveMessage|null|undefined} interactiveMessage + * @memberof proto.Message + * @instance + */ + Message.prototype.interactiveMessage = null; + /** * Creates a new Message instance using the specified properties. * @function create @@ -43271,6 +25938,8 @@ $root.proto = (function() { $root.proto.ButtonsResponseMessage.encode(message.buttonsResponseMessage, writer.uint32(/* id 43, wireType 2 =*/346).fork()).ldelim(); if (message.paymentInviteMessage != null && Object.hasOwnProperty.call(message, "paymentInviteMessage")) $root.proto.PaymentInviteMessage.encode(message.paymentInviteMessage, writer.uint32(/* id 44, wireType 2 =*/354).fork()).ldelim(); + if (message.interactiveMessage != null && Object.hasOwnProperty.call(message, "interactiveMessage")) + $root.proto.InteractiveMessage.encode(message.interactiveMessage, writer.uint32(/* id 45, wireType 2 =*/362).fork()).ldelim(); return writer; }; @@ -43413,6 +26082,9 @@ $root.proto = (function() { case 44: message.paymentInviteMessage = $root.proto.PaymentInviteMessage.decode(reader, reader.uint32()); break; + case 45: + message.interactiveMessage = $root.proto.InteractiveMessage.decode(reader, reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -43626,6 +26298,11 @@ $root.proto = (function() { if (error) return "paymentInviteMessage." + error; } + if (message.interactiveMessage != null && message.hasOwnProperty("interactiveMessage")) { + var error = $root.proto.InteractiveMessage.verify(message.interactiveMessage); + if (error) + return "interactiveMessage." + error; + } return null; }; @@ -43818,6 +26495,11 @@ $root.proto = (function() { throw TypeError(".proto.Message.paymentInviteMessage: object expected"); message.paymentInviteMessage = $root.proto.PaymentInviteMessage.fromObject(object.paymentInviteMessage); } + if (object.interactiveMessage != null) { + if (typeof object.interactiveMessage !== "object") + throw TypeError(".proto.Message.interactiveMessage: object expected"); + message.interactiveMessage = $root.proto.InteractiveMessage.fromObject(object.interactiveMessage); + } return message; }; @@ -43871,6 +26553,7 @@ $root.proto = (function() { object.buttonsMessage = null; object.buttonsResponseMessage = null; object.paymentInviteMessage = null; + object.interactiveMessage = null; } if (message.conversation != null && message.hasOwnProperty("conversation")) object.conversation = message.conversation; @@ -43944,6 +26627,8 @@ $root.proto = (function() { object.buttonsResponseMessage = $root.proto.ButtonsResponseMessage.toObject(message.buttonsResponseMessage, options); if (message.paymentInviteMessage != null && message.hasOwnProperty("paymentInviteMessage")) object.paymentInviteMessage = $root.proto.PaymentInviteMessage.toObject(message.paymentInviteMessage, options); + if (message.interactiveMessage != null && message.hasOwnProperty("interactiveMessage")) + object.interactiveMessage = $root.proto.InteractiveMessage.toObject(message.interactiveMessage, options); return object; }; @@ -43961,27 +26646,24 @@ $root.proto = (function() { return Message; })(); - proto.CompanionProps = (function() { + proto.DisappearingMode = (function() { /** - * Properties of a CompanionProps. + * Properties of a DisappearingMode. * @memberof proto - * @interface ICompanionProps - * @property {string|null} [os] CompanionProps os - * @property {proto.IAppVersion|null} [version] CompanionProps version - * @property {proto.CompanionProps.CompanionPropsPlatformType|null} [platformType] CompanionProps platformType - * @property {boolean|null} [requireFullSync] CompanionProps requireFullSync + * @interface IDisappearingMode + * @property {proto.DisappearingMode.DisappearingModeInitiator|null} [initiator] DisappearingMode initiator */ /** - * Constructs a new CompanionProps. + * Constructs a new DisappearingMode. * @memberof proto - * @classdesc Represents a CompanionProps. - * @implements ICompanionProps + * @classdesc Represents a DisappearingMode. + * @implements IDisappearingMode * @constructor - * @param {proto.ICompanionProps=} [properties] Properties to set + * @param {proto.IDisappearingMode=} [properties] Properties to set */ - function CompanionProps(properties) { + function DisappearingMode(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -43989,114 +26671,75 @@ $root.proto = (function() { } /** - * CompanionProps os. - * @member {string} os - * @memberof proto.CompanionProps + * DisappearingMode initiator. + * @member {proto.DisappearingMode.DisappearingModeInitiator} initiator + * @memberof proto.DisappearingMode * @instance */ - CompanionProps.prototype.os = ""; + DisappearingMode.prototype.initiator = 0; /** - * CompanionProps version. - * @member {proto.IAppVersion|null|undefined} version - * @memberof proto.CompanionProps - * @instance - */ - CompanionProps.prototype.version = null; - - /** - * CompanionProps platformType. - * @member {proto.CompanionProps.CompanionPropsPlatformType} platformType - * @memberof proto.CompanionProps - * @instance - */ - CompanionProps.prototype.platformType = 0; - - /** - * CompanionProps requireFullSync. - * @member {boolean} requireFullSync - * @memberof proto.CompanionProps - * @instance - */ - CompanionProps.prototype.requireFullSync = false; - - /** - * Creates a new CompanionProps instance using the specified properties. + * Creates a new DisappearingMode instance using the specified properties. * @function create - * @memberof proto.CompanionProps + * @memberof proto.DisappearingMode * @static - * @param {proto.ICompanionProps=} [properties] Properties to set - * @returns {proto.CompanionProps} CompanionProps instance + * @param {proto.IDisappearingMode=} [properties] Properties to set + * @returns {proto.DisappearingMode} DisappearingMode instance */ - CompanionProps.create = function create(properties) { - return new CompanionProps(properties); + DisappearingMode.create = function create(properties) { + return new DisappearingMode(properties); }; /** - * Encodes the specified CompanionProps message. Does not implicitly {@link proto.CompanionProps.verify|verify} messages. + * Encodes the specified DisappearingMode message. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages. * @function encode - * @memberof proto.CompanionProps + * @memberof proto.DisappearingMode * @static - * @param {proto.ICompanionProps} message CompanionProps message or plain object to encode + * @param {proto.IDisappearingMode} message DisappearingMode message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - CompanionProps.encode = function encode(message, writer) { + DisappearingMode.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.os != null && Object.hasOwnProperty.call(message, "os")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.os); - if (message.version != null && Object.hasOwnProperty.call(message, "version")) - $root.proto.AppVersion.encode(message.version, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.platformType != null && Object.hasOwnProperty.call(message, "platformType")) - writer.uint32(/* id 3, wireType 0 =*/24).int32(message.platformType); - if (message.requireFullSync != null && Object.hasOwnProperty.call(message, "requireFullSync")) - writer.uint32(/* id 4, wireType 0 =*/32).bool(message.requireFullSync); + if (message.initiator != null && Object.hasOwnProperty.call(message, "initiator")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.initiator); return writer; }; /** - * Encodes the specified CompanionProps message, length delimited. Does not implicitly {@link proto.CompanionProps.verify|verify} messages. + * Encodes the specified DisappearingMode message, length delimited. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages. * @function encodeDelimited - * @memberof proto.CompanionProps + * @memberof proto.DisappearingMode * @static - * @param {proto.ICompanionProps} message CompanionProps message or plain object to encode + * @param {proto.IDisappearingMode} message DisappearingMode message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - CompanionProps.encodeDelimited = function encodeDelimited(message, writer) { + DisappearingMode.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; /** - * Decodes a CompanionProps message from the specified reader or buffer. + * Decodes a DisappearingMode message from the specified reader or buffer. * @function decode - * @memberof proto.CompanionProps + * @memberof proto.DisappearingMode * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from * @param {number} [length] Message length if known beforehand - * @returns {proto.CompanionProps} CompanionProps + * @returns {proto.DisappearingMode} DisappearingMode * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - CompanionProps.decode = function decode(reader, length) { + DisappearingMode.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CompanionProps(); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DisappearingMode(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.os = reader.string(); - break; - case 2: - message.version = $root.proto.AppVersion.decode(reader, reader.uint32()); - break; - case 3: - message.platformType = reader.int32(); - break; - case 4: - message.requireFullSync = reader.bool(); + message.initiator = reader.int32(); break; default: reader.skipType(tag & 7); @@ -44107,242 +26750,148 @@ $root.proto = (function() { }; /** - * Decodes a CompanionProps message from the specified reader or buffer, length delimited. + * Decodes a DisappearingMode message from the specified reader or buffer, length delimited. * @function decodeDelimited - * @memberof proto.CompanionProps + * @memberof proto.DisappearingMode * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.CompanionProps} CompanionProps + * @returns {proto.DisappearingMode} DisappearingMode * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - CompanionProps.decodeDelimited = function decodeDelimited(reader) { + DisappearingMode.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; /** - * Verifies a CompanionProps message. + * Verifies a DisappearingMode message. * @function verify - * @memberof proto.CompanionProps + * @memberof proto.DisappearingMode * @static * @param {Object.} message Plain object to verify * @returns {string|null} `null` if valid, otherwise the reason why it is not */ - CompanionProps.verify = function verify(message) { + DisappearingMode.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.os != null && message.hasOwnProperty("os")) - if (!$util.isString(message.os)) - return "os: string expected"; - if (message.version != null && message.hasOwnProperty("version")) { - var error = $root.proto.AppVersion.verify(message.version); - if (error) - return "version." + error; - } - if (message.platformType != null && message.hasOwnProperty("platformType")) - switch (message.platformType) { + if (message.initiator != null && message.hasOwnProperty("initiator")) + switch (message.initiator) { default: - return "platformType: enum value expected"; + return "initiator: enum value expected"; case 0: case 1: case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: break; } - if (message.requireFullSync != null && message.hasOwnProperty("requireFullSync")) - if (typeof message.requireFullSync !== "boolean") - return "requireFullSync: boolean expected"; return null; }; /** - * Creates a CompanionProps message from a plain object. Also converts values to their respective internal types. + * Creates a DisappearingMode message from a plain object. Also converts values to their respective internal types. * @function fromObject - * @memberof proto.CompanionProps + * @memberof proto.DisappearingMode * @static * @param {Object.} object Plain object - * @returns {proto.CompanionProps} CompanionProps + * @returns {proto.DisappearingMode} DisappearingMode */ - CompanionProps.fromObject = function fromObject(object) { - if (object instanceof $root.proto.CompanionProps) + DisappearingMode.fromObject = function fromObject(object) { + if (object instanceof $root.proto.DisappearingMode) return object; - var message = new $root.proto.CompanionProps(); - if (object.os != null) - message.os = String(object.os); - if (object.version != null) { - if (typeof object.version !== "object") - throw TypeError(".proto.CompanionProps.version: object expected"); - message.version = $root.proto.AppVersion.fromObject(object.version); - } - switch (object.platformType) { - case "UNKNOWN": + var message = new $root.proto.DisappearingMode(); + switch (object.initiator) { + case "CHANGED_IN_CHAT": case 0: - message.platformType = 0; + message.initiator = 0; break; - case "CHROME": + case "INITIATED_BY_ME": case 1: - message.platformType = 1; + message.initiator = 1; break; - case "FIREFOX": + case "INITIATED_BY_OTHER": case 2: - message.platformType = 2; - break; - case "IE": - case 3: - message.platformType = 3; - break; - case "OPERA": - case 4: - message.platformType = 4; - break; - case "SAFARI": - case 5: - message.platformType = 5; - break; - case "EDGE": - case 6: - message.platformType = 6; - break; - case "DESKTOP": - case 7: - message.platformType = 7; - break; - case "IPAD": - case 8: - message.platformType = 8; - break; - case "ANDROID_TABLET": - case 9: - message.platformType = 9; - break; - case "OHANA": - case 10: - message.platformType = 10; - break; - case "ALOHA": - case 11: - message.platformType = 11; - break; - case "CATALINA": - case 12: - message.platformType = 12; + message.initiator = 2; break; } - if (object.requireFullSync != null) - message.requireFullSync = Boolean(object.requireFullSync); return message; }; /** - * Creates a plain object from a CompanionProps message. Also converts values to other types if specified. + * Creates a plain object from a DisappearingMode message. Also converts values to other types if specified. * @function toObject - * @memberof proto.CompanionProps + * @memberof proto.DisappearingMode * @static - * @param {proto.CompanionProps} message CompanionProps + * @param {proto.DisappearingMode} message DisappearingMode * @param {$protobuf.IConversionOptions} [options] Conversion options * @returns {Object.} Plain object */ - CompanionProps.toObject = function toObject(message, options) { + DisappearingMode.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; - if (options.defaults) { - object.os = ""; - object.version = null; - object.platformType = options.enums === String ? "UNKNOWN" : 0; - object.requireFullSync = false; - } - if (message.os != null && message.hasOwnProperty("os")) - object.os = message.os; - if (message.version != null && message.hasOwnProperty("version")) - object.version = $root.proto.AppVersion.toObject(message.version, options); - if (message.platformType != null && message.hasOwnProperty("platformType")) - object.platformType = options.enums === String ? $root.proto.CompanionProps.CompanionPropsPlatformType[message.platformType] : message.platformType; - if (message.requireFullSync != null && message.hasOwnProperty("requireFullSync")) - object.requireFullSync = message.requireFullSync; + if (options.defaults) + object.initiator = options.enums === String ? "CHANGED_IN_CHAT" : 0; + if (message.initiator != null && message.hasOwnProperty("initiator")) + object.initiator = options.enums === String ? $root.proto.DisappearingMode.DisappearingModeInitiator[message.initiator] : message.initiator; return object; }; /** - * Converts this CompanionProps to JSON. + * Converts this DisappearingMode to JSON. * @function toJSON - * @memberof proto.CompanionProps + * @memberof proto.DisappearingMode * @instance * @returns {Object.} JSON object */ - CompanionProps.prototype.toJSON = function toJSON() { + DisappearingMode.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; /** - * CompanionPropsPlatformType enum. - * @name proto.CompanionProps.CompanionPropsPlatformType + * DisappearingModeInitiator enum. + * @name proto.DisappearingMode.DisappearingModeInitiator * @enum {number} - * @property {number} UNKNOWN=0 UNKNOWN value - * @property {number} CHROME=1 CHROME value - * @property {number} FIREFOX=2 FIREFOX value - * @property {number} IE=3 IE value - * @property {number} OPERA=4 OPERA value - * @property {number} SAFARI=5 SAFARI value - * @property {number} EDGE=6 EDGE value - * @property {number} DESKTOP=7 DESKTOP value - * @property {number} IPAD=8 IPAD value - * @property {number} ANDROID_TABLET=9 ANDROID_TABLET value - * @property {number} OHANA=10 OHANA value - * @property {number} ALOHA=11 ALOHA value - * @property {number} CATALINA=12 CATALINA value + * @property {number} CHANGED_IN_CHAT=0 CHANGED_IN_CHAT value + * @property {number} INITIATED_BY_ME=1 INITIATED_BY_ME value + * @property {number} INITIATED_BY_OTHER=2 INITIATED_BY_OTHER value */ - CompanionProps.CompanionPropsPlatformType = (function() { + DisappearingMode.DisappearingModeInitiator = (function() { var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "UNKNOWN"] = 0; - values[valuesById[1] = "CHROME"] = 1; - values[valuesById[2] = "FIREFOX"] = 2; - values[valuesById[3] = "IE"] = 3; - values[valuesById[4] = "OPERA"] = 4; - values[valuesById[5] = "SAFARI"] = 5; - values[valuesById[6] = "EDGE"] = 6; - values[valuesById[7] = "DESKTOP"] = 7; - values[valuesById[8] = "IPAD"] = 8; - values[valuesById[9] = "ANDROID_TABLET"] = 9; - values[valuesById[10] = "OHANA"] = 10; - values[valuesById[11] = "ALOHA"] = 11; - values[valuesById[12] = "CATALINA"] = 12; + values[valuesById[0] = "CHANGED_IN_CHAT"] = 0; + values[valuesById[1] = "INITIATED_BY_ME"] = 1; + values[valuesById[2] = "INITIATED_BY_OTHER"] = 2; return values; })(); - return CompanionProps; + return DisappearingMode; })(); - proto.ADVSignedDeviceIdentityHMAC = (function() { + proto.PaymentBackground = (function() { /** - * Properties of a ADVSignedDeviceIdentityHMAC. + * Properties of a PaymentBackground. * @memberof proto - * @interface IADVSignedDeviceIdentityHMAC - * @property {Uint8Array|null} [details] ADVSignedDeviceIdentityHMAC details - * @property {Uint8Array|null} [hmac] ADVSignedDeviceIdentityHMAC hmac + * @interface IPaymentBackground + * @property {string|null} [id] PaymentBackground id + * @property {number|Long|null} [fileLength] PaymentBackground fileLength + * @property {number|null} [width] PaymentBackground width + * @property {number|null} [height] PaymentBackground height + * @property {string|null} [mimetype] PaymentBackground mimetype + * @property {number|null} [placeholderArgb] PaymentBackground placeholderArgb + * @property {number|null} [textArgb] PaymentBackground textArgb + * @property {number|null} [subtextArgb] PaymentBackground subtextArgb */ /** - * Constructs a new ADVSignedDeviceIdentityHMAC. + * Constructs a new PaymentBackground. * @memberof proto - * @classdesc Represents a ADVSignedDeviceIdentityHMAC. - * @implements IADVSignedDeviceIdentityHMAC + * @classdesc Represents a PaymentBackground. + * @implements IPaymentBackground * @constructor - * @param {proto.IADVSignedDeviceIdentityHMAC=} [properties] Properties to set + * @param {proto.IPaymentBackground=} [properties] Properties to set */ - function ADVSignedDeviceIdentityHMAC(properties) { + function PaymentBackground(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -44350,1401 +26899,166 @@ $root.proto = (function() { } /** - * ADVSignedDeviceIdentityHMAC details. - * @member {Uint8Array} details - * @memberof proto.ADVSignedDeviceIdentityHMAC - * @instance - */ - ADVSignedDeviceIdentityHMAC.prototype.details = $util.newBuffer([]); - - /** - * ADVSignedDeviceIdentityHMAC hmac. - * @member {Uint8Array} hmac - * @memberof proto.ADVSignedDeviceIdentityHMAC - * @instance - */ - ADVSignedDeviceIdentityHMAC.prototype.hmac = $util.newBuffer([]); - - /** - * Creates a new ADVSignedDeviceIdentityHMAC instance using the specified properties. - * @function create - * @memberof proto.ADVSignedDeviceIdentityHMAC - * @static - * @param {proto.IADVSignedDeviceIdentityHMAC=} [properties] Properties to set - * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC instance - */ - ADVSignedDeviceIdentityHMAC.create = function create(properties) { - return new ADVSignedDeviceIdentityHMAC(properties); - }; - - /** - * Encodes the specified ADVSignedDeviceIdentityHMAC message. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages. - * @function encode - * @memberof proto.ADVSignedDeviceIdentityHMAC - * @static - * @param {proto.IADVSignedDeviceIdentityHMAC} message ADVSignedDeviceIdentityHMAC message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ADVSignedDeviceIdentityHMAC.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.details != null && Object.hasOwnProperty.call(message, "details")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); - if (message.hmac != null && Object.hasOwnProperty.call(message, "hmac")) - writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.hmac); - return writer; - }; - - /** - * Encodes the specified ADVSignedDeviceIdentityHMAC message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ADVSignedDeviceIdentityHMAC - * @static - * @param {proto.IADVSignedDeviceIdentityHMAC} message ADVSignedDeviceIdentityHMAC message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ADVSignedDeviceIdentityHMAC.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer. - * @function decode - * @memberof proto.ADVSignedDeviceIdentityHMAC - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ADVSignedDeviceIdentityHMAC.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVSignedDeviceIdentityHMAC(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.details = reader.bytes(); - break; - case 2: - message.hmac = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ADVSignedDeviceIdentityHMAC - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ADVSignedDeviceIdentityHMAC.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ADVSignedDeviceIdentityHMAC message. - * @function verify - * @memberof proto.ADVSignedDeviceIdentityHMAC - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ADVSignedDeviceIdentityHMAC.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.details != null && message.hasOwnProperty("details")) - if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) - return "details: buffer expected"; - if (message.hmac != null && message.hasOwnProperty("hmac")) - if (!(message.hmac && typeof message.hmac.length === "number" || $util.isString(message.hmac))) - return "hmac: buffer expected"; - return null; - }; - - /** - * Creates a ADVSignedDeviceIdentityHMAC message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ADVSignedDeviceIdentityHMAC - * @static - * @param {Object.} object Plain object - * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC - */ - ADVSignedDeviceIdentityHMAC.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ADVSignedDeviceIdentityHMAC) - return object; - var message = new $root.proto.ADVSignedDeviceIdentityHMAC(); - if (object.details != null) - if (typeof object.details === "string") - $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); - else if (object.details.length) - message.details = object.details; - if (object.hmac != null) - if (typeof object.hmac === "string") - $util.base64.decode(object.hmac, message.hmac = $util.newBuffer($util.base64.length(object.hmac)), 0); - else if (object.hmac.length) - message.hmac = object.hmac; - return message; - }; - - /** - * Creates a plain object from a ADVSignedDeviceIdentityHMAC message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ADVSignedDeviceIdentityHMAC - * @static - * @param {proto.ADVSignedDeviceIdentityHMAC} message ADVSignedDeviceIdentityHMAC - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ADVSignedDeviceIdentityHMAC.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if (options.bytes === String) - object.details = ""; - else { - object.details = []; - if (options.bytes !== Array) - object.details = $util.newBuffer(object.details); - } - if (options.bytes === String) - object.hmac = ""; - else { - object.hmac = []; - if (options.bytes !== Array) - object.hmac = $util.newBuffer(object.hmac); - } - } - if (message.details != null && message.hasOwnProperty("details")) - object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; - if (message.hmac != null && message.hasOwnProperty("hmac")) - object.hmac = options.bytes === String ? $util.base64.encode(message.hmac, 0, message.hmac.length) : options.bytes === Array ? Array.prototype.slice.call(message.hmac) : message.hmac; - return object; - }; - - /** - * Converts this ADVSignedDeviceIdentityHMAC to JSON. - * @function toJSON - * @memberof proto.ADVSignedDeviceIdentityHMAC - * @instance - * @returns {Object.} JSON object - */ - ADVSignedDeviceIdentityHMAC.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ADVSignedDeviceIdentityHMAC; - })(); - - proto.ADVSignedDeviceIdentity = (function() { - - /** - * Properties of a ADVSignedDeviceIdentity. - * @memberof proto - * @interface IADVSignedDeviceIdentity - * @property {Uint8Array|null} [details] ADVSignedDeviceIdentity details - * @property {Uint8Array|null} [accountSignatureKey] ADVSignedDeviceIdentity accountSignatureKey - * @property {Uint8Array|null} [accountSignature] ADVSignedDeviceIdentity accountSignature - * @property {Uint8Array|null} [deviceSignature] ADVSignedDeviceIdentity deviceSignature - */ - - /** - * Constructs a new ADVSignedDeviceIdentity. - * @memberof proto - * @classdesc Represents a ADVSignedDeviceIdentity. - * @implements IADVSignedDeviceIdentity - * @constructor - * @param {proto.IADVSignedDeviceIdentity=} [properties] Properties to set - */ - function ADVSignedDeviceIdentity(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ADVSignedDeviceIdentity details. - * @member {Uint8Array} details - * @memberof proto.ADVSignedDeviceIdentity - * @instance - */ - ADVSignedDeviceIdentity.prototype.details = $util.newBuffer([]); - - /** - * ADVSignedDeviceIdentity accountSignatureKey. - * @member {Uint8Array} accountSignatureKey - * @memberof proto.ADVSignedDeviceIdentity - * @instance - */ - ADVSignedDeviceIdentity.prototype.accountSignatureKey = $util.newBuffer([]); - - /** - * ADVSignedDeviceIdentity accountSignature. - * @member {Uint8Array} accountSignature - * @memberof proto.ADVSignedDeviceIdentity - * @instance - */ - ADVSignedDeviceIdentity.prototype.accountSignature = $util.newBuffer([]); - - /** - * ADVSignedDeviceIdentity deviceSignature. - * @member {Uint8Array} deviceSignature - * @memberof proto.ADVSignedDeviceIdentity - * @instance - */ - ADVSignedDeviceIdentity.prototype.deviceSignature = $util.newBuffer([]); - - /** - * Creates a new ADVSignedDeviceIdentity instance using the specified properties. - * @function create - * @memberof proto.ADVSignedDeviceIdentity - * @static - * @param {proto.IADVSignedDeviceIdentity=} [properties] Properties to set - * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity instance - */ - ADVSignedDeviceIdentity.create = function create(properties) { - return new ADVSignedDeviceIdentity(properties); - }; - - /** - * Encodes the specified ADVSignedDeviceIdentity message. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages. - * @function encode - * @memberof proto.ADVSignedDeviceIdentity - * @static - * @param {proto.IADVSignedDeviceIdentity} message ADVSignedDeviceIdentity message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ADVSignedDeviceIdentity.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.details != null && Object.hasOwnProperty.call(message, "details")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); - if (message.accountSignatureKey != null && Object.hasOwnProperty.call(message, "accountSignatureKey")) - writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.accountSignatureKey); - if (message.accountSignature != null && Object.hasOwnProperty.call(message, "accountSignature")) - writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.accountSignature); - if (message.deviceSignature != null && Object.hasOwnProperty.call(message, "deviceSignature")) - writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.deviceSignature); - return writer; - }; - - /** - * Encodes the specified ADVSignedDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ADVSignedDeviceIdentity - * @static - * @param {proto.IADVSignedDeviceIdentity} message ADVSignedDeviceIdentity message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ADVSignedDeviceIdentity.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer. - * @function decode - * @memberof proto.ADVSignedDeviceIdentity - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ADVSignedDeviceIdentity.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVSignedDeviceIdentity(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.details = reader.bytes(); - break; - case 2: - message.accountSignatureKey = reader.bytes(); - break; - case 3: - message.accountSignature = reader.bytes(); - break; - case 4: - message.deviceSignature = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ADVSignedDeviceIdentity - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ADVSignedDeviceIdentity.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ADVSignedDeviceIdentity message. - * @function verify - * @memberof proto.ADVSignedDeviceIdentity - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ADVSignedDeviceIdentity.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.details != null && message.hasOwnProperty("details")) - if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) - return "details: buffer expected"; - if (message.accountSignatureKey != null && message.hasOwnProperty("accountSignatureKey")) - if (!(message.accountSignatureKey && typeof message.accountSignatureKey.length === "number" || $util.isString(message.accountSignatureKey))) - return "accountSignatureKey: buffer expected"; - if (message.accountSignature != null && message.hasOwnProperty("accountSignature")) - if (!(message.accountSignature && typeof message.accountSignature.length === "number" || $util.isString(message.accountSignature))) - return "accountSignature: buffer expected"; - if (message.deviceSignature != null && message.hasOwnProperty("deviceSignature")) - if (!(message.deviceSignature && typeof message.deviceSignature.length === "number" || $util.isString(message.deviceSignature))) - return "deviceSignature: buffer expected"; - return null; - }; - - /** - * Creates a ADVSignedDeviceIdentity message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ADVSignedDeviceIdentity - * @static - * @param {Object.} object Plain object - * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity - */ - ADVSignedDeviceIdentity.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ADVSignedDeviceIdentity) - return object; - var message = new $root.proto.ADVSignedDeviceIdentity(); - if (object.details != null) - if (typeof object.details === "string") - $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); - else if (object.details.length) - message.details = object.details; - if (object.accountSignatureKey != null) - if (typeof object.accountSignatureKey === "string") - $util.base64.decode(object.accountSignatureKey, message.accountSignatureKey = $util.newBuffer($util.base64.length(object.accountSignatureKey)), 0); - else if (object.accountSignatureKey.length) - message.accountSignatureKey = object.accountSignatureKey; - if (object.accountSignature != null) - if (typeof object.accountSignature === "string") - $util.base64.decode(object.accountSignature, message.accountSignature = $util.newBuffer($util.base64.length(object.accountSignature)), 0); - else if (object.accountSignature.length) - message.accountSignature = object.accountSignature; - if (object.deviceSignature != null) - if (typeof object.deviceSignature === "string") - $util.base64.decode(object.deviceSignature, message.deviceSignature = $util.newBuffer($util.base64.length(object.deviceSignature)), 0); - else if (object.deviceSignature.length) - message.deviceSignature = object.deviceSignature; - return message; - }; - - /** - * Creates a plain object from a ADVSignedDeviceIdentity message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ADVSignedDeviceIdentity - * @static - * @param {proto.ADVSignedDeviceIdentity} message ADVSignedDeviceIdentity - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ADVSignedDeviceIdentity.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if (options.bytes === String) - object.details = ""; - else { - object.details = []; - if (options.bytes !== Array) - object.details = $util.newBuffer(object.details); - } - if (options.bytes === String) - object.accountSignatureKey = ""; - else { - object.accountSignatureKey = []; - if (options.bytes !== Array) - object.accountSignatureKey = $util.newBuffer(object.accountSignatureKey); - } - if (options.bytes === String) - object.accountSignature = ""; - else { - object.accountSignature = []; - if (options.bytes !== Array) - object.accountSignature = $util.newBuffer(object.accountSignature); - } - if (options.bytes === String) - object.deviceSignature = ""; - else { - object.deviceSignature = []; - if (options.bytes !== Array) - object.deviceSignature = $util.newBuffer(object.deviceSignature); - } - } - if (message.details != null && message.hasOwnProperty("details")) - object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; - if (message.accountSignatureKey != null && message.hasOwnProperty("accountSignatureKey")) - object.accountSignatureKey = options.bytes === String ? $util.base64.encode(message.accountSignatureKey, 0, message.accountSignatureKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.accountSignatureKey) : message.accountSignatureKey; - if (message.accountSignature != null && message.hasOwnProperty("accountSignature")) - object.accountSignature = options.bytes === String ? $util.base64.encode(message.accountSignature, 0, message.accountSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.accountSignature) : message.accountSignature; - if (message.deviceSignature != null && message.hasOwnProperty("deviceSignature")) - object.deviceSignature = options.bytes === String ? $util.base64.encode(message.deviceSignature, 0, message.deviceSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.deviceSignature) : message.deviceSignature; - return object; - }; - - /** - * Converts this ADVSignedDeviceIdentity to JSON. - * @function toJSON - * @memberof proto.ADVSignedDeviceIdentity - * @instance - * @returns {Object.} JSON object - */ - ADVSignedDeviceIdentity.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ADVSignedDeviceIdentity; - })(); - - proto.ADVDeviceIdentity = (function() { - - /** - * Properties of a ADVDeviceIdentity. - * @memberof proto - * @interface IADVDeviceIdentity - * @property {number|null} [rawId] ADVDeviceIdentity rawId - * @property {number|Long|null} [timestamp] ADVDeviceIdentity timestamp - * @property {number|null} [keyIndex] ADVDeviceIdentity keyIndex - */ - - /** - * Constructs a new ADVDeviceIdentity. - * @memberof proto - * @classdesc Represents a ADVDeviceIdentity. - * @implements IADVDeviceIdentity - * @constructor - * @param {proto.IADVDeviceIdentity=} [properties] Properties to set - */ - function ADVDeviceIdentity(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ADVDeviceIdentity rawId. - * @member {number} rawId - * @memberof proto.ADVDeviceIdentity - * @instance - */ - ADVDeviceIdentity.prototype.rawId = 0; - - /** - * ADVDeviceIdentity timestamp. - * @member {number|Long} timestamp - * @memberof proto.ADVDeviceIdentity - * @instance - */ - ADVDeviceIdentity.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * ADVDeviceIdentity keyIndex. - * @member {number} keyIndex - * @memberof proto.ADVDeviceIdentity - * @instance - */ - ADVDeviceIdentity.prototype.keyIndex = 0; - - /** - * Creates a new ADVDeviceIdentity instance using the specified properties. - * @function create - * @memberof proto.ADVDeviceIdentity - * @static - * @param {proto.IADVDeviceIdentity=} [properties] Properties to set - * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity instance - */ - ADVDeviceIdentity.create = function create(properties) { - return new ADVDeviceIdentity(properties); - }; - - /** - * Encodes the specified ADVDeviceIdentity message. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages. - * @function encode - * @memberof proto.ADVDeviceIdentity - * @static - * @param {proto.IADVDeviceIdentity} message ADVDeviceIdentity message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ADVDeviceIdentity.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.rawId != null && Object.hasOwnProperty.call(message, "rawId")) - writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.rawId); - if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) - writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.timestamp); - if (message.keyIndex != null && Object.hasOwnProperty.call(message, "keyIndex")) - writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.keyIndex); - return writer; - }; - - /** - * Encodes the specified ADVDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ADVDeviceIdentity - * @static - * @param {proto.IADVDeviceIdentity} message ADVDeviceIdentity message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ADVDeviceIdentity.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ADVDeviceIdentity message from the specified reader or buffer. - * @function decode - * @memberof proto.ADVDeviceIdentity - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ADVDeviceIdentity.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVDeviceIdentity(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.rawId = reader.uint32(); - break; - case 2: - message.timestamp = reader.uint64(); - break; - case 3: - message.keyIndex = reader.uint32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ADVDeviceIdentity message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ADVDeviceIdentity - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ADVDeviceIdentity.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ADVDeviceIdentity message. - * @function verify - * @memberof proto.ADVDeviceIdentity - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ADVDeviceIdentity.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.rawId != null && message.hasOwnProperty("rawId")) - if (!$util.isInteger(message.rawId)) - return "rawId: integer expected"; - if (message.timestamp != null && message.hasOwnProperty("timestamp")) - if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) - return "timestamp: integer|Long expected"; - if (message.keyIndex != null && message.hasOwnProperty("keyIndex")) - if (!$util.isInteger(message.keyIndex)) - return "keyIndex: integer expected"; - return null; - }; - - /** - * Creates a ADVDeviceIdentity message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ADVDeviceIdentity - * @static - * @param {Object.} object Plain object - * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity - */ - ADVDeviceIdentity.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ADVDeviceIdentity) - return object; - var message = new $root.proto.ADVDeviceIdentity(); - if (object.rawId != null) - message.rawId = object.rawId >>> 0; - if (object.timestamp != null) - if ($util.Long) - (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = true; - else if (typeof object.timestamp === "string") - message.timestamp = parseInt(object.timestamp, 10); - else if (typeof object.timestamp === "number") - message.timestamp = object.timestamp; - else if (typeof object.timestamp === "object") - message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(true); - if (object.keyIndex != null) - message.keyIndex = object.keyIndex >>> 0; - return message; - }; - - /** - * Creates a plain object from a ADVDeviceIdentity message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ADVDeviceIdentity - * @static - * @param {proto.ADVDeviceIdentity} message ADVDeviceIdentity - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ADVDeviceIdentity.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.rawId = 0; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.timestamp = options.longs === String ? "0" : 0; - object.keyIndex = 0; - } - if (message.rawId != null && message.hasOwnProperty("rawId")) - object.rawId = message.rawId; - if (message.timestamp != null && message.hasOwnProperty("timestamp")) - if (typeof message.timestamp === "number") - object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; - else - object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber(true) : message.timestamp; - if (message.keyIndex != null && message.hasOwnProperty("keyIndex")) - object.keyIndex = message.keyIndex; - return object; - }; - - /** - * Converts this ADVDeviceIdentity to JSON. - * @function toJSON - * @memberof proto.ADVDeviceIdentity - * @instance - * @returns {Object.} JSON object - */ - ADVDeviceIdentity.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ADVDeviceIdentity; - })(); - - proto.ADVSignedKeyIndexList = (function() { - - /** - * Properties of a ADVSignedKeyIndexList. - * @memberof proto - * @interface IADVSignedKeyIndexList - * @property {Uint8Array|null} [details] ADVSignedKeyIndexList details - * @property {Uint8Array|null} [accountSignature] ADVSignedKeyIndexList accountSignature - */ - - /** - * Constructs a new ADVSignedKeyIndexList. - * @memberof proto - * @classdesc Represents a ADVSignedKeyIndexList. - * @implements IADVSignedKeyIndexList - * @constructor - * @param {proto.IADVSignedKeyIndexList=} [properties] Properties to set - */ - function ADVSignedKeyIndexList(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ADVSignedKeyIndexList details. - * @member {Uint8Array} details - * @memberof proto.ADVSignedKeyIndexList - * @instance - */ - ADVSignedKeyIndexList.prototype.details = $util.newBuffer([]); - - /** - * ADVSignedKeyIndexList accountSignature. - * @member {Uint8Array} accountSignature - * @memberof proto.ADVSignedKeyIndexList - * @instance - */ - ADVSignedKeyIndexList.prototype.accountSignature = $util.newBuffer([]); - - /** - * Creates a new ADVSignedKeyIndexList instance using the specified properties. - * @function create - * @memberof proto.ADVSignedKeyIndexList - * @static - * @param {proto.IADVSignedKeyIndexList=} [properties] Properties to set - * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList instance - */ - ADVSignedKeyIndexList.create = function create(properties) { - return new ADVSignedKeyIndexList(properties); - }; - - /** - * Encodes the specified ADVSignedKeyIndexList message. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages. - * @function encode - * @memberof proto.ADVSignedKeyIndexList - * @static - * @param {proto.IADVSignedKeyIndexList} message ADVSignedKeyIndexList message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ADVSignedKeyIndexList.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.details != null && Object.hasOwnProperty.call(message, "details")) - writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); - if (message.accountSignature != null && Object.hasOwnProperty.call(message, "accountSignature")) - writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.accountSignature); - return writer; - }; - - /** - * Encodes the specified ADVSignedKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ADVSignedKeyIndexList - * @static - * @param {proto.IADVSignedKeyIndexList} message ADVSignedKeyIndexList message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ADVSignedKeyIndexList.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer. - * @function decode - * @memberof proto.ADVSignedKeyIndexList - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ADVSignedKeyIndexList.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVSignedKeyIndexList(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.details = reader.bytes(); - break; - case 2: - message.accountSignature = reader.bytes(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ADVSignedKeyIndexList - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ADVSignedKeyIndexList.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ADVSignedKeyIndexList message. - * @function verify - * @memberof proto.ADVSignedKeyIndexList - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ADVSignedKeyIndexList.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.details != null && message.hasOwnProperty("details")) - if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) - return "details: buffer expected"; - if (message.accountSignature != null && message.hasOwnProperty("accountSignature")) - if (!(message.accountSignature && typeof message.accountSignature.length === "number" || $util.isString(message.accountSignature))) - return "accountSignature: buffer expected"; - return null; - }; - - /** - * Creates a ADVSignedKeyIndexList message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ADVSignedKeyIndexList - * @static - * @param {Object.} object Plain object - * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList - */ - ADVSignedKeyIndexList.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ADVSignedKeyIndexList) - return object; - var message = new $root.proto.ADVSignedKeyIndexList(); - if (object.details != null) - if (typeof object.details === "string") - $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); - else if (object.details.length) - message.details = object.details; - if (object.accountSignature != null) - if (typeof object.accountSignature === "string") - $util.base64.decode(object.accountSignature, message.accountSignature = $util.newBuffer($util.base64.length(object.accountSignature)), 0); - else if (object.accountSignature.length) - message.accountSignature = object.accountSignature; - return message; - }; - - /** - * Creates a plain object from a ADVSignedKeyIndexList message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ADVSignedKeyIndexList - * @static - * @param {proto.ADVSignedKeyIndexList} message ADVSignedKeyIndexList - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ADVSignedKeyIndexList.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if (options.bytes === String) - object.details = ""; - else { - object.details = []; - if (options.bytes !== Array) - object.details = $util.newBuffer(object.details); - } - if (options.bytes === String) - object.accountSignature = ""; - else { - object.accountSignature = []; - if (options.bytes !== Array) - object.accountSignature = $util.newBuffer(object.accountSignature); - } - } - if (message.details != null && message.hasOwnProperty("details")) - object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; - if (message.accountSignature != null && message.hasOwnProperty("accountSignature")) - object.accountSignature = options.bytes === String ? $util.base64.encode(message.accountSignature, 0, message.accountSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.accountSignature) : message.accountSignature; - return object; - }; - - /** - * Converts this ADVSignedKeyIndexList to JSON. - * @function toJSON - * @memberof proto.ADVSignedKeyIndexList - * @instance - * @returns {Object.} JSON object - */ - ADVSignedKeyIndexList.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ADVSignedKeyIndexList; - })(); - - proto.ADVKeyIndexList = (function() { - - /** - * Properties of a ADVKeyIndexList. - * @memberof proto - * @interface IADVKeyIndexList - * @property {number|null} [rawId] ADVKeyIndexList rawId - * @property {number|Long|null} [timestamp] ADVKeyIndexList timestamp - * @property {number|null} [currentIndex] ADVKeyIndexList currentIndex - * @property {Array.|null} [validIndexes] ADVKeyIndexList validIndexes - */ - - /** - * Constructs a new ADVKeyIndexList. - * @memberof proto - * @classdesc Represents a ADVKeyIndexList. - * @implements IADVKeyIndexList - * @constructor - * @param {proto.IADVKeyIndexList=} [properties] Properties to set - */ - function ADVKeyIndexList(properties) { - this.validIndexes = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ADVKeyIndexList rawId. - * @member {number} rawId - * @memberof proto.ADVKeyIndexList - * @instance - */ - ADVKeyIndexList.prototype.rawId = 0; - - /** - * ADVKeyIndexList timestamp. - * @member {number|Long} timestamp - * @memberof proto.ADVKeyIndexList - * @instance - */ - ADVKeyIndexList.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - /** - * ADVKeyIndexList currentIndex. - * @member {number} currentIndex - * @memberof proto.ADVKeyIndexList - * @instance - */ - ADVKeyIndexList.prototype.currentIndex = 0; - - /** - * ADVKeyIndexList validIndexes. - * @member {Array.} validIndexes - * @memberof proto.ADVKeyIndexList - * @instance - */ - ADVKeyIndexList.prototype.validIndexes = $util.emptyArray; - - /** - * Creates a new ADVKeyIndexList instance using the specified properties. - * @function create - * @memberof proto.ADVKeyIndexList - * @static - * @param {proto.IADVKeyIndexList=} [properties] Properties to set - * @returns {proto.ADVKeyIndexList} ADVKeyIndexList instance - */ - ADVKeyIndexList.create = function create(properties) { - return new ADVKeyIndexList(properties); - }; - - /** - * Encodes the specified ADVKeyIndexList message. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages. - * @function encode - * @memberof proto.ADVKeyIndexList - * @static - * @param {proto.IADVKeyIndexList} message ADVKeyIndexList message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ADVKeyIndexList.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.rawId != null && Object.hasOwnProperty.call(message, "rawId")) - writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.rawId); - if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) - writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.timestamp); - if (message.currentIndex != null && Object.hasOwnProperty.call(message, "currentIndex")) - writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.currentIndex); - if (message.validIndexes != null && message.validIndexes.length) { - writer.uint32(/* id 4, wireType 2 =*/34).fork(); - for (var i = 0; i < message.validIndexes.length; ++i) - writer.uint32(message.validIndexes[i]); - writer.ldelim(); - } - return writer; - }; - - /** - * Encodes the specified ADVKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ADVKeyIndexList - * @static - * @param {proto.IADVKeyIndexList} message ADVKeyIndexList message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ADVKeyIndexList.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ADVKeyIndexList message from the specified reader or buffer. - * @function decode - * @memberof proto.ADVKeyIndexList - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ADVKeyIndexList} ADVKeyIndexList - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ADVKeyIndexList.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVKeyIndexList(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.rawId = reader.uint32(); - break; - case 2: - message.timestamp = reader.uint64(); - break; - case 3: - message.currentIndex = reader.uint32(); - break; - case 4: - if (!(message.validIndexes && message.validIndexes.length)) - message.validIndexes = []; - if ((tag & 7) === 2) { - var end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) - message.validIndexes.push(reader.uint32()); - } else - message.validIndexes.push(reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ADVKeyIndexList message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ADVKeyIndexList - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ADVKeyIndexList} ADVKeyIndexList - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ADVKeyIndexList.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ADVKeyIndexList message. - * @function verify - * @memberof proto.ADVKeyIndexList - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ADVKeyIndexList.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.rawId != null && message.hasOwnProperty("rawId")) - if (!$util.isInteger(message.rawId)) - return "rawId: integer expected"; - if (message.timestamp != null && message.hasOwnProperty("timestamp")) - if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) - return "timestamp: integer|Long expected"; - if (message.currentIndex != null && message.hasOwnProperty("currentIndex")) - if (!$util.isInteger(message.currentIndex)) - return "currentIndex: integer expected"; - if (message.validIndexes != null && message.hasOwnProperty("validIndexes")) { - if (!Array.isArray(message.validIndexes)) - return "validIndexes: array expected"; - for (var i = 0; i < message.validIndexes.length; ++i) - if (!$util.isInteger(message.validIndexes[i])) - return "validIndexes: integer[] expected"; - } - return null; - }; - - /** - * Creates a ADVKeyIndexList message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ADVKeyIndexList - * @static - * @param {Object.} object Plain object - * @returns {proto.ADVKeyIndexList} ADVKeyIndexList - */ - ADVKeyIndexList.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ADVKeyIndexList) - return object; - var message = new $root.proto.ADVKeyIndexList(); - if (object.rawId != null) - message.rawId = object.rawId >>> 0; - if (object.timestamp != null) - if ($util.Long) - (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = true; - else if (typeof object.timestamp === "string") - message.timestamp = parseInt(object.timestamp, 10); - else if (typeof object.timestamp === "number") - message.timestamp = object.timestamp; - else if (typeof object.timestamp === "object") - message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(true); - if (object.currentIndex != null) - message.currentIndex = object.currentIndex >>> 0; - if (object.validIndexes) { - if (!Array.isArray(object.validIndexes)) - throw TypeError(".proto.ADVKeyIndexList.validIndexes: array expected"); - message.validIndexes = []; - for (var i = 0; i < object.validIndexes.length; ++i) - message.validIndexes[i] = object.validIndexes[i] >>> 0; - } - return message; - }; - - /** - * Creates a plain object from a ADVKeyIndexList message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ADVKeyIndexList - * @static - * @param {proto.ADVKeyIndexList} message ADVKeyIndexList - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ADVKeyIndexList.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.validIndexes = []; - if (options.defaults) { - object.rawId = 0; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.timestamp = options.longs === String ? "0" : 0; - object.currentIndex = 0; - } - if (message.rawId != null && message.hasOwnProperty("rawId")) - object.rawId = message.rawId; - if (message.timestamp != null && message.hasOwnProperty("timestamp")) - if (typeof message.timestamp === "number") - object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; - else - object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber(true) : message.timestamp; - if (message.currentIndex != null && message.hasOwnProperty("currentIndex")) - object.currentIndex = message.currentIndex; - if (message.validIndexes && message.validIndexes.length) { - object.validIndexes = []; - for (var j = 0; j < message.validIndexes.length; ++j) - object.validIndexes[j] = message.validIndexes[j]; - } - return object; - }; - - /** - * Converts this ADVKeyIndexList to JSON. - * @function toJSON - * @memberof proto.ADVKeyIndexList - * @instance - * @returns {Object.} JSON object - */ - ADVKeyIndexList.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return ADVKeyIndexList; - })(); - - proto.MessageKey = (function() { - - /** - * Properties of a MessageKey. - * @memberof proto - * @interface IMessageKey - * @property {string|null} [remoteJid] MessageKey remoteJid - * @property {boolean|null} [fromMe] MessageKey fromMe - * @property {string|null} [id] MessageKey id - * @property {string|null} [participant] MessageKey participant - */ - - /** - * Constructs a new MessageKey. - * @memberof proto - * @classdesc Represents a MessageKey. - * @implements IMessageKey - * @constructor - * @param {proto.IMessageKey=} [properties] Properties to set - */ - function MessageKey(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * MessageKey remoteJid. - * @member {string} remoteJid - * @memberof proto.MessageKey - * @instance - */ - MessageKey.prototype.remoteJid = ""; - - /** - * MessageKey fromMe. - * @member {boolean} fromMe - * @memberof proto.MessageKey - * @instance - */ - MessageKey.prototype.fromMe = false; - - /** - * MessageKey id. + * PaymentBackground id. * @member {string} id - * @memberof proto.MessageKey + * @memberof proto.PaymentBackground * @instance */ - MessageKey.prototype.id = ""; + PaymentBackground.prototype.id = ""; /** - * MessageKey participant. - * @member {string} participant - * @memberof proto.MessageKey + * PaymentBackground fileLength. + * @member {number|Long} fileLength + * @memberof proto.PaymentBackground * @instance */ - MessageKey.prototype.participant = ""; + PaymentBackground.prototype.fileLength = $util.Long ? $util.Long.fromBits(0,0,true) : 0; /** - * Creates a new MessageKey instance using the specified properties. + * PaymentBackground width. + * @member {number} width + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.width = 0; + + /** + * PaymentBackground height. + * @member {number} height + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.height = 0; + + /** + * PaymentBackground mimetype. + * @member {string} mimetype + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.mimetype = ""; + + /** + * PaymentBackground placeholderArgb. + * @member {number} placeholderArgb + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.placeholderArgb = 0; + + /** + * PaymentBackground textArgb. + * @member {number} textArgb + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.textArgb = 0; + + /** + * PaymentBackground subtextArgb. + * @member {number} subtextArgb + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.subtextArgb = 0; + + /** + * Creates a new PaymentBackground instance using the specified properties. * @function create - * @memberof proto.MessageKey + * @memberof proto.PaymentBackground * @static - * @param {proto.IMessageKey=} [properties] Properties to set - * @returns {proto.MessageKey} MessageKey instance + * @param {proto.IPaymentBackground=} [properties] Properties to set + * @returns {proto.PaymentBackground} PaymentBackground instance */ - MessageKey.create = function create(properties) { - return new MessageKey(properties); + PaymentBackground.create = function create(properties) { + return new PaymentBackground(properties); }; /** - * Encodes the specified MessageKey message. Does not implicitly {@link proto.MessageKey.verify|verify} messages. + * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. * @function encode - * @memberof proto.MessageKey + * @memberof proto.PaymentBackground * @static - * @param {proto.IMessageKey} message MessageKey message or plain object to encode + * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - MessageKey.encode = function encode(message, writer) { + PaymentBackground.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.remoteJid != null && Object.hasOwnProperty.call(message, "remoteJid")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.remoteJid); - if (message.fromMe != null && Object.hasOwnProperty.call(message, "fromMe")) - writer.uint32(/* id 2, wireType 0 =*/16).bool(message.fromMe); if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.id); - if (message.participant != null && Object.hasOwnProperty.call(message, "participant")) - writer.uint32(/* id 4, wireType 2 =*/34).string(message.participant); + writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); + if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength")) + writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.fileLength); + if (message.width != null && Object.hasOwnProperty.call(message, "width")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.width); + if (message.height != null && Object.hasOwnProperty.call(message, "height")) + writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.height); + if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.mimetype); + if (message.placeholderArgb != null && Object.hasOwnProperty.call(message, "placeholderArgb")) + writer.uint32(/* id 6, wireType 5 =*/53).fixed32(message.placeholderArgb); + if (message.textArgb != null && Object.hasOwnProperty.call(message, "textArgb")) + writer.uint32(/* id 7, wireType 5 =*/61).fixed32(message.textArgb); + if (message.subtextArgb != null && Object.hasOwnProperty.call(message, "subtextArgb")) + writer.uint32(/* id 8, wireType 5 =*/69).fixed32(message.subtextArgb); return writer; }; /** - * Encodes the specified MessageKey message, length delimited. Does not implicitly {@link proto.MessageKey.verify|verify} messages. + * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. * @function encodeDelimited - * @memberof proto.MessageKey + * @memberof proto.PaymentBackground * @static - * @param {proto.IMessageKey} message MessageKey message or plain object to encode + * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - MessageKey.encodeDelimited = function encodeDelimited(message, writer) { + PaymentBackground.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; /** - * Decodes a MessageKey message from the specified reader or buffer. + * Decodes a PaymentBackground message from the specified reader or buffer. * @function decode - * @memberof proto.MessageKey + * @memberof proto.PaymentBackground * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from * @param {number} [length] Message length if known beforehand - * @returns {proto.MessageKey} MessageKey + * @returns {proto.PaymentBackground} PaymentBackground * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - MessageKey.decode = function decode(reader, length) { + PaymentBackground.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MessageKey(); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentBackground(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.remoteJid = reader.string(); - break; - case 2: - message.fromMe = reader.bool(); - break; - case 3: message.id = reader.string(); break; + case 2: + message.fileLength = reader.uint64(); + break; + case 3: + message.width = reader.uint32(); + break; case 4: - message.participant = reader.string(); + message.height = reader.uint32(); + break; + case 5: + message.mimetype = reader.string(); + break; + case 6: + message.placeholderArgb = reader.fixed32(); + break; + case 7: + message.textArgb = reader.fixed32(); + break; + case 8: + message.subtextArgb = reader.fixed32(); break; default: reader.skipType(tag & 7); @@ -45755,112 +27069,1710 @@ $root.proto = (function() { }; /** - * Decodes a MessageKey message from the specified reader or buffer, length delimited. + * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. * @function decodeDelimited - * @memberof proto.MessageKey + * @memberof proto.PaymentBackground * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.MessageKey} MessageKey + * @returns {proto.PaymentBackground} PaymentBackground * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - MessageKey.decodeDelimited = function decodeDelimited(reader) { + PaymentBackground.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; /** - * Verifies a MessageKey message. + * Verifies a PaymentBackground message. * @function verify - * @memberof proto.MessageKey + * @memberof proto.PaymentBackground * @static * @param {Object.} message Plain object to verify * @returns {string|null} `null` if valid, otherwise the reason why it is not */ - MessageKey.verify = function verify(message) { + PaymentBackground.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.remoteJid != null && message.hasOwnProperty("remoteJid")) - if (!$util.isString(message.remoteJid)) - return "remoteJid: string expected"; - if (message.fromMe != null && message.hasOwnProperty("fromMe")) - if (typeof message.fromMe !== "boolean") - return "fromMe: boolean expected"; if (message.id != null && message.hasOwnProperty("id")) if (!$util.isString(message.id)) return "id: string expected"; - if (message.participant != null && message.hasOwnProperty("participant")) - if (!$util.isString(message.participant)) - return "participant: string expected"; + if (message.fileLength != null && message.hasOwnProperty("fileLength")) + if (!$util.isInteger(message.fileLength) && !(message.fileLength && $util.isInteger(message.fileLength.low) && $util.isInteger(message.fileLength.high))) + return "fileLength: integer|Long expected"; + if (message.width != null && message.hasOwnProperty("width")) + if (!$util.isInteger(message.width)) + return "width: integer expected"; + if (message.height != null && message.hasOwnProperty("height")) + if (!$util.isInteger(message.height)) + return "height: integer expected"; + if (message.mimetype != null && message.hasOwnProperty("mimetype")) + if (!$util.isString(message.mimetype)) + return "mimetype: string expected"; + if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) + if (!$util.isInteger(message.placeholderArgb)) + return "placeholderArgb: integer expected"; + if (message.textArgb != null && message.hasOwnProperty("textArgb")) + if (!$util.isInteger(message.textArgb)) + return "textArgb: integer expected"; + if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) + if (!$util.isInteger(message.subtextArgb)) + return "subtextArgb: integer expected"; return null; }; /** - * Creates a MessageKey message from a plain object. Also converts values to their respective internal types. + * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. * @function fromObject - * @memberof proto.MessageKey + * @memberof proto.PaymentBackground * @static * @param {Object.} object Plain object - * @returns {proto.MessageKey} MessageKey + * @returns {proto.PaymentBackground} PaymentBackground */ - MessageKey.fromObject = function fromObject(object) { - if (object instanceof $root.proto.MessageKey) + PaymentBackground.fromObject = function fromObject(object) { + if (object instanceof $root.proto.PaymentBackground) return object; - var message = new $root.proto.MessageKey(); - if (object.remoteJid != null) - message.remoteJid = String(object.remoteJid); - if (object.fromMe != null) - message.fromMe = Boolean(object.fromMe); + var message = new $root.proto.PaymentBackground(); if (object.id != null) message.id = String(object.id); - if (object.participant != null) - message.participant = String(object.participant); + if (object.fileLength != null) + if ($util.Long) + (message.fileLength = $util.Long.fromValue(object.fileLength)).unsigned = true; + else if (typeof object.fileLength === "string") + message.fileLength = parseInt(object.fileLength, 10); + else if (typeof object.fileLength === "number") + message.fileLength = object.fileLength; + else if (typeof object.fileLength === "object") + message.fileLength = new $util.LongBits(object.fileLength.low >>> 0, object.fileLength.high >>> 0).toNumber(true); + if (object.width != null) + message.width = object.width >>> 0; + if (object.height != null) + message.height = object.height >>> 0; + if (object.mimetype != null) + message.mimetype = String(object.mimetype); + if (object.placeholderArgb != null) + message.placeholderArgb = object.placeholderArgb >>> 0; + if (object.textArgb != null) + message.textArgb = object.textArgb >>> 0; + if (object.subtextArgb != null) + message.subtextArgb = object.subtextArgb >>> 0; return message; }; /** - * Creates a plain object from a MessageKey message. Also converts values to other types if specified. + * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. * @function toObject - * @memberof proto.MessageKey + * @memberof proto.PaymentBackground * @static - * @param {proto.MessageKey} message MessageKey + * @param {proto.PaymentBackground} message PaymentBackground * @param {$protobuf.IConversionOptions} [options] Conversion options * @returns {Object.} Plain object */ - MessageKey.toObject = function toObject(message, options) { + PaymentBackground.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { - object.remoteJid = ""; - object.fromMe = false; object.id = ""; - object.participant = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.fileLength = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.fileLength = options.longs === String ? "0" : 0; + object.width = 0; + object.height = 0; + object.mimetype = ""; + object.placeholderArgb = 0; + object.textArgb = 0; + object.subtextArgb = 0; } - if (message.remoteJid != null && message.hasOwnProperty("remoteJid")) - object.remoteJid = message.remoteJid; - if (message.fromMe != null && message.hasOwnProperty("fromMe")) - object.fromMe = message.fromMe; if (message.id != null && message.hasOwnProperty("id")) object.id = message.id; - if (message.participant != null && message.hasOwnProperty("participant")) - object.participant = message.participant; + if (message.fileLength != null && message.hasOwnProperty("fileLength")) + if (typeof message.fileLength === "number") + object.fileLength = options.longs === String ? String(message.fileLength) : message.fileLength; + else + object.fileLength = options.longs === String ? $util.Long.prototype.toString.call(message.fileLength) : options.longs === Number ? new $util.LongBits(message.fileLength.low >>> 0, message.fileLength.high >>> 0).toNumber(true) : message.fileLength; + if (message.width != null && message.hasOwnProperty("width")) + object.width = message.width; + if (message.height != null && message.hasOwnProperty("height")) + object.height = message.height; + if (message.mimetype != null && message.hasOwnProperty("mimetype")) + object.mimetype = message.mimetype; + if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) + object.placeholderArgb = message.placeholderArgb; + if (message.textArgb != null && message.hasOwnProperty("textArgb")) + object.textArgb = message.textArgb; + if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) + object.subtextArgb = message.subtextArgb; return object; }; /** - * Converts this MessageKey to JSON. + * Converts this PaymentBackground to JSON. * @function toJSON - * @memberof proto.MessageKey + * @memberof proto.PaymentBackground * @instance * @returns {Object.} JSON object */ - MessageKey.prototype.toJSON = function toJSON() { + PaymentBackground.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - return MessageKey; + return PaymentBackground; + })(); + + proto.Money = (function() { + + /** + * Properties of a Money. + * @memberof proto + * @interface IMoney + * @property {number|Long|null} [value] Money value + * @property {number|null} [offset] Money offset + * @property {string|null} [currencyCode] Money currencyCode + */ + + /** + * Constructs a new Money. + * @memberof proto + * @classdesc Represents a Money. + * @implements IMoney + * @constructor + * @param {proto.IMoney=} [properties] Properties to set + */ + function Money(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Money value. + * @member {number|Long} value + * @memberof proto.Money + * @instance + */ + Money.prototype.value = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Money offset. + * @member {number} offset + * @memberof proto.Money + * @instance + */ + Money.prototype.offset = 0; + + /** + * Money currencyCode. + * @member {string} currencyCode + * @memberof proto.Money + * @instance + */ + Money.prototype.currencyCode = ""; + + /** + * Creates a new Money instance using the specified properties. + * @function create + * @memberof proto.Money + * @static + * @param {proto.IMoney=} [properties] Properties to set + * @returns {proto.Money} Money instance + */ + Money.create = function create(properties) { + return new Money(properties); + }; + + /** + * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. + * @function encode + * @memberof proto.Money + * @static + * @param {proto.IMoney} message Money message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Money.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.value != null && Object.hasOwnProperty.call(message, "value")) + writer.uint32(/* id 1, wireType 0 =*/8).int64(message.value); + if (message.offset != null && Object.hasOwnProperty.call(message, "offset")) + writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.offset); + if (message.currencyCode != null && Object.hasOwnProperty.call(message, "currencyCode")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.currencyCode); + return writer; + }; + + /** + * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Money + * @static + * @param {proto.IMoney} message Money message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Money.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Money message from the specified reader or buffer. + * @function decode + * @memberof proto.Money + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Money} Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Money.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Money(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.value = reader.int64(); + break; + case 2: + message.offset = reader.uint32(); + break; + case 3: + message.currencyCode = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Money message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Money + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Money} Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Money.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Money message. + * @function verify + * @memberof proto.Money + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Money.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.value != null && message.hasOwnProperty("value")) + if (!$util.isInteger(message.value) && !(message.value && $util.isInteger(message.value.low) && $util.isInteger(message.value.high))) + return "value: integer|Long expected"; + if (message.offset != null && message.hasOwnProperty("offset")) + if (!$util.isInteger(message.offset)) + return "offset: integer expected"; + if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) + if (!$util.isString(message.currencyCode)) + return "currencyCode: string expected"; + return null; + }; + + /** + * Creates a Money message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Money + * @static + * @param {Object.} object Plain object + * @returns {proto.Money} Money + */ + Money.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Money) + return object; + var message = new $root.proto.Money(); + if (object.value != null) + if ($util.Long) + (message.value = $util.Long.fromValue(object.value)).unsigned = false; + else if (typeof object.value === "string") + message.value = parseInt(object.value, 10); + else if (typeof object.value === "number") + message.value = object.value; + else if (typeof object.value === "object") + message.value = new $util.LongBits(object.value.low >>> 0, object.value.high >>> 0).toNumber(); + if (object.offset != null) + message.offset = object.offset >>> 0; + if (object.currencyCode != null) + message.currencyCode = String(object.currencyCode); + return message; + }; + + /** + * Creates a plain object from a Money message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Money + * @static + * @param {proto.Money} message Money + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Money.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.value = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.value = options.longs === String ? "0" : 0; + object.offset = 0; + object.currencyCode = ""; + } + if (message.value != null && message.hasOwnProperty("value")) + if (typeof message.value === "number") + object.value = options.longs === String ? String(message.value) : message.value; + else + object.value = options.longs === String ? $util.Long.prototype.toString.call(message.value) : options.longs === Number ? new $util.LongBits(message.value.low >>> 0, message.value.high >>> 0).toNumber() : message.value; + if (message.offset != null && message.hasOwnProperty("offset")) + object.offset = message.offset; + if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) + object.currencyCode = message.currencyCode; + return object; + }; + + /** + * Converts this Money to JSON. + * @function toJSON + * @memberof proto.Money + * @instance + * @returns {Object.} JSON object + */ + Money.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Money; + })(); + + proto.HydratedQuickReplyButton = (function() { + + /** + * Properties of a HydratedQuickReplyButton. + * @memberof proto + * @interface IHydratedQuickReplyButton + * @property {string|null} [displayText] HydratedQuickReplyButton displayText + * @property {string|null} [id] HydratedQuickReplyButton id + */ + + /** + * Constructs a new HydratedQuickReplyButton. + * @memberof proto + * @classdesc Represents a HydratedQuickReplyButton. + * @implements IHydratedQuickReplyButton + * @constructor + * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set + */ + function HydratedQuickReplyButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HydratedQuickReplyButton displayText. + * @member {string} displayText + * @memberof proto.HydratedQuickReplyButton + * @instance + */ + HydratedQuickReplyButton.prototype.displayText = ""; + + /** + * HydratedQuickReplyButton id. + * @member {string} id + * @memberof proto.HydratedQuickReplyButton + * @instance + */ + HydratedQuickReplyButton.prototype.id = ""; + + /** + * Creates a new HydratedQuickReplyButton instance using the specified properties. + * @function create + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set + * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton instance + */ + HydratedQuickReplyButton.create = function create(properties) { + return new HydratedQuickReplyButton(properties); + }; + + /** + * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * @function encode + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedQuickReplyButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.id); + return writer; + }; + + /** + * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedQuickReplyButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HydratedQuickReplyButton message from the specified reader or buffer. + * @function decode + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedQuickReplyButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedQuickReplyButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = reader.string(); + break; + case 2: + message.id = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedQuickReplyButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HydratedQuickReplyButton message. + * @function verify + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HydratedQuickReplyButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) + if (!$util.isString(message.displayText)) + return "displayText: string expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + return null; + }; + + /** + * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {Object.} object Plain object + * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton + */ + HydratedQuickReplyButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HydratedQuickReplyButton) + return object; + var message = new $root.proto.HydratedQuickReplyButton(); + if (object.displayText != null) + message.displayText = String(object.displayText); + if (object.id != null) + message.id = String(object.id); + return message; + }; + + /** + * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {proto.HydratedQuickReplyButton} message HydratedQuickReplyButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HydratedQuickReplyButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.displayText = ""; + object.id = ""; + } + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = message.displayText; + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + return object; + }; + + /** + * Converts this HydratedQuickReplyButton to JSON. + * @function toJSON + * @memberof proto.HydratedQuickReplyButton + * @instance + * @returns {Object.} JSON object + */ + HydratedQuickReplyButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HydratedQuickReplyButton; + })(); + + proto.HydratedURLButton = (function() { + + /** + * Properties of a HydratedURLButton. + * @memberof proto + * @interface IHydratedURLButton + * @property {string|null} [displayText] HydratedURLButton displayText + * @property {string|null} [url] HydratedURLButton url + */ + + /** + * Constructs a new HydratedURLButton. + * @memberof proto + * @classdesc Represents a HydratedURLButton. + * @implements IHydratedURLButton + * @constructor + * @param {proto.IHydratedURLButton=} [properties] Properties to set + */ + function HydratedURLButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HydratedURLButton displayText. + * @member {string} displayText + * @memberof proto.HydratedURLButton + * @instance + */ + HydratedURLButton.prototype.displayText = ""; + + /** + * HydratedURLButton url. + * @member {string} url + * @memberof proto.HydratedURLButton + * @instance + */ + HydratedURLButton.prototype.url = ""; + + /** + * Creates a new HydratedURLButton instance using the specified properties. + * @function create + * @memberof proto.HydratedURLButton + * @static + * @param {proto.IHydratedURLButton=} [properties] Properties to set + * @returns {proto.HydratedURLButton} HydratedURLButton instance + */ + HydratedURLButton.create = function create(properties) { + return new HydratedURLButton(properties); + }; + + /** + * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. + * @function encode + * @memberof proto.HydratedURLButton + * @static + * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedURLButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); + if (message.url != null && Object.hasOwnProperty.call(message, "url")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.url); + return writer; + }; + + /** + * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HydratedURLButton + * @static + * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedURLButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HydratedURLButton message from the specified reader or buffer. + * @function decode + * @memberof proto.HydratedURLButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HydratedURLButton} HydratedURLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedURLButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedURLButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = reader.string(); + break; + case 2: + message.url = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HydratedURLButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HydratedURLButton} HydratedURLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedURLButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HydratedURLButton message. + * @function verify + * @memberof proto.HydratedURLButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HydratedURLButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) + if (!$util.isString(message.displayText)) + return "displayText: string expected"; + if (message.url != null && message.hasOwnProperty("url")) + if (!$util.isString(message.url)) + return "url: string expected"; + return null; + }; + + /** + * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HydratedURLButton + * @static + * @param {Object.} object Plain object + * @returns {proto.HydratedURLButton} HydratedURLButton + */ + HydratedURLButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HydratedURLButton) + return object; + var message = new $root.proto.HydratedURLButton(); + if (object.displayText != null) + message.displayText = String(object.displayText); + if (object.url != null) + message.url = String(object.url); + return message; + }; + + /** + * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HydratedURLButton + * @static + * @param {proto.HydratedURLButton} message HydratedURLButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HydratedURLButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.displayText = ""; + object.url = ""; + } + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = message.displayText; + if (message.url != null && message.hasOwnProperty("url")) + object.url = message.url; + return object; + }; + + /** + * Converts this HydratedURLButton to JSON. + * @function toJSON + * @memberof proto.HydratedURLButton + * @instance + * @returns {Object.} JSON object + */ + HydratedURLButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HydratedURLButton; + })(); + + proto.HydratedCallButton = (function() { + + /** + * Properties of a HydratedCallButton. + * @memberof proto + * @interface IHydratedCallButton + * @property {string|null} [displayText] HydratedCallButton displayText + * @property {string|null} [phoneNumber] HydratedCallButton phoneNumber + */ + + /** + * Constructs a new HydratedCallButton. + * @memberof proto + * @classdesc Represents a HydratedCallButton. + * @implements IHydratedCallButton + * @constructor + * @param {proto.IHydratedCallButton=} [properties] Properties to set + */ + function HydratedCallButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HydratedCallButton displayText. + * @member {string} displayText + * @memberof proto.HydratedCallButton + * @instance + */ + HydratedCallButton.prototype.displayText = ""; + + /** + * HydratedCallButton phoneNumber. + * @member {string} phoneNumber + * @memberof proto.HydratedCallButton + * @instance + */ + HydratedCallButton.prototype.phoneNumber = ""; + + /** + * Creates a new HydratedCallButton instance using the specified properties. + * @function create + * @memberof proto.HydratedCallButton + * @static + * @param {proto.IHydratedCallButton=} [properties] Properties to set + * @returns {proto.HydratedCallButton} HydratedCallButton instance + */ + HydratedCallButton.create = function create(properties) { + return new HydratedCallButton(properties); + }; + + /** + * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. + * @function encode + * @memberof proto.HydratedCallButton + * @static + * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedCallButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); + if (message.phoneNumber != null && Object.hasOwnProperty.call(message, "phoneNumber")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.phoneNumber); + return writer; + }; + + /** + * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HydratedCallButton + * @static + * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedCallButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HydratedCallButton message from the specified reader or buffer. + * @function decode + * @memberof proto.HydratedCallButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HydratedCallButton} HydratedCallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedCallButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedCallButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = reader.string(); + break; + case 2: + message.phoneNumber = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HydratedCallButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HydratedCallButton} HydratedCallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedCallButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HydratedCallButton message. + * @function verify + * @memberof proto.HydratedCallButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HydratedCallButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) + if (!$util.isString(message.displayText)) + return "displayText: string expected"; + if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) + if (!$util.isString(message.phoneNumber)) + return "phoneNumber: string expected"; + return null; + }; + + /** + * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HydratedCallButton + * @static + * @param {Object.} object Plain object + * @returns {proto.HydratedCallButton} HydratedCallButton + */ + HydratedCallButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HydratedCallButton) + return object; + var message = new $root.proto.HydratedCallButton(); + if (object.displayText != null) + message.displayText = String(object.displayText); + if (object.phoneNumber != null) + message.phoneNumber = String(object.phoneNumber); + return message; + }; + + /** + * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HydratedCallButton + * @static + * @param {proto.HydratedCallButton} message HydratedCallButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HydratedCallButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.displayText = ""; + object.phoneNumber = ""; + } + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = message.displayText; + if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) + object.phoneNumber = message.phoneNumber; + return object; + }; + + /** + * Converts this HydratedCallButton to JSON. + * @function toJSON + * @memberof proto.HydratedCallButton + * @instance + * @returns {Object.} JSON object + */ + HydratedCallButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HydratedCallButton; + })(); + + proto.HydratedTemplateButton = (function() { + + /** + * Properties of a HydratedTemplateButton. + * @memberof proto + * @interface IHydratedTemplateButton + * @property {number|null} [index] HydratedTemplateButton index + * @property {proto.IHydratedQuickReplyButton|null} [quickReplyButton] HydratedTemplateButton quickReplyButton + * @property {proto.IHydratedURLButton|null} [urlButton] HydratedTemplateButton urlButton + * @property {proto.IHydratedCallButton|null} [callButton] HydratedTemplateButton callButton + */ + + /** + * Constructs a new HydratedTemplateButton. + * @memberof proto + * @classdesc Represents a HydratedTemplateButton. + * @implements IHydratedTemplateButton + * @constructor + * @param {proto.IHydratedTemplateButton=} [properties] Properties to set + */ + function HydratedTemplateButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HydratedTemplateButton index. + * @member {number} index + * @memberof proto.HydratedTemplateButton + * @instance + */ + HydratedTemplateButton.prototype.index = 0; + + /** + * HydratedTemplateButton quickReplyButton. + * @member {proto.IHydratedQuickReplyButton|null|undefined} quickReplyButton + * @memberof proto.HydratedTemplateButton + * @instance + */ + HydratedTemplateButton.prototype.quickReplyButton = null; + + /** + * HydratedTemplateButton urlButton. + * @member {proto.IHydratedURLButton|null|undefined} urlButton + * @memberof proto.HydratedTemplateButton + * @instance + */ + HydratedTemplateButton.prototype.urlButton = null; + + /** + * HydratedTemplateButton callButton. + * @member {proto.IHydratedCallButton|null|undefined} callButton + * @memberof proto.HydratedTemplateButton + * @instance + */ + HydratedTemplateButton.prototype.callButton = null; + + // OneOf field names bound to virtual getters and setters + var $oneOfFields; + + /** + * HydratedTemplateButton hydratedButton. + * @member {"quickReplyButton"|"urlButton"|"callButton"|undefined} hydratedButton + * @memberof proto.HydratedTemplateButton + * @instance + */ + Object.defineProperty(HydratedTemplateButton.prototype, "hydratedButton", { + get: $util.oneOfGetter($oneOfFields = ["quickReplyButton", "urlButton", "callButton"]), + set: $util.oneOfSetter($oneOfFields) + }); + + /** + * Creates a new HydratedTemplateButton instance using the specified properties. + * @function create + * @memberof proto.HydratedTemplateButton + * @static + * @param {proto.IHydratedTemplateButton=} [properties] Properties to set + * @returns {proto.HydratedTemplateButton} HydratedTemplateButton instance + */ + HydratedTemplateButton.create = function create(properties) { + return new HydratedTemplateButton(properties); + }; + + /** + * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. + * @function encode + * @memberof proto.HydratedTemplateButton + * @static + * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedTemplateButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.quickReplyButton != null && Object.hasOwnProperty.call(message, "quickReplyButton")) + $root.proto.HydratedQuickReplyButton.encode(message.quickReplyButton, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.urlButton != null && Object.hasOwnProperty.call(message, "urlButton")) + $root.proto.HydratedURLButton.encode(message.urlButton, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.callButton != null && Object.hasOwnProperty.call(message, "callButton")) + $root.proto.HydratedCallButton.encode(message.callButton, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.index != null && Object.hasOwnProperty.call(message, "index")) + writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.index); + return writer; + }; + + /** + * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HydratedTemplateButton + * @static + * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedTemplateButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HydratedTemplateButton message from the specified reader or buffer. + * @function decode + * @memberof proto.HydratedTemplateButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HydratedTemplateButton} HydratedTemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedTemplateButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedTemplateButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 4: + message.index = reader.uint32(); + break; + case 1: + message.quickReplyButton = $root.proto.HydratedQuickReplyButton.decode(reader, reader.uint32()); + break; + case 2: + message.urlButton = $root.proto.HydratedURLButton.decode(reader, reader.uint32()); + break; + case 3: + message.callButton = $root.proto.HydratedCallButton.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HydratedTemplateButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HydratedTemplateButton} HydratedTemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedTemplateButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HydratedTemplateButton message. + * @function verify + * @memberof proto.HydratedTemplateButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HydratedTemplateButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var properties = {}; + if (message.index != null && message.hasOwnProperty("index")) + if (!$util.isInteger(message.index)) + return "index: integer expected"; + if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { + properties.hydratedButton = 1; + { + var error = $root.proto.HydratedQuickReplyButton.verify(message.quickReplyButton); + if (error) + return "quickReplyButton." + error; + } + } + if (message.urlButton != null && message.hasOwnProperty("urlButton")) { + if (properties.hydratedButton === 1) + return "hydratedButton: multiple values"; + properties.hydratedButton = 1; + { + var error = $root.proto.HydratedURLButton.verify(message.urlButton); + if (error) + return "urlButton." + error; + } + } + if (message.callButton != null && message.hasOwnProperty("callButton")) { + if (properties.hydratedButton === 1) + return "hydratedButton: multiple values"; + properties.hydratedButton = 1; + { + var error = $root.proto.HydratedCallButton.verify(message.callButton); + if (error) + return "callButton." + error; + } + } + return null; + }; + + /** + * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HydratedTemplateButton + * @static + * @param {Object.} object Plain object + * @returns {proto.HydratedTemplateButton} HydratedTemplateButton + */ + HydratedTemplateButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HydratedTemplateButton) + return object; + var message = new $root.proto.HydratedTemplateButton(); + if (object.index != null) + message.index = object.index >>> 0; + if (object.quickReplyButton != null) { + if (typeof object.quickReplyButton !== "object") + throw TypeError(".proto.HydratedTemplateButton.quickReplyButton: object expected"); + message.quickReplyButton = $root.proto.HydratedQuickReplyButton.fromObject(object.quickReplyButton); + } + if (object.urlButton != null) { + if (typeof object.urlButton !== "object") + throw TypeError(".proto.HydratedTemplateButton.urlButton: object expected"); + message.urlButton = $root.proto.HydratedURLButton.fromObject(object.urlButton); + } + if (object.callButton != null) { + if (typeof object.callButton !== "object") + throw TypeError(".proto.HydratedTemplateButton.callButton: object expected"); + message.callButton = $root.proto.HydratedCallButton.fromObject(object.callButton); + } + return message; + }; + + /** + * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HydratedTemplateButton + * @static + * @param {proto.HydratedTemplateButton} message HydratedTemplateButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HydratedTemplateButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.index = 0; + if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { + object.quickReplyButton = $root.proto.HydratedQuickReplyButton.toObject(message.quickReplyButton, options); + if (options.oneofs) + object.hydratedButton = "quickReplyButton"; + } + if (message.urlButton != null && message.hasOwnProperty("urlButton")) { + object.urlButton = $root.proto.HydratedURLButton.toObject(message.urlButton, options); + if (options.oneofs) + object.hydratedButton = "urlButton"; + } + if (message.callButton != null && message.hasOwnProperty("callButton")) { + object.callButton = $root.proto.HydratedCallButton.toObject(message.callButton, options); + if (options.oneofs) + object.hydratedButton = "callButton"; + } + if (message.index != null && message.hasOwnProperty("index")) + object.index = message.index; + return object; + }; + + /** + * Converts this HydratedTemplateButton to JSON. + * @function toJSON + * @memberof proto.HydratedTemplateButton + * @instance + * @returns {Object.} JSON object + */ + HydratedTemplateButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HydratedTemplateButton; + })(); + + proto.UserReceipt = (function() { + + /** + * Properties of a UserReceipt. + * @memberof proto + * @interface IUserReceipt + * @property {string} userJid UserReceipt userJid + * @property {number|Long|null} [receiptTimestamp] UserReceipt receiptTimestamp + * @property {number|Long|null} [readTimestamp] UserReceipt readTimestamp + * @property {number|Long|null} [playedTimestamp] UserReceipt playedTimestamp + * @property {Array.|null} [pendingDeviceJid] UserReceipt pendingDeviceJid + * @property {Array.|null} [deliveredDeviceJid] UserReceipt deliveredDeviceJid + */ + + /** + * Constructs a new UserReceipt. + * @memberof proto + * @classdesc Represents a UserReceipt. + * @implements IUserReceipt + * @constructor + * @param {proto.IUserReceipt=} [properties] Properties to set + */ + function UserReceipt(properties) { + this.pendingDeviceJid = []; + this.deliveredDeviceJid = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * UserReceipt userJid. + * @member {string} userJid + * @memberof proto.UserReceipt + * @instance + */ + UserReceipt.prototype.userJid = ""; + + /** + * UserReceipt receiptTimestamp. + * @member {number|Long} receiptTimestamp + * @memberof proto.UserReceipt + * @instance + */ + UserReceipt.prototype.receiptTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * UserReceipt readTimestamp. + * @member {number|Long} readTimestamp + * @memberof proto.UserReceipt + * @instance + */ + UserReceipt.prototype.readTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * UserReceipt playedTimestamp. + * @member {number|Long} playedTimestamp + * @memberof proto.UserReceipt + * @instance + */ + UserReceipt.prototype.playedTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * UserReceipt pendingDeviceJid. + * @member {Array.} pendingDeviceJid + * @memberof proto.UserReceipt + * @instance + */ + UserReceipt.prototype.pendingDeviceJid = $util.emptyArray; + + /** + * UserReceipt deliveredDeviceJid. + * @member {Array.} deliveredDeviceJid + * @memberof proto.UserReceipt + * @instance + */ + UserReceipt.prototype.deliveredDeviceJid = $util.emptyArray; + + /** + * Creates a new UserReceipt instance using the specified properties. + * @function create + * @memberof proto.UserReceipt + * @static + * @param {proto.IUserReceipt=} [properties] Properties to set + * @returns {proto.UserReceipt} UserReceipt instance + */ + UserReceipt.create = function create(properties) { + return new UserReceipt(properties); + }; + + /** + * Encodes the specified UserReceipt message. Does not implicitly {@link proto.UserReceipt.verify|verify} messages. + * @function encode + * @memberof proto.UserReceipt + * @static + * @param {proto.IUserReceipt} message UserReceipt message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UserReceipt.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + writer.uint32(/* id 1, wireType 2 =*/10).string(message.userJid); + if (message.receiptTimestamp != null && Object.hasOwnProperty.call(message, "receiptTimestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.receiptTimestamp); + if (message.readTimestamp != null && Object.hasOwnProperty.call(message, "readTimestamp")) + writer.uint32(/* id 3, wireType 0 =*/24).int64(message.readTimestamp); + if (message.playedTimestamp != null && Object.hasOwnProperty.call(message, "playedTimestamp")) + writer.uint32(/* id 4, wireType 0 =*/32).int64(message.playedTimestamp); + if (message.pendingDeviceJid != null && message.pendingDeviceJid.length) + for (var i = 0; i < message.pendingDeviceJid.length; ++i) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.pendingDeviceJid[i]); + if (message.deliveredDeviceJid != null && message.deliveredDeviceJid.length) + for (var i = 0; i < message.deliveredDeviceJid.length; ++i) + writer.uint32(/* id 6, wireType 2 =*/50).string(message.deliveredDeviceJid[i]); + return writer; + }; + + /** + * Encodes the specified UserReceipt message, length delimited. Does not implicitly {@link proto.UserReceipt.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.UserReceipt + * @static + * @param {proto.IUserReceipt} message UserReceipt message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UserReceipt.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a UserReceipt message from the specified reader or buffer. + * @function decode + * @memberof proto.UserReceipt + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.UserReceipt} UserReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UserReceipt.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.UserReceipt(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.userJid = reader.string(); + break; + case 2: + message.receiptTimestamp = reader.int64(); + break; + case 3: + message.readTimestamp = reader.int64(); + break; + case 4: + message.playedTimestamp = reader.int64(); + break; + case 5: + if (!(message.pendingDeviceJid && message.pendingDeviceJid.length)) + message.pendingDeviceJid = []; + message.pendingDeviceJid.push(reader.string()); + break; + case 6: + if (!(message.deliveredDeviceJid && message.deliveredDeviceJid.length)) + message.deliveredDeviceJid = []; + message.deliveredDeviceJid.push(reader.string()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + if (!message.hasOwnProperty("userJid")) + throw $util.ProtocolError("missing required 'userJid'", { instance: message }); + return message; + }; + + /** + * Decodes a UserReceipt message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.UserReceipt + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.UserReceipt} UserReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UserReceipt.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a UserReceipt message. + * @function verify + * @memberof proto.UserReceipt + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + UserReceipt.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isString(message.userJid)) + return "userJid: string expected"; + if (message.receiptTimestamp != null && message.hasOwnProperty("receiptTimestamp")) + if (!$util.isInteger(message.receiptTimestamp) && !(message.receiptTimestamp && $util.isInteger(message.receiptTimestamp.low) && $util.isInteger(message.receiptTimestamp.high))) + return "receiptTimestamp: integer|Long expected"; + if (message.readTimestamp != null && message.hasOwnProperty("readTimestamp")) + if (!$util.isInteger(message.readTimestamp) && !(message.readTimestamp && $util.isInteger(message.readTimestamp.low) && $util.isInteger(message.readTimestamp.high))) + return "readTimestamp: integer|Long expected"; + if (message.playedTimestamp != null && message.hasOwnProperty("playedTimestamp")) + if (!$util.isInteger(message.playedTimestamp) && !(message.playedTimestamp && $util.isInteger(message.playedTimestamp.low) && $util.isInteger(message.playedTimestamp.high))) + return "playedTimestamp: integer|Long expected"; + if (message.pendingDeviceJid != null && message.hasOwnProperty("pendingDeviceJid")) { + if (!Array.isArray(message.pendingDeviceJid)) + return "pendingDeviceJid: array expected"; + for (var i = 0; i < message.pendingDeviceJid.length; ++i) + if (!$util.isString(message.pendingDeviceJid[i])) + return "pendingDeviceJid: string[] expected"; + } + if (message.deliveredDeviceJid != null && message.hasOwnProperty("deliveredDeviceJid")) { + if (!Array.isArray(message.deliveredDeviceJid)) + return "deliveredDeviceJid: array expected"; + for (var i = 0; i < message.deliveredDeviceJid.length; ++i) + if (!$util.isString(message.deliveredDeviceJid[i])) + return "deliveredDeviceJid: string[] expected"; + } + return null; + }; + + /** + * Creates a UserReceipt message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.UserReceipt + * @static + * @param {Object.} object Plain object + * @returns {proto.UserReceipt} UserReceipt + */ + UserReceipt.fromObject = function fromObject(object) { + if (object instanceof $root.proto.UserReceipt) + return object; + var message = new $root.proto.UserReceipt(); + if (object.userJid != null) + message.userJid = String(object.userJid); + if (object.receiptTimestamp != null) + if ($util.Long) + (message.receiptTimestamp = $util.Long.fromValue(object.receiptTimestamp)).unsigned = false; + else if (typeof object.receiptTimestamp === "string") + message.receiptTimestamp = parseInt(object.receiptTimestamp, 10); + else if (typeof object.receiptTimestamp === "number") + message.receiptTimestamp = object.receiptTimestamp; + else if (typeof object.receiptTimestamp === "object") + message.receiptTimestamp = new $util.LongBits(object.receiptTimestamp.low >>> 0, object.receiptTimestamp.high >>> 0).toNumber(); + if (object.readTimestamp != null) + if ($util.Long) + (message.readTimestamp = $util.Long.fromValue(object.readTimestamp)).unsigned = false; + else if (typeof object.readTimestamp === "string") + message.readTimestamp = parseInt(object.readTimestamp, 10); + else if (typeof object.readTimestamp === "number") + message.readTimestamp = object.readTimestamp; + else if (typeof object.readTimestamp === "object") + message.readTimestamp = new $util.LongBits(object.readTimestamp.low >>> 0, object.readTimestamp.high >>> 0).toNumber(); + if (object.playedTimestamp != null) + if ($util.Long) + (message.playedTimestamp = $util.Long.fromValue(object.playedTimestamp)).unsigned = false; + else if (typeof object.playedTimestamp === "string") + message.playedTimestamp = parseInt(object.playedTimestamp, 10); + else if (typeof object.playedTimestamp === "number") + message.playedTimestamp = object.playedTimestamp; + else if (typeof object.playedTimestamp === "object") + message.playedTimestamp = new $util.LongBits(object.playedTimestamp.low >>> 0, object.playedTimestamp.high >>> 0).toNumber(); + if (object.pendingDeviceJid) { + if (!Array.isArray(object.pendingDeviceJid)) + throw TypeError(".proto.UserReceipt.pendingDeviceJid: array expected"); + message.pendingDeviceJid = []; + for (var i = 0; i < object.pendingDeviceJid.length; ++i) + message.pendingDeviceJid[i] = String(object.pendingDeviceJid[i]); + } + if (object.deliveredDeviceJid) { + if (!Array.isArray(object.deliveredDeviceJid)) + throw TypeError(".proto.UserReceipt.deliveredDeviceJid: array expected"); + message.deliveredDeviceJid = []; + for (var i = 0; i < object.deliveredDeviceJid.length; ++i) + message.deliveredDeviceJid[i] = String(object.deliveredDeviceJid[i]); + } + return message; + }; + + /** + * Creates a plain object from a UserReceipt message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.UserReceipt + * @static + * @param {proto.UserReceipt} message UserReceipt + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + UserReceipt.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.pendingDeviceJid = []; + object.deliveredDeviceJid = []; + } + if (options.defaults) { + object.userJid = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.receiptTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.receiptTimestamp = options.longs === String ? "0" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.readTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.readTimestamp = options.longs === String ? "0" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.playedTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.playedTimestamp = options.longs === String ? "0" : 0; + } + if (message.userJid != null && message.hasOwnProperty("userJid")) + object.userJid = message.userJid; + if (message.receiptTimestamp != null && message.hasOwnProperty("receiptTimestamp")) + if (typeof message.receiptTimestamp === "number") + object.receiptTimestamp = options.longs === String ? String(message.receiptTimestamp) : message.receiptTimestamp; + else + object.receiptTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.receiptTimestamp) : options.longs === Number ? new $util.LongBits(message.receiptTimestamp.low >>> 0, message.receiptTimestamp.high >>> 0).toNumber() : message.receiptTimestamp; + if (message.readTimestamp != null && message.hasOwnProperty("readTimestamp")) + if (typeof message.readTimestamp === "number") + object.readTimestamp = options.longs === String ? String(message.readTimestamp) : message.readTimestamp; + else + object.readTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.readTimestamp) : options.longs === Number ? new $util.LongBits(message.readTimestamp.low >>> 0, message.readTimestamp.high >>> 0).toNumber() : message.readTimestamp; + if (message.playedTimestamp != null && message.hasOwnProperty("playedTimestamp")) + if (typeof message.playedTimestamp === "number") + object.playedTimestamp = options.longs === String ? String(message.playedTimestamp) : message.playedTimestamp; + else + object.playedTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.playedTimestamp) : options.longs === Number ? new $util.LongBits(message.playedTimestamp.low >>> 0, message.playedTimestamp.high >>> 0).toNumber() : message.playedTimestamp; + if (message.pendingDeviceJid && message.pendingDeviceJid.length) { + object.pendingDeviceJid = []; + for (var j = 0; j < message.pendingDeviceJid.length; ++j) + object.pendingDeviceJid[j] = message.pendingDeviceJid[j]; + } + if (message.deliveredDeviceJid && message.deliveredDeviceJid.length) { + object.deliveredDeviceJid = []; + for (var j = 0; j < message.deliveredDeviceJid.length; ++j) + object.deliveredDeviceJid[j] = message.deliveredDeviceJid[j]; + } + return object; + }; + + /** + * Converts this UserReceipt to JSON. + * @function toJSON + * @memberof proto.UserReceipt + * @instance + * @returns {Object.} JSON object + */ + UserReceipt.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return UserReceipt; })(); proto.PhotoChange = (function() { @@ -46348,6 +29260,7 @@ $root.proto = (function() { * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeralAllowGroupMembers] WebFeatures ephemeralAllowGroupMembers * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeral24HDuration] WebFeatures ephemeral24HDuration * @property {proto.WebFeatures.WebFeaturesFlag|null} [mdForceUpgrade] WebFeatures mdForceUpgrade + * @property {proto.WebFeatures.WebFeaturesFlag|null} [disappearingMode] WebFeatures disappearingMode */ /** @@ -46701,6 +29614,14 @@ $root.proto = (function() { */ WebFeatures.prototype.mdForceUpgrade = 0; + /** + * WebFeatures disappearingMode. + * @member {proto.WebFeatures.WebFeaturesFlag} disappearingMode + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.disappearingMode = 0; + /** * Creates a new WebFeatures instance using the specified properties. * @function create @@ -46809,6 +29730,8 @@ $root.proto = (function() { writer.uint32(/* id 45, wireType 0 =*/360).int32(message.ephemeral24HDuration); if (message.mdForceUpgrade != null && Object.hasOwnProperty.call(message, "mdForceUpgrade")) writer.uint32(/* id 46, wireType 0 =*/368).int32(message.mdForceUpgrade); + if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode")) + writer.uint32(/* id 47, wireType 0 =*/376).int32(message.disappearingMode); return writer; }; @@ -46969,6 +29892,9 @@ $root.proto = (function() { case 46: message.mdForceUpgrade = reader.int32(); break; + case 47: + message.disappearingMode = reader.int32(); + break; default: reader.skipType(tag & 7); break; @@ -47424,6 +30350,16 @@ $root.proto = (function() { case 3: break; } + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) + switch (message.disappearingMode) { + default: + return "disappearingMode: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } return null; }; @@ -48195,6 +31131,24 @@ $root.proto = (function() { message.mdForceUpgrade = 3; break; } + switch (object.disappearingMode) { + case "NOT_STARTED": + case 0: + message.disappearingMode = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.disappearingMode = 1; + break; + case "DEVELOPMENT": + case 2: + message.disappearingMode = 2; + break; + case "PRODUCTION": + case 3: + message.disappearingMode = 3; + break; + } return message; }; @@ -48254,6 +31208,7 @@ $root.proto = (function() { object.ephemeralAllowGroupMembers = options.enums === String ? "NOT_STARTED" : 0; object.ephemeral24HDuration = options.enums === String ? "NOT_STARTED" : 0; object.mdForceUpgrade = options.enums === String ? "NOT_STARTED" : 0; + object.disappearingMode = options.enums === String ? "NOT_STARTED" : 0; } if (message.labelsDisplay != null && message.hasOwnProperty("labelsDisplay")) object.labelsDisplay = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.labelsDisplay] : message.labelsDisplay; @@ -48339,6 +31294,8 @@ $root.proto = (function() { object.ephemeral24HDuration = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.ephemeral24HDuration] : message.ephemeral24HDuration; if (message.mdForceUpgrade != null && message.hasOwnProperty("mdForceUpgrade")) object.mdForceUpgrade = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.mdForceUpgrade] : message.mdForceUpgrade; + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) + object.disappearingMode = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.disappearingMode] : message.disappearingMode; return object; }; @@ -49827,6 +32784,7 @@ $root.proto = (function() { * @property {string|null} [verifiedBizName] WebMessageInfo verifiedBizName * @property {proto.IMediaData|null} [mediaData] WebMessageInfo mediaData * @property {proto.IPhotoChange|null} [photoChange] WebMessageInfo photoChange + * @property {Array.|null} [userReceipt] WebMessageInfo userReceipt */ /** @@ -49840,6 +32798,7 @@ $root.proto = (function() { function WebMessageInfo(properties) { this.messageStubParameters = []; this.labels = []; + this.userReceipt = []; if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -50086,6 +33045,14 @@ $root.proto = (function() { */ WebMessageInfo.prototype.photoChange = null; + /** + * WebMessageInfo userReceipt. + * @member {Array.} userReceipt + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.userReceipt = $util.emptyArray; + /** * Creates a new WebMessageInfo instance using the specified properties. * @function create @@ -50171,6 +33138,9 @@ $root.proto = (function() { $root.proto.MediaData.encode(message.mediaData, writer.uint32(/* id 38, wireType 2 =*/306).fork()).ldelim(); if (message.photoChange != null && Object.hasOwnProperty.call(message, "photoChange")) $root.proto.PhotoChange.encode(message.photoChange, writer.uint32(/* id 39, wireType 2 =*/314).fork()).ldelim(); + if (message.userReceipt != null && message.userReceipt.length) + for (var i = 0; i < message.userReceipt.length; ++i) + $root.proto.UserReceipt.encode(message.userReceipt[i], writer.uint32(/* id 40, wireType 2 =*/322).fork()).ldelim(); return writer; }; @@ -50299,6 +33269,11 @@ $root.proto = (function() { case 39: message.photoChange = $root.proto.PhotoChange.decode(reader, reader.uint32()); break; + case 40: + if (!(message.userReceipt && message.userReceipt.length)) + message.userReceipt = []; + message.userReceipt.push($root.proto.UserReceipt.decode(reader, reader.uint32())); + break; default: reader.skipType(tag & 7); break; @@ -50525,6 +33500,7 @@ $root.proto = (function() { case 127: case 128: case 129: + case 130: break; } if (message.clearMedia != null && message.hasOwnProperty("clearMedia")) @@ -50597,6 +33573,15 @@ $root.proto = (function() { if (error) return "photoChange." + error; } + if (message.userReceipt != null && message.hasOwnProperty("userReceipt")) { + if (!Array.isArray(message.userReceipt)) + return "userReceipt: array expected"; + for (var i = 0; i < message.userReceipt.length; ++i) { + var error = $root.proto.UserReceipt.verify(message.userReceipt[i]); + if (error) + return "userReceipt." + error; + } + } return null; }; @@ -51208,6 +34193,10 @@ $root.proto = (function() { case 129: message.messageStubType = 129; break; + case "DISAPPEARING_MODE": + case 130: + message.messageStubType = 130; + break; } if (object.clearMedia != null) message.clearMedia = Boolean(object.clearMedia); @@ -51287,6 +34276,16 @@ $root.proto = (function() { throw TypeError(".proto.WebMessageInfo.photoChange: object expected"); message.photoChange = $root.proto.PhotoChange.fromObject(object.photoChange); } + if (object.userReceipt) { + if (!Array.isArray(object.userReceipt)) + throw TypeError(".proto.WebMessageInfo.userReceipt: array expected"); + message.userReceipt = []; + for (var i = 0; i < object.userReceipt.length; ++i) { + if (typeof object.userReceipt[i] !== "object") + throw TypeError(".proto.WebMessageInfo.userReceipt: object expected"); + message.userReceipt[i] = $root.proto.UserReceipt.fromObject(object.userReceipt[i]); + } + } return message; }; @@ -51306,6 +34305,7 @@ $root.proto = (function() { if (options.arrays || options.defaults) { object.messageStubParameters = []; object.labels = []; + object.userReceipt = []; } if (options.defaults) { object.key = null; @@ -51430,6 +34430,11 @@ $root.proto = (function() { object.mediaData = $root.proto.MediaData.toObject(message.mediaData, options); if (message.photoChange != null && message.hasOwnProperty("photoChange")) object.photoChange = $root.proto.PhotoChange.toObject(message.photoChange, options); + if (message.userReceipt && message.userReceipt.length) { + object.userReceipt = []; + for (var j = 0; j < message.userReceipt.length; ++j) + object.userReceipt[j] = $root.proto.UserReceipt.toObject(message.userReceipt[j], options); + } return object; }; @@ -51600,6 +34605,7 @@ $root.proto = (function() { * @property {number} BIZ_PRIVACY_MODE_INIT_BSP=127 BIZ_PRIVACY_MODE_INIT_BSP value * @property {number} BIZ_PRIVACY_MODE_TO_FB=128 BIZ_PRIVACY_MODE_TO_FB value * @property {number} BIZ_PRIVACY_MODE_TO_BSP=129 BIZ_PRIVACY_MODE_TO_BSP value + * @property {number} DISAPPEARING_MODE=130 DISAPPEARING_MODE value */ WebMessageInfo.WebMessageInfoStubType = (function() { var valuesById = {}, values = Object.create(valuesById); @@ -51733,6 +34739,7 @@ $root.proto = (function() { values[valuesById[127] = "BIZ_PRIVACY_MODE_INIT_BSP"] = 127; values[valuesById[128] = "BIZ_PRIVACY_MODE_TO_FB"] = 128; values[valuesById[129] = "BIZ_PRIVACY_MODE_TO_BSP"] = 129; + values[valuesById[130] = "DISAPPEARING_MODE"] = 130; return values; })(); @@ -51760,4 +34767,4 @@ $root.proto = (function() { return proto; })(); -module.exports = $root; \ No newline at end of file +module.exports = $root; diff --git a/package.json b/package.json index b62abca..1a277fd 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "build:docs": "typedoc", "build:tsc": "tsc", "example": "node --inspect -r ts-node/register Example/example.ts", - "gen-protobuf": "bash src/Binary/GenerateStatics.sh", + "gen-protobuf": "bash src/BinaryNode/GenerateStatics.sh", "browser-decode": "yarn ts-node src/BrowserMessageDecoding.ts" }, "author": "Adhiraj Singh", diff --git a/src/BinaryNode/GenerateStatics.sh b/src/BinaryNode/GenerateStatics.sh index 3c8c85b..295f6bb 100644 --- a/src/BinaryNode/GenerateStatics.sh +++ b/src/BinaryNode/GenerateStatics.sh @@ -1,4 +1,4 @@ -yarn pbjs -t static-module -w commonjs -o ./WAMessage/WAMessage.js ./src/Binary/WAMessage.proto; -yarn pbts -o ./WAMessage/WAMessage.d.ts ./WAMessage/WAMessage.js; +yarn pbjs -t static-module -w commonjs -o ./WAMessage/index.js ./src/BinaryNode/WAMessage.proto; +yarn pbts -o ./WAMessage/index.d.ts ./WAMessage/index.js; #protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_opt=env=node,useOptionals=true,forceLong=long --ts_proto_out=. ./src/Binary/WAMessage.proto; \ No newline at end of file diff --git a/src/BinaryNode/WAMessage.proto b/src/BinaryNode/WAMessage.proto index e5313bd..98cd6ec 100644 --- a/src/BinaryNode/WAMessage.proto +++ b/src/BinaryNode/WAMessage.proto @@ -1,6 +1,914 @@ syntax = "proto2"; package proto; +message MessageKey { + optional string remoteJid = 1; + optional bool fromMe = 2; + optional string id = 3; + optional string participant = 4; +} + +message QuickReplyButton { + optional HighlyStructuredMessage displayText = 1; + optional string id = 2; +} + +message URLButton { + optional HighlyStructuredMessage displayText = 1; + optional HighlyStructuredMessage url = 2; +} + +message CallButton { + optional HighlyStructuredMessage displayText = 1; + optional HighlyStructuredMessage phoneNumber = 2; +} + +message TemplateButton { + optional uint32 index = 4; + oneof button { + QuickReplyButton quickReplyButton = 1; + URLButton urlButton = 2; + CallButton callButton = 3; + } +} + +message Location { + optional double degreesLatitude = 1; + optional double degreesLongitude = 2; + optional string name = 3; +} + +message Point { + optional int32 xDeprecated = 1; + optional int32 yDeprecated = 2; + optional double x = 3; + optional double y = 4; +} + +message InteractiveAnnotation { + repeated Point polygonVertices = 1; + oneof action { + Location location = 2; + } +} + +message DeviceListMetadata { + optional bytes senderKeyHash = 1; + optional uint64 senderTimestamp = 2; + repeated uint32 senderKeyIndexes = 3 [packed=true]; + optional bytes recipientKeyHash = 8; + optional uint64 recipientTimestamp = 9; + repeated uint32 recipientKeyIndexes = 10 [packed=true]; +} + +message MessageContextInfo { + optional DeviceListMetadata deviceListMetadata = 1; + optional int32 deviceListMetadataVersion = 2; +} + +message AdReplyInfo { + optional string advertiserName = 1; + enum AdReplyInfoMediaType { + NONE = 0; + IMAGE = 1; + VIDEO = 2; + } + optional AdReplyInfoMediaType mediaType = 2; + optional bytes jpegThumbnail = 16; + optional string caption = 17; +} + +message ExternalAdReplyInfo { + optional string title = 1; + optional string body = 2; + enum ExternalAdReplyInfoMediaType { + NONE = 0; + IMAGE = 1; + VIDEO = 2; + } + optional ExternalAdReplyInfoMediaType mediaType = 3; + optional string thumbnailUrl = 4; + optional string mediaUrl = 5; + optional bytes thumbnail = 6; + optional string sourceType = 7; + optional string sourceId = 8; + optional string sourceUrl = 9; +} + +message ContextInfo { + optional string stanzaId = 1; + optional string participant = 2; + optional Message quotedMessage = 3; + optional string remoteJid = 4; + repeated string mentionedJid = 15; + optional string conversionSource = 18; + optional bytes conversionData = 19; + optional uint32 conversionDelaySeconds = 20; + optional uint32 forwardingScore = 21; + optional bool isForwarded = 22; + optional AdReplyInfo quotedAd = 23; + optional MessageKey placeholderKey = 24; + optional uint32 expiration = 25; + optional int64 ephemeralSettingTimestamp = 26; + optional bytes ephemeralSharedSecret = 27; + optional ExternalAdReplyInfo externalAdReply = 28; + optional string entryPointConversionSource = 29; + optional string entryPointConversionApp = 30; + optional uint32 entryPointConversionDelaySeconds = 31; + optional DisappearingMode disappearingMode = 32; +} + +message SenderKeyDistributionMessage { + optional string groupId = 1; + optional bytes axolotlSenderKeyDistributionMessage = 2; +} + +message ImageMessage { + optional string url = 1; + optional string mimetype = 2; + optional string caption = 3; + optional bytes fileSha256 = 4; + optional uint64 fileLength = 5; + optional uint32 height = 6; + optional uint32 width = 7; + optional bytes mediaKey = 8; + optional bytes fileEncSha256 = 9; + repeated InteractiveAnnotation interactiveAnnotations = 10; + optional string directPath = 11; + optional int64 mediaKeyTimestamp = 12; + optional bytes jpegThumbnail = 16; + optional ContextInfo contextInfo = 17; + optional bytes firstScanSidecar = 18; + optional uint32 firstScanLength = 19; + optional uint32 experimentGroupId = 20; + optional bytes scansSidecar = 21; + repeated uint32 scanLengths = 22; + optional bytes midQualityFileSha256 = 23; + optional bytes midQualityFileEncSha256 = 24; + optional bool viewOnce = 25; + optional string thumbnailDirectPath = 26; + optional bytes thumbnailSha256 = 27; + optional bytes thumbnailEncSha256 = 28; + optional string staticUrl = 29; +} + +message InvoiceMessage { + optional string note = 1; + optional string token = 2; + enum InvoiceMessageAttachmentType { + IMAGE = 0; + PDF = 1; + } + optional InvoiceMessageAttachmentType attachmentType = 3; + optional string attachmentMimetype = 4; + optional bytes attachmentMediaKey = 5; + optional int64 attachmentMediaKeyTimestamp = 6; + optional bytes attachmentFileSha256 = 7; + optional bytes attachmentFileEncSha256 = 8; + optional string attachmentDirectPath = 9; + optional bytes attachmentJpegThumbnail = 10; +} + +message ContactMessage { + optional string displayName = 1; + optional string vcard = 16; + optional ContextInfo contextInfo = 17; +} + +message LocationMessage { + optional double degreesLatitude = 1; + optional double degreesLongitude = 2; + optional string name = 3; + optional string address = 4; + optional string url = 5; + optional bool isLive = 6; + optional uint32 accuracyInMeters = 7; + optional float speedInMps = 8; + optional uint32 degreesClockwiseFromMagneticNorth = 9; + optional string comment = 11; + optional bytes jpegThumbnail = 16; + optional ContextInfo contextInfo = 17; +} + +message ExtendedTextMessage { + optional string text = 1; + optional string matchedText = 2; + optional string canonicalUrl = 4; + optional string description = 5; + optional string title = 6; + optional fixed32 textArgb = 7; + optional fixed32 backgroundArgb = 8; + enum ExtendedTextMessageFontType { + SANS_SERIF = 0; + SERIF = 1; + NORICAN_REGULAR = 2; + BRYNDAN_WRITE = 3; + BEBASNEUE_REGULAR = 4; + OSWALD_HEAVY = 5; + } + optional ExtendedTextMessageFontType font = 9; + enum ExtendedTextMessagePreviewType { + NONE = 0; + VIDEO = 1; + } + optional ExtendedTextMessagePreviewType previewType = 10; + optional bytes jpegThumbnail = 16; + optional ContextInfo contextInfo = 17; + optional bool doNotPlayInline = 18; + optional string thumbnailDirectPath = 19; + optional bytes thumbnailSha256 = 20; + optional bytes thumbnailEncSha256 = 21; + optional bytes mediaKey = 22; + optional int64 mediaKeyTimestamp = 23; + optional uint32 thumbnailHeight = 24; + optional uint32 thumbnailWidth = 25; +} + +message DocumentMessage { + optional string url = 1; + optional string mimetype = 2; + optional string title = 3; + optional bytes fileSha256 = 4; + optional uint64 fileLength = 5; + optional uint32 pageCount = 6; + optional bytes mediaKey = 7; + optional string fileName = 8; + optional bytes fileEncSha256 = 9; + optional string directPath = 10; + optional int64 mediaKeyTimestamp = 11; + optional bool contactVcard = 12; + optional string thumbnailDirectPath = 13; + optional bytes thumbnailSha256 = 14; + optional bytes thumbnailEncSha256 = 15; + optional bytes jpegThumbnail = 16; + optional ContextInfo contextInfo = 17; + optional uint32 thumbnailHeight = 18; + optional uint32 thumbnailWidth = 19; +} + +message AudioMessage { + optional string url = 1; + optional string mimetype = 2; + optional bytes fileSha256 = 3; + optional uint64 fileLength = 4; + optional uint32 seconds = 5; + optional bool ptt = 6; + optional bytes mediaKey = 7; + optional bytes fileEncSha256 = 8; + optional string directPath = 9; + optional int64 mediaKeyTimestamp = 10; + optional ContextInfo contextInfo = 17; + optional bytes streamingSidecar = 18; +} + +message VideoMessage { + optional string url = 1; + optional string mimetype = 2; + optional bytes fileSha256 = 3; + optional uint64 fileLength = 4; + optional uint32 seconds = 5; + optional bytes mediaKey = 6; + optional string caption = 7; + optional bool gifPlayback = 8; + optional uint32 height = 9; + optional uint32 width = 10; + optional bytes fileEncSha256 = 11; + repeated InteractiveAnnotation interactiveAnnotations = 12; + optional string directPath = 13; + optional int64 mediaKeyTimestamp = 14; + optional bytes jpegThumbnail = 16; + optional ContextInfo contextInfo = 17; + optional bytes streamingSidecar = 18; + enum VideoMessageAttribution { + NONE = 0; + GIPHY = 1; + TENOR = 2; + } + optional VideoMessageAttribution gifAttribution = 19; + optional bool viewOnce = 20; + optional string thumbnailDirectPath = 21; + optional bytes thumbnailSha256 = 22; + optional bytes thumbnailEncSha256 = 23; + optional string staticUrl = 24; +} + +message Call { + optional bytes callKey = 1; + optional string conversionSource = 2; + optional bytes conversionData = 3; + optional uint32 conversionDelaySeconds = 4; +} + +message Chat { + optional string displayName = 1; + optional string id = 2; +} + +message ProtocolMessage { + optional MessageKey key = 1; + enum ProtocolMessageType { + REVOKE = 0; + EPHEMERAL_SETTING = 3; + EPHEMERAL_SYNC_RESPONSE = 4; + HISTORY_SYNC_NOTIFICATION = 5; + APP_STATE_SYNC_KEY_SHARE = 6; + APP_STATE_SYNC_KEY_REQUEST = 7; + MSG_FANOUT_BACKFILL_REQUEST = 8; + INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC = 9; + APP_STATE_FATAL_EXCEPTION_NOTIFICATION = 10; + } + optional ProtocolMessageType type = 2; + optional uint32 ephemeralExpiration = 4; + optional int64 ephemeralSettingTimestamp = 5; + optional HistorySyncNotification historySyncNotification = 6; + optional AppStateSyncKeyShare appStateSyncKeyShare = 7; + optional AppStateSyncKeyRequest appStateSyncKeyRequest = 8; + optional InitialSecurityNotificationSettingSync initialSecurityNotificationSettingSync = 9; + optional AppStateFatalExceptionNotification appStateFatalExceptionNotification = 10; + optional DisappearingMode disappearingMode = 11; +} + +message HistorySyncNotification { + optional bytes fileSha256 = 1; + optional uint64 fileLength = 2; + optional bytes mediaKey = 3; + optional bytes fileEncSha256 = 4; + optional string directPath = 5; + enum HistorySyncNotificationHistorySyncType { + INITIAL_BOOTSTRAP = 0; + INITIAL_STATUS_V3 = 1; + FULL = 2; + RECENT = 3; + PUSH_NAME = 4; + } + optional HistorySyncNotificationHistorySyncType syncType = 6; + optional uint32 chunkOrder = 7; + optional string originalMessageId = 8; +} + +message AppStateSyncKey { + optional AppStateSyncKeyId keyId = 1; + optional AppStateSyncKeyData keyData = 2; +} + +message AppStateSyncKeyId { + optional bytes keyId = 1; +} + +message AppStateSyncKeyFingerprint { + optional uint32 rawId = 1; + optional uint32 currentIndex = 2; + repeated uint32 deviceIndexes = 3 [packed=true]; +} + +message AppStateSyncKeyData { + optional bytes keyData = 1; + optional AppStateSyncKeyFingerprint fingerprint = 2; + optional int64 timestamp = 3; +} + +message AppStateSyncKeyShare { + repeated AppStateSyncKey keys = 1; +} + +message AppStateSyncKeyRequest { + repeated AppStateSyncKeyId keyIds = 1; +} + +message AppStateFatalExceptionNotification { + repeated string collectionNames = 1; + optional int64 timestamp = 2; +} + +message InitialSecurityNotificationSettingSync { + optional bool securityNotificationEnabled = 1; +} + +message ContactsArrayMessage { + optional string displayName = 1; + repeated ContactMessage contacts = 2; + optional ContextInfo contextInfo = 17; +} + +message HSMCurrency { + optional string currencyCode = 1; + optional int64 amount1000 = 2; +} + +message HSMDateTimeComponent { + enum HSMDateTimeComponentDayOfWeekType { + MONDAY = 1; + TUESDAY = 2; + WEDNESDAY = 3; + THURSDAY = 4; + FRIDAY = 5; + SATURDAY = 6; + SUNDAY = 7; + } + optional HSMDateTimeComponentDayOfWeekType dayOfWeek = 1; + optional uint32 year = 2; + optional uint32 month = 3; + optional uint32 dayOfMonth = 4; + optional uint32 hour = 5; + optional uint32 minute = 6; + enum HSMDateTimeComponentCalendarType { + GREGORIAN = 1; + SOLAR_HIJRI = 2; + } + optional HSMDateTimeComponentCalendarType calendar = 7; +} + +message HSMDateTimeUnixEpoch { + optional int64 timestamp = 1; +} + +message HSMDateTime { + oneof datetimeOneof { + HSMDateTimeComponent component = 1; + HSMDateTimeUnixEpoch unixEpoch = 2; + } +} + +message HSMLocalizableParameter { + optional string default = 1; + oneof paramOneof { + HSMCurrency currency = 2; + HSMDateTime dateTime = 3; + } +} + +message HighlyStructuredMessage { + optional string namespace = 1; + optional string elementName = 2; + repeated string params = 3; + optional string fallbackLg = 4; + optional string fallbackLc = 5; + repeated HSMLocalizableParameter localizableParams = 6; + optional string deterministicLg = 7; + optional string deterministicLc = 8; + optional TemplateMessage hydratedHsm = 9; +} + +message SendPaymentMessage { + optional Message noteMessage = 2; + optional MessageKey requestMessageKey = 3; + optional PaymentBackground background = 4; +} + +message RequestPaymentMessage { + optional Message noteMessage = 4; + optional string currencyCodeIso4217 = 1; + optional uint64 amount1000 = 2; + optional string requestFrom = 3; + optional int64 expiryTimestamp = 5; + optional Money amount = 6; + optional PaymentBackground background = 7; +} + +message DeclinePaymentRequestMessage { + optional MessageKey key = 1; +} + +message CancelPaymentRequestMessage { + optional MessageKey key = 1; +} + +message PaymentInviteMessage { + enum PaymentInviteMessageServiceType { + UNKNOWN = 0; + FBPAY = 1; + NOVI = 2; + UPI = 3; + } + optional PaymentInviteMessageServiceType serviceType = 1; + optional int64 expiryTimestamp = 2; +} + +message LiveLocationMessage { + optional double degreesLatitude = 1; + optional double degreesLongitude = 2; + optional uint32 accuracyInMeters = 3; + optional float speedInMps = 4; + optional uint32 degreesClockwiseFromMagneticNorth = 5; + optional string caption = 6; + optional int64 sequenceNumber = 7; + optional uint32 timeOffset = 8; + optional bytes jpegThumbnail = 16; + optional ContextInfo contextInfo = 17; +} + +message StickerMessage { + optional string url = 1; + optional bytes fileSha256 = 2; + optional bytes fileEncSha256 = 3; + optional bytes mediaKey = 4; + optional string mimetype = 5; + optional uint32 height = 6; + optional uint32 width = 7; + optional string directPath = 8; + optional uint64 fileLength = 9; + optional int64 mediaKeyTimestamp = 10; + optional uint32 firstFrameLength = 11; + optional bytes firstFrameSidecar = 12; + optional bool isAnimated = 13; + optional bytes pngThumbnail = 16; + optional ContextInfo contextInfo = 17; +} + +message FourRowTemplate { + optional HighlyStructuredMessage content = 6; + optional HighlyStructuredMessage footer = 7; + repeated TemplateButton buttons = 8; + oneof title { + DocumentMessage documentMessage = 1; + HighlyStructuredMessage highlyStructuredMessage = 2; + ImageMessage imageMessage = 3; + VideoMessage videoMessage = 4; + LocationMessage locationMessage = 5; + } +} + +message HydratedFourRowTemplate { + optional string hydratedContentText = 6; + optional string hydratedFooterText = 7; + repeated HydratedTemplateButton hydratedButtons = 8; + optional string templateId = 9; + oneof title { + DocumentMessage documentMessage = 1; + string hydratedTitleText = 2; + ImageMessage imageMessage = 3; + VideoMessage videoMessage = 4; + LocationMessage locationMessage = 5; + } +} + +message TemplateMessage { + optional ContextInfo contextInfo = 3; + optional HydratedFourRowTemplate hydratedTemplate = 4; + oneof format { + FourRowTemplate fourRowTemplate = 1; + HydratedFourRowTemplate hydratedFourRowTemplate = 2; + } +} + +message TemplateButtonReplyMessage { + optional string selectedId = 1; + optional string selectedDisplayText = 2; + optional ContextInfo contextInfo = 3; + optional uint32 selectedIndex = 4; +} + +message CatalogSnapshot { + optional ImageMessage catalogImage = 1; + optional string title = 2; + optional string description = 3; +} + +message ProductSnapshot { + optional ImageMessage productImage = 1; + optional string productId = 2; + optional string title = 3; + optional string description = 4; + optional string currencyCode = 5; + optional int64 priceAmount1000 = 6; + optional string retailerId = 7; + optional string url = 8; + optional uint32 productImageCount = 9; + optional string firstImageId = 11; + optional int64 salePriceAmount1000 = 12; +} + +message ProductMessage { + optional ProductSnapshot product = 1; + optional string businessOwnerJid = 2; + optional CatalogSnapshot catalog = 4; + optional ContextInfo contextInfo = 17; +} + +message OrderMessage { + optional string orderId = 1; + optional bytes thumbnail = 2; + optional int32 itemCount = 3; + enum OrderMessageOrderStatus { + INQUIRY = 1; + } + optional OrderMessageOrderStatus status = 4; + enum OrderMessageOrderSurface { + CATALOG = 1; + } + optional OrderMessageOrderSurface surface = 5; + optional string message = 6; + optional string orderTitle = 7; + optional string sellerJid = 8; + optional string token = 9; + optional int64 totalAmount1000 = 10; + optional string totalCurrencyCode = 11; + optional ContextInfo contextInfo = 17; +} + +message Row { + optional string title = 1; + optional string description = 2; + optional string rowId = 3; +} + +message Section { + optional string title = 1; + repeated Row rows = 2; +} + +message Product { + optional string productId = 1; +} + +message ProductSection { + optional string title = 1; + repeated Product products = 2; +} + +message ProductListHeaderImage { + optional string productId = 1; + optional bytes jpegThumbnail = 2; +} + +message ProductListInfo { + repeated ProductSection productSections = 1; + optional ProductListHeaderImage headerImage = 2; + optional string businessOwnerJid = 3; +} + +message ListMessage { + optional string title = 1; + optional string description = 2; + optional string buttonText = 3; + enum ListMessageListType { + UNKNOWN = 0; + SINGLE_SELECT = 1; + PRODUCT_LIST = 2; + } + optional ListMessageListType listType = 4; + repeated Section sections = 5; + optional ProductListInfo productListInfo = 6; + optional string footerText = 7; + optional ContextInfo contextInfo = 8; +} + +message SingleSelectReply { + optional string selectedRowId = 1; +} + +message ListResponseMessage { + optional string title = 1; + enum ListResponseMessageListType { + UNKNOWN = 0; + SINGLE_SELECT = 1; + } + optional ListResponseMessageListType listType = 2; + optional SingleSelectReply singleSelectReply = 3; + optional ContextInfo contextInfo = 4; + optional string description = 5; +} + +message Header { + optional string title = 1; + optional string subtitle = 2; + oneof media { + DocumentMessage documentMessage = 3; + ImageMessage imageMessage = 4; + } +} + +message Body { + optional string text = 1; +} + +message Footer { + optional string text = 1; +} + +message ShopsMessage { + optional string id = 1; + enum ShopsMessageSurface { + UNKNOWN_SURFACE = 0; + FB = 1; + IG = 2; + WA = 3; + } + optional ShopsMessageSurface surface = 2; + enum ShopsMessageType { + UNKNOWN_TYPE = 0; + PRODUCT = 1; + STOREFRONT = 2; + COLLECTION = 3; + } + optional ShopsMessageType type = 3; + optional int32 messageVersion = 4; +} + +message CollectionMessage { + optional string bizJid = 1; + optional string id = 2; + optional int32 messageVersion = 3; +} + +message InteractiveMessage { + optional Header header = 1; + optional Body body = 2; + optional Footer footer = 3; + optional ContextInfo contextInfo = 15; + oneof interactiveMessage { + ShopsMessage shopsMessage = 4; + CollectionMessage collectionMessage = 5; + } +} + +message GroupInviteMessage { + optional string groupJid = 1; + optional string inviteCode = 2; + optional int64 inviteExpiration = 3; + optional string groupName = 4; + optional bytes jpegThumbnail = 5; + optional string caption = 6; + optional ContextInfo contextInfo = 7; +} + +message DeviceSentMessage { + optional string destinationJid = 1; + optional Message message = 2; + optional string phash = 3; +} + +message FutureProofMessage { + optional Message message = 1; +} + +message ButtonText { + optional string displayText = 1; +} + +message NativeFlowInfo { + optional string name = 1; + optional string paramsJson = 2; +} + +message Button { + optional string buttonId = 1; + optional ButtonText buttonText = 2; + enum ButtonType { + UNKNOWN = 0; + RESPONSE = 1; + NATIVE_FLOW = 2; + } + optional ButtonType type = 3; + optional NativeFlowInfo nativeFlowInfo = 4; +} + +message ButtonsMessage { + optional string contentText = 6; + optional string footerText = 7; + optional ContextInfo contextInfo = 8; + repeated Button buttons = 9; + enum ButtonsMessageHeaderType { + UNKNOWN = 0; + EMPTY = 1; + TEXT = 2; + DOCUMENT = 3; + IMAGE = 4; + VIDEO = 5; + LOCATION = 6; + } + optional ButtonsMessageHeaderType headerType = 10; + oneof header { + string text = 1; + DocumentMessage documentMessage = 2; + ImageMessage imageMessage = 3; + VideoMessage videoMessage = 4; + LocationMessage locationMessage = 5; + } +} + +message ButtonsResponseMessage { + optional string selectedButtonId = 1; + optional ContextInfo contextInfo = 3; + enum ButtonsResponseMessageType { + UNKNOWN = 0; + DISPLAY_TEXT = 1; + } + optional ButtonsResponseMessageType type = 4; + oneof response { + string selectedDisplayText = 2; + } +} + +message Message { + optional string conversation = 1; + optional SenderKeyDistributionMessage senderKeyDistributionMessage = 2; + optional ImageMessage imageMessage = 3; + optional ContactMessage contactMessage = 4; + optional LocationMessage locationMessage = 5; + optional ExtendedTextMessage extendedTextMessage = 6; + optional DocumentMessage documentMessage = 7; + optional AudioMessage audioMessage = 8; + optional VideoMessage videoMessage = 9; + optional Call call = 10; + optional Chat chat = 11; + optional ProtocolMessage protocolMessage = 12; + optional ContactsArrayMessage contactsArrayMessage = 13; + optional HighlyStructuredMessage highlyStructuredMessage = 14; + optional SenderKeyDistributionMessage fastRatchetKeySenderKeyDistributionMessage = 15; + optional SendPaymentMessage sendPaymentMessage = 16; + optional LiveLocationMessage liveLocationMessage = 18; + optional RequestPaymentMessage requestPaymentMessage = 22; + optional DeclinePaymentRequestMessage declinePaymentRequestMessage = 23; + optional CancelPaymentRequestMessage cancelPaymentRequestMessage = 24; + optional TemplateMessage templateMessage = 25; + optional StickerMessage stickerMessage = 26; + optional GroupInviteMessage groupInviteMessage = 28; + optional TemplateButtonReplyMessage templateButtonReplyMessage = 29; + optional ProductMessage productMessage = 30; + optional DeviceSentMessage deviceSentMessage = 31; + optional MessageContextInfo messageContextInfo = 35; + optional ListMessage listMessage = 36; + optional FutureProofMessage viewOnceMessage = 37; + optional OrderMessage orderMessage = 38; + optional ListResponseMessage listResponseMessage = 39; + optional FutureProofMessage ephemeralMessage = 40; + optional InvoiceMessage invoiceMessage = 41; + optional ButtonsMessage buttonsMessage = 42; + optional ButtonsResponseMessage buttonsResponseMessage = 43; + optional PaymentInviteMessage paymentInviteMessage = 44; + optional InteractiveMessage interactiveMessage = 45; +} + +message DisappearingMode { + enum DisappearingModeInitiator { + CHANGED_IN_CHAT = 0; + INITIATED_BY_ME = 1; + INITIATED_BY_OTHER = 2; + } + optional DisappearingModeInitiator initiator = 1; +} + +message PaymentBackground { + optional string id = 1; + optional uint64 fileLength = 2; + optional uint32 width = 3; + optional uint32 height = 4; + optional string mimetype = 5; + optional fixed32 placeholderArgb = 6; + optional fixed32 textArgb = 7; + optional fixed32 subtextArgb = 8; +} + +message Money { + optional int64 value = 1; + optional uint32 offset = 2; + optional string currencyCode = 3; +} + +message HydratedQuickReplyButton { + optional string displayText = 1; + optional string id = 2; +} + +message HydratedURLButton { + optional string displayText = 1; + optional string url = 2; +} + +message HydratedCallButton { + optional string displayText = 1; + optional string phoneNumber = 2; +} + +message HydratedTemplateButton { + optional uint32 index = 4; + oneof hydratedButton { + HydratedQuickReplyButton quickReplyButton = 1; + HydratedURLButton urlButton = 2; + HydratedCallButton callButton = 3; + } +} + +message UserReceipt { + required string userJid = 1; + optional int64 receiptTimestamp = 2; + optional int64 readTimestamp = 3; + optional int64 playedTimestamp = 4; + repeated string pendingDeviceJid = 5; + repeated string deliveredDeviceJid = 6; +} + +message PhotoChange { + optional bytes oldPhoto = 1; + optional bytes newPhoto = 2; + optional uint32 newPhotoId = 3; +} + +message MediaData { + optional string localPath = 1; +} + message WebFeatures { enum WebFeaturesFlag { NOT_STARTED = 0; @@ -40,11 +948,17 @@ message WebFeatures { optional WebFeaturesFlag ephemeralMessages = 32; optional WebFeaturesFlag e2ENotificationSync = 33; optional WebFeaturesFlag recentStickersV2 = 34; - optional WebFeaturesFlag syncdRelease1 = 35; optional WebFeaturesFlag recentStickersV3 = 36; optional WebFeaturesFlag userNotice = 37; - optional WebFeaturesFlag syncdRelease11 = 38; optional WebFeaturesFlag support = 39; + optional WebFeaturesFlag groupUiiCleanup = 40; + optional WebFeaturesFlag groupDogfoodingInternalOnly = 41; + optional WebFeaturesFlag settingsSync = 42; + optional WebFeaturesFlag archiveV2 = 43; + optional WebFeaturesFlag ephemeralAllowGroupMembers = 44; + optional WebFeaturesFlag ephemeral24HDuration = 45; + optional WebFeaturesFlag mdForceUpgrade = 46; + optional WebFeaturesFlag disappearingMode = 47; } message NotificationMessageInfo { @@ -118,8 +1032,12 @@ message PaymentInfo { COLLECT_EXPIRED = 25; COLLECT_CANCELED = 26; COLLECT_CANCELLING = 27; + IN_REVIEW = 28; } optional PaymentInfoTxnStatus txnStatus = 10; + optional bool useNoviFiatFormat = 11; + optional Money primaryAmount = 12; + optional Money exchangeAmount = 13; } message WebMessageInfo { @@ -136,6 +1054,7 @@ message WebMessageInfo { } optional WebMessageInfoStatus status = 4; optional string participant = 5; + optional uint64 messageC2STimestamp = 6; optional bool ignore = 16; optional bool starred = 17; optional bool broadcast = 18; @@ -264,6 +1183,18 @@ message WebMessageInfo { BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED = 116; BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED = 117; E2E_IDENTITY_UNAVAILABLE = 118; + GROUP_CREATING = 119; + GROUP_CREATE_FAILED = 120; + GROUP_BOUNCED = 121; + BLOCK_CONTACT = 122; + EPHEMERAL_SETTING_NOT_APPLIED = 123; + SYNC_FAILED = 124; + SYNCING = 125; + BIZ_PRIVACY_MODE_INIT_FB = 126; + BIZ_PRIVACY_MODE_INIT_BSP = 127; + BIZ_PRIVACY_MODE_TO_FB = 128; + BIZ_PRIVACY_MODE_TO_BSP = 129; + DISAPPEARING_MODE = 130; } optional WebMessageInfoStubType messageStubType = 24; optional bool clearMedia = 25; @@ -285,651 +1216,7 @@ message WebMessageInfo { } optional WebMessageInfoBizPrivacyStatus bizPrivacyStatus = 36; optional string verifiedBizName = 37; + optional MediaData mediaData = 38; + optional PhotoChange photoChange = 39; + repeated UserReceipt userReceipt = 40; } - -message HydratedQuickReplyButton { - optional string displayText = 1; - optional string id = 2; -} - -message HydratedURLButton { - optional string displayText = 1; - optional string url = 2; -} - -message HydratedCallButton { - optional string displayText = 1; - optional string phoneNumber = 2; -} - -message HydratedTemplateButton { - optional uint32 index = 4; - oneof hydratedButton { - HydratedQuickReplyButton quickReplyButton = 1; - HydratedURLButton urlButton = 2; - HydratedCallButton callButton = 3; - } -} - -message QuickReplyButton { - optional HighlyStructuredMessage displayText = 1; - optional string id = 2; -} - -message URLButton { - optional HighlyStructuredMessage displayText = 1; - optional HighlyStructuredMessage url = 2; -} - -message CallButton { - optional HighlyStructuredMessage displayText = 1; - optional HighlyStructuredMessage phoneNumber = 2; -} - -message TemplateButton { - optional uint32 index = 4; - oneof button { - QuickReplyButton quickReplyButton = 1; - URLButton urlButton = 2; - CallButton callButton = 3; - } -} - -message Location { - optional double degreesLatitude = 1; - optional double degreesLongitude = 2; - optional string name = 3; -} - -message Point { - optional int32 xDeprecated = 1; - optional int32 yDeprecated = 2; - optional double x = 3; - optional double y = 4; -} - -message InteractiveAnnotation { - repeated Point polygonVertices = 1; - oneof action { - Location location = 2; - } -} -message AdReplyInfo { - optional string advertiserName = 1; - enum AdReplyInfoMediaType { - NONE = 0; - IMAGE = 1; - VIDEO = 2; - } - optional AdReplyInfoMediaType mediaType = 2; - optional bytes jpegThumbnail = 16; - optional string caption = 17; -} - -message ExternalAdReplyInfo { - optional string title = 1; - optional string body = 2; - enum ExternalAdReplyInfoMediaType { - NONE = 0; - IMAGE = 1; - VIDEO = 2; - } - optional ExternalAdReplyInfoMediaType mediaType = 3; - optional string thumbnailUrl = 4; - optional string mediaUrl = 5; - optional bytes thumbnail = 6; - optional string sourceType = 7; - optional string sourceId = 8; - optional string sourceUrl = 9; -} - -message ContextInfo { - optional string stanzaId = 1; - optional string participant = 2; - optional Message quotedMessage = 3; - optional string remoteJid = 4; - repeated string mentionedJid = 15; - optional string conversionSource = 18; - optional bytes conversionData = 19; - optional uint32 conversionDelaySeconds = 20; - optional uint32 forwardingScore = 21; - optional bool isForwarded = 22; - optional AdReplyInfo quotedAd = 23; - optional MessageKey placeholderKey = 24; - optional uint32 expiration = 25; - optional int64 ephemeralSettingTimestamp = 26; - optional bytes ephemeralSharedSecret = 27; - optional ExternalAdReplyInfo externalAdReply = 28; -} - -message SenderKeyDistributionMessage { - optional string groupId = 1; - optional bytes axolotlSenderKeyDistributionMessage = 2; -} - -message ImageMessage { - optional string url = 1; - optional string mimetype = 2; - optional string caption = 3; - optional bytes fileSha256 = 4; - optional uint64 fileLength = 5; - optional uint32 height = 6; - optional uint32 width = 7; - optional bytes mediaKey = 8; - optional bytes fileEncSha256 = 9; - repeated InteractiveAnnotation interactiveAnnotations = 10; - optional string directPath = 11; - optional int64 mediaKeyTimestamp = 12; - optional bytes jpegThumbnail = 16; - optional ContextInfo contextInfo = 17; - optional bytes firstScanSidecar = 18; - optional uint32 firstScanLength = 19; - optional uint32 experimentGroupId = 20; - optional bytes scansSidecar = 21; - repeated uint32 scanLengths = 22; - optional bytes midQualityFileSha256 = 23; - optional bytes midQualityFileEncSha256 = 24; - optional bool viewOnce = 25; -} - -message ContactMessage { - optional string displayName = 1; - optional string vcard = 16; - optional ContextInfo contextInfo = 17; -} - -message LocationMessage { - optional double degreesLatitude = 1; - optional double degreesLongitude = 2; - optional string name = 3; - optional string address = 4; - optional string url = 5; - optional bool isLive = 6; - optional uint32 accuracyInMeters = 7; - optional float speedInMps = 8; - optional uint32 degreesClockwiseFromMagneticNorth = 9; - optional string comment = 11; - optional bytes jpegThumbnail = 16; - optional ContextInfo contextInfo = 17; -} - -message ExtendedTextMessage { - optional string text = 1; - optional string matchedText = 2; - optional string canonicalUrl = 4; - optional string description = 5; - optional string title = 6; - optional fixed32 textArgb = 7; - optional fixed32 backgroundArgb = 8; - enum ExtendedTextMessageFontType { - SANS_SERIF = 0; - SERIF = 1; - NORICAN_REGULAR = 2; - BRYNDAN_WRITE = 3; - BEBASNEUE_REGULAR = 4; - OSWALD_HEAVY = 5; - } - optional ExtendedTextMessageFontType font = 9; - enum ExtendedTextMessagePreviewType { - NONE = 0; - VIDEO = 1; - } - optional ExtendedTextMessagePreviewType previewType = 10; - optional bytes jpegThumbnail = 16; - optional ContextInfo contextInfo = 17; - optional bool doNotPlayInline = 18; -} - -message DocumentMessage { - optional string url = 1; - optional string mimetype = 2; - optional string title = 3; - optional bytes fileSha256 = 4; - optional uint64 fileLength = 5; - optional uint32 pageCount = 6; - optional bytes mediaKey = 7; - optional string fileName = 8; - optional bytes fileEncSha256 = 9; - optional string directPath = 10; - optional int64 mediaKeyTimestamp = 11; - optional bool contactVcard = 12; - optional string thumbnailDirectPath = 13; - optional bytes thumbnailSha256 = 14; - optional bytes thumbnailEncSha256 = 15; - optional bytes jpegThumbnail = 16; - optional ContextInfo contextInfo = 17; - optional uint32 thumbnailHeight = 18; - optional uint32 thumbnailWidth = 19; -} - -message AudioMessage { - optional string url = 1; - optional string mimetype = 2; - optional bytes fileSha256 = 3; - optional uint64 fileLength = 4; - optional uint32 seconds = 5; - optional bool ptt = 6; - optional bytes mediaKey = 7; - optional bytes fileEncSha256 = 8; - optional string directPath = 9; - optional int64 mediaKeyTimestamp = 10; - optional ContextInfo contextInfo = 17; - optional bytes streamingSidecar = 18; -} - -message VideoMessage { - optional string url = 1; - optional string mimetype = 2; - optional bytes fileSha256 = 3; - optional uint64 fileLength = 4; - optional uint32 seconds = 5; - optional bytes mediaKey = 6; - optional string caption = 7; - optional bool gifPlayback = 8; - optional uint32 height = 9; - optional uint32 width = 10; - optional bytes fileEncSha256 = 11; - repeated InteractiveAnnotation interactiveAnnotations = 12; - optional string directPath = 13; - optional int64 mediaKeyTimestamp = 14; - optional bytes jpegThumbnail = 16; - optional ContextInfo contextInfo = 17; - optional bytes streamingSidecar = 18; - enum VideoMessageAttribution { - NONE = 0; - GIPHY = 1; - TENOR = 2; - } - optional VideoMessageAttribution gifAttribution = 19; - optional bool viewOnce = 20; -} - -message Call { - optional bytes callKey = 1; -} - -message Chat { - optional string displayName = 1; - optional string id = 2; -} - -message ProtocolMessage { - optional MessageKey key = 1; - enum ProtocolMessageType { - REVOKE = 0; - EPHEMERAL_SETTING = 3; - EPHEMERAL_SYNC_RESPONSE = 4; - HISTORY_SYNC_NOTIFICATION = 5; - APP_STATE_SYNC_KEY_SHARE = 6; - APP_STATE_SYNC_KEY_REQUEST = 7; - MSG_FANOUT_BACKFILL_REQUEST = 8; - INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC = 9; - } - optional ProtocolMessageType type = 2; - optional uint32 ephemeralExpiration = 4; - optional int64 ephemeralSettingTimestamp = 5; - optional HistorySyncNotification historySyncNotification = 6; - optional AppStateSyncKeyShare appStateSyncKeyShare = 7; - optional AppStateSyncKeyRequest appStateSyncKeyRequest = 8; - optional InitialSecurityNotificationSettingSync initialSecurityNotificationSettingSync = 9; -} - -message HistorySyncNotification { - optional bytes fileSha256 = 1; - optional uint64 fileLength = 2; - optional bytes mediaKey = 3; - optional bytes fileEncSha256 = 4; - optional string directPath = 5; - enum HistorySyncNotificationHistorySyncType { - INITIAL_BOOTSTRAP = 0; - INITIAL_STATUS_V3 = 1; - FULL = 2; - RECENT = 3; - } - optional HistorySyncNotificationHistorySyncType syncType = 6; - optional uint32 chunkOrder = 7; - optional string originalMessageId = 8; -} - -message AppStateSyncKey { - optional AppStateSyncKeyId keyId = 1; - optional AppStateSyncKeyData keyData = 2; -} - -message AppStateSyncKeyId { - optional bytes keyId = 1; -} - -message AppStateSyncKeyFingerprint { - optional uint32 rawId = 1; - optional uint32 currentIndex = 2; -} - -message AppStateSyncKeyData { - optional bytes keyData = 1; - optional AppStateSyncKeyFingerprint fingerprint = 2; - optional int64 timestamp = 3; -} - -message AppStateSyncKeyShare { - repeated AppStateSyncKey keys = 1; -} - -message AppStateSyncKeyRequest { - repeated AppStateSyncKeyId keyIds = 1; -} - -message InitialSecurityNotificationSettingSync { - optional bool securityNotificationEnabled = 1; -} - -message ContactsArrayMessage { - optional string displayName = 1; - repeated ContactMessage contacts = 2; - optional ContextInfo contextInfo = 17; -} - -message HSMCurrency { - optional string currencyCode = 1; - optional int64 amount1000 = 2; -} - -message HSMDateTimeComponent { - enum HSMDateTimeComponentDayOfWeekType { - MONDAY = 1; - TUESDAY = 2; - WEDNESDAY = 3; - THURSDAY = 4; - FRIDAY = 5; - SATURDAY = 6; - SUNDAY = 7; - } - optional HSMDateTimeComponentDayOfWeekType dayOfWeek = 1; - optional uint32 year = 2; - optional uint32 month = 3; - optional uint32 dayOfMonth = 4; - optional uint32 hour = 5; - optional uint32 minute = 6; - enum HSMDateTimeComponentCalendarType { - GREGORIAN = 1; - SOLAR_HIJRI = 2; - } - optional HSMDateTimeComponentCalendarType calendar = 7; -} - -message HSMDateTimeUnixEpoch { - optional int64 timestamp = 1; -} - -message HSMDateTime { - oneof datetimeOneof { - HSMDateTimeComponent component = 1; - HSMDateTimeUnixEpoch unixEpoch = 2; - } -} - -message HSMLocalizableParameter { - optional string default = 1; - oneof paramOneof { - HSMCurrency currency = 2; - HSMDateTime dateTime = 3; - } -} - -message HighlyStructuredMessage { - optional string namespace = 1; - optional string elementName = 2; - repeated string params = 3; - optional string fallbackLg = 4; - optional string fallbackLc = 5; - repeated HSMLocalizableParameter localizableParams = 6; - optional string deterministicLg = 7; - optional string deterministicLc = 8; - optional TemplateMessage hydratedHsm = 9; -} - -message SendPaymentMessage { - optional Message noteMessage = 2; - optional MessageKey requestMessageKey = 3; -} - -message RequestPaymentMessage { - optional Message noteMessage = 4; - optional string currencyCodeIso4217 = 1; - optional uint64 amount1000 = 2; - optional string requestFrom = 3; - optional int64 expiryTimestamp = 5; -} - -message DeclinePaymentRequestMessage { - optional MessageKey key = 1; -} - -message CancelPaymentRequestMessage { - optional MessageKey key = 1; -} - -message LiveLocationMessage { - optional double degreesLatitude = 1; - optional double degreesLongitude = 2; - optional uint32 accuracyInMeters = 3; - optional float speedInMps = 4; - optional uint32 degreesClockwiseFromMagneticNorth = 5; - optional string caption = 6; - optional int64 sequenceNumber = 7; - optional uint32 timeOffset = 8; - optional bytes jpegThumbnail = 16; - optional ContextInfo contextInfo = 17; -} - -message StickerMessage { - optional string url = 1; - optional bytes fileSha256 = 2; - optional bytes fileEncSha256 = 3; - optional bytes mediaKey = 4; - optional string mimetype = 5; - optional uint32 height = 6; - optional uint32 width = 7; - optional string directPath = 8; - optional uint64 fileLength = 9; - optional int64 mediaKeyTimestamp = 10; - optional uint32 firstFrameLength = 11; - optional bytes firstFrameSidecar = 12; - optional bool isAnimated = 13; - optional bytes pngThumbnail = 16; - optional ContextInfo contextInfo = 17; -} - -message FourRowTemplate { - optional HighlyStructuredMessage content = 6; - optional HighlyStructuredMessage footer = 7; - repeated TemplateButton buttons = 8; - oneof title { - DocumentMessage documentMessage = 1; - HighlyStructuredMessage highlyStructuredMessage = 2; - ImageMessage imageMessage = 3; - VideoMessage videoMessage = 4; - LocationMessage locationMessage = 5; - } -} - -message HydratedFourRowTemplate { - optional string hydratedContentText = 6; - optional string hydratedFooterText = 7; - repeated HydratedTemplateButton hydratedButtons = 8; - optional string templateId = 9; - oneof title { - DocumentMessage documentMessage = 1; - string hydratedTitleText = 2; - ImageMessage imageMessage = 3; - VideoMessage videoMessage = 4; - LocationMessage locationMessage = 5; - } -} - -message TemplateMessage { - optional ContextInfo contextInfo = 3; - optional HydratedFourRowTemplate hydratedTemplate = 4; - oneof format { - FourRowTemplate fourRowTemplate = 1; - HydratedFourRowTemplate hydratedFourRowTemplate = 2; - } -} - -message TemplateButtonReplyMessage { - optional string selectedId = 1; - optional string selectedDisplayText = 2; - optional ContextInfo contextInfo = 3; - optional uint32 selectedIndex = 4; -} - -message CatalogSnapshot { - optional ImageMessage catalogImage = 1; - optional string title = 2; - optional string description = 3; -} - -message ProductSnapshot { - optional ImageMessage productImage = 1; - optional string productId = 2; - optional string title = 3; - optional string description = 4; - optional string currencyCode = 5; - optional int64 priceAmount1000 = 6; - optional string retailerId = 7; - optional string url = 8; - optional uint32 productImageCount = 9; - optional string firstImageId = 11; -} - -message ProductMessage { - optional ProductSnapshot product = 1; - optional string businessOwnerJid = 2; - optional CatalogSnapshot catalog = 4; - optional ContextInfo contextInfo = 17; -} - -message OrderMessage { - optional string orderId = 1; - optional bytes thumbnail = 2; - optional int32 itemCount = 3; - enum OrderMessageOrderStatus { - INQUIRY = 1; - } - optional OrderMessageOrderStatus status = 4; - enum OrderMessageOrderSurface { - CATALOG = 1; - } - optional OrderMessageOrderSurface surface = 5; - optional string message = 6; - optional string orderTitle = 7; - optional string sellerJid = 8; - optional string token = 9; - optional ContextInfo contextInfo = 17; -} - -message Row { - optional string title = 1; - optional string description = 2; - optional string rowId = 3; -} - -message Section { - optional string title = 1; - repeated Row rows = 2; -} - -message ListMessage { - optional string title = 1; - optional string description = 2; - optional string buttonText = 3; - enum ListMessageListType { - UNKNOWN = 0; - SINGLE_SELECT = 1; - } - optional ListMessageListType listType = 4; - repeated Section sections = 5; -} - -message SingleSelectReply { - optional string selectedRowId = 1; -} - -message ListResponseMessage { - optional string selectedDisplayText = 1; - enum ListResponseMessageListType { - UNKNOWN = 0; - SINGLE_SELECT = 1; - } - optional ListResponseMessageListType listType = 2; - optional SingleSelectReply singleSelectReply = 3; - optional ContextInfo contextInfo = 4; -} - -message GroupInviteMessage { - optional string groupJid = 1; - optional string inviteCode = 2; - optional int64 inviteExpiration = 3; - optional string groupName = 4; - optional bytes jpegThumbnail = 5; - optional string caption = 6; - optional ContextInfo contextInfo = 7; -} - -message EphemeralSetting { - optional string chatJid = 1; - optional uint32 ephemeralExpiration = 2; - optional int64 ephemeralSettingTimestamp = 3; -} - -message DeviceSentMessage { - optional string destinationJid = 1; - optional Message message = 2; - optional string phash = 3; - repeated EphemeralSetting broadcastEphemeralSettings = 4; -} - -message FutureProofMessage { - optional Message message = 1; -} - -message Message { - optional string conversation = 1; - optional SenderKeyDistributionMessage senderKeyDistributionMessage = 2; - optional ImageMessage imageMessage = 3; - optional ContactMessage contactMessage = 4; - optional LocationMessage locationMessage = 5; - optional ExtendedTextMessage extendedTextMessage = 6; - optional DocumentMessage documentMessage = 7; - optional AudioMessage audioMessage = 8; - optional VideoMessage videoMessage = 9; - optional Call call = 10; - optional Chat chat = 11; - optional ProtocolMessage protocolMessage = 12; - optional ContactsArrayMessage contactsArrayMessage = 13; - optional HighlyStructuredMessage highlyStructuredMessage = 14; - optional SenderKeyDistributionMessage fastRatchetKeySenderKeyDistributionMessage = 15; - optional SendPaymentMessage sendPaymentMessage = 16; - optional LiveLocationMessage liveLocationMessage = 18; - optional RequestPaymentMessage requestPaymentMessage = 22; - optional DeclinePaymentRequestMessage declinePaymentRequestMessage = 23; - optional CancelPaymentRequestMessage cancelPaymentRequestMessage = 24; - optional TemplateMessage templateMessage = 25; - optional StickerMessage stickerMessage = 26; - optional GroupInviteMessage groupInviteMessage = 28; - optional TemplateButtonReplyMessage templateButtonReplyMessage = 29; - optional ProductMessage productMessage = 30; - optional DeviceSentMessage deviceSentMessage = 31; - optional ListMessage listMessage = 36; - optional FutureProofMessage viewOnceMessage = 37; - optional OrderMessage orderMessage = 38; - optional ListResponseMessage listResponseMessage = 39; - optional FutureProofMessage ephemeralMessage = 40; -} - -message MessageKey { - optional string remoteJid = 1; - optional bool fromMe = 2; - optional string id = 3; - optional string participant = 4; -} \ No newline at end of file diff --git a/src/BinaryNode/decode.ts b/src/BinaryNode/decode.ts index bed96f1..7f26239 100644 --- a/src/BinaryNode/decode.ts +++ b/src/BinaryNode/decode.ts @@ -1,4 +1,4 @@ -import { proto } from '../../WAMessage/WAMessage' +import { proto } from '../../WAMessage' import { BinaryNode, DoubleByteTokens, SingleByteTokens, Tags } from './types' function decode(buffer: Buffer, makeNode: () => T, indexRef: { index: number }) { diff --git a/src/BinaryNode/encode.ts b/src/BinaryNode/encode.ts index db29abf..4499236 100644 --- a/src/BinaryNode/encode.ts +++ b/src/BinaryNode/encode.ts @@ -1,4 +1,4 @@ -import { proto } from "../../WAMessage/WAMessage"; +import { proto } from "../../WAMessage"; import { BinaryNode, SingleByteTokens, Tags } from "./types"; const encode = ({ header, attributes, data }: BinaryNode, buffer: number[] = []) => { diff --git a/src/BinaryNode/types.ts b/src/BinaryNode/types.ts index 9139342..8e5e56a 100644 --- a/src/BinaryNode/types.ts +++ b/src/BinaryNode/types.ts @@ -1,4 +1,4 @@ -import { proto } from "../../WAMessage/WAMessage" +import { proto } from "../../WAMessage" export type Attributes = { [key: string]: string } export type BinaryNodeData = BinaryNode[] | string | Buffer | proto.IWebMessageInfo | undefined diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index 09112d7..2fcf818 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -5,7 +5,6 @@ import { Chat, Presence, WAMessageCursor, SocketConfig, WAMessage, WAMessageKey, import { isGroupID, toNumber, whatsappID, generateWAMessage, decryptMediaMessageBuffer } from "../Utils"; import makeChatsSocket from "./chats"; import { WA_DEFAULT_EPHEMERAL } from "../Defaults"; -import { Attributes } from "../BinaryNode/types"; const STATUS_MAP = { read: WAMessageStatus.READ, @@ -19,8 +18,7 @@ const makeMessagesSocket = (config: SocketConfig) => { const { ev, socketEvents, - query, - sendMessage, + query, generateMessageTag, currentEpoch, setQuery, diff --git a/src/Tests/Tests.Media.ts b/src/Tests/Tests.Media.ts index 34426ad..6960438 100644 --- a/src/Tests/Tests.Media.ts +++ b/src/Tests/Tests.Media.ts @@ -1,7 +1,7 @@ import { deepStrictEqual, strictEqual } from 'assert' import { createWriteStream } from 'fs' import { readFile } from 'fs/promises' -import { proto } from '../../WAMessage/WAMessage' +import { proto } from '../../WAMessage' import { MessageType } from '../WAConnection' import { aesEncrypWithIV, decryptMediaMessageBuffer, encryptedStream, getMediaKeys, getStream, hmacSign, sha256 } from '../WAConnection/Utils' import { WAConnectionTest } from './Common' diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 01df8a3..51c038a 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -1,7 +1,7 @@ import type { Agent } from "https" import type { Logger } from "pino" import type { URL } from "url" -import { proto } from '../../WAMessage/WAMessage' +import { proto } from '../../WAMessage' // export the WAMessage Prototypes export { proto as WAMessageProto } diff --git a/src/Types/index.ts b/src/Types/index.ts index d074864..0a32093 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -17,7 +17,7 @@ import { ConnectionState } from './Store' import { GroupMetadata, ParticipantAction } from './GroupMetadata' import { MessageInfo, MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageKey, WAMessageUpdate } from './Message' -import { proto } from '../../WAMessage/WAMessage' +import { proto } from '../../WAMessage' /** used for binary messages */ export enum WAMetric { diff --git a/src/index.ts b/src/index.ts index 331f02b..1c46348 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import makeConnection from './Connection' -export * from '../WAMessage/WAMessage' +export * from '../WAMessage' export * from './Utils' export * from './Types' export * from './Store' From 39a6d804e1c91b76c3dced8e7a534b0604a738d4 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 4 Aug 2021 17:19:28 +0530 Subject: [PATCH 016/311] group disappearing messages fix + state maintain --- src/Connection/messages.ts | 16 ++++++++++++---- src/Types/GroupMetadata.ts | 1 + src/Types/Message.ts | 2 +- src/Utils/messages.ts | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index 2fcf818..f436478 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -103,6 +103,10 @@ const makeMessagesSocket = (config: SocketConfig) => { jid, t: +toNumber(message.messageTimestamp) } + + const emitGroupUpdate = (update: Partial) => { + ev.emit('groups.update', [ { id: jid, ...update } ]) + } // add to count if the message isn't from me & there exists a message if(!message.key.fromMe && message.message) { chatUpdate.count = 1 @@ -121,6 +125,10 @@ const makeMessagesSocket = (config: SocketConfig) => { ) { chatUpdate.eph_setting_ts = message.messageTimestamp.toString() chatUpdate.ephemeral = ephemeralProtocolMsg.ephemeralExpiration.toString() + + if(isGroupID(jid)) { + emitGroupUpdate({ ephemeralDuration: ephemeralProtocolMsg.ephemeralExpiration || null }) + } } const protocolMessage = message.message?.protocolMessage // if it's a message to delete another message @@ -150,14 +158,14 @@ const makeMessagesSocket = (config: SocketConfig) => { const emitParticipantsUpdate = (action: ParticipantAction) => ( ev.emit('group-participants.update', { jid, participants, action }) ) - const emitGroupUpdate = (update: Partial) => { - ev.emit('groups.update', [ { id: jid, ...update } ]) - } - + switch (message.messageStubType) { case WAMessageStubType.CHANGE_EPHEMERAL_SETTING: chatUpdate.eph_setting_ts = message.messageTimestamp.toString() chatUpdate.ephemeral = message.messageStubParameters[0] + if(isGroupID(jid)) { + emitGroupUpdate({ ephemeralDuration: +message.messageStubParameters[0] || null }) + } break case WAMessageStubType.GROUP_PARTICIPANT_LEAVE: case WAMessageStubType.GROUP_PARTICIPANT_REMOVE: diff --git a/src/Types/GroupMetadata.ts b/src/Types/GroupMetadata.ts index 9aedf6d..5e86b97 100644 --- a/src/Types/GroupMetadata.ts +++ b/src/Types/GroupMetadata.ts @@ -18,6 +18,7 @@ export interface GroupMetadata { announce?: 'true' | 'false' // Baileys modified array participants: GroupParticipant[] + ephemeralDuration?: number } diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 51c038a..20ed675 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -111,7 +111,7 @@ export type MiscMessageGenerationOptions = { /** disappearing messages settings */ ephemeralOptions?: { expiration: number | string - eph_setting_ts: number | string + eph_setting_ts?: number | string } } export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & { diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 6bb1b4a..dd3a455 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -312,7 +312,7 @@ export const generateWAMessageFromContent = ( message[key].contextInfo = { ...(message[key].contextInfo || {}), expiration: options.ephemeralOptions.expiration || WA_DEFAULT_EPHEMERAL, - ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts.toString() + ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts?.toString() } message = { ephemeralMessage: { From 0a746b9f5388513baa75c46032b3371e78cf384a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 6 Aug 2021 11:55:09 +0530 Subject: [PATCH 017/311] add viewOnce + buttons --- src/Types/Message.ts | 20 ++++++++++++++------ src/Utils/messages.ts | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 20ed675..29cbe44 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -50,19 +50,26 @@ type Mentionable = { /** list of jids that are mentioned in the accompanying text */ mentions?: string[] } +type ViewOnce = { + viewOnce?: boolean +} +type Buttonable = { + /** add buttons to the message */ + buttons?: proto.IButton[] +} export type MediaType = 'image' | 'video' | 'sticker' | 'audio' | 'document' export type AnyMediaMessageContent = ( ({ image: WAMediaUpload caption?: string jpegThumbnail?: string - } & Mentionable) | + } & Mentionable & Buttonable) | ({ video: WAMediaUpload caption?: string gifPlayback?: boolean jpegThumbnail?: string - } & Mentionable) | { + } & Mentionable & Buttonable) | { audio: WAMediaUpload /** if set to true, will send as a `voice note` */ pttAudio?: boolean @@ -70,18 +77,18 @@ export type AnyMediaMessageContent = ( seconds?: number } | { sticker: WAMediaUpload - } | { + } | ({ document: WAMediaUpload mimetype: string fileName?: string - }) & + } & Buttonable)) & { mimetype?: string } -export type AnyRegularMessageContent = +export type AnyRegularMessageContent = ( ({ text: string } - & Mentionable) | + & Mentionable & Buttonable) | AnyMediaMessageContent | { contacts: { @@ -92,6 +99,7 @@ export type AnyRegularMessageContent = { location: WALocationMessage } +) & ViewOnce export type AnyMessageContent = AnyRegularMessageContent | { forward: WAMessage diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index dd3a455..95e6231 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -1,6 +1,7 @@ import { Boom } from '@hapi/boom' import { createReadStream, promises as fs } from "fs" import got from "got" +import { proto } from '../../WAMessage' import { DEFAULT_ORIGIN, URL_REGEX, WA_DEFAULT_EPHEMERAL } from "../Defaults" import { AnyMediaMessageContent, @@ -235,7 +236,7 @@ export const generateWAMessageContent = async( } } - m.extendedTextMessage = WAMessageProto.ExtendedTextMessage.fromObject(extContent) + m.extendedTextMessage = extContent } else if('contacts' in message) { const contactLen = message.contacts.contacts.length if(!contactLen) { @@ -267,6 +268,21 @@ export const generateWAMessageContent = async( options ) } + if('buttons' in message && !!message.buttons) { + const buttonsMessage: proto.IButtonsMessage = { + buttons: message.buttons!, + text: '' + } + if('text' in message) { + buttonsMessage.contentText = message.text + } else { + Object.assign(buttonsMessage, m) + } + m = { buttonsMessage } + } + if('viewOnce' in message && !!message.viewOnce) { + m = { viewOnceMessage: { message: m } } + } if('mentions' in message && message.mentions?.length) { const [messageType] = Object.keys(m) m[messageType].contextInfo = m[messageType] || { } From 75c15e7767b84143909990979f99eece1a893e23 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 6 Aug 2021 18:41:07 +0530 Subject: [PATCH 018/311] generic media uploads --- src/Connection/messages.ts | 52 +++++++++++++++++++++++++++++-- src/Defaults/index.ts | 13 +++++++- src/Tests/test.message-gen.ts | 8 +++++ src/Types/Message.ts | 8 +++-- src/Utils/messages.ts | 58 +++-------------------------------- 5 files changed, 79 insertions(+), 60 deletions(-) create mode 100644 src/Tests/test.message-gen.ts diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index f436478..82fcbfa 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -1,10 +1,11 @@ import BinaryNode from "../BinaryNode"; import { Boom } from '@hapi/boom' import { EventEmitter } from 'events' -import { Chat, Presence, WAMessageCursor, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo, MessageInfoUpdate } from "../Types"; +import { Chat, Presence, WAMessageCursor, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo, MessageInfoUpdate, WAMediaUploadFunction, MediaType } from "../Types"; import { isGroupID, toNumber, whatsappID, generateWAMessage, decryptMediaMessageBuffer } from "../Utils"; import makeChatsSocket from "./chats"; -import { WA_DEFAULT_EPHEMERAL } from "../Defaults"; +import { DEFAULT_ORIGIN, MEDIA_PATH_MAP, WA_DEFAULT_EPHEMERAL } from "../Defaults"; +import got from "got"; const STATUS_MAP = { read: WAMessageStatus.READ, @@ -211,6 +212,51 @@ const makeMessagesSocket = (config: SocketConfig) => { } } + const waUploadToServer: WAMediaUploadFunction = async(stream, { mediaType, fileEncSha256B64 }) => { + // send a query JSON to obtain the url & auth token to upload our media + let uploadInfo = await refreshMediaConn(false) + + let mediaUrl: string + for (let host of uploadInfo.hosts) { + const auth = encodeURIComponent(uploadInfo.auth) // the auth token + const url = `https://${host.hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` + + try { + const {body: responseText} = await got.post( + url, + { + headers: { + 'Content-Type': 'application/octet-stream', + 'Origin': DEFAULT_ORIGIN + }, + agent: { + https: config.agent + }, + body: stream + } + ) + const result = JSON.parse(responseText) + mediaUrl = result?.url + + if (mediaUrl) break + else { + uploadInfo = await refreshMediaConn(true) + throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) + } + } catch (error) { + const isLast = host.hostname === uploadInfo.hosts[uploadInfo.hosts.length-1].hostname + logger.debug(`Error in uploading to ${host.hostname} (${error}) ${isLast ? '' : ', retrying...'}`) + } + } + if (!mediaUrl) { + throw new Boom( + 'Media upload failed on all hosts', + { statusCode: 500 } + ) + } + return { mediaUrl } + } + /** Query a string to check if it has a url, if it does, return WAUrlInfo */ const generateUrlInfo = async(text: string) => { const response = await query({ @@ -484,7 +530,7 @@ const makeMessagesSocket = (config: SocketConfig) => { ...options, userJid: userJid, getUrlInfo: generateUrlInfo, - getMediaOptions: refreshMediaConn + upload: waUploadToServer } ) await relayWAMessage(msg, { waitForAck: options.waitForAck }) diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index caca01f..852e25d 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -1,5 +1,5 @@ import P from "pino" -import type { SocketConfig } from "../Types" +import type { MediaType, SocketConfig } from "../Types" import { Browsers } from "../Utils/generics" export const UNAUTHORIZED_CODES = [401, 403, 419] @@ -34,3 +34,14 @@ export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { maxQRCodes: Infinity, printQRInTerminal: false, } + + +export const MEDIA_PATH_MAP: { [T in MediaType]: string } = { + image: '/mms/image', + video: '/mms/video', + document: '/mms/document', + audio: '/mms/audio', + sticker: '/mms/image', +} + +export const MEDIA_KEYS = Object.keys(MEDIA_PATH_MAP) as MediaType[] \ No newline at end of file diff --git a/src/Tests/test.message-gen.ts b/src/Tests/test.message-gen.ts new file mode 100644 index 0000000..6b325b4 --- /dev/null +++ b/src/Tests/test.message-gen.ts @@ -0,0 +1,8 @@ + +describe('Message Generation', () => { + + it('should generate a text message', () => { + + }) + +}) \ No newline at end of file diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 29cbe44..da7e5a1 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -1,4 +1,4 @@ -import type { Agent } from "https" +import type { ReadStream } from "fs" import type { Logger } from "pino" import type { URL } from "url" import { proto } from '../../WAMessage' @@ -125,10 +125,12 @@ export type MiscMessageGenerationOptions = { export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & { userJid: string } + +export type WAMediaUploadFunction = (readStream: ReadStream, opts: { fileEncSha256B64: string, mediaType: MediaType }) => Promise<{ mediaUrl: string }> + export type MediaGenerationOptions = { logger?: Logger - agent?: Agent - getMediaOptions: (refresh: boolean) => Promise + upload: WAMediaUploadFunction } export type MessageContentGenerationOptions = MediaGenerationOptions & { getUrlInfo?: (text: string) => Promise diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 95e6231..b15e689 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -1,8 +1,7 @@ import { Boom } from '@hapi/boom' import { createReadStream, promises as fs } from "fs" -import got from "got" import { proto } from '../../WAMessage' -import { DEFAULT_ORIGIN, URL_REGEX, WA_DEFAULT_EPHEMERAL } from "../Defaults" +import { MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from "../Defaults" import { AnyMediaMessageContent, AnyMessageContent, @@ -33,14 +32,6 @@ type MediaUploadData = { mimetype?: string } -const MEDIA_PATH_MAP: { [T in MediaType]: string } = { - image: '/mms/image', - video: '/mms/video', - document: '/mms/document', - audio: '/mms/audio', - sticker: '/mms/image', -} as const - const MIMETYPE_MAP: { [T in MediaType]: string } = { image: 'image/jpeg', video: 'video/mp4', @@ -57,8 +48,6 @@ const MessageTypeProto = { 'document': WAMessageProto.DocumentMessage, } as const -const MEDIA_KEYS = Object.keys(MEDIA_PATH_MAP) as MediaType[] - export const prepareWAMessageMedia = async( message: AnyMediaMessageContent, options: MediaGenerationOptions @@ -110,47 +99,10 @@ export const prepareWAMessageMedia = async( } catch (error) { options.logger?.debug ({ error }, 'failed to obtain audio duration: ' + error.message) } - // send a query JSON to obtain the url & auth token to upload our media - let uploadInfo = await options.getMediaOptions(false) - - let mediaUrl: string - for (let host of uploadInfo.hosts) { - const auth = encodeURIComponent(uploadInfo.auth) // the auth token - const url = `https://${host.hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` - - try { - const {body: responseText} = await got.post( - url, - { - headers: { - 'Content-Type': 'application/octet-stream', - 'Origin': DEFAULT_ORIGIN - }, - agent: { - https: options.agent - }, - body: createReadStream(encBodyPath) - } - ) - const result = JSON.parse(responseText) - mediaUrl = result?.url - - if (mediaUrl) break - else { - uploadInfo = await options.getMediaOptions(true) - throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) - } - } catch (error) { - const isLast = host.hostname === uploadInfo.hosts[uploadInfo.hosts.length-1].hostname - options.logger?.debug(`Error in uploading to ${host.hostname} (${error}) ${isLast ? '' : ', retrying...'}`) - } - } - if (!mediaUrl) { - throw new Boom( - 'Media upload failed on all hosts', - { statusCode: 500 } - ) - } + const {mediaUrl} = await options.upload( + createReadStream(encBodyPath), + { fileEncSha256B64, mediaType } + ) // remove tmp files await Promise.all( [ From ab58843b8a983a93dd5b3876c0a04c98fbcbf193 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 7 Aug 2021 10:55:52 +0530 Subject: [PATCH 019/311] iterable error in groups fix --- src/Connection/groups.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Connection/groups.ts b/src/Connection/groups.ts index 86540c8..44ba2e9 100644 --- a/src/Connection/groups.ts +++ b/src/Connection/groups.ts @@ -64,8 +64,8 @@ const makeGroupsSocket = (config: SocketConfig) => { }) const participants: GroupParticipant[] = [] let desc: string | undefined - if(Array.isArray(data)) { - const nodes = data[0].data as BinaryNode[] + if(Array.isArray(data) && Array.isArray(data[0].data)) { + const nodes = data[0].data for(const item of nodes) { if(item.header === 'participant') { participants.push({ From f8c53947059965df8607321cc4ed9e20d5373eca Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 9 Aug 2021 19:57:56 +0530 Subject: [PATCH 020/311] sticker media fix --- src/Connection/groups.ts | 1 - src/Connection/messages.ts | 6 ++++-- src/Store/in-memory-store.ts | 1 - src/Utils/messages-media.ts | 2 ++ 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Connection/groups.ts b/src/Connection/groups.ts index 44ba2e9..ca98665 100644 --- a/src/Connection/groups.ts +++ b/src/Connection/groups.ts @@ -199,7 +199,6 @@ const makeGroupsSocket = (config: SocketConfig) => { ev.emit('group-participants.update', { jid, participants: jids, action }) return jids }, - /** Query broadcast list info */ getBroadcastListInfo: async(jid: string) => { interface WABroadcastListInfo { diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index 82fcbfa..db75d02 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -1,7 +1,7 @@ import BinaryNode from "../BinaryNode"; import { Boom } from '@hapi/boom' import { EventEmitter } from 'events' -import { Chat, Presence, WAMessageCursor, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo, MessageInfoUpdate, WAMediaUploadFunction, MediaType } from "../Types"; +import { Chat, Presence, WAMessageCursor, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo, MessageInfoUpdate, WAMediaUploadFunction, MediaType, WAMessageUpdate } from "../Types"; import { isGroupID, toNumber, whatsappID, generateWAMessage, decryptMediaMessageBuffer } from "../Utils"; import makeChatsSocket from "./chats"; import { DEFAULT_ORIGIN, MEDIA_PATH_MAP, WA_DEFAULT_EPHEMERAL } from "../Defaults"; @@ -345,6 +345,7 @@ const makeMessagesSocket = (config: SocketConfig) => { // message status updates const onMessageStatusUpdate = ({ data }: BinaryNode) => { if(Array.isArray(data)) { + const updates: WAMessageUpdate[] = [] for(const { attributes: json } of data) { const key: WAMessageKey = { remoteJid: whatsappID(json.jid), @@ -354,11 +355,12 @@ const makeMessagesSocket = (config: SocketConfig) => { const status = STATUS_MAP[json.type] if(status) { - ev.emit('messages.update', [ { key, update: { status } } ]) + updates.push({ key, update: { status } }) } else { logger.warn({ data }, 'got unknown status update for message') } } + ev.emit('messages.update', updates) } } const onMessageInfoUpdate = ([,attributes]: [string,{[_: string]: any}]) => { diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index 9aea81e..564ad8e 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -143,7 +143,6 @@ export default( logger.debug({ update }, `got update for non-existent message`) } } - }) ev.on('messages.delete', item => { const list = assertMessageList(item.jid) diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index c8f3208..e8716c7 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -18,6 +18,8 @@ import { MediaType } from '../Types' import { DEFAULT_ORIGIN } from '../Defaults' export const hkdfInfoKey = (type: MediaType) => { + if(type === 'sticker') type = 'image' + let hkdfInfo = type[0].toUpperCase() + type.slice(1) return `WhatsApp ${hkdfInfo} Keys` } From 6d578399fc5b139801d6fecb20d4d499a8384fdc Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 9 Aug 2021 21:36:58 +0530 Subject: [PATCH 021/311] minor media update --- src/Connection/messages.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index db75d02..2721f0a 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -432,10 +432,11 @@ const makeMessagesSocket = (config: SocketConfig) => { return info }, downloadMediaMessage: async(message: WAMessage, type: 'buffer' | 'stream' = 'buffer') => { - let mContent = message.message?.ephemeralMessage?.message || message.message - if (!mContent) throw new Boom('No message present', { statusCode: 400, data: message }) - + const downloadMediaMessage = async () => { + let mContent = message.message?.ephemeralMessage?.message || message.message + if (!mContent) throw new Boom('No message present', { statusCode: 400, data: message }) + const stream = await decryptMediaMessageBuffer(mContent) if(type === 'buffer') { let buffer = Buffer.from([]) @@ -451,12 +452,11 @@ const makeMessagesSocket = (config: SocketConfig) => { const result = await downloadMediaMessage() return result } catch (error) { - if(error instanceof Boom && error.output?.statusCode === 404) { // media needs to be updated + if(error.message.includes('404')) { // media needs to be updated logger.info (`updating media of message: ${message.key.id}`) await updateMediaMessage(message) - mContent = message.message?.ephemeralMessage?.message || message.message const result = await downloadMediaMessage() return result } From 5ee5cd8c01c71f7227cea885367ea826b31da8e5 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 12 Aug 2021 20:00:40 +0530 Subject: [PATCH 022/311] fix message update bug --- src/Store/ordered-dictionary.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Store/ordered-dictionary.ts b/src/Store/ordered-dictionary.ts index fb6cd7e..d604586 100644 --- a/src/Store/ordered-dictionary.ts +++ b/src/Store/ordered-dictionary.ts @@ -51,7 +51,7 @@ const makeOrderedDictionary = function(idGetter: (item: T) => string) { if(item) { Object.assign(item, update) delete dict[id] - dict[id] = item + dict[idGetter(item)] = item return true } return false From e09d0ba24eade1bded02467761a6f63c2d2116ac Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 13 Aug 2021 18:06:11 +0530 Subject: [PATCH 023/311] update version --- src/Connection/messages.ts | 3 +++ src/Defaults/index.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index 2721f0a..7fec400 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -90,6 +90,9 @@ const makeMessagesSocket = (config: SocketConfig) => { expect200: true, requiresPhoneConnection: true }) + if(!response[1]) { + throw new Boom('Media not present on phone', { statusCode: 422 }) + } Object.keys(response[1]).forEach (key => content[key] = response[1][key]) // update message ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]) diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 852e25d..d0c7751 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -17,7 +17,7 @@ export const WA_DEFAULT_EPHEMERAL = 7*24*60*60 export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { - version: [2, 2123, 8], + version: [2, 2130, 9], browser: Browsers.baileys('Chrome'), waWebSocketUrl: 'wss://web.whatsapp.com/ws', From 15f759a52be249e62d482f74d6af7b81696c9189 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 15 Aug 2021 13:16:03 +0530 Subject: [PATCH 024/311] include media fix from @saviosg --- src/Utils/messages-media.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index e8716c7..9404b34 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -16,6 +16,7 @@ import { generateMessageID, hkdf } from './generics' import { Boom } from '@hapi/boom' import { MediaType } from '../Types' import { DEFAULT_ORIGIN } from '../Defaults' +import { once } from 'events' export const hkdfInfoKey = (type: MediaType) => { if(type === 'sticker') type = 'image' @@ -173,6 +174,8 @@ export const encryptedStream = async(media: WAMediaUpload, mediaType: MediaType, for await(const data of stream) { fileLength += data.length sha256Plain = sha256Plain.update(data) + if (writeStream && !writeStream.write(data)) await once(writeStream, 'drain') + writeStream && writeStream.write(data) onChunk(aes.update(data)) } @@ -185,9 +188,9 @@ export const encryptedStream = async(media: WAMediaUpload, mediaType: MediaType, const fileEncSha256 = sha256Enc.digest() encWriteStream.write(mac) - encWriteStream.close() + encWriteStream.end() - writeStream && writeStream.close() + writeStream && writeStream.end() return { mediaKey, From 96cd3b985ee8742c8d6231fc77e0c443c5d31584 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 15 Aug 2021 13:19:54 +0530 Subject: [PATCH 025/311] add image+video+sticker dimensions --- src/Types/Message.ts | 12 ++++++++---- src/Utils/messages.ts | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Types/Message.ts b/src/Types/Message.ts index da7e5a1..8bfd74e 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -57,27 +57,31 @@ type Buttonable = { /** add buttons to the message */ buttons?: proto.IButton[] } +type WithDimensions = { + width?: number + height?: number +} export type MediaType = 'image' | 'video' | 'sticker' | 'audio' | 'document' export type AnyMediaMessageContent = ( ({ image: WAMediaUpload caption?: string jpegThumbnail?: string - } & Mentionable & Buttonable) | + } & Mentionable & Buttonable & WithDimensions) | ({ video: WAMediaUpload caption?: string gifPlayback?: boolean jpegThumbnail?: string - } & Mentionable & Buttonable) | { + } & Mentionable & Buttonable & WithDimensions) | { audio: WAMediaUpload /** if set to true, will send as a `voice note` */ pttAudio?: boolean /** optionally tell the duration of the audio */ seconds?: number - } | { - sticker: WAMediaUpload } | ({ + sticker: WAMediaUpload + } & WithDimensions) | ({ document: WAMediaUpload mimetype: string fileName?: string diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index b15e689..c084b1e 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -120,6 +120,7 @@ export const prepareWAMessageMedia = async( fileEncSha256, fileSha256, fileLength, + ...uploadData } ) From a0bb9717b5638fc1b106b3f0c22678957075ea81 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 15 Aug 2021 16:13:20 +0530 Subject: [PATCH 026/311] fix media binary node --- src/Connection/messages.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index 7fec400..cbb4c32 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -81,7 +81,7 @@ const makeMessagesSocket = (config: SocketConfig) => { { statusCode: 400, data: message } ) - const response = await query ({ + const response: BinaryNode = await query ({ json: new BinaryNode( 'query', {type: 'media', index: message.key.id, owner: message.key.fromMe ? 'true' : 'false', jid: message.key.remoteJid, epoch: currentEpoch().toString()} @@ -90,10 +90,8 @@ const makeMessagesSocket = (config: SocketConfig) => { expect200: true, requiresPhoneConnection: true }) - if(!response[1]) { - throw new Boom('Media not present on phone', { statusCode: 422 }) - } - Object.keys(response[1]).forEach (key => content[key] = response[1][key]) // update message + const attrs = response.attributes + Object.keys(attrs).forEach (key => content[key] = attrs[key]) // update message ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]) From 4638f1261d675bf890a9f9a4dd97469e29e224b5 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 18 Aug 2021 11:25:56 +0530 Subject: [PATCH 027/311] add index to chat modifications --- src/Connection/chats.ts | 9 +++++++-- src/Connection/messages.ts | 8 +++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts index 1394c90..3cf8c34 100644 --- a/src/Connection/chats.ts +++ b/src/Connection/chats.ts @@ -280,7 +280,7 @@ const makeChatsSocket = (config: SocketConfig) => { * Modify a given chat (archive, pin etc.) * @param jid the ID of the person/group you are modifiying */ - modifyChat: async(jid: string, modification: ChatModification) => { + modifyChat: async(jid: string, modification: ChatModification, index?: WAMessageKey) => { let chatAttrs: Attributes = { jid: jid } let data: BinaryNode[] | undefined = undefined const stamp = unixTimestampSeconds() @@ -322,8 +322,13 @@ const makeChatsSocket = (config: SocketConfig) => { )) } + if(index) { + chatAttrs.index = index.id + chatAttrs.owner = index.fromMe ? 'true' : 'false' + } + const node = new BinaryNode('chat', chatAttrs, data) - const response = await setQuery ([node], [ WAMetric.chat, WAFlag.ignore ]) + const response = await setQuery([node], [ WAMetric.chat, WAFlag.ignore ]) // apply it and emit events executeChatModification(node) return response diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index cbb4c32..08d1f16 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -84,7 +84,13 @@ const makeMessagesSocket = (config: SocketConfig) => { const response: BinaryNode = await query ({ json: new BinaryNode( 'query', - {type: 'media', index: message.key.id, owner: message.key.fromMe ? 'true' : 'false', jid: message.key.remoteJid, epoch: currentEpoch().toString()} + { + type: 'media', + index: message.key.id, + owner: message.key.fromMe ? 'true' : 'false', + jid: message.key.remoteJid, + epoch: currentEpoch().toString() + } ), binaryTag: [WAMetric.queryMedia, WAFlag.ignore], expect200: true, From bbe58b7fa3e7256d5177ecf31fc0666c3d379c70 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 18 Aug 2021 11:44:07 +0530 Subject: [PATCH 028/311] minor bug fix --- src/Connection/auth.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Connection/auth.ts b/src/Connection/auth.ts index d6983ed..547340b 100644 --- a/src/Connection/auth.ts +++ b/src/Connection/auth.ts @@ -110,6 +110,11 @@ const makeAuthSocket = (config: SocketConfig) => { ) } + const updateEncKeys = () => { + // update the keys so we can decrypt traffic + socket.updateKeys({ encKey: authInfo!.encKey, macKey: authInfo!.macKey }) + } + const generateKeysForAuth = async(ref: string, ttl?: number) => { curveKeys = Curve.generateKeyPair(randomBytes(32)) const publicKey = Buffer.from(curveKeys.public).toString('base64') @@ -168,6 +173,7 @@ const makeAuthSocket = (config: SocketConfig) => { })(); let loginTag: string if(canDoLogin) { + updateEncKeys() // if we have the info to restore a closed session const json = [ 'admin', @@ -223,8 +229,7 @@ const makeAuthSocket = (config: SocketConfig) => { const isNewLogin = user.jid !== state.user?.jid authInfo = auth - // update the keys so we can decrypt traffic - socket.updateKeys({ encKey: auth.encKey, macKey: auth.macKey }) + updateEncKeys() logger.info({ user }, 'logged in') From 006d9e516fbc49037b73bf58dd65c7085a3c7f1d Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 18 Aug 2021 13:39:51 +0530 Subject: [PATCH 029/311] log bad session query --- src/Connection/socket.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Connection/socket.ts b/src/Connection/socket.ts index 739768a..2ee6a02 100644 --- a/src/Connection/socket.ts +++ b/src/Connection/socket.ts @@ -257,7 +257,7 @@ export const makeSocket = ({ const responseStatusCode = +(response.status ? response.status : 200) // default status // read here: http://getstatuscode.com/599 if(responseStatusCode === 599) { // the connection has gone bad - end(new Boom('WA server overloaded', { statusCode: 599 })) + end(new Boom('WA server overloaded', { statusCode: 599, data: { query: json, response } })) } if(expect200 && Math.floor(responseStatusCode/100) !== 2) { const message = STATUS_CODES[responseStatusCode] || 'unknown' From 3a914d69876b7f1d0ad0dd996691057618e01cae Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 18 Aug 2021 15:20:36 +0530 Subject: [PATCH 030/311] toNumber fix --- src/Utils/generics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/generics.ts b/src/Utils/generics.ts index 7fec9d1..3435a85 100644 --- a/src/Utils/generics.ts +++ b/src/Utils/generics.ts @@ -16,7 +16,7 @@ export const Browsers = { /** The appropriate browser based on your OS & release */ appropriate: browser => [ PLATFORM_MAP[platform()] || 'Ubuntu', browser, release() ] as [string, string, string] } -export const toNumber = (t: Long | number) => (t['low'] || t) as number +export const toNumber = (t: Long | number) => (typeof t?.['low'] !== 'undefined' ? t['low'] : t) as number export const whatsappID = (jid: string) => jid?.replace ('@c.us', '@s.whatsapp.net') export const isGroupID = (jid: string) => jid?.endsWith ('@g.us') From b0909c03ebffeb64f5a924f7523e8374c7ea649c Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 20 Aug 2021 17:05:58 +0530 Subject: [PATCH 031/311] contact upsert fix --- src/Connection/chats.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts index 3cf8c34..8d7d2b0 100644 --- a/src/Connection/chats.ts +++ b/src/Connection/chats.ts @@ -229,10 +229,9 @@ const makeChatsSocket = (config: SocketConfig) => { } }) - socketEvents.on ('CB:action,,user', json => { - const node = json[2][0] - if (node) { - const user = node[1] as Contact + socketEvents.on('CB:action,,user', (json: BinaryNode) => { + if(Array.isArray(json.data)) { + const user = json.data[0].attributes as any as Contact user.jid = whatsappID(user.jid) ev.emit('contacts.upsert', [user]) From 1fdc385307ee4496528708d3e1c1054b4131a9b8 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 21 Aug 2021 18:10:56 +0530 Subject: [PATCH 032/311] unlimited listeners --- src/Connection/socket.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Connection/socket.ts b/src/Connection/socket.ts index 2ee6a02..c250871 100644 --- a/src/Connection/socket.ts +++ b/src/Connection/socket.ts @@ -26,6 +26,7 @@ export const makeSocket = ({ phoneConnectionChanged }: SocketConfig) => { const socketEvents = new EventEmitter() + socketEvents.setMaxListeners(0) // for generating tags const referenceDateSeconds = unixTimestampSeconds(new Date()) const ws = new WebSocket(waWebSocketUrl, undefined, { @@ -41,6 +42,7 @@ export const makeSocket = ({ 'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits', } }) + ws.setMaxListeners(0) let lastDateRecv: Date let epoch = 0 let authInfo: { encKey: Buffer, macKey: Buffer } From 1a5b6388597ba137c7adedb6c4f46be54d6b36f6 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 21 Aug 2021 20:31:18 +0530 Subject: [PATCH 033/311] remove socketEvents, use ws instead for events --- src/Connection/chats.ts | 3 +-- src/Connection/groups.ts | 3 +-- src/Connection/index.ts | 1 - src/Connection/messages.ts | 2 +- src/Connection/socket.ts | 54 ++++++++++++++++++-------------------- 5 files changed, 28 insertions(+), 35 deletions(-) diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts index 8d7d2b0..b752018 100644 --- a/src/Connection/chats.ts +++ b/src/Connection/chats.ts @@ -1,5 +1,4 @@ import BinaryNode from "../BinaryNode"; -import { EventEmitter } from 'events' import { Chat, Contact, Presence, PresenceData, SocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessage, WAMessageUpdate } from "../Types"; import { debouncedTimeout, unixTimestampSeconds, whatsappID } from "../Utils/generics"; import makeAuthSocket from "./auth"; @@ -10,7 +9,7 @@ const makeChatsSocket = (config: SocketConfig) => { const sock = makeAuthSocket(config) const { ev, - socketEvents, + ws: socketEvents, currentEpoch, setQuery, query, diff --git a/src/Connection/groups.ts b/src/Connection/groups.ts index ca98665..a3085fa 100644 --- a/src/Connection/groups.ts +++ b/src/Connection/groups.ts @@ -1,5 +1,4 @@ import BinaryNode from "../BinaryNode"; -import { EventEmitter } from 'events' import { SocketConfig, GroupModificationResponse, ParticipantAction, GroupMetadata, WAFlag, WAMetric, WAGroupCreateResponse, GroupParticipant } from "../Types"; import { generateMessageID, unixTimestampSeconds, whatsappID } from "../Utils/generics"; import makeMessagesSocket from "./messages"; @@ -9,7 +8,7 @@ const makeGroupsSocket = (config: SocketConfig) => { const sock = makeMessagesSocket(config) const { ev, - socketEvents, + ws: socketEvents, query, generateMessageTag, currentEpoch, diff --git a/src/Connection/index.ts b/src/Connection/index.ts index 6c3eedd..b305b20 100644 --- a/src/Connection/index.ts +++ b/src/Connection/index.ts @@ -1,6 +1,5 @@ import { SocketConfig } from '../Types' import { DEFAULT_CONNECTION_CONFIG } from '../Defaults' -import { EventEmitter } from 'events' import _makeConnection from './groups' // export the last socket layer const makeConnection = (config: Partial) => ( diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index 08d1f16..f1562b6 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -18,7 +18,7 @@ const makeMessagesSocket = (config: SocketConfig) => { const sock = makeChatsSocket(config) const { ev, - socketEvents, + ws: socketEvents, query, generateMessageTag, currentEpoch, diff --git a/src/Connection/socket.ts b/src/Connection/socket.ts index c250871..50b1ab5 100644 --- a/src/Connection/socket.ts +++ b/src/Connection/socket.ts @@ -1,5 +1,4 @@ import { Boom } from '@hapi/boom' -import EventEmitter from "events" import { STATUS_CODES } from "http" import { promisify } from "util" import WebSocket from "ws" @@ -25,8 +24,6 @@ export const makeSocket = ({ expectResponseTimeout, phoneConnectionChanged }: SocketConfig) => { - const socketEvents = new EventEmitter() - socketEvents.setMaxListeners(0) // for generating tags const referenceDateSeconds = unixTimestampSeconds(new Date()) const ws = new WebSocket(waWebSocketUrl, undefined, { @@ -99,7 +96,7 @@ export const makeSocket = ({ const end = (error: Error | undefined) => { logger.debug({ error }, 'connection closed') - ws.removeAllListeners('close') + ws.removeAllListeners('close') ws.removeAllListeners('error') ws.removeAllListeners('open') ws.removeAllListeners('message') @@ -111,8 +108,8 @@ export const makeSocket = ({ if(ws.readyState !== ws.CLOSED && ws.readyState !== ws.CLOSING) { try { ws.close() } catch { } } + ws.emit('ws-close', error) - // so it cannot be re-emitted ws.removeAllListeners('ws-close') } const onMessageRecieved = (message: string | Buffer) => { @@ -120,7 +117,7 @@ export const makeSocket = ({ // when the first character in the message is an '!', the server is sending a pong frame const timestamp = message.slice(1, message.length).toString ('utf-8') lastDateRecv = new Date(parseInt(timestamp)) - socketEvents.emit('received-pong') + ws.emit('received-pong') } else { let messageTag: string let json: any @@ -141,19 +138,19 @@ export const makeSocket = ({ let anyTriggered = false /* Check if this is a response to a message we sent */ - anyTriggered = socketEvents.emit(`${DEF_TAG_PREFIX}${messageTag}`, json) + anyTriggered = ws.emit(`${DEF_TAG_PREFIX}${messageTag}`, json) /* Check if this is a response to a message we are expecting */ const l0 = json.header || json[0] || '' const l1 = json?.attributes || json?.[1] || { } const l2 = json?.data?.[0]?.header || json[2]?.[0] || '' Object.keys(l1).forEach(key => { - anyTriggered = socketEvents.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, json) || anyTriggered - anyTriggered = socketEvents.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, json) || anyTriggered - anyTriggered = socketEvents.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, json) || anyTriggered }) - anyTriggered = socketEvents.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, json) || anyTriggered - anyTriggered = socketEvents.emit(`${DEF_CALLBACK_PREFIX}${l0}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0}`, json) || anyTriggered if (!anyTriggered && logger.level === 'debug') { logger.debug({ unhandled: true, tag: messageTag, fromMe: false, json }, 'communication recv') @@ -170,12 +167,12 @@ export const makeSocket = ({ logger.info({ tag }, `cancelling wait for message as a response is no longer expected from the phone`) cancel(new Boom('Not expecting a response', { statusCode: 422 })) }, expectResponseTimeout) - socketEvents.off(PHONE_CONNECTION_CB, listener) + ws.off(PHONE_CONNECTION_CB, listener) } } - socketEvents.on(PHONE_CONNECTION_CB, listener) + ws.on(PHONE_CONNECTION_CB, listener) return () => { - socketEvents.off(PHONE_CONNECTION_CB, listener) + ws.off(PHONE_CONNECTION_CB, listener) timeout && clearTimeout(timeout) } } @@ -216,7 +213,7 @@ export const makeSocket = ({ let onRecv: (json) => void let onErr: (err) => void let cancelPhoneChecker: () => void - if (requiresPhoneConnection) { + if(requiresPhoneConnection) { startPhoneCheckInterval() cancelPhoneChecker = exitQueryIfResponseNotExpected(tag, onErr) } @@ -224,11 +221,12 @@ export const makeSocket = ({ const result = await promiseTimeout(timeoutMs, (resolve, reject) => { onRecv = resolve - onErr = err => reject(err || new Boom('Connection Closed', { statusCode: 429 })) + onErr = err => { + reject(err || new Boom('Connection Closed', { statusCode: 429 })) + } - socketEvents.on(`TAG:${tag}`, onRecv) - ws.on('close', onErr) // if the socket closes, you'll never receive the message - ws.on('error', onErr) + ws.on(`TAG:${tag}`, onRecv) + ws.on('ws-close', onErr) // if the socket closes, you'll never receive the message }, ) return result as any @@ -236,9 +234,8 @@ export const makeSocket = ({ requiresPhoneConnection && clearPhoneCheckInterval() cancelPhoneChecker && cancelPhoneChecker() - socketEvents.off(`TAG:${tag}`, onRecv) - ws.off('close', onErr) // if the socket closes, you'll never receive the message - ws.off('error', onErr) + ws.off(`TAG:${tag}`, onRecv) + ws.off('ws-close', onErr) // if the socket closes, you'll never receive the message } } /** @@ -303,9 +300,9 @@ export const makeSocket = ({ ws.on('error', onClose) }) .finally(() => { - socketEvents.off('open', onOpen) - socketEvents.off('close', onClose) - socketEvents.off('error', onClose) + ws.off('open', onOpen) + ws.off('close', onClose) + ws.off('error', onClose) }) } @@ -317,7 +314,7 @@ export const makeSocket = ({ ws.on('error', end) ws.on('close', () => end(new Boom('Connection Terminated', { statusCode: DisconnectReason.connectionLost }))) - socketEvents.on(PHONE_CONNECTION_CB, json => { + ws.on(PHONE_CONNECTION_CB, json => { if (!json[1]) { end(new Boom('Connection terminated by phone', { statusCode: DisconnectReason.connectionLost })) logger.info('Connection terminated by phone, closing...') @@ -325,7 +322,7 @@ export const makeSocket = ({ phoneConnectionChanged(true) } }) - socketEvents.on('CB:Cmd,type:disconnect', json => { + ws.on('CB:Cmd,type:disconnect', json => { const {kind} = json[1] let reason: DisconnectReason switch(kind) { @@ -343,7 +340,6 @@ export const makeSocket = ({ }) return { - socketEvents, ws, updateKeys: (info: { encKey: Buffer, macKey: Buffer }) => authInfo = info, waitForSocketOpen, From 77fb0322fd3f110b35d8dd712b0f34b181ecd76b Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 22 Aug 2021 14:17:11 +0530 Subject: [PATCH 034/311] Update Message.ts --- src/Types/Message.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 8bfd74e..d45bada 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -97,7 +97,7 @@ export type AnyRegularMessageContent = ( { contacts: { displayName?: string - contacts: WAContactMessage[] + contacts: proto.IContactMessage[] } } | { From acc551a3f11eb80e56d0ba6867e40569a81ad426 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 22 Aug 2021 14:30:48 +0530 Subject: [PATCH 035/311] add media cache option --- src/Types/Message.ts | 2 ++ src/Utils/messages.ts | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Types/Message.ts b/src/Types/Message.ts index d45bada..7deb27e 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -135,6 +135,8 @@ export type WAMediaUploadFunction = (readStream: ReadStream, opts: { fileEncSha2 export type MediaGenerationOptions = { logger?: Logger upload: WAMediaUploadFunction + /** cache media so it does not have to be uploaded again */ + mediaCache?: (url: string) => Promise | WAGenericMediaMessage } export type MessageContentGenerationOptions = MediaGenerationOptions & { getUrlInfo?: (text: string) => Promise diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index c084b1e..02cb2d7 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -63,6 +63,15 @@ export const prepareWAMessageMedia = async( [mediaType]: undefined, media: message[mediaType] } + // check for cache hit + if(typeof uploadData.media === 'object' && 'url' in uploadData.media) { + const result = !!options.mediaCache && await options.mediaCache!(uploadData.media.url?.toString()) + if(result) { + return WAMessageProto.Message.fromObject({ + [`${mediaType}Message`]: result + }) + } + } if(mediaType === 'document' && !uploadData.fileName) { uploadData.fileName = 'file' } @@ -71,7 +80,7 @@ export const prepareWAMessageMedia = async( } const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined' const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') && - !('jpegThumbnail' in uploadData) + (typeof uploadData['jpegThumbnail'] === 'undefined') const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation const { mediaKey, From b0699a1be9348e52c1c2a5b3745a65c0dc53a9c6 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 22 Aug 2021 15:35:16 +0530 Subject: [PATCH 036/311] button message headertype fix --- src/Utils/messages.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 02cb2d7..fed3587 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -48,6 +48,8 @@ const MessageTypeProto = { 'document': WAMessageProto.DocumentMessage, } as const +const ButtonType = proto.ButtonsMessage.ButtonsMessageHeaderType + export const prepareWAMessageMedia = async( message: AnyMediaMessageContent, options: MediaGenerationOptions @@ -237,7 +239,14 @@ export const generateWAMessageContent = async( } if('text' in message) { buttonsMessage.contentText = message.text + buttonsMessage.headerType = ButtonType.TEXT } else { + if('caption' in message) { + buttonsMessage.contentText = message.caption + } + const type = Object.keys(m)[0].replace('Message', '').toUpperCase() + buttonsMessage.headerType = ButtonType[type] + Object.assign(buttonsMessage, m) } m = { buttonsMessage } From 48f477e0c11ad7bee147e9f469d37f34b7d1aa8a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 22 Aug 2021 15:48:50 +0530 Subject: [PATCH 037/311] thumb generation fixes --- src/Connection/messages.ts | 2 ++ src/Utils/messages-media.ts | 7 ++++--- src/Utils/messages.ts | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index f1562b6..7d99b11 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -537,11 +537,13 @@ const makeMessagesSocket = (config: SocketConfig) => { content, { ...options, + logger, userJid: userJid, getUrlInfo: generateUrlInfo, upload: waUploadToServer } ) + await relayWAMessage(msg, { waitForAck: options.waitForAck }) return msg } diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 9404b34..7131df7 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -121,6 +121,7 @@ export async function generateThumbnail( options.logger?.debug('could not generate video thumb: ' + err) } } + return thumbnail } export const getGotStream = async(url: string | URL, options: Options & { isStream?: true } = {}) => { @@ -174,9 +175,9 @@ export const encryptedStream = async(media: WAMediaUpload, mediaType: MediaType, for await(const data of stream) { fileLength += data.length sha256Plain = sha256Plain.update(data) - if (writeStream && !writeStream.write(data)) await once(writeStream, 'drain') - - writeStream && writeStream.write(data) + if(writeStream) { + if(!writeStream.write(data)) await once(writeStream, 'drain') + } onChunk(aes.update(data)) } onChunk(aes.final()) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index fed3587..958d8f2 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -108,7 +108,7 @@ export const prepareWAMessageMedia = async( uploadData.seconds = await getAudioDuration(bodyPath) } } catch (error) { - options.logger?.debug ({ error }, 'failed to obtain audio duration: ' + error.message) + options.logger?.info({ trace: error.stack }, 'failed to obtain extra info') } const {mediaUrl} = await options.upload( createReadStream(encBodyPath), From 8a014df1c57c552bd178bd427000c0590763df8f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 24 Aug 2021 11:00:37 +0530 Subject: [PATCH 038/311] separate data structure for presence --- src/Connection/chats.ts | 33 +++++++++++---------------------- src/Connection/messages.ts | 11 +++++++---- src/Store/in-memory-store.ts | 14 ++++++++++---- src/Types/Chat.ts | 6 +----- src/Types/index.ts | 4 +++- 5 files changed, 32 insertions(+), 36 deletions(-) diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts index b752018..136a7bd 100644 --- a/src/Connection/chats.ts +++ b/src/Connection/chats.ts @@ -1,5 +1,5 @@ import BinaryNode from "../BinaryNode"; -import { Chat, Contact, Presence, PresenceData, SocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessage, WAMessageUpdate } from "../Types"; +import { Chat, Contact, Presence, PresenceData, SocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessage, WAMessageUpdate, BaileysEventMap } from "../Types"; import { debouncedTimeout, unixTimestampSeconds, whatsappID } from "../Utils/generics"; import makeAuthSocket from "./auth"; import { Attributes, BinaryNode as BinaryNodeBase } from "../BinaryNode/types"; @@ -91,26 +91,15 @@ const makeChatsSocket = (config: SocketConfig) => { } } - const applyingPresenceUpdate = (update: Attributes, chat: Partial) => { - chat.jid = whatsappID(update.id) - const jid = whatsappID(update.participant || update.id) + const applyingPresenceUpdate = (update: Attributes): BaileysEventMap['presence.update'] => { + const jid = whatsappID(update.id) + const participant = whatsappID(update.participant || update.id) - if (jid.endsWith('@s.whatsapp.net')) { // if its a single chat - chat.presences = chat.presences || {} - - const presence = { } as PresenceData - - if(update.t) { - presence.lastSeen = +update.t - } - presence.lastKnownPresence = update.type as Presence - chat.presences[jid] = presence - - chat.presences = { - [jid]: presence - } - } - return chat + const presence: PresenceData = { + lastSeen: update.t ? +update.t : undefined, + lastKnownPresence: update.type as Presence + } + return { jid, presences: { [participant]: presence } } } ev.on('connection.update', async({ connection }) => { @@ -239,8 +228,8 @@ const makeChatsSocket = (config: SocketConfig) => { // presence updates socketEvents.on('CB:Presence', json => { - const chat = applyingPresenceUpdate(json[1], { }) - ev.emit('chats.update', [ chat ]) + const update = applyingPresenceUpdate(json[1]) + ev.emit('presence.update', update) }) // blocklist updates diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index 7d99b11..aff4cb9 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -119,11 +119,14 @@ const makeMessagesSocket = (config: SocketConfig) => { if(!message.key.fromMe && message.message) { chatUpdate.count = 1 const participant = whatsappID(message.participant || jid) - chatUpdate.presences = { - [participant]: { - lastKnownPresence: Presence.available + + ev.emit( + 'presence.update', + { + jid, + presences: { [participant]: { lastKnownPresence: Presence.available } } } - } + ) } const ephemeralProtocolMsg = message.message?.ephemeralMessage?.message?.protocolMessage diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index 564ad8e..8e4ac32 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -2,7 +2,7 @@ import type KeyedDB from "@adiwajshing/keyed-db" import type { Comparable } from "@adiwajshing/keyed-db/lib/Types" import type { Logger } from "pino" import type { Connection } from "../Connection" -import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, MessageInfo, WAMessage, WAMessageCursor, WAMessageKey } from "../Types" +import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, MessageInfo, PresenceData, WAMessage, WAMessageCursor, WAMessageKey } from "../Types" import { toNumber } from "../Utils" import makeOrderedDictionary from "./ordered-dictionary" @@ -25,10 +25,11 @@ export default( ) => { const KeyedDBConstructor = require('@adiwajshing/keyed-db').default as new (...args: any[]) => KeyedDB const chats = new KeyedDBConstructor(chatKey, c => c.jid) - const messages: { [_: string]: ReturnType } = {} - const contacts: { [_: string]: Contact } = {} - const groupMetadata: { [_: string]: GroupMetadata } = {} + const messages: { [_: string]: ReturnType } = { } + const contacts: { [_: string]: Contact } = { } + const groupMetadata: { [_: string]: GroupMetadata } = { } const messageInfos: { [id: string]: MessageInfo } = { } + const presences: { [id: string]: { [participant: string]: PresenceData } } = { } const state: ConnectionState = { connection: 'close', phoneConnected: false @@ -88,6 +89,10 @@ export default( } } }) + ev.on('presence.update', ({ jid, presences: update }) => { + presences[jid] = presences[jid] || {} + Object.assign(presences[jid], update) + }) ev.on('chats.delete', deletions => { for(const item of deletions) { chats.deleteById(item) @@ -207,6 +212,7 @@ export default( groupMetadata, messageInfos, state, + presences, listen, loadMessages: async(jid: string, count: number, cursor: WAMessageCursor, sock: Connection | undefined) => { const list = assertMessageList(jid) diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index d35b929..5815b5a 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -8,9 +8,8 @@ export enum Presence { } export interface PresenceData { - lastKnownPresence?: Presence + lastKnownPresence: Presence lastSeen?: number - name?: string } export interface Chat { @@ -31,9 +30,6 @@ export interface Chat { eph_setting_ts?: string /** how long each message lasts for */ ephemeral?: string - - // Baileys added properties - presences?: { [k: string]: PresenceData } } export type ChatModification = diff --git a/src/Types/index.ts b/src/Types/index.ts index 0a32093..5b0008f 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -11,7 +11,7 @@ import type { Logger } from "pino" import type { URL } from "url" import type BinaryNode from "../BinaryNode" import { AnyAuthenticationCredentials, AuthenticationCredentials } from './Auth' -import { Chat } from './Chat' +import { Chat, PresenceData } from './Chat' import { Contact } from './Contact' import { ConnectionState } from './Store' @@ -176,6 +176,8 @@ export type BaileysEventMap = { 'chats.update': Partial[] 'chats.delete': string[] + 'presence.update': { jid: string, presences: { [participant: string]: PresenceData } } + 'contacts.set': { contacts: Contact[] } 'contacts.upsert': Contact[] 'contacts.update': Partial[] From dc471b365a493eb60f99b8d9044707cd640295e1 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 26 Aug 2021 19:32:53 +0530 Subject: [PATCH 039/311] impl orderdictionary filter --- src/Store/ordered-dictionary.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Store/ordered-dictionary.ts b/src/Store/ordered-dictionary.ts index d604586..a1a7af1 100644 --- a/src/Store/ordered-dictionary.ts +++ b/src/Store/ordered-dictionary.ts @@ -61,7 +61,15 @@ const makeOrderedDictionary = function(idGetter: (item: T) => string) { Object.keys(dict).forEach(key => { delete dict[key] }) }, filter: (contain: (item: T) => boolean) => { - //const copy = + let i = 0 + while(i < array.length) { + if(!contain(array[i])) { + delete dict[idGetter(array[i])] + array.splice(i, 1) + } else { + i += 1 + } + } } } } From e66e29f4725d506095a581b72c01376ab57bc2b5 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 26 Aug 2021 20:44:27 +0530 Subject: [PATCH 040/311] add extractMessageContent --- src/Connection/messages.ts | 4 ++-- src/Utils/messages.ts | 28 +++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index aff4cb9..27db7b6 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -2,7 +2,7 @@ import BinaryNode from "../BinaryNode"; import { Boom } from '@hapi/boom' import { EventEmitter } from 'events' import { Chat, Presence, WAMessageCursor, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo, MessageInfoUpdate, WAMediaUploadFunction, MediaType, WAMessageUpdate } from "../Types"; -import { isGroupID, toNumber, whatsappID, generateWAMessage, decryptMediaMessageBuffer } from "../Utils"; +import { isGroupID, toNumber, whatsappID, generateWAMessage, decryptMediaMessageBuffer, extractMessageContent } from "../Utils"; import makeChatsSocket from "./chats"; import { DEFAULT_ORIGIN, MEDIA_PATH_MAP, WA_DEFAULT_EPHEMERAL } from "../Defaults"; import got from "got"; @@ -444,7 +444,7 @@ const makeMessagesSocket = (config: SocketConfig) => { downloadMediaMessage: async(message: WAMessage, type: 'buffer' | 'stream' = 'buffer') => { const downloadMediaMessage = async () => { - let mContent = message.message?.ephemeralMessage?.message || message.message + let mContent = extractMessageContent(message.message) if (!mContent) throw new Boom('No message present', { statusCode: 400, data: message }) const stream = await decryptMediaMessageBuffer(mContent) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 958d8f2..1f0f9f7 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -336,4 +336,30 @@ export const generateWAMessage = async( ), options ) -) \ No newline at end of file +) + +/** + * Extract the true message content from a message + * Eg. extracts the inner message from a disappearing message/view once message + */ +export const extractMessageContent = (content: WAMessageContent | undefined | null): WAMessageContent | undefined => { + if(content?.buttonsMessage) { + const { buttonsMessage } = content + if(buttonsMessage.imageMessage) { + return { imageMessage: buttonsMessage.imageMessage } + } else if(buttonsMessage.documentMessage) { + return { documentMessage: buttonsMessage.documentMessage } + } else if(buttonsMessage.videoMessage) { + return { videoMessage: buttonsMessage.videoMessage } + } else if(buttonsMessage.locationMessage) { + return { locationMessage: buttonsMessage.locationMessage } + } else { + return { conversation: buttonsMessage.contentText } + } + } else { + return content?.ephemeralMessage?.message || + content?.viewOnceMessage?.message || + content || + undefined + } + } \ No newline at end of file From 241ac3ba6618882c8eb73fdaf4eada6b27710ad6 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 26 Aug 2021 21:52:47 +0530 Subject: [PATCH 041/311] minor connection error code typo --- src/Connection/socket.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Connection/socket.ts b/src/Connection/socket.ts index 50b1ab5..0c65f2d 100644 --- a/src/Connection/socket.ts +++ b/src/Connection/socket.ts @@ -222,7 +222,7 @@ export const makeSocket = ({ (resolve, reject) => { onRecv = resolve onErr = err => { - reject(err || new Boom('Connection Closed', { statusCode: 429 })) + reject(err || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) } ws.on(`TAG:${tag}`, onRecv) From 546cffcad2051fe27668a9a1734c5f45cb349e8e Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 27 Aug 2021 16:38:55 +0530 Subject: [PATCH 042/311] make jimp dynamic import --- src/Utils/messages-media.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 7131df7..798a8ca 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -3,7 +3,6 @@ import type { Logger } from 'pino' import type { IAudioMetadata } from 'music-metadata' import * as Crypto from 'crypto' import { Readable, Transform } from 'stream' -import Jimp from 'jimp' import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs' import { exec } from 'child_process' import { tmpdir } from 'os' @@ -53,17 +52,19 @@ const extractVideoThumb = async ( }) as Promise export const compressImage = async (bufferOrFilePath: Buffer | string) => { - const jimp = await Jimp.read(bufferOrFilePath as any) - const result = await jimp.resize(48, 48).getBufferAsync(Jimp.MIME_JPEG) + const { read, MIME_JPEG } = await import('jimp') + const jimp = await read(bufferOrFilePath as any) + const result = await jimp.resize(48, 48).getBufferAsync(MIME_JPEG) return result } export const generateProfilePicture = async (buffer: Buffer) => { - const jimp = await Jimp.read (buffer) + const { read, MIME_JPEG } = await import('jimp') + const jimp = await read (buffer) const min = Math.min(jimp.getWidth (), jimp.getHeight ()) const cropped = jimp.crop (0, 0, min, min) return { - img: await cropped.resize(640, 640).getBufferAsync (Jimp.MIME_JPEG), - preview: await cropped.resize(96, 96).getBufferAsync (Jimp.MIME_JPEG) + img: await cropped.resize(640, 640).getBufferAsync (MIME_JPEG), + preview: await cropped.resize(96, 96).getBufferAsync (MIME_JPEG) } } export const ProxyAgent = (host: string | URL) => HttpsProxyAgent(host) as any as Agent From c476510ab55f35c90865f2a7f0f64569f36f5cc0 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 2 Sep 2021 14:28:28 +0530 Subject: [PATCH 043/311] don't enforce unread count --- src/Connection/chats.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts index 136a7bd..d23d0e8 100644 --- a/src/Connection/chats.ts +++ b/src/Connection/chats.ts @@ -244,9 +244,6 @@ const makeChatsSocket = (config: SocketConfig) => { sendChatsQuery, fetchImageUrl, chatRead: async(fromMessage: WAMessageKey, count: number) => { - if(count < 0) { - count = -2 - } await setQuery ( [ new BinaryNode( From c4a9f26e92e21ac1eda28a34e718b477a1d9805a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 4 Sep 2021 21:42:27 +0530 Subject: [PATCH 044/311] fix chat t update --- src/Connection/messages.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index 27db7b6..89178de 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -109,12 +109,15 @@ const makeMessagesSocket = (config: SocketConfig) => { // store chat updates in this const chatUpdate: Partial = { jid, - t: +toNumber(message.messageTimestamp) } const emitGroupUpdate = (update: Partial) => { ev.emit('groups.update', [ { id: jid, ...update } ]) } + + if(message.message) { + chatUpdate.t = +toNumber(message.messageTimestamp) + } // add to count if the message isn't from me & there exists a message if(!message.key.fromMe && message.message) { chatUpdate.count = 1 From 7be1db3beb5d6577ee76088b5f78105fd8a76eee Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 8 Sep 2021 15:25:34 +0530 Subject: [PATCH 045/311] add inviteCode --- src/Connection/groups.ts | 10 +++++++++- src/Connection/messages.ts | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/Connection/groups.ts b/src/Connection/groups.ts index a3085fa..9ee0a1c 100644 --- a/src/Connection/groups.ts +++ b/src/Connection/groups.ts @@ -222,7 +222,15 @@ const makeGroupsSocket = (config: SocketConfig) => { )) } return metadata - } + }, + inviteCode: async(jid: string) => { + const response = await sock.query({ + json: ['query', 'inviteCode', jid], + expect200: true, + requiresPhoneConnection: false + }) + return response.code as string + } } } diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index 89178de..87af84f 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -117,19 +117,19 @@ const makeMessagesSocket = (config: SocketConfig) => { if(message.message) { chatUpdate.t = +toNumber(message.messageTimestamp) - } - // add to count if the message isn't from me & there exists a message - if(!message.key.fromMe && message.message) { - chatUpdate.count = 1 - const participant = whatsappID(message.participant || jid) + // add to count if the message isn't from me & there exists a message + if(!message.key.fromMe) { + chatUpdate.count = 1 + const participant = whatsappID(message.participant || jid) - ev.emit( - 'presence.update', - { - jid, - presences: { [participant]: { lastKnownPresence: Presence.available } } - } - ) + ev.emit( + 'presence.update', + { + jid, + presences: { [participant]: { lastKnownPresence: Presence.available } } + } + ) + } } const ephemeralProtocolMsg = message.message?.ephemeralMessage?.message?.protocolMessage From 9993de834051f2ecbcf1e48a398d64b196f4021a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 9 Sep 2021 17:21:11 +0530 Subject: [PATCH 046/311] urlInfo fix --- src/Connection/messages.ts | 15 ++++++++++----- src/Utils/messages.ts | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index 87af84f..c6a3bc8 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -272,19 +272,24 @@ const makeMessagesSocket = (config: SocketConfig) => { /** Query a string to check if it has a url, if it does, return WAUrlInfo */ const generateUrlInfo = async(text: string) => { - const response = await query({ + const response: BinaryNode = await query({ json: new BinaryNode( 'query', - {type: 'url', url: text, epoch: currentEpoch().toString()} + { + type: 'url', + url: text, + epoch: currentEpoch().toString() + } ), binaryTag: [26, WAFlag.ignore], expect200: true, requiresPhoneConnection: false }) - if(response[1]) { - response[1].jpegThumbnail = response[2] + const urlInfo = { ...response.attributes } as any as WAUrlInfo + if(response && response.data) { + urlInfo.jpegThumbnail = response.data as Buffer } - return response[1] as WAUrlInfo + return urlInfo } /** Relay (send) a WAMessage; more advanced functionality to send a built WA Message, you may want to stick with sendMessage() */ diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 1f0f9f7..7e81860 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -197,7 +197,7 @@ export const generateWAMessageContent = async( extContent.title = data.title extContent.previewType = 0 } catch (error) { // ignore if fails - + options.logger?.warn({ trace: error.stack }, 'url generation failed') } } m.extendedTextMessage = extContent From c195e999f13196dc2802210950e61a2d5100a8ba Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 9 Sep 2021 18:24:33 +0530 Subject: [PATCH 047/311] push msg updates for individual chats --- src/Connection/messages.ts | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts index c6a3bc8..9432eb0 100644 --- a/src/Connection/messages.ts +++ b/src/Connection/messages.ts @@ -398,17 +398,29 @@ const makeMessagesSocket = (config: SocketConfig) => { logger.warn({ attributes }, `received unknown message info update`) return } + const keyPartial = { + remoteJid: whatsappID(attributes.to), + fromMe: whatsappID(attributes.from) === getState().user?.jid, + } const updates = ids.map(id => ({ - key: { - remoteJid: whatsappID(attributes.to), - id, - fromMe: whatsappID(attributes.from) === getState().user?.jid, - }, + key: { ...keyPartial, id }, update: { [updateKey]: { [whatsappID(attributes.participant)]: new Date(+attributes.t) } } })) ev.emit('message-info.update', updates) + // for individual messages + // it means the message is marked read/delivered + if(!isGroupID(keyPartial.remoteJid)) { + ev.emit('messages.update', ids.map(id => ( + { + key: { ...keyPartial, id }, + update: { + status: updateKey === 'deliveries' ? WAMessageStatus.DELIVERY_ACK : WAMessageStatus.READ + } + } + ))) + } } socketEvents.on('CB:action,add:relay,received', onMessageStatusUpdate) From 9cba28e891039099860357ede78cce5fb7f4610b Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 9 Sep 2021 20:54:33 +0530 Subject: [PATCH 048/311] undefined onErr bug fix --- src/Connection/socket.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Connection/socket.ts b/src/Connection/socket.ts index 0c65f2d..a192638 100644 --- a/src/Connection/socket.ts +++ b/src/Connection/socket.ts @@ -213,10 +213,6 @@ export const makeSocket = ({ let onRecv: (json) => void let onErr: (err) => void let cancelPhoneChecker: () => void - if(requiresPhoneConnection) { - startPhoneCheckInterval() - cancelPhoneChecker = exitQueryIfResponseNotExpected(tag, onErr) - } try { const result = await promiseTimeout(timeoutMs, (resolve, reject) => { @@ -224,6 +220,11 @@ export const makeSocket = ({ onErr = err => { reject(err || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) } + + if(requiresPhoneConnection) { + startPhoneCheckInterval() + cancelPhoneChecker = exitQueryIfResponseNotExpected(tag, onErr) + } ws.on(`TAG:${tag}`, onRecv) ws.on('ws-close', onErr) // if the socket closes, you'll never receive the message From f267f27adaa2dbbd4a9e1c029a6362e5e8bc5ed5 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 15 Sep 2021 13:40:02 +0530 Subject: [PATCH 049/311] finalize multi-device --- .gitignore | 3 +- Example/ConversationExtract.js | 97 - Example/example.ts | 93 +- LICENSE.md | 21 - README.md | 558 +- WABinary/Binary.js | 585 + WABinary/Constants.js | 21 + WABinary/HexHelper.js | 117 + WABinary/readme.md | 15 + .../BinaryNode => WAProto}/GenerateStatics.sh | 4 +- .../WAMessage.proto => WAProto/WAProto.proto | 771 +- {WAMessage => WAProto}/index.d.ts | 9715 +++++- {WAMessage => WAProto}/index.js | 24306 +++++++++++++--- WASignalGroup/ciphertext_message.js | 16 + WASignalGroup/group.proto | 41 + WASignalGroup/group_cipher.js | 106 + WASignalGroup/group_session_builder.js | 51 + WASignalGroup/index.js | 5 + WASignalGroup/protobufs.js | 13 + WASignalGroup/readme.md | 6 + WASignalGroup/sender_chain_key.js | 50 + .../sender_key_distribution_message.js | 78 + WASignalGroup/sender_key_message.js | 92 + WASignalGroup/sender_key_name.js | 70 + WASignalGroup/sender_key_record.js | 54 + WASignalGroup/sender_key_state.js | 129 + WASignalGroup/sender_message_key.js | 39 + package.json | 8 +- src/BinaryNode/decode.ts | 204 - src/BinaryNode/encode.ts | 123 - src/BinaryNode/index.ts | 8 - src/BinaryNode/types.ts | 212 - src/BrowserMessageDecoding.ts | 41 - src/Connection/auth.ts | 275 - src/Connection/chats.ts | 478 - src/Connection/groups.ts | 237 - src/Connection/index.ts | 14 - src/Connection/messages.ts | 577 - src/Connection/socket.ts | 367 - src/Defaults/index.ts | 25 +- src/Socket/chats.ts | 430 + src/Socket/groups.ts | 149 + src/Socket/index.ts | 13 + src/Socket/messages-recv.ts | 437 + src/Socket/messages-send.ts | 392 + src/Socket/socket.ts | 469 + src/Store/in-memory-store.ts | 13 +- src/Tests/Common.ts | 76 - src/Tests/Tests.Binary.ts | 89 - src/Tests/Tests.Connect.ts | 407 - src/Tests/Tests.Groups.ts | 193 - src/Tests/Tests.Media.ts | 43 - src/Tests/Tests.Messages.ts | 268 - src/Tests/Tests.Misc.ts | 430 - src/Tests/Tests.Mutex.ts | 111 - src/Tests/_test.manual_tests.ts | 112 - src/Tests/test.binary.ts | 95 - src/Tests/test.connect.ts | 94 - src/Tests/test.message-gen.ts | 8 - src/Tests/test.queries.ts | 165 - src/Types/Auth.ts | 65 +- src/Types/Chat.ts | 43 +- src/Types/Contact.ts | 14 +- src/Types/GroupMetadata.ts | 2 +- src/Types/Message.ts | 35 +- src/Types/State.ts | 17 + src/Types/Store.ts | 25 - src/Types/index.ts | 134 +- src/Utils/chat-utils.ts | 198 + src/Utils/decode-wa-message.ts | 154 +- src/Utils/generics.ts | 166 +- src/Utils/history.ts | 25 + src/Utils/messages-media.ts | 110 +- src/Utils/messages.ts | 41 +- src/Utils/noise-handler.ts | 167 + src/Utils/signal.ts | 253 + src/Utils/validate-connection.ts | 300 +- src/WABinary/JidUtils.ts | 47 + src/WABinary/LTHash.js | 48 + src/WABinary/index.ts | 305 + src/index.ts | 10 +- yarn.lock | 94 +- 82 files changed, 35228 insertions(+), 10644 deletions(-) delete mode 100644 Example/ConversationExtract.js delete mode 100644 LICENSE.md create mode 100644 WABinary/Binary.js create mode 100644 WABinary/Constants.js create mode 100644 WABinary/HexHelper.js create mode 100644 WABinary/readme.md rename {src/BinaryNode => WAProto}/GenerateStatics.sh (50%) rename src/BinaryNode/WAMessage.proto => WAProto/WAProto.proto (69%) rename {WAMessage => WAProto}/index.d.ts (60%) rename {WAMessage => WAProto}/index.js (65%) create mode 100644 WASignalGroup/ciphertext_message.js create mode 100644 WASignalGroup/group.proto create mode 100644 WASignalGroup/group_cipher.js create mode 100644 WASignalGroup/group_session_builder.js create mode 100644 WASignalGroup/index.js create mode 100644 WASignalGroup/protobufs.js create mode 100644 WASignalGroup/readme.md create mode 100644 WASignalGroup/sender_chain_key.js create mode 100644 WASignalGroup/sender_key_distribution_message.js create mode 100644 WASignalGroup/sender_key_message.js create mode 100644 WASignalGroup/sender_key_name.js create mode 100644 WASignalGroup/sender_key_record.js create mode 100644 WASignalGroup/sender_key_state.js create mode 100644 WASignalGroup/sender_message_key.js delete mode 100644 src/BinaryNode/decode.ts delete mode 100644 src/BinaryNode/encode.ts delete mode 100644 src/BinaryNode/index.ts delete mode 100644 src/BinaryNode/types.ts delete mode 100644 src/BrowserMessageDecoding.ts delete mode 100644 src/Connection/auth.ts delete mode 100644 src/Connection/chats.ts delete mode 100644 src/Connection/groups.ts delete mode 100644 src/Connection/index.ts delete mode 100644 src/Connection/messages.ts delete mode 100644 src/Connection/socket.ts create mode 100644 src/Socket/chats.ts create mode 100644 src/Socket/groups.ts create mode 100644 src/Socket/index.ts create mode 100644 src/Socket/messages-recv.ts create mode 100644 src/Socket/messages-send.ts create mode 100644 src/Socket/socket.ts delete mode 100644 src/Tests/Common.ts delete mode 100644 src/Tests/Tests.Binary.ts delete mode 100644 src/Tests/Tests.Connect.ts delete mode 100644 src/Tests/Tests.Groups.ts delete mode 100644 src/Tests/Tests.Media.ts delete mode 100644 src/Tests/Tests.Messages.ts delete mode 100644 src/Tests/Tests.Misc.ts delete mode 100644 src/Tests/Tests.Mutex.ts delete mode 100644 src/Tests/_test.manual_tests.ts delete mode 100644 src/Tests/test.binary.ts delete mode 100644 src/Tests/test.connect.ts delete mode 100644 src/Tests/test.message-gen.ts delete mode 100644 src/Tests/test.queries.ts create mode 100644 src/Types/State.ts delete mode 100644 src/Types/Store.ts create mode 100644 src/Utils/chat-utils.ts create mode 100644 src/Utils/history.ts create mode 100644 src/Utils/noise-handler.ts create mode 100644 src/Utils/signal.ts create mode 100644 src/WABinary/JidUtils.ts create mode 100644 src/WABinary/LTHash.js create mode 100644 src/WABinary/index.ts diff --git a/.gitignore b/.gitignore index 529e08a..ad1c15d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ lib docs browser-token.json Proxy -messages*.json \ No newline at end of file +messages*.json +test.ts \ No newline at end of file diff --git a/Example/ConversationExtract.js b/Example/ConversationExtract.js deleted file mode 100644 index d1a7333..0000000 --- a/Example/ConversationExtract.js +++ /dev/null @@ -1,97 +0,0 @@ -const WhatsAppWeb = require("../WhatsAppWeb") -const fs = require("fs") - -/** - * Extract all your WhatsApp conversations & save them to a file - * produceAnonData => should the Id of the chat be recorded - * */ -function extractChats (authCreds, outputFile, produceAnonData=false, offset=null) { - let client = new WhatsAppWeb() // instantiate an instance - // internal extract function - const extract = function () { - let rows = 0 - let chats = Object.keys(client.chats) - let encounteredOffset - if (offset) { - encounteredOffset = false - } else { - encounteredOffset = true - fs.writeFileSync(outputFile, "chat,input,output\n") // write header to file - } - - const extractChat = function (index) { - const id = chats[index] - if (id.includes("g.us") || !encounteredOffset) { // skip groups - if (id === offset) { - encounteredOffset = true - } - if (index+1 < chats.length) { - return extractChat(index+1) - } - return - } - console.log("extracting for " + id + "...") - - var curInput = "" - var curOutput = "" - var lastMessage - return client.loadEntireConversation (id, m => { - var text - if (!m.message) { // if message not present, return - return - } else if (m.message.conversation) { // if its a plain text message - text = m.message.conversation - } else if (m.message.extendedTextMessage && m.message.extendedTextMessage.contextInfo) { // if its a reply to a previous message - const mText = m.message.extendedTextMessage.text - const quotedMessage = m.message.extendedTextMessage.contextInfo.quotedMessage - // if it's like a '.' and the quoted message has no text, then just forget it - if (mText.length <= 2 && !quotedMessage.conversation) { - return - } - // if somebody sent like a '.', then the text should be the quoted message - if (mText.length <= 2) { - text = quotedMessage.conversation - } else { // otherwise just use this text - text = mText - } - } else { - return - } - // if the person who sent the message has switched, flush the row - if (lastMessage && !m.key.fromMe && lastMessage.key.fromMe) { - - let row = "" + (produceAnonData ? "" : id) + ",\"" + curInput + "\",\"" + curOutput + "\"\n" - fs.appendFileSync (outputFile, row) - rows += 1 - curInput = "" - curOutput = "" - } - - if (m.key.fromMe) { - curOutput += curOutput === "" ? text : ("\n"+text) - } else { - curInput += curInput === "" ? text : ("\n"+text) - } - - lastMessage = m - }, 50, false) // load from the start, in chunks of 50 - .then (() => console.log("finished extraction for " + id)) - .then (() => { - if (index+1 < chats.length) { - return extractChat(index+1) - } - }) - } - - extractChat(0) - .then (() => { - console.log("extracted all; total " + rows + " rows") - client.logout () - }) - } - client.connect (authCreds) - .then (() => extract()) - .catch (err => console.log("got error: " + error)) -} -let creds = null//JSON.parse(fs.readFileSync("auth_info.json")) -extractChats(creds, "output.csv") \ No newline at end of file diff --git a/Example/example.ts b/Example/example.ts index ad85df4..09545f1 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -1,13 +1,84 @@ -import makeConnection from '../src' -import * as fs from 'fs' +import { readFileSync, writeFileSync } from "fs" +import P from "pino" +import { Boom } from "@hapi/boom" +import makeWASocket, { WASocket, AuthenticationState, DisconnectReason, AnyMessageContent, BufferJSON, initInMemoryKeyStore, delay } from '../src' -async function example() { - const conn = makeConnection({ - credentials: './auth_info.json' - }) - conn.ev.on('connection.update', state => { - console.log(state) - }) -} +(async() => { + let sock: WASocket | undefined = undefined + // load authentication state from a file + const loadState = () => { + let state: AuthenticationState | undefined = undefined + try { + const value = JSON.parse( + readFileSync('./auth_info_multi.json', { encoding: 'utf-8' }), + BufferJSON.reviver + ) + state = { + creds: value.creds, + // stores pre-keys, session & other keys in a JSON object + // we deserialize it here + keys: initInMemoryKeyStore(value.keys) + } + } catch{ } + return state + } + // save the authentication state to a file + const saveState = (state?: any) => { + console.log('saving pre-keys') + state = state || sock?.authState + writeFileSync( + './auth_info_multi.json', + // BufferJSON replacer utility saves buffers nicely + JSON.stringify(state, BufferJSON.replacer, 2) + ) + } + // start a connection + const startSock = () => { + const sock = makeWASocket({ + logger: P({ level: 'trace' }), + auth: loadState() + }) + sock.ev.on('messages.upsert', m => { + console.log(JSON.stringify(m, undefined, 2)) + + const msg = m.messages[0] + if(!msg.key.fromMe && m.type === 'notify') { + console.log('replying to', m.messages[0].key.remoteJid) + sendMessageWTyping({ text: 'Hello there!' }, m.messages[0].key.remoteJid!) + } + + }) + sock.ev.on('messages.update', m => console.log(m)) + sock.ev.on('presence.update', m => console.log(m)) + sock.ev.on('chats.update', m => console.log(m)) + return sock + } -example().catch((err) => console.log(`encountered error`, err)) \ No newline at end of file + const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { + + await sock.presenceSubscribe(jid) + await delay(500) + + await sock.sendPresenceUpdate('composing', jid) + await delay(2000) + + await sock.sendPresenceUpdate('paused', jid) + } + + sock = startSock() + sock.ev.on('connection.update', (update) => { + const { connection, lastDisconnect } = update + if(connection === 'close') { + // reconnect if not logged out + if((lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut) { + sock = startSock() + } else { + console.log('connection closed') + } + } + console.log('connection update', update) + }) + // listen for when the auth state is updated + // it is imperative you save this data, it affects the signing keys you need to have conversations + sock.ev.on('auth-state.update', () => saveState()) +})() \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index bc4e5a9..0000000 --- a/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Adhiraj Singh - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index c51a2bc..ac52bfd 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ -# Baileys - Typescript/Javascript WhatsApp Web API +# Baileys MD - Typescript/Javascript WhatsApp Web API + Early Multi-Device Edition. Breaks completely from master. + Baileys does not require Selenium or any other browser to be interface with WhatsApp Web, it does so directly using a **WebSocket**. Not running Selenium or Chromimum saves you like **half a gig** of ram :/ - Thank you to [@Sigalor](https://github.com/sigalor/whatsapp-web-reveng) for writing his observations on the workings of WhatsApp Web and thanks to [@Rhymen](https://github.com/Rhymen/go-whatsapp/) for the __go__ implementation. + Thank you to [@pokearaujo](https://github.com/pokearaujo/multidevice) for writing his observations on the workings of WhatsApp Multi-Device. Baileys is type-safe, extensible and simple to use. If you require more functionality than provided, it'll super easy for you to write an extension. More on this [here](#WritingCustomFunctionality). @@ -12,107 +14,102 @@ **Join the Discord [here](https://discord.gg/7FYURJyqng)** ## Example + Do check out & run [example.ts](Example/example.ts) to see example usage of the library. The script covers most common use cases. To run the example script, download or clone the repo and then type the following in terminal: 1. ``` cd path/to/Baileys ``` -2. ``` npm install ``` -3. ``` npm run example ``` +2. ``` yarn``` +3. ``` yarn example ``` ## Install -Create and cd to your NPM project directory and then in terminal, write: -1. stable: `npm install @adiwajshing/baileys` -2. stabl-ish w quicker fixes & latest features: `npm install github:adiwajshing/baileys` -Do note, the library will likely vary if you're using the NPM package, read that [here](https://www.npmjs.com/package/@adiwajshing/baileys) +Right now, the multi-device branch is only available from GitHub, install using: +``` +yarn add github:adiwajshing/baileys#multi-device +``` Then import in your code using: ``` ts -import { WAConnection } from '@adiwajshing/baileys' +import makeWASocket from '@adiwajshing/baileys' ``` ## Unit Tests -Baileys also comes with a unit test suite. Simply cd into the Baileys directory & run `npm test`. -You will require a phone with WhatsApp to test, and a second WhatsApp number to send messages to. -Set the phone number you can randomly send messages to in a `.env` file with `TEST_JID=1234@s.whatsapp.net` +TODO ## Connecting + ``` ts -import { WAConnection } from '@adiwajshing/baileys' +import makeWASocket from '@adiwajshing/baileys' async function connectToWhatsApp () { - const conn = new WAConnection() - // called when WA sends chats - // this can take up to a few minutes if you have thousands of chats! - conn.on('chats-received', async ({ hasNewChats }) => { - console.log(`you have ${conn.chats.length} chats, new chats available: ${hasNewChats}`) - - const unread = await conn.loadAllUnreadMessages () - console.log ("you have " + unread.length + " unread messages") + const conn = makeWASocket({ + // can provide additional config here + printQRInTerminal: true }) - // called when WA sends chats - // this can take up to a few minutes if you have thousands of contacts! - conn.on('contacts-received', () => { - console.log('you have ' + Object.keys(conn.contacts).length + ' contacts') + sock.ev.on('connection.update', (update) => { + const { connection, lastDisconnect } = update + if(connection === 'close') { + const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut + console.log('connection closed due to ', lastDisconnect.error, ', reconnecting ', shouldReconnect) + // reconnect if not logged out + if(shouldReconnect) { + sock = startSock() + } + } else if(connection === 'open') { + console.log('opened connection') + } }) + sock.ev.on('messages.upsert', m => { + console.log(JSON.stringify(m, undefined, 2)) - await conn.connect () - conn.on('chat-update', chatUpdate => { - // `chatUpdate` is a partial object, containing the updated properties of the chat - // received a new message - if (chatUpdate.messages && chatUpdate.count) { - const message = chatUpdate.messages.all()[0] - console.log (message) - } else console.log (chatUpdate) // see updates (can be archived, pinned etc.) + console.log('replying to', m.messages[0].key.remoteJid) + sendMessageWTyping({ text: 'Hello there!' }, m.messages[0].key.remoteJid!) }) } // run in main file -connectToWhatsApp () -.catch (err => console.log("unexpected error: " + err) ) // catch any errors +connectToWhatsApp() ``` If the connection is successful, you will see a QR code printed on your terminal screen, scan it with WhatsApp on your phone and you'll be logged in! -Do note, the `conn.chats` object is a [KeyedDB](https://github.com/adiwajshing/keyed-db). This is done for the following reasons: -- Most applications require chats to be ordered in descending order of time. (`KeyedDB` does this in `log(N)` time) -- Most applications require pagination of chats (Use `chats.paginated()`) -- Most applications require **O(1)** access to chats via the chat ID. (Use `chats.get(jid)` with `KeyedDB`) +**Note:** install `qrcode-terminal` using `yarn add qrcode-terminal` to auto-print the QR to the terminal. + +## Notable Differences Between Baileys Web & MD + +1. Baileys no longer maintains an internal state of chats/contacts/messages. You must take this on your own, simply because your state in MD is its own source of truth & there is no one-size-fits-all way to handle the storage for this. +2. A baileys "socket" is meant to be a temporary & disposable object -- this is done to maintain simplicity & prevent bugs. I felt the entire Baileys object became too bloated as it supported too many configurations. +3. Moreover, Baileys does not offer an inbuilt reconnect mechanism anymore (though it's super easy to set one up on your own with your own rules, check the example script) ## Configuring the Connection -You can configure the connection via the `connectOptions` property. You can even specify an HTTPS proxy. For example: +You can configure the connection by passing a `SocketConfig` object. +The entire `SocketConfig` structure is mentioned here with default values: ``` ts -import { WAConnection, ProxyAgent } from '@adiwajshing/baileys' - -const conn = new WAConnecion () -conn.connectOptions.agent = ProxyAgent ('http://some-host:1234') - -await conn.connect () -console.log ("oh hello " + conn.user.name + "! You connected via a proxy") -``` - -The entire `WAConnectOptions` struct is mentioned here with default values: -``` ts -conn.connectOptions = { - /** fails the connection if no data is received for X seconds */ - maxIdleTimeMs?: 60_000, - /** maximum attempts to connect */ - maxRetries?: 10, - /** max time for the phone to respond to a connectivity test */ - phoneResponseTime?: 15_000, - /** minimum time between new connections */ - connectCooldownMs?: 4000, - /** agent used for WS connections (could be a proxy agent) */ - agent?: Agent = undefined, - /** agent used for fetch requests -- uploading/downloading media */ - fetchAgent?: Agent = undefined, - /** always uses takeover for connecting */ - alwaysUseTakeover: true - /** log QR to terminal */ - logQR: true -} as WAConnectOptions +type SocketConfig = { + /** provide an auth state object to maintain the auth state */ + auth?: AuthenticationState + /** the WS url to connect to WA */ + waWebSocketUrl: string | URL + /** Fails the connection if the connection times out in this time interval or no data is received */ + connectTimeoutMs: number + /** ping-pong interval for WS connection */ + keepAliveIntervalMs: number + /** proxy agent */ + agent?: Agent + /** pino logger */ + logger: Logger + /** version to connect with */ + version: WAVersion + /** override browser config */ + browser: WABrowserDescription + /** agent used for fetch requests -- uploading/downloading media */ + fetchAgent?: Agent + /** should the QR be printed in the terminal */ + printQRInTerminal: boolean +} ``` ## Saving & Restoring Sessions @@ -121,92 +118,126 @@ You obviously don't want to keep scanning the QR code every time you want to con So, you can save the credentials to log back in via: ``` ts +import makeWASocket, { BufferJSON } from '@adiwajshing/baileys' import * as fs from 'fs' -const conn = new WAConnection() +// will initialize a default in-memory auth session +const conn = makeSocket() // this will be called as soon as the credentials are updated -conn.on ('open', () => { +conn.ev.on ('auth-state.update', () => { // save credentials whenever updated console.log (`credentials updated!`) - const authInfo = conn.base64EncodedAuthInfo() // get all the auth info we need to restore this session - fs.writeFileSync('./auth_info.json', JSON.stringify(authInfo, null, '\t')) // save this info to a file + const authInfo = conn.authState // get all the auth info we need to restore this session + // save this info to a file + fs.writeFileSync( + './auth_info.json', + JSON.stringify(authInfo, BufferJSON.replacer, 2) + ) }) -await conn.connect() // connect ``` Then, to restore a session: ``` ts -const conn = new WAConnection() -conn.loadAuthInfo ('./auth_info.json') // will load JSON credentials from file -await conn.connect() -// yay connected without scanning QR -/* - Optionally, you can load the credentials yourself from somewhere - & pass in the JSON object to loadAuthInfo () as well. -*/ -``` +import makeWASocket, { BufferJSON, initInMemoryKeyStore } from '@adiwajshing/baileys' +import * as fs from 'fs' -If you're considering switching from a Chromium/Puppeteer based library, you can use WhatsApp Web's Browser credentials to restore sessions too: -``` ts -conn.loadAuthInfo ('./auth_info_browser.json') -await conn.connect() // works the same -``` -See the browser credentials type in the docs. - -**Note**: Upon every successive connection, WA can update part of the stored credentials. Whenever that happens, the credentials are uploaded, and you should probably update your saved credentials upon receiving the `open` event. Not doing so *may* lead WA to log you out after a few weeks with a 419 error code. - -## QR Callback - -If you want to do some custom processing with the QR code used to authenticate, you can register for the following event: -``` ts -conn.on('qr', qr => { - // Now, use the 'qr' string to display in QR UI or send somewhere +const authJSON = JSON.parse( + fs.readFileSync( + './auth_info.json', + { encoding: 'utf-8' } + ), + BufferJSON.reviver +) +const auth = { + creds: authJSON.creds, + // stores pre-keys, session & other keys in a JSON object + // we deserialize it here + keys: initInMemoryKeyStore(authJSON.keys) } -await conn.connect () +const conn = makeWASocket(auth) +// yay will connect without scanning QR ``` +**Note**: Upon every successive connection, the auth state can update part of the stored credentials. It will also update when a message is received/sent due to signal sessions needing updating. Whenever that happens, the `auth-state.update` event is fired uploaded, and you must update your saved credentials upon receiving the event. Not doing so will prevent your messages from reaching the recipient & other unexpected consequences. + +## Listening to Connection Updates + +Baileys now fires the `connection.update` event to let you know something has updated in the connection. This data has the following structure: +``` ts +type ConnectionState = { + /** connection is now open, connecting or closed */ + connection: WAConnectionState + /** the error that caused the connection to close */ + lastDisconnect?: { + error: Error + date: Date + } + /** is this a new login */ + isNewLogin?: boolean + /** the current QR code */ + qr?: string + /** has the device received all pending notifications while it was offline */ + receivedPendingNotifications?: boolean +} +``` + +Note: this also offers any updates to the QR + ## Handling Events -Baileys now uses the EventEmitter syntax for events. +Baileys uses the EventEmitter syntax for events. They're all nicely typed up, so you shouldn't have any issues with an Intellisense editor like VS Code. -Also, these events are fired regardless of whether they are initiated by the Baileys client or are relayed from your phone. +The events are typed up in a type map, as mentioned here: ``` ts -/** when the connection has opened successfully */ -on (event: 'open', listener: (result: WAOpenResult) => void): this -/** when the connection is opening */ -on (event: 'connecting', listener: () => void): this -/** when the connection has closed */ -on (event: 'close', listener: (err: {reason?: DisconnectReason | string, isReconnecting: boolean}) => void): this -/** when the socket is closed */ -on (event: 'ws-close', listener: (err: {reason?: DisconnectReason | string}) => void): this -/** when a new QR is generated, ready for scanning */ -on (event: 'qr', listener: (qr: string) => void): this -/** when the connection to the phone changes */ -on (event: 'connection-phone-change', listener: (state: {connected: boolean}) => void): this -/** when a contact is updated */ -on (event: 'contact-update', listener: (update: WAContactUpdate) => void): this -/** when a new chat is added */ -on (event: 'chat-new', listener: (chat: WAChat) => void): this -/** when contacts are sent by WA */ -on (event: 'contacts-received', listener: (u: { updatedContacts: Partial[] }) => void): this -/** when chats are sent by WA, and when all messages are received */ -on (event: 'chats-received', listener: (update: {hasNewChats?: boolean}) => void): this -/** when all initial messages are received from WA */ -on (event: 'initial-data-received', listener: (update: {chatsWithMissingMessages: { jid: string, count: number }[] }) => void): this -/** when multiple chats are updated (new message, updated message, deleted, pinned, etc) */ -on (event: 'chats-update', listener: (chats: WAChatUpdate[]) => void): this -/** when a chat is updated (new message, updated message, read message, deleted, pinned, presence updated etc) */ -on (event: 'chat-update', listener: (chat: WAChatUpdate) => void): this -/** when participants are added to a group */ -on (event: 'group-participants-update', listener: (update: {jid: string, participants: string[], actor?: string, action: WAParticipantAction}) => void): this -/** when the group is updated */ -on (event: 'group-update', listener: (update: Partial & {jid: string, actor?: string}) => void): this -/** when WA sends back a pong */ -on (event: 'received-pong', listener: () => void): this -/** when a user is blocked or unblockd */ -on (event: 'blocklist-update', listener: (update: BlocklistUpdate) => void): this + +export type BaileysEventMap = { + /** connection state has been updated -- WS closed, opened, connecting etc. */ + 'connection.update': Partial + /** auth state updated -- some pre keys, or identity keys etc. */ + 'auth-state.update': AuthenticationState + /** set chats (history sync), messages are reverse chronologically sorted */ + 'chats.set': { chats: Chat[], messages: WAMessage[] } + /** update/insert chats */ + 'chats.upsert': Chat[] + /** update the given chats */ + 'chats.update': Partial[] + /** delete chats with given ID */ + 'chats.delete': string[] + /** presence of contact in a chat updated */ + 'presence.update': { id: string, presences: { [participant: string]: PresenceData } } + + 'contacts.upsert': Contact[] + 'contacts.update': Partial[] + + 'messages.delete': { jid: string, ids: string[] } | { jid: string, all: true } + 'messages.update': WAMessageUpdate[] + /** + * add/update the given messages. If they were received while the connection was online, + * the update will have type: "notify" + * */ + 'messages.upsert': { messages: WAMessage[], type: MessageUpdateType } + + 'message-info.update': MessageInfoUpdate[] + + 'groups.update': Partial[] + /** apply an action to participants in a group */ + 'group-participants.update': { id: string, participants: string[], action: ParticipantAction } + + 'blocklist.set': { blocklist: string[] } + 'blocklist.update': { blocklist: string[], type: 'add' | 'remove' } +} +``` + +You can listen to these events like this: +``` ts + +const sock = makeWASocket() +sock.ev.on('messages.upsert', ({ messages }) => { + console.log('got messages', messages) +}) + ``` ## Sending Messages @@ -220,9 +251,12 @@ import { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys' const id = 'abcd@s.whatsapp.net' // the WhatsApp ID // send a simple text! -const sentMsg = await conn.sendMessage (id, 'oh hello there', MessageType.text) +const sentMsg = await conn.sendMessage(id, { text: 'oh hello there' }) // send a location! -const sentMsg = await conn.sendMessage(id, {degreesLatitude: 24.121231, degreesLongitude: 55.1121221}, MessageType.location) +const sentMsg = await conn.sendMessage( + id, + { location: { degreesLatitude: 24.121231, degreesLongitude: 55.1121221 } } +) // send a contact! const vcard = 'BEGIN:VCARD\n' // metadata of the contact card + 'VERSION:3.0\n' @@ -230,7 +264,15 @@ const vcard = 'BEGIN:VCARD\n' // metadata of the contact card + 'ORG:Ashoka Uni;\n' // the organization of the contact + 'TEL;type=CELL;type=VOICE;waid=911234567890:+91 12345 67890\n' // WhatsApp ID + phone number + 'END:VCARD' -const sentMsg = await conn.sendMessage(id, {displayname: "Jeff", vcard: vcard}, MessageType.contact) +const sentMsg = await conn.sendMessage( + id, + { + contacts: { + displayName: 'Jeff', + contacts: [{ vcard }] + } + } +) ``` ### Media Messages @@ -244,34 +286,38 @@ import { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys' // Sending gifs await conn.sendMessage( id, - fs.readFileSync("Media/ma_gif.mp4"), // load a gif and send it - MessageType.video, - { mimetype: Mimetype.gif, caption: "hello!" } + { + video: fs.readFileSync("Media/ma_gif.mp4"), + caption: "hello!", + gifPlayback: true + } ) await conn.sendMessage( id, - { url: 'Media/ma_gif.mp4' }, // send directly from local file - MessageType.video, - { mimetype: Mimetype.gif, caption: "hello!" } + { + video: "./Media/ma_gif.mp4", + caption: "hello!", + gifPlayback: true + } ) await conn.sendMessage( id, - { url: 'https://giphy.com/gifs/11JTxkrmq4bGE0/html5' }, // send directly from remote url! - MessageType.video, - { mimetype: Mimetype.gif, caption: "hello!" } + { + video: "./Media/ma_gif.mp4", + caption: "hello!", + gifPlayback: true + } ) // send an audio file await conn.sendMessage( id, + { audio: { url: "./Media/audio.mp3" }, mimetype: 'audio/mp4' } { url: "Media/audio.mp3" }, // can send mp3, mp4, & ogg - MessageType.audio, - { mimetype: Mimetype.mp4Audio } // some metadata (can't have caption in audio) ) ``` - ### Notes - `id` is the WhatsApp ID of the person or group you're sending the message to. @@ -279,7 +325,7 @@ await conn.sendMessage( - For broadcast lists it's `[timestamp of creation]@broadcast`. - For stories, the ID is `status@broadcast`. - For media messages, the thumbnail can be generated automatically for images & stickers. Thumbnails for videos can also be generated automatically, though, you need to have `ffmpeg` installed on your system. -- **MessageOptions**: some extra info about the message. It can have the following __optional__ values: +- **MiscGenerationOptions**: some extra info about the message. It can have the following __optional__ values: ``` ts const info: MessageOptions = { quoted: quotedMessage, // the message you want to quote @@ -313,12 +359,16 @@ await conn.forwardMessage ('455@s.whatsapp.net', message) // WA forward the mess ## Reading Messages +A set of message IDs must be explicitly marked read now. +Cannot mark an entire "chat" read as it were with Baileys Web. +This does mean you have to keep track of unread messages. + ``` ts const id = '1234-123@g.us' const messageID = 'AHASHH123123AHGA' // id of the message you want to read +const participant = '912121232@s.whatsapp.net' // the ID of the user that sent the message (undefined for individual chats) -await conn.chatRead (id) // mark all messages in chat as read (equivalent of opening a chat in WA) -await conn.chatRead (id, 'unread') // mark the chat as unread +await conn.sendReadReceipt(id, participant, [messageID]) ``` The message ID is the unique identifier of the message that you are marking as read. On a `WAMessage`, the `messageID` can be accessed using ```messageID = message.key.id```. @@ -326,18 +376,12 @@ The message ID is the unique identifier of the message that you are marking as r ## Update Presence ``` ts -import { Presence } from '@adiwajshing/baileys' -await conn.updatePresence(id, Presence.available) +await conn.updatePresence(id, 'available') ``` This lets the person/group with ``` id ``` know whether you're online, offline, typing etc. where ``` presence ``` can be one of the following: ``` ts -export enum Presence { - available = 'available', // "online" - composing = 'composing', // "typing..." - recording = 'recording', // "recording..." - paused = 'paused' // stopped typing, back to "online" -} +type WAPresence = 'unavailable' | 'available' | 'composing' | 'recording' | 'paused' ``` The presence expires after about 10 seconds. @@ -364,108 +408,74 @@ conn.on ('message-new', async m => { ``` ts const jid = '1234@s.whatsapp.net' // can also be a group -const response = await conn.sendMessage (jid, 'hello!', MessageType.text) // send a message - -await conn.deleteMessage (jid, {id: response.messageID, remoteJid: jid, fromMe: true}) // will delete the sent message for everyone! -await conn.clearMessage (jid, {id: response.messageID, remoteJid: jid, fromMe: true}) // will delete the sent message for only you! +const response = await conn.sendMessage(jid, { text: 'hello!' }) // send a message +// sends a message to delete the given message +// this deletes the message for everyone +await conn.sendMessage(jid, { delete: response.key }) ``` +Note: deleting for oneself is not supported yet + ## Modifying Chats -``` ts -const jid = '1234@s.whatsapp.net' // can also be a group -await conn.modifyChat (jid, ChatModification.archive) // archive chat -await conn.modifyChat (jid, ChatModification.unarchive) // unarchive chat - -const response = await conn.modifyChat (jid, ChatModification.pin) // pin the chat -await conn.modifyChat (jid, ChatModification.unpin) // unpin it - -await conn.modifyChat (jid, ChatModification.mute, 8*60*60*1000) // mute for 8 hours -setTimeout (() => { - conn.modifyChat (jid, ChatModification.unmute) -}, 5000) // unmute after 5 seconds - -await conn.modifyChat (jid, ChatModification.delete) // will delete the chat (can be a group or broadcast list as well) -``` - -**Note:** to unmute or unpin a chat, one must pass the timestamp of the pinning or muting. This is returned by the pin & mute functions. This is also available in the `WAChat` objects of the respective chats, as a `mute` or `pin` property. +TODO: haven't figured this bit out yet. Can receive chat modifications tho. ## Disappearing Messages ``` ts const jid = '1234@s.whatsapp.net' // can also be a group // turn on disappearing messages -await conn.toggleDisappearingMessages( +await conn.sendMessage( jid, - WA_DEFAULT_EPHEMERAL // this is 1 week in seconds -- how long you want messages to appear for -) -// will automatically send as a disappearing message -await conn.sendMessage(jid, 'Hello poof!', MessageType.text) + // this is 1 week in seconds -- how long you want messages to appear for + { disappearingMessagesInChat: WA_DEFAULT_EPHEMERAL } +) +// will send as a disappearing message +await conn.sendMessage(jid, { text: 'hello' }, { ephemeralExpiration: WA_DEFAULT_EPHEMERAL }) // turn off disappearing messages -await conn.toggleDisappearingMessages(jid, 0) +await conn.sendMessage( + jid, + { disappearingMessagesInChat: false } +) ``` ## Misc -- To load chats in a paginated manner - ``` ts - const {chats, cursor} = await conn.loadChats (25) - if (cursor) { - const moreChats = await conn.loadChats (25, cursor) // load the next 25 chats - } - ``` - To check if a given ID is on WhatsApp - Note: this method falls back to using `https://wa.me` to determine whether a number is on WhatsApp in case the WebSocket connection is not open yet. ``` ts const id = '123456' - const exists = await conn.isOnWhatsApp (id) - if (exists) console.log (`${id} exists on WhatsApp, as jid: ${exists.jid}`) + const [result] = await conn.onWhatsApp(id) + if (result.exists) console.log (`${id} exists on WhatsApp, as jid: ${result.jid}`) ``` - To query chat history on a group or with someone - ``` ts - // query the last 25 messages (replace 25 with the number of messages you want to query) - const messages = await conn.loadMessages ("xyz-abc@g.us", 25) - console.log("got back " + messages.length + " messages") - ``` - You can also load the entire conversation history if you want - ``` ts - await conn.loadAllMessages ("xyz@c.us", message => console.log("Loaded message with ID: " + message.key.id)) - console.log("queried all messages") // promise resolves once all messages are retrieved - ``` + TODO, if possible - To get the status of some person ``` ts - const status = await conn.getStatus ("xyz@c.us") // leave empty to get your own status + const status = await conn.fetchStatus("xyz@s.whatsapp.net") console.log("status: " + status) ``` - To get the display picture of some person/group ``` ts - const ppUrl = await conn.getProfilePicture ("xyz@g.us") // leave empty to get your own + const ppUrl = await conn.profilePictureUrl("xyz@g.us") console.log("download profile picture from: " + ppUrl) ``` - To change your display picture or a group's ``` ts const jid = '111234567890-1594482450@g.us' // can be your own too - const img = fs.readFileSync ('new-profile-picture.jpeg') // can be PNG also - await conn.updateProfilePicture (jid, img) + await conn.updateProfilePicture(jid, { url: './new-profile-picture.jpeg' }) ``` - To get someone's presence (if they're typing, online) ``` ts // the presence update is fetched and called here - conn.on ('CB:Presence', json => console.log(json.id + " presence is " + json.type)) - await conn.requestPresenceUpdate ("xyz@c.us") // request the update - ``` -- To search through messages - ``` ts - const response = await conn.searchMessages ('so cool', null, 25, 1) // search in all chats - console.log (`got ${response.messages.length} messages in search`) - - const response2 = await conn.searchMessages ('so cool', '1234@c.us', 25, 1) // search in given chat + conn.ev.on('presence-update', json => console.log(json)) + // request updates for a chat + await conn.presenceSubscribe("xyz@s.whatsapp.net") ``` - To block or unblock user ``` ts - await conn.blockUser ("xyz@c.us", "add") // Block user - await conn.blockUser ("xyz@c.us", "remove") // Unblock user + await conn.updateBlockStatus("xyz@s.whatsapp.net", "block") // Block user + await conn.updateBlockStatus("xyz@s.whatsapp.net", "unblock") // Unblock user ``` Of course, replace ``` xyz ``` with an actual ID. @@ -473,67 +483,52 @@ Of course, replace ``` xyz ``` with an actual ID. - To create a group ``` ts // title & participants - const group = await conn.groupCreate ("My Fab Group", ["abcd@s.whatsapp.net", "efgh@s.whatsapp.net"]) + const group = await conn.groupCreate("My Fab Group", ["1234@s.whatsapp.net", "4564@s.whatsapp.net"]) console.log ("created group with id: " + group.gid) - conn.sendMessage(group.gid, "hello everyone", MessageType.extendedText) // say hello to everyone on the group + conn.sendMessage(group.id, { text: 'hello there' }) // say hello to everyone on the group ``` -- To add people to a group +- To add/remove people to a group or demote/promote people ``` ts // id & people to add to the group (will throw error if it fails) - const response = await conn.groupAdd ("abcd-xyz@g.us", ["abcd@s.whatsapp.net", "efgh@s.whatsapp.net"]) - ``` -- To make/demote admins on a group - ``` ts - // id & people to make admin (will throw error if it fails) - await conn.groupMakeAdmin ("abcd-xyz@g.us", ["abcd@s.whatsapp.net", "efgh@s.whatsapp.net"]) - await conn.groupDemoteAdmin ("abcd-xyz@g.us", ["abcd@s.whatsapp.net", "efgh@s.whatsapp.net"]) // demote admins + const response = await conn.groupParticipantsUpdate( + "abcd-xyz@g.us", + ["abcd@s.whatsapp.net", "efgh@s.whatsapp.net"], + "add" // replace this parameter with "remove", "demote" or "promote" + ) ``` - To change the group's subject ``` ts await conn.groupUpdateSubject("abcd-xyz@g.us", "New Subject!") ``` -- To change the group's description - ``` ts - await conn.groupUpdateDescription("abcd-xyz@g.us", "This group has a new description") - ``` - To change group settings ``` ts - import { GroupSettingChange } from '@adiwajshing/baileys' // only allow admins to send messages - await conn.groupSettingChange ("abcd-xyz@g.us", GroupSettingChange.messageSend, true) + await conn.groupSettingUpdate("abcd-xyz@g.us", 'announcement') // allow everyone to modify the group's settings -- like display picture etc. - await conn.groupSettingChange ("abcd-xyz@g.us", GroupSettingChange.settingChange, false) + await conn.groupSettingUpdate("abcd-xyz@g.us", 'unlocked') // only allow admins to modify the group's settings - await conn.groupSettingChange ("abcd-xyz@g.us", GroupSettingChange.settingChange, true) + await conn.groupSettingUpdate("abcd-xyz@g.us", 'locked') ``` - To leave a group ``` ts - await conn.groupLeave ("abcd-xyz@g.us") // (will throw error if it fails) + await conn.groupLeave("abcd-xyz@g.us") // (will throw error if it fails) ``` - To get the invite code for a group ``` ts - const code = await conn.groupInviteCode ("abcd-xyz@g.us") + const code = await conn.groupInviteCode("abcd-xyz@g.us") console.log("group code: " + code) ``` - To query the metadata of a group ``` ts - const metadata = await conn.groupMetadata ("abcd-xyz@g.us") + const metadata = await conn.groupMetadata("abcd-xyz@g.us") console.log(json.id + ", title: " + json.subject + ", description: " + json.desc) - - // Or if you've left the group -- call this - const metadata2 = await conn.groupMetadataMinimal ("abcd-xyz@g.us") ``` - To join the group using the invitation code ``` ts - const response = await conn.acceptInvite ("xxx") + const response = await conn.acceptInvite("xxx") console.log("joined to: " + response.gid) ``` Of course, replace ``` xxx ``` with invitation code. -- To revokes the current invite link of a group - ``` ts - const response = await conn.revokeInvite ("abcd-xyz@g.us") - console.log("new group code: " + response.code) - ``` ## Broadcast Lists & Stories @@ -542,7 +537,7 @@ Of course, replace ``` xyz ``` with an actual ID. - Broadcast IDs are in the format `12345678@broadcast` - To query a broadcast list's recipients & name: ``` ts - const bList = await conn.getBroadcastListInfo ("1234@broadcast") + const bList = await conn.getBroadcastListInfo("1234@broadcast") console.log (`list name: ${bList.name}, recps: ${bList.recipients}`) ``` @@ -551,53 +546,34 @@ Baileys is written, keeping in mind, that you may require other custom functiona First, enable the logging of unhandled messages from WhatsApp by setting ``` ts -conn.logger.level = 'debug' +const sock = makeWASocket({ + logger: P({ level: 'debug' }), +}) ``` This will enable you to see all sorts of messages WhatsApp sends in the console. Some examples: 1. Functionality to track of the battery percentage of your phone. You enable logging and you'll see a message about your battery pop up in the console: - ```s22, ["action",null,[["battery",{"live":"false","value":"52"},null]]] ``` + ```{"level":10,"fromMe":false,"frame":{"tag":"ib","attrs":{"from":"@s.whatsapp.net"},"content":[{"tag":"edge_routing","attrs":{},"content":[{"tag":"routing_info","attrs":{},"content":{"type":"Buffer","data":[8,2,8,5]}}]}]},"msg":"communication"} ``` - You now know what a battery update looks like. It'll have the following characteristics. - - Given ```const bMessage = ["action",null,[["battery",{"live":"false","value":"52"},null]]]``` - - ```bMessage[0]``` is always ``` "action" ``` - - ```bMessage[1]``` is always ``` null ``` - - ```bMessage[2][0][0]``` is always ``` "battery" ``` + The "frame" is what the message received is, it has three components: + - `tag` -- what this frame is about (eg. message will have "message") + - `attrs` -- a string key-value pair with some metadata (contains ID of the message usually) + - `content` -- the actual data (eg. a message node will have the actual message content in it) + - read more about this format [here](/src/WABinary/readme.md) Hence, you can register a callback for an event using the following: ``` ts - conn.on (`CB:action,,battery`, json => { - const batteryLevelStr = json[2][0][1].value - const batterylevel = parseInt (batteryLevelStr) - console.log ("battery level: " + batterylevel + "%") - }) + // for any message with tag 'edge_routing' + conn.ws.on(`CB:edge_routing`, (node: BinaryNode) => { }) + // for any message with tag 'edge_routing' and id attribute = abcd + conn.ws.on(`CB:edge_routing,id:abcd`, (node: BinaryNode) => { }) + // for any message with tag 'edge_routing', id attribute = abcd & first content node routing_info + conn.ws.on(`CB:edge_routing,id:abcd,routing_info`, (node: BinaryNode) => { }) ``` - This callback will be fired any time a message is received matching the following criteria: - ``` message [0] === "action" && message [1] === null && message[2][0][0] === "battery" ``` -2. Functionality to keep track of the pushname changes on your phone. - You enable logging and you'll see an unhandled message about your pushanme pop up like this: - ```s24, ["Conn",{"pushname":"adiwajshing"}]``` - - You now know what a pushname update looks like. It'll have the following characteristics. - - Given ```const pMessage = ["Conn",{"pushname":"adiwajshing"}] ``` - - ```pMessage[0]``` is always ``` "Conn" ``` - - ```pMessage[1]``` always has the key ``` "pushname" ``` - - ```pMessage[2]``` is always ``` undefined ``` - - Following this, one can implement the following callback: - ``` ts - conn.on ('CB:Conn,pushname', json => { - const pushname = json[1].pushname - conn.user.name = pushname // update on client too - console.log ("Name updated: " + pushname) - }) - ``` - This callback will be fired any time a message is received matching the following criteria: - ``` message [0] === "Conn" && message [1].pushname ``` - -A little more testing will reveal that almost all WhatsApp messages are in the format illustrated above. -Note: except for the first parameter (in the above cases, ```"action"``` or ```"Conn"```), all the other parameters are optional. ### Note + This library was originally a project for **CS-2362 at Ashoka University** and is in no way affiliated with WhatsApp. Use at your own discretion. Do not spam people with this. + + Also, this repo is now licenced under GPL 3 since it uses [libsignal-node](https://git.questbook.io/backend/service-coderunner/-/merge_requests/1) diff --git a/WABinary/Binary.js b/WABinary/Binary.js new file mode 100644 index 0000000..375b63c --- /dev/null +++ b/WABinary/Binary.js @@ -0,0 +1,585 @@ +import { hexAt, hexLongIsNegative, hexLongToHex, negateHexLong, NUM_HEX_IN_LONG } from "./HexHelper"; +import { inflateSync } from 'zlib' + +var l = "", + d = 0; + + const i = 65533, + n = new Uint8Array(10), + s = new Uint8Array(0); + +function u(e) { + if (e === l) return d; + for (var t = e.length, r = 0, a = 0; a < t; a++) { + var i = e.charCodeAt(a); + if (i < 128) r++; + else if (i < 2048) r += 2; + else if (i < 55296 || (57344 <= i && i <= 65535)) r += 3; + else if (55296 <= i && i < 56320 && a + 1 !== t) { + var n = e.charCodeAt(a + 1); + 56320 <= n && n < 57344 ? (a++, (r += 4)) : (r += 3); + } else r += 3; + } + return (l = e), (d = r); +} +function c(e, t, r) { + var a = t >> 21; + if (e) { + var i = Boolean(2097151 & t || r); + return 0 === a || (-1 === a && i); + } + return 0 === a; +} +function p(e, t, r, a, i = undefined) { + return e.readWithViewParser(t, r, a, i); +} +function f(e, t, r, a = undefined, i = undefined) { + return e.readWithBytesParser(t, r, a, i); +} +function h(e, t, r, a) { + return a ? e.getInt8(t) : e.getUint8(t); +} +function _(e, t, r, a) { + return e.getUint16(t, a); +} +function m(e, t, r, a) { + return e.getInt32(t, a); +} +function g(e, t, r, a) { + return e.getUint32(t, a); +} +function v(e, t, r, a, i) { + return a(e.getInt32(i ? t + 4 : t, i), e.getInt32(i ? t : t + 4, i)); +} +function y(e, t, r, a) { + return e.getFloat32(t, a); +} +function E(e, t, r, a) { + return e.getFloat64(t, a); +} +function S(e, t, r, a) { + for (var i = Math.min(a, 10), n = 0, s = 128; n < i && 128 & s; ) + s = e[t + n++]; + if (10 === n && s > 1) throw new Error("ParseError: varint exceeds 64 bits"); + return 128 & s ? n + 1 : n; +} +function T(e, t, r, a) { + var i = 0, + n = 0, + s = r; + 10 === r && (n = 1 & e[t + --s]); + for (var o = s - 1; o >= 0; o--) + (i = (i << 7) | (n >>> 25)), (n = (n << 7) | (127 & e[t + o])); + return a(i, n); +} +function A(e, t, r) { + var a = t + e.byteOffset, + i = e.buffer; + return 0 === a && r === i.byteLength ? i : i.slice(a, a + r); +} +function b(e, t, r) { + return e.subarray(t, t + r); +} +function C(e, t, r) { + for (var a = t + r, n = [], s = null, o = t; o < a; o++) { + n.length > 5e3 && + (s || (s = []), s.push(String.fromCharCode.apply(String, n)), (n = [])); + var l = 0 | e[o]; + if (0 == (128 & l)) n.push(l); + else if (192 == (224 & l)) { + var d = H(e, o + 1, a); + if (d) { + o++; + var u = ((31 & l) << 6) | (63 & d); + u >= 128 ? n.push(u) : n.push(i); + } else n.push(i); + } else if (224 == (240 & l)) { + var c = H(e, o + 1, a), + p = H(e, o + 2, a); + if (c && p) { + o += 2; + var f = ((15 & l) << 12) | ((63 & c) << 6) | (63 & p); + f >= 2048 && !(55296 <= f && f < 57344) ? n.push(f) : n.push(i); + } else c ? (o++, n.push(i)) : n.push(i); + } else if (240 == (248 & l)) { + var h = H(e, o + 1, a), + _ = H(e, o + 2, a), + m = H(e, o + 3, a); + if (h && _ && m) { + o += 3; + var g = ((7 & l) << 18) | ((63 & h) << 12) | ((63 & _) << 6) | (63 & m); + if (g >= 65536 && g <= 1114111) { + var v = g - 65536; + n.push(55296 | (v >> 10), 56320 | (1023 & v)); + } else n.push(i); + } else h && _ ? ((o += 2), n.push(i)) : h ? (o++, n.push(i)) : n.push(i); + } else n.push(i); + } + var y = String.fromCharCode.apply(String, n); + return s ? (s.push(y), s.join("")) : y; +} +function P(e, t, r, a, i) { + return e.writeToView(t, r, a, i); +} +function O(e, t, r, a, i = undefined) { + return e.writeToBytes(t, r, a, i); +} +function M(e, t, r, a) { + e[t] = a; +} +function w(e, t, r, a, i) { + e.setUint16(t, a, i); +} +function I(e, t, r, a, i) { + e.setInt16(t, a, i); +} +function R(e, t, r, a, i) { + e.setUint32(t, a, i); +} +function D(e, t, r, a, i) { + e.setInt32(t, a, i); +} +function N(e, t, r, a, i) { + var n = a < 0, + s = n ? -a : a, + o = Math.floor(s / 4294967296), + l = s - 4294967296 * o; + n && ((o = ~o), 0 === l ? o++ : (l = -l)), + e.setUint32(i ? t + 4 : t, o, i), + e.setUint32(i ? t : t + 4, l, i); +} +function L(e, t, r, a, i) { + e.setFloat32(t, a, i); +} +function k(e, t, r, a, i) { + e.setFloat64(t, a, i); +} +function U(e, t, r, a, i) { + for (var n = a, s = i, o = t + r - 1, l = t; l < o; l++) + (e[l] = 128 | (127 & s)), (s = (n << 25) | (s >>> 7)), (n >>>= 7); + e[o] = s; +} +function G(e, t, r, a) { + for (var i = t, n = a.length, s = 0; s < n; s++) { + var o = a.charCodeAt(s); + if (o < 128) e[i++] = o; + else if (o < 2048) (e[i++] = 192 | (o >> 6)), (e[i++] = 128 | (63 & o)); + else if (o < 55296 || 57344 <= o) + (e[i++] = 224 | (o >> 12)), + (e[i++] = 128 | ((o >> 6) & 63)), + (e[i++] = 128 | (63 & o)); + else if (55296 <= o && o < 56320 && s + 1 !== n) { + var l = a.charCodeAt(s + 1); + if (56320 <= l && l < 57344) { + s++; + var d = 65536 + (((1023 & o) << 10) | (1023 & l)); + (e[i++] = 240 | (d >> 18)), + (e[i++] = 128 | ((d >> 12) & 63)), + (e[i++] = 128 | ((d >> 6) & 63)), + (e[i++] = 128 | (63 & d)); + } else (e[i++] = 239), (e[i++] = 191), (e[i++] = 189); + } else (e[i++] = 239), (e[i++] = 191), (e[i++] = 189); + } +} +function F(e, t, r, i, n) { + for ( + var s = hexLongIsNegative(i), + o = hexLongToHex(i), + l = 0, + d = 0, + u = 0; + u < 16; + u++ + ) + (l = (l << 4) | (d >>> 28)), (d = (d << 4) | hexAt(o, u)); + s && ((l = ~l), 0 === d ? l++ : (d = -d)), + e.setUint32(n ? t + 4 : t, l, n), + e.setUint32(n ? t : t + 4, d, n); +} +function x(e, t, r, a) { + for (var i = 0; i < r; i++) e[t + i] = a[i]; +} +function B(e, t) { + var r, a; + for (e ? ((r = 5), (a = e >>> 3)) : ((r = 1), (a = t >>> 7)); a; ) + r++, (a >>>= 7); + return r; +} +function Y(e, t, r, a) { + if ("number" != typeof e || e != e || Math.floor(e) !== e || e < t || e >= r) { + console.trace('here') + throw new TypeError( + "string" == typeof e + ? `WriteError: string "${e}" is not a valid ${a}` + : `WriteError: ${String(e)} is not a valid ${a}` + ); + } + +} +function K(e, t, r) { + var a = + 4294967296 * (t >= 0 || e ? t : 4294967296 + t) + + (r >= 0 ? r : 4294967296 + r); + if (!c(e, t, r)) + throw new Error(`ReadError: integer exceeded 53 bits (${a})`); + return a; +} +function j(e, t) { + return K(!0, e, t); +} +function W(e, t) { + return K(!1, e, t); +} +function H(e, t, r) { + if (t >= r) return 0; + var a = 0 | e[t]; + return 128 == (192 & a) ? a : 0; +} + +export const numUtf8Bytes = u; +export const longFitsInDouble = c; +export const parseInt64OrThrow = j; +export const parseUint64OrThrow = W; + +export class Binary { + /** @type {Uint8Array} */ + buffer; + readEndIndex; + writeIndex; + bytesTrashed = 0; + earliestIndex = 0; + readIndex = 0; + /** @type {DataView} */ + view = null; + littleEndian = false; + hiddenReads = 0; + hiddenWrites = 0; + + constructor(data = new Uint8Array(0), littleEndian = false) { + if (data instanceof ArrayBuffer) { + this.buffer = new Uint8Array(data); + this.readEndIndex = data.byteLength; + this.writeIndex = data.byteLength; + } + + if (data instanceof Uint8Array) { + this.buffer = data; + this.readEndIndex = data.length; + this.writeIndex = data.length; + } + + this.littleEndian = littleEndian; + } + + size() { + return this.readEndIndex - this.readIndex; + } + + peek(e, t = undefined) { + this.hiddenReads++; + + const r = this.readIndex; + const a = this.bytesTrashed; + + try { + return e(this, t); + } finally { + this.hiddenReads--, (this.readIndex = r - (this.bytesTrashed - a)); + } + } + + advance(e) { + this.shiftReadOrThrow(e); + } + + readWithViewParser(e, t, r, a) { + return t(this.getView(), this.shiftReadOrThrow(e), e, r, a); + } + + readWithBytesParser(e, t, r, a) { + return t(this.buffer, this.shiftReadOrThrow(e), e, r, a); + } + + readUint8() { + //return this.readWithViewParser(1, h, false) + return p(this, 1, h, !1); + } + readInt8() { + return p(this, 1, h, !0); + } + readUint16(e = this.littleEndian) { + return p(this, 2, _, e); + } + readInt32(e = this.littleEndian) { + return p(this, 4, m, e); + } + readUint32(e = this.littleEndian) { + return p(this, 4, g, e); + } + readInt64(e = this.littleEndian) { + return p(this, 8, v, j, e); + } + readUint64(e = this.littleEndian) { + return p(this, 8, v, W, e); + } + readLong(e, t = this.littleEndian) { + return p(this, 8, v, e, t); + } + readFloat32(e = this.littleEndian) { + return p(this, 4, y, e); + } + readFloat64(e = this.littleEndian) { + return p(this, 8, E, e); + } + readVarInt(e) { + var t = f(this, 0, S, this.size()); + return f(this, t, T, e); + } + readBuffer(e = this.size()) { + return 0 === e ? new ArrayBuffer(0) : f(this, e, A); + } + readByteArray(e = this.size()) { + return 0 === e ? new Uint8Array(0) : f(this, e, b); + } + readBinary(e = this.size(), t = this.littleEndian) { + if (0 === e) return new Binary(void 0, t); + var r = f(this, e, b); + return new Binary(r, t); + } + indexOf(e) { + if (0 === e.length) return 0; + for ( + var t = this.buffer, + r = this.readEndIndex, + a = this.readIndex, + i = 0, + n = a, + s = a; + s < r; + s++ + ) + if (t[s] === e[i]) { + if ((0 === i && (n = s), ++i === e.byteLength)) + return s - a - e.byteLength + 1; + } else i > 0 && ((i = 0), (s = n)); + return -1; + 1; + } + readString(e) { + return f(this, e, C); + } + ensureCapacity(e) { + this.maybeReallocate(this.readIndex + e); + } + ensureAdditionalCapacity(e) { + this.maybeReallocate(this.writeIndex + e); + } + writeToView(e, t, r, a) { + var i = this.shiftWriteMaybeReallocate(e); + return t(this.getView(), i, e, r, a); + } + writeToBytes(e, t, r, a) { + var i = this.shiftWriteMaybeReallocate(e); + return t(this.buffer, i, e, r, a); + } + write(...e) { + for (var t = 0; t < e.length; t++) { + var r = e[t]; + "string" == typeof r + ? this.writeString(r) + : "number" == typeof r + ? this.writeUint8(r) + : r instanceof Binary + ? this.writeBinary(r) + : r instanceof ArrayBuffer + ? this.writeBuffer(r) + : r instanceof Uint8Array && this.writeByteArray(r); + } + } + writeUint8(e) { + Y(e, 0, 256, "uint8"), O(this, 1, M, e, !1); + } + writeInt8(e) { + Y(e, -128, 128, "signed int8"), O(this, 1, M, e, !0); + } + writeUint16(e, t = this.littleEndian) { + Y(e, 0, 65536, "uint16"), P(this, 2, w, e, t); + } + writeInt16(e, t = this.littleEndian) { + Y(e, -32768, 32768, "signed int16"), P(this, 2, I, e, t); + } + writeUint32(e, t = this.littleEndian) { + Y(e, 0, 4294967296, "uint32"), P(this, 4, R, e, t); + } + writeInt32(e, t = this.littleEndian) { + Y(e, -2147483648, 2147483648, "signed int32"), P(this, 4, D, e, t); + } + writeUint64(e, t = this.littleEndian) { + Y(e, 0, 0x10000000000000000, "uint64"), P(this, 8, N, e, t); + } + writeInt64(e, t = this.littleEndian) { + Y(e, -0x8000000000000000, 0x8000000000000000, "signed int64"), + P(this, 8, N, e, t); + } + writeFloat32(e, t = this.littleEndian) { + P(this, 4, L, e, t); + } + writeFloat64(e, t = this.littleEndian) { + P(this, 8, k, e, t); + } + writeVarInt(e) { + Y(e, -0x8000000000000000, 0x8000000000000000, "varint (signed int64)"); + var t = e < 0, + r = t ? -e : e, + a = Math.floor(r / 4294967296), + i = r - 4294967296 * a; + t && ((a = ~a), 0 === i ? a++ : (i = -i)), O(this, B(a, i), U, a, i); + } + writeVarIntFromHexLong(e) { + for ( + var t = hexLongIsNegative(e), + r = t ? negateHexLong(e) : e, + i = hexLongToHex(r), + n = 0, + s = 0, + o = 0; + o < NUM_HEX_IN_LONG; + o++ + ) + (n = (n << 4) | (s >>> 28)), (s = (s << 4) | hexAt(i, o)); + t && ((n = ~n), 0 === s ? n++ : (s = -s)), O(this, B(n, s), U, n, s); + } + writeBinary(e) { + var t = e.peek((e) => e.readByteArray()); + if (t.length) { + var r = this.shiftWriteMaybeReallocate(t.length); + this.buffer.set(t, r); + } + } + writeBuffer(e) { + this.writeByteArray(new Uint8Array(e)); + } + writeByteArray(e) { + var t = this.shiftWriteMaybeReallocate(e.length); + this.buffer.set(e, t); + } + writeBufferView(e) { + this.writeByteArray(new Uint8Array(e.buffer, e.byteOffset, e.byteLength)); + } + writeString(e) { + O(this, u(e), G, e); + } + writeHexLong(e, t = this.littleEndian) { + P(this, 8, F, e, t); + } + writeBytes(...e) { + for (var t = 0; t < e.length; t++) Y(e[t], 0, 256, "byte"); + O(this, e.length, x, e); + } + writeAtomically(e, t) { + this.hiddenWrites++; + var r = this.writeIndex, + a = this.bytesTrashed; + try { + var i = e(this, t); + return (r = this.writeIndex), (a = this.bytesTrashed), i; + } finally { + this.hiddenWrites--, (this.writeIndex = r - (this.bytesTrashed - a)); + } + } + + writeWithVarIntLength(e, t) { + var r = this.writeIndex, + a = this.writeAtomically(e, t), + i = this.writeIndex; + this.writeVarInt(i - r); + for (var s = this.writeIndex - i, o = this.buffer, l = 0; l < s; l++) + n[l] = o[i + l]; + for (var d = i - 1; d >= r; d--) o[d + s] = o[d]; + for (var u = 0; u < s; u++) o[r + u] = n[u]; + return a; + } + + static build(...e) { + let t = 0; + let r = 0; + for (t = 0, r = 0; r < e.length; r++) { + let a = e[r]; + "string" == typeof a + ? (t += u(a)) + : "number" == typeof a + ? t++ + : a instanceof Binary + ? (t += a.size()) + : a instanceof ArrayBuffer + ? (t += a.byteLength) + : a instanceof Uint8Array && (t += a.length); + } + + var i = new Binary(); + return i.ensureCapacity(t), i.write.apply(i, arguments), i; + } + + getView() { + return ( + this.view || + (this.view = new DataView(this.buffer.buffer, this.buffer.byteOffset)) + ); + } + + shiftReadOrThrow(e) { + if (e < 0) + throw new Error("ReadError: given negative number of bytes to read"); + var t = this.readIndex, + r = t + e; + if (r > this.readEndIndex) + throw new Error( + t === this.readEndIndex + ? "ReadError: tried to read from depleted binary" + : "ReadError: tried to read beyond end of binary" + ); + return ( + (this.readIndex = r), this.hiddenReads || (this.earliestIndex = r), t + ); + } + + maybeReallocate(e) { + const t = this.buffer; + if (e <= t.length) { + return e; + } + + const r = this.earliestIndex; + const a = e - r; + const i = Math.max(a, 2 * (t.length - r), 64); + const n = new Uint8Array(i); + return ( + r + ? (n.set(t.subarray(r)), + (this.bytesTrashed += r), + (this.readIndex -= r), + (this.readEndIndex -= r), + (this.writeIndex -= r), + (this.earliestIndex = 0)) + : n.set(t), + (this.buffer = n), + (this.view = null), + a + ); + } + + shiftWriteMaybeReallocate(e) { + const t = this.maybeReallocate(this.writeIndex + e); + const r = this.writeIndex; + return ( + (this.writeIndex = t), this.hiddenWrites || (this.readEndIndex = t), r + ); + } + decompressed = () => { + if (2 & this.readUint8()) { + const result = inflateSync(this.readByteArray()) + return new Binary(result) + } + return this + } +} diff --git a/WABinary/Constants.js b/WABinary/Constants.js new file mode 100644 index 0000000..ea674c1 --- /dev/null +++ b/WABinary/Constants.js @@ -0,0 +1,21 @@ +export const DEVICE = { PRIMARY_DEVICE: 0, PRIMARY_VERSION: 0 } + +export const SINGLE_BYTE_TOKEN = ["xmlstreamstart", "xmlstreamend", "s.whatsapp.net", "type", "participant", "from", "receipt", "id", "broadcast", "status", "message", "notification", "notify", "to", "jid", "user", "class", "offline", "g.us", "result", "mediatype", "enc", "skmsg", "off_cnt", "xmlns", "presence", "participants", "ack", "t", "iq", "device_hash", "read", "value", "media", "picture", "chatstate", "unavailable", "text", "urn:xmpp:whatsapp:push", "devices", "verified_name", "contact", "composing", "edge_routing", "routing_info", "item", "image", "verified_level", "get", "fallback_hostname", "2", "media_conn", "1", "v", "handshake", "fallback_class", "count", "config", "offline_preview", "download_buckets", "w:profile:picture", "set", "creation", "location", "fallback_ip4", "msg", "urn:xmpp:ping", "fallback_ip6", "call-creator", "relaylatency", "success", "subscribe", "video", "business_hours_config", "platform", "hostname", "version", "unknown", "0", "ping", "hash", "edit", "subject", "max_buckets", "download", "delivery", "props", "sticker", "name", "last", "contacts", "business", "primary", "preview", "w:p", "pkmsg", "call-id", "retry", "prop", "call", "auth_ttl", "available", "relay_id", "last_id", "day_of_week", "w", "host", "seen", "bits", "list", "atn", "upload", "is_new", "w:stats", "key", "paused", "specific_hours", "multicast", "stream:error", "mmg.whatsapp.net", "code", "deny", "played", "profile", "fna", "device-list", "close_time", "latency", "gcm", "pop", "audio", "26", "w:web", "open_time", "error", "auth", "ip4", "update", "profile_options", "config_value", "category", "catalog_not_created", "00", "config_code", "mode", "catalog_status", "ip6", "blocklist", "registration", "7", "web", "fail", "w:m", "cart_enabled", "ttl", "gif", "300", "device_orientation", "identity", "query", "401", "media-gig2-1.cdn.whatsapp.net", "in", "3", "te2", "add", "fallback", "categories", "ptt", "encrypt", "notice", "thumbnail-document", "item-not-found", "12", "thumbnail-image", "stage", "thumbnail-link", "usync", "out", "thumbnail-video", "8", "01", "context", "sidelist", "thumbnail-gif", "terminate", "not-authorized", "orientation", "dhash", "capability", "side_list", "md-app-state", "description", "serial", "readreceipts", "te", "business_hours", "md-msg-hist", "tag", "attribute_padding", "document", "open_24h", "delete", "expiration", "active", "prev_v_id", "true", "passive", "index", "4", "conflict", "remove", "w:gp2", "config_expo_key", "screen_height", "replaced", "02", "screen_width", "uploadfieldstat", "2:47DEQpj8", "media-bog1-1.cdn.whatsapp.net", "encopt", "url", "catalog_exists", "keygen", "rate", "offer", "opus", "media-mia3-1.cdn.whatsapp.net", "privacy", "media-mia3-2.cdn.whatsapp.net", "signature", "preaccept", "token_id", "media-eze1-1.cdn.whatsapp.net"]; +export const DICTIONARY_0_TOKEN = ["media-for1-1.cdn.whatsapp.net", "relay", "media-gru2-2.cdn.whatsapp.net", "uncompressed", "medium", "voip_settings", "device", "reason", "media-lim1-1.cdn.whatsapp.net", "media-qro1-2.cdn.whatsapp.net", "media-gru1-2.cdn.whatsapp.net", "action", "features", "media-gru2-1.cdn.whatsapp.net", "media-gru1-1.cdn.whatsapp.net", "media-otp1-1.cdn.whatsapp.net", "kyc-id", "priority", "phash", "mute", "token", "100", "media-qro1-1.cdn.whatsapp.net", "none", "media-mrs2-2.cdn.whatsapp.net", "sign_credential", "03", "media-mrs2-1.cdn.whatsapp.net", "protocol", "timezone", "transport", "eph_setting", "1080", "original_dimensions", "media-frx5-1.cdn.whatsapp.net", "background", "disable", "original_image_url", "5", "transaction-id", "direct_path", "103", "appointment_only", "request_image_url", "peer_pid", "address", "105", "104", "102", "media-cdt1-1.cdn.whatsapp.net", "101", "109", "110", "106", "background_location", "v_id", "sync", "status-old", "111", "107", "ppic", "media-scl2-1.cdn.whatsapp.net", "business_profile", "108", "invite", "04", "audio_duration", "media-mct1-1.cdn.whatsapp.net", "media-cdg2-1.cdn.whatsapp.net", "media-los2-1.cdn.whatsapp.net", "invis", "net", "voip_payload_type", "status-revoke-delay", "404", "state", "use_correct_order_for_hmac_sha1", "ver", "media-mad1-1.cdn.whatsapp.net", "order", "540", "skey", "blinded_credential", "android", "contact_remove", "enable_downlink_relay_latency_only", "duration", "enable_vid_one_way_codec_nego", "6", "media-sof1-1.cdn.whatsapp.net", "accept", "all", "signed_credential", "media-atl3-1.cdn.whatsapp.net", "media-lhr8-1.cdn.whatsapp.net", "website", "05", "latitude", "media-dfw5-1.cdn.whatsapp.net", "forbidden", "enable_audio_piggyback_network_mtu_fix", "media-dfw5-2.cdn.whatsapp.net", "note.m4r", "media-atl3-2.cdn.whatsapp.net", "jb_nack_discard_count_fix", "longitude", "Opening.m4r", "media-arn2-1.cdn.whatsapp.net", "email", "timestamp", "admin", "media-pmo1-1.cdn.whatsapp.net", "America/Sao_Paulo", "contact_add", "media-sin6-1.cdn.whatsapp.net", "interactive", "8000", "acs_public_key", "sigquit_anr_detector_release_rollover_percent", "media.fmed1-2.fna.whatsapp.net", "groupadd", "enabled_for_video_upgrade", "latency_update_threshold", "media-frt3-2.cdn.whatsapp.net", "calls_row_constraint_layout", "media.fgbb2-1.fna.whatsapp.net", "mms4_media_retry_notification_encryption_enabled", "timeout", "media-sin6-3.cdn.whatsapp.net", "audio_nack_jitter_multiplier", "jb_discard_count_adjust_pct_rc", "audio_reserve_bps", "delta", "account_sync", "default", "media.fjed4-6.fna.whatsapp.net", "06", "lock_video_orientation", "media-frt3-1.cdn.whatsapp.net", "w:g2", "media-sin6-2.cdn.whatsapp.net", "audio_nack_algo_mask", "media.fgbb2-2.fna.whatsapp.net", "media.fmed1-1.fna.whatsapp.net", "cond_range_target_bitrate", "mms4_server_error_receipt_encryption_enabled", "vid_rc_dyn", "fri", "cart_v1_1_order_message_changes_enabled", "reg_push", "jb_hist_deposit_value", "privatestats", "media.fist7-2.fna.whatsapp.net", "thu", "jb_discard_count_adjust_pct", "mon", "group_call_video_maximization_enabled", "mms_cat_v1_forward_hot_override_enabled", "audio_nack_new_rtt", "media.fsub2-3.fna.whatsapp.net", "media_upload_aggressive_retry_exponential_backoff_enabled", "tue", "wed", "media.fruh4-2.fna.whatsapp.net", "audio_nack_max_seq_req", "max_rtp_audio_packet_resends", "jb_hist_max_cdf_value", "07", "audio_nack_max_jb_delay", "mms_forward_partially_downloaded_video", "media-lcy1-1.cdn.whatsapp.net", "resume", "jb_inband_fec_aware", "new_commerce_entry_point_enabled", "480", "payments_upi_generate_qr_amount_limit", "sigquit_anr_detector_rollover_percent", "media.fsdu2-1.fna.whatsapp.net", "fbns", "aud_pkt_reorder_pct", "dec", "stop_probing_before_accept_send", "media_upload_max_aggressive_retries", "edit_business_profile_new_mode_enabled", "media.fhex4-1.fna.whatsapp.net", "media.fjed4-3.fna.whatsapp.net", "sigquit_anr_detector_64bit_rollover_percent", "cond_range_ema_jb_last_delay", "watls_enable_early_data_http_get", "media.fsdu2-2.fna.whatsapp.net", "message_qr_disambiguation_enabled", "media-mxp1-1.cdn.whatsapp.net", "sat", "vertical", "media.fruh4-5.fna.whatsapp.net", "200", "media-sof1-2.cdn.whatsapp.net", "-1", "height", "product_catalog_hide_show_items_enabled", "deep_copy_frm_last", "tsoffline", "vp8/h.264", "media.fgye5-3.fna.whatsapp.net", "media.ftuc1-2.fna.whatsapp.net", "smb_upsell_chat_banner_enabled", "canonical", "08", "9", ".", "media.fgyd4-4.fna.whatsapp.net", "media.fsti4-1.fna.whatsapp.net", "mms_vcache_aggregation_enabled", "mms_hot_content_timespan_in_seconds", "nse_ver", "rte", "third_party_sticker_web_sync", "cond_range_target_total_bitrate", "media_upload_aggressive_retry_enabled", "instrument_spam_report_enabled", "disable_reconnect_tone", "move_media_folder_from_sister_app", "one_tap_calling_in_group_chat_size", "10", "storage_mgmt_banner_threshold_mb", "enable_backup_passive_mode", "sharechat_inline_player_enabled", "media.fcnq2-1.fna.whatsapp.net", "media.fhex4-2.fna.whatsapp.net", "media.fist6-3.fna.whatsapp.net", "ephemeral_drop_column_stage", "reconnecting_after_network_change_threshold_ms", "media-lhr8-2.cdn.whatsapp.net", "cond_jb_last_delay_ema_alpha", "entry_point_block_logging_enabled", "critical_event_upload_log_config", "respect_initial_bitrate_estimate", "smaller_image_thumbs_status_enabled", "media.fbtz1-4.fna.whatsapp.net", "media.fjed4-1.fna.whatsapp.net", "width", "720", "enable_frame_dropper", "enable_one_side_mode", "urn:xmpp:whatsapp:dirty", "new_sticker_animation_behavior_v2", "media.flim3-2.fna.whatsapp.net", "media.fuio6-2.fna.whatsapp.net", "skip_forced_signaling", "dleq_proof", "status_video_max_bitrate", "lazy_send_probing_req", "enhanced_storage_management", "android_privatestats_endpoint_dit_enabled", "media.fscl13-2.fna.whatsapp.net", "video_duration"]; +export const DICTIONARY_1_TOKEN = ["group_call_discoverability_enabled", "media.faep9-2.fna.whatsapp.net", "msgr", "bloks_loggedin_access_app_id", "db_status_migration_step", "watls_prefer_ip6", "jabber:iq:privacy", "68", "media.fsaw1-11.fna.whatsapp.net", "mms4_media_conn_persist_enabled", "animated_stickers_thread_clean_up", "media.fcgk3-2.fna.whatsapp.net", "media.fcgk4-6.fna.whatsapp.net", "media.fgye5-2.fna.whatsapp.net", "media.flpb1-1.fna.whatsapp.net", "media.fsub2-1.fna.whatsapp.net", "media.fuio6-3.fna.whatsapp.net", "not-allowed", "partial_pjpeg_bw_threshold", "cap_estimated_bitrate", "mms_chatd_resume_check_over_thrift", "smb_upsell_business_profile_enabled", "product_catalog_webclient", "groups", "sigquit_anr_detector_release_updated_rollout", "syncd_key_rotation_enabled", "media.fdmm2-1.fna.whatsapp.net", "media-hou1-1.cdn.whatsapp.net", "remove_old_chat_notifications", "smb_biztools_deeplink_enabled", "use_downloadable_filters_int", "group_qr_codes_enabled", "max_receipt_processing_time", "optimistic_image_processing_enabled", "smaller_video_thumbs_status_enabled", "watls_early_data", "reconnecting_before_relay_failover_threshold_ms", "cond_range_packet_loss_pct", "groups_privacy_blacklist", "status-revoke-drop", "stickers_animated_thumbnail_download", "dedupe_transcode_shared_images", "dedupe_transcode_shared_videos", "media.fcnq2-2.fna.whatsapp.net", "media.fgyd4-1.fna.whatsapp.net", "media.fist7-1.fna.whatsapp.net", "media.flim3-3.fna.whatsapp.net", "add_contact_by_qr_enabled", "https://faq.whatsapp.com/payments", "multicast_limit_global", "sticker_notification_preview", "smb_better_catalog_list_adapters_enabled", "bloks_use_minscript_android", "pen_smoothing_enabled", "media.fcgk4-5.fna.whatsapp.net", "media.fevn1-3.fna.whatsapp.net", "media.fpoj7-1.fna.whatsapp.net", "media-arn2-2.cdn.whatsapp.net", "reconnecting_before_network_change_threshold_ms", "android_media_use_fresco_for_gifs", "cond_in_congestion", "status_image_max_edge", "sticker_search_enabled", "starred_stickers_web_sync", "db_blank_me_jid_migration_step", "media.fist6-2.fna.whatsapp.net", "media.ftuc1-1.fna.whatsapp.net", "09", "anr_fast_logs_upload_rollout", "camera_core_integration_enabled", "11", "third_party_sticker_caching", "thread_dump_contact_support", "wam_privatestats_enabled", "vcard_as_document_size_kb", "maxfpp", "fbip", "ephemeral_allow_group_members", "media-bom1-2.cdn.whatsapp.net", "media-xsp1-1.cdn.whatsapp.net", "disable_prewarm", "frequently_forwarded_max", "media.fbtz1-5.fna.whatsapp.net", "media.fevn7-1.fna.whatsapp.net", "media.fgyd4-2.fna.whatsapp.net", "sticker_tray_animation_fully_visible_items", "green_alert_banner_duration", "reconnecting_after_p2p_failover_threshold_ms", "connected", "share_biz_vcard_enabled", "stickers_animation", "0a", "1200", "WhatsApp", "group_description_length", "p_v_id", "payments_upi_intent_transaction_limit", "frequently_forwarded_messages", "media-xsp1-2.cdn.whatsapp.net", "media.faep8-1.fna.whatsapp.net", "media.faep8-2.fna.whatsapp.net", "media.faep9-1.fna.whatsapp.net", "media.fdmm2-2.fna.whatsapp.net", "media.fgzt3-1.fna.whatsapp.net", "media.flim4-2.fna.whatsapp.net", "media.frao1-1.fna.whatsapp.net", "media.fscl9-2.fna.whatsapp.net", "media.fsub2-2.fna.whatsapp.net", "superadmin", "media.fbog10-1.fna.whatsapp.net", "media.fcgh28-1.fna.whatsapp.net", "media.fjdo10-1.fna.whatsapp.net", "third_party_animated_sticker_import", "delay_fec", "attachment_picker_refresh", "android_linked_devices_re_auth_enabled", "rc_dyn", "green_alert_block_jitter", "add_contact_logging_enabled", "biz_message_logging_enabled", "conversation_media_preview_v2", "media-jnb1-1.cdn.whatsapp.net", "ab_key", "media.fcgk4-2.fna.whatsapp.net", "media.fevn1-1.fna.whatsapp.net", "media.fist6-1.fna.whatsapp.net", "media.fruh4-4.fna.whatsapp.net", "media.fsti4-2.fna.whatsapp.net", "mms_vcard_autodownload_size_kb", "watls_enabled", "notif_ch_override_off", "media.fsaw1-14.fna.whatsapp.net", "media.fscl13-1.fna.whatsapp.net", "db_group_participant_migration_step", "1020", "cond_range_sterm_rtt", "invites_logging_enabled", "triggered_block_enabled", "group_call_max_participants", "media-iad3-1.cdn.whatsapp.net", "product_catalog_open_deeplink", "shops_required_tos_version", "image_max_kbytes", "cond_low_quality_vid_mode", "db_receipt_migration_step", "jb_early_prob_hist_shrink", "media.fdmm2-3.fna.whatsapp.net", "media.fdmm2-4.fna.whatsapp.net", "media.fruh4-1.fna.whatsapp.net", "media.fsaw2-2.fna.whatsapp.net", "remove_geolocation_videos", "new_animation_behavior", "fieldstats_beacon_chance", "403", "authkey_reset_on_ban", "continuous_ptt_playback", "reconnecting_after_relay_failover_threshold_ms", "false", "group", "sun", "conversation_swipe_to_reply", "ephemeral_messages_setting", "smaller_video_thumbs_enabled", "md_device_sync_enabled", "bloks_shops_pdp_url_regex", "lasso_integration_enabled", "media-bom1-1.cdn.whatsapp.net", "new_backup_format_enabled", "256", "media.faep6-1.fna.whatsapp.net", "media.fasr1-1.fna.whatsapp.net", "media.fbtz1-7.fna.whatsapp.net", "media.fesb4-1.fna.whatsapp.net", "media.fjdo1-2.fna.whatsapp.net", "media.frba2-1.fna.whatsapp.net", "watls_no_dns", "600", "db_broadcast_me_jid_migration_step", "new_wam_runtime_enabled", "group_update", "enhanced_block_enabled", "sync_wifi_threshold_kb", "mms_download_nc_cat", "bloks_minification_enabled", "ephemeral_messages_enabled", "reject", "voip_outgoing_xml_signaling", "creator", "dl_bw", "payments_request_messages", "target_bitrate", "bloks_rendercore_enabled", "media-hbe1-1.cdn.whatsapp.net", "media-hel3-1.cdn.whatsapp.net", "media-kut2-2.cdn.whatsapp.net", "media-lax3-1.cdn.whatsapp.net", "media-lax3-2.cdn.whatsapp.net", "sticker_pack_deeplink_enabled", "hq_image_bw_threshold", "status_info", "voip", "dedupe_transcode_videos", "grp_uii_cleanup", "linked_device_max_count", "media.flim1-1.fna.whatsapp.net", "media.fsaw2-1.fna.whatsapp.net", "reconnecting_after_call_active_threshold_ms", "1140", "catalog_pdp_new_design", "media.fbtz1-10.fna.whatsapp.net", "media.fsaw1-15.fna.whatsapp.net", "0b", "consumer_rc_provider", "mms_async_fast_forward_ttl", "jb_eff_size_fix", "voip_incoming_xml_signaling", "media_provider_share_by_uuid", "suspicious_links", "dedupe_transcode_images", "green_alert_modal_start", "media-cgk1-1.cdn.whatsapp.net", "media-lga3-1.cdn.whatsapp.net", "template_doc_mime_types", "important_messages", "user_add", "vcard_max_size_kb", "media.fada2-1.fna.whatsapp.net", "media.fbog2-5.fna.whatsapp.net", "media.fbtz1-3.fna.whatsapp.net", "media.fcgk3-1.fna.whatsapp.net", "media.fcgk7-1.fna.whatsapp.net", "media.flim1-3.fna.whatsapp.net", "media.fscl9-1.fna.whatsapp.net", "ctwa_context_enterprise_enabled", "media.fsaw1-13.fna.whatsapp.net", "media.fuio11-2.fna.whatsapp.net", "status_collapse_muted", "db_migration_level_force", "recent_stickers_web_sync", "bloks_session_state", "bloks_shops_enabled", "green_alert_setting_deep_links_enabled", "restrict_groups", "battery", "green_alert_block_start", "refresh", "ctwa_context_enabled", "md_messaging_enabled", "status_image_quality", "md_blocklist_v2_server", "media-del1-1.cdn.whatsapp.net", "13", "userrate", "a_v_id", "cond_rtt_ema_alpha", "invalid"]; +export const DICTIONARY_2_TOKEN = ["media.fada1-1.fna.whatsapp.net", "media.fadb3-2.fna.whatsapp.net", "media.fbhz2-1.fna.whatsapp.net", "media.fcor2-1.fna.whatsapp.net", "media.fjed4-2.fna.whatsapp.net", "media.flhe4-1.fna.whatsapp.net", "media.frak1-2.fna.whatsapp.net", "media.fsub6-3.fna.whatsapp.net", "media.fsub6-7.fna.whatsapp.net", "media.fvvi1-1.fna.whatsapp.net", "search_v5_eligible", "wam_real_time_enabled", "report_disk_event", "max_tx_rott_based_bitrate", "product", "media.fjdo10-2.fna.whatsapp.net", "video_frame_crc_sample_interval", "media_max_autodownload", "15", "h.264", "wam_privatestats_buffer_count", "md_phash_v2_enabled", "account_transfer_enabled", "business_product_catalog", "enable_non_dyn_codec_param_fix", "is_user_under_epd_jurisdiction", "media.fbog2-4.fna.whatsapp.net", "media.fbtz1-2.fna.whatsapp.net", "media.fcfc1-1.fna.whatsapp.net", "media.fjed4-5.fna.whatsapp.net", "media.flhe4-2.fna.whatsapp.net", "media.flim1-2.fna.whatsapp.net", "media.flos5-1.fna.whatsapp.net", "android_key_store_auth_ver", "010", "anr_process_monitor", "delete_old_auth_key", "media.fcor10-3.fna.whatsapp.net", "storage_usage_enabled", "android_camera2_support_level", "dirty", "consumer_content_provider", "status_video_max_duration", "0c", "bloks_cache_enabled", "media.fadb2-2.fna.whatsapp.net", "media.fbko1-1.fna.whatsapp.net", "media.fbtz1-9.fna.whatsapp.net", "media.fcgk4-4.fna.whatsapp.net", "media.fesb4-2.fna.whatsapp.net", "media.fevn1-2.fna.whatsapp.net", "media.fist2-4.fna.whatsapp.net", "media.fjdo1-1.fna.whatsapp.net", "media.fruh4-6.fna.whatsapp.net", "media.fsrg5-1.fna.whatsapp.net", "media.fsub6-6.fna.whatsapp.net", "minfpp", "5000", "locales", "video_max_bitrate", "use_new_auth_key", "bloks_http_enabled", "heartbeat_interval", "media.fbog11-1.fna.whatsapp.net", "ephemeral_group_query_ts", "fec_nack", "search_in_storage_usage", "c", "media-amt2-1.cdn.whatsapp.net", "linked_devices_ui_enabled", "14", "async_data_load_on_startup", "voip_incoming_xml_ack", "16", "db_migration_step", "init_bwe", "max_participants", "wam_buffer_count", "media.fada2-2.fna.whatsapp.net", "media.fadb3-1.fna.whatsapp.net", "media.fcor2-2.fna.whatsapp.net", "media.fdiy1-2.fna.whatsapp.net", "media.frba3-2.fna.whatsapp.net", "media.fsaw2-3.fna.whatsapp.net", "1280", "status_grid_enabled", "w:biz", "product_catalog_deeplink", "media.fgye10-2.fna.whatsapp.net", "media.fuio11-1.fna.whatsapp.net", "optimistic_upload", "work_manager_init", "lc", "catalog_message", "cond_net_medium", "enable_periodical_aud_rr_processing", "cond_range_ema_rtt", "media-tir2-1.cdn.whatsapp.net", "frame_ms", "group_invite_sending", "payments_web_enabled", "wallpapers_v2", "0d", "browser", "hq_image_max_edge", "image_edit_zoom", "linked_devices_re_auth_enabled", "media.faly3-2.fna.whatsapp.net", "media.fdoh5-3.fna.whatsapp.net", "media.fesb3-1.fna.whatsapp.net", "media.fknu1-1.fna.whatsapp.net", "media.fmex3-1.fna.whatsapp.net", "media.fruh4-3.fna.whatsapp.net", "255", "web_upgrade_to_md_modal", "audio_piggyback_timeout_msec", "enable_audio_oob_fec_feature", "from_ip", "image_max_edge", "message_qr_enabled", "powersave", "receipt_pre_acking", "video_max_edge", "full", "011", "012", "enable_audio_oob_fec_for_sender", "md_voip_enabled", "enable_privatestats", "max_fec_ratio", "payments_cs_faq_url", "media-xsp1-3.cdn.whatsapp.net", "hq_image_quality", "media.fasr1-2.fna.whatsapp.net", "media.fbog3-1.fna.whatsapp.net", "media.ffjr1-6.fna.whatsapp.net", "media.fist2-3.fna.whatsapp.net", "media.flim4-3.fna.whatsapp.net", "media.fpbc2-4.fna.whatsapp.net", "media.fpku1-1.fna.whatsapp.net", "media.frba1-1.fna.whatsapp.net", "media.fudi1-1.fna.whatsapp.net", "media.fvvi1-2.fna.whatsapp.net", "gcm_fg_service", "enable_dec_ltr_size_check", "clear", "lg", "media.fgru11-1.fna.whatsapp.net", "18", "media-lga3-2.cdn.whatsapp.net", "pkey", "0e", "max_subject", "cond_range_lterm_rtt", "announcement_groups", "biz_profile_options", "s_t", "media.fabv2-1.fna.whatsapp.net", "media.fcai3-1.fna.whatsapp.net", "media.fcgh1-1.fna.whatsapp.net", "media.fctg1-4.fna.whatsapp.net", "media.fdiy1-1.fna.whatsapp.net", "media.fisb4-1.fna.whatsapp.net", "media.fpku1-2.fna.whatsapp.net", "media.fros9-1.fna.whatsapp.net", "status_v3_text", "usync_sidelist", "17", "announcement", "...", "md_group_notification", "0f", "animated_pack_in_store", "013", "America/Mexico_City", "1260", "media-ams4-1.cdn.whatsapp.net", "media-cgk1-2.cdn.whatsapp.net", "media-cpt1-1.cdn.whatsapp.net", "media-maa2-1.cdn.whatsapp.net", "media.fgye10-1.fna.whatsapp.net", "e", "catalog_cart", "hfm_string_changes", "init_bitrate", "packless_hsm", "group_info", "America/Belem", "50", "960", "cond_range_bwe", "decode", "encode", "media.fada1-8.fna.whatsapp.net", "media.fadb1-2.fna.whatsapp.net", "media.fasu6-1.fna.whatsapp.net", "media.fbog4-1.fna.whatsapp.net", "media.fcgk9-2.fna.whatsapp.net", "media.fdoh5-2.fna.whatsapp.net", "media.ffjr1-2.fna.whatsapp.net", "media.fgua1-1.fna.whatsapp.net", "media.fgye1-1.fna.whatsapp.net", "media.fist1-4.fna.whatsapp.net", "media.fpbc2-2.fna.whatsapp.net", "media.fres2-1.fna.whatsapp.net", "media.fsdq1-2.fna.whatsapp.net", "media.fsub6-5.fna.whatsapp.net", "profilo_enabled", "template_hsm", "use_disorder_prefetching_timer", "video_codec_priority", "vpx_max_qp", "ptt_reduce_recording_delay", "25", "iphone", "Windows", "s_o", "Africa/Lagos", "abt", "media-kut2-1.cdn.whatsapp.net", "media-mba1-1.cdn.whatsapp.net", "media-mxp1-2.cdn.whatsapp.net", "md_blocklist_v2", "url_text", "enable_short_offset", "group_join_permissions", "enable_audio_piggyback_feature", "image_quality", "media.fcgk7-2.fna.whatsapp.net", "media.fcgk8-2.fna.whatsapp.net", "media.fclo7-1.fna.whatsapp.net", "media.fcmn1-1.fna.whatsapp.net", "media.feoh1-1.fna.whatsapp.net", "media.fgyd4-3.fna.whatsapp.net", "media.fjed4-4.fna.whatsapp.net", "media.flim1-4.fna.whatsapp.net", "media.flim2-4.fna.whatsapp.net", "media.fplu6-1.fna.whatsapp.net", "media.frak1-1.fna.whatsapp.net", "media.fsdq1-1.fna.whatsapp.net", "to_ip", "015", "vp8", "19", "21", "1320", "auth_key_ver", "message_processing_dedup", "server-error", "wap4_enabled", "420", "014", "cond_range_rtt", "ptt_fast_lock_enabled", "media-ort2-1.cdn.whatsapp.net", "fwd_ui_start_ts"]; + +export const DICTIONARY_3_TOKEN = ["contact_blacklist", "Asia/Jakarta", "media.fepa10-1.fna.whatsapp.net", "media.fmex10-3.fna.whatsapp.net", "disorder_prefetching_start_when_empty", "America/Bogota", "use_local_probing_rx_bitrate", "America/Argentina/Buenos_Aires", "cross_post", "media.fabb1-1.fna.whatsapp.net", "media.fbog4-2.fna.whatsapp.net", "media.fcgk9-1.fna.whatsapp.net", "media.fcmn2-1.fna.whatsapp.net", "media.fdel3-1.fna.whatsapp.net", "media.ffjr1-1.fna.whatsapp.net", "media.fgdl5-1.fna.whatsapp.net", "media.flpb1-2.fna.whatsapp.net", "media.fmex2-1.fna.whatsapp.net", "media.frba2-2.fna.whatsapp.net", "media.fros2-2.fna.whatsapp.net", "media.fruh2-1.fna.whatsapp.net", "media.fybz2-2.fna.whatsapp.net", "options", "20", "a", "017", "018", "mute_always", "user_notice", "Asia/Kolkata", "gif_provider", "locked", "media-gua1-1.cdn.whatsapp.net", "piggyback_exclude_force_flush", "24", "media.frec39-1.fna.whatsapp.net", "user_remove", "file_max_size", "cond_packet_loss_pct_ema_alpha", "media.facc1-1.fna.whatsapp.net", "media.fadb2-1.fna.whatsapp.net", "media.faly3-1.fna.whatsapp.net", "media.fbdo6-2.fna.whatsapp.net", "media.fcmn2-2.fna.whatsapp.net", "media.fctg1-3.fna.whatsapp.net", "media.ffez1-2.fna.whatsapp.net", "media.fist1-3.fna.whatsapp.net", "media.fist2-2.fna.whatsapp.net", "media.flim2-2.fna.whatsapp.net", "media.fmct2-3.fna.whatsapp.net", "media.fpei3-1.fna.whatsapp.net", "media.frba3-1.fna.whatsapp.net", "media.fsdu8-2.fna.whatsapp.net", "media.fstu2-1.fna.whatsapp.net", "media_type", "receipt_agg", "016", "enable_pli_for_crc_mismatch", "live", "enc_rekey", "frskmsg", "d", "media.fdel11-2.fna.whatsapp.net", "proto", "2250", "audio_piggyback_enable_cache", "skip_nack_if_ltrp_sent", "mark_dtx_jb_frames", "web_service_delay", "7282", "catalog_send_all", "outgoing", "360", "30", "LIMITED", "019", "audio_picker", "bpv2_phase", "media.fada1-7.fna.whatsapp.net", "media.faep7-1.fna.whatsapp.net", "media.fbko1-2.fna.whatsapp.net", "media.fbni1-2.fna.whatsapp.net", "media.fbtz1-1.fna.whatsapp.net", "media.fbtz1-8.fna.whatsapp.net", "media.fcjs3-1.fna.whatsapp.net", "media.fesb3-2.fna.whatsapp.net", "media.fgdl5-4.fna.whatsapp.net", "media.fist2-1.fna.whatsapp.net", "media.flhe2-2.fna.whatsapp.net", "media.flim2-1.fna.whatsapp.net", "media.fmex1-1.fna.whatsapp.net", "media.fpat3-2.fna.whatsapp.net", "media.fpat3-3.fna.whatsapp.net", "media.fros2-1.fna.whatsapp.net", "media.fsdu8-1.fna.whatsapp.net", "media.fsub3-2.fna.whatsapp.net", "payments_chat_plugin", "cond_congestion_no_rtcp_thr", "green_alert", "not-a-biz", "..", "shops_pdp_urls_config", "source", "media-dus1-1.cdn.whatsapp.net", "mute_video", "01b", "currency", "max_keys", "resume_check", "contact_array", "qr_scanning", "23", "b", "media.fbfh15-1.fna.whatsapp.net", "media.flim22-1.fna.whatsapp.net", "media.fsdu11-1.fna.whatsapp.net", "media.fsdu15-1.fna.whatsapp.net", "Chrome", "fts_version", "60", "media.fada1-6.fna.whatsapp.net", "media.faep4-2.fna.whatsapp.net", "media.fbaq5-1.fna.whatsapp.net", "media.fbni1-1.fna.whatsapp.net", "media.fcai3-2.fna.whatsapp.net", "media.fdel3-2.fna.whatsapp.net", "media.fdmm3-2.fna.whatsapp.net", "media.fhex3-1.fna.whatsapp.net", "media.fisb4-2.fna.whatsapp.net", "media.fkhi5-2.fna.whatsapp.net", "media.flos2-1.fna.whatsapp.net", "media.fmct2-1.fna.whatsapp.net", "media.fntr7-1.fna.whatsapp.net", "media.frak3-1.fna.whatsapp.net", "media.fruh5-2.fna.whatsapp.net", "media.fsub6-1.fna.whatsapp.net", "media.fuab1-2.fna.whatsapp.net", "media.fuio1-1.fna.whatsapp.net", "media.fver1-1.fna.whatsapp.net", "media.fymy1-1.fna.whatsapp.net", "product_catalog", "1380", "audio_oob_fec_max_pkts", "22", "254", "media-ort2-2.cdn.whatsapp.net", "media-sjc3-1.cdn.whatsapp.net", "1600", "01a", "01c", "405", "key_frame_interval", "body", "media.fcgh20-1.fna.whatsapp.net", "media.fesb10-2.fna.whatsapp.net", "125", "2000", "media.fbsb1-1.fna.whatsapp.net", "media.fcmn3-2.fna.whatsapp.net", "media.fcpq1-1.fna.whatsapp.net", "media.fdel1-2.fna.whatsapp.net", "media.ffor2-1.fna.whatsapp.net", "media.fgdl1-4.fna.whatsapp.net", "media.fhex2-1.fna.whatsapp.net", "media.fist1-2.fna.whatsapp.net", "media.fjed5-2.fna.whatsapp.net", "media.flim6-4.fna.whatsapp.net", "media.flos2-2.fna.whatsapp.net", "media.fntr6-2.fna.whatsapp.net", "media.fpku3-2.fna.whatsapp.net", "media.fros8-1.fna.whatsapp.net", "media.fymy1-2.fna.whatsapp.net", "ul_bw", "ltrp_qp_offset", "request", "nack", "dtx_delay_state_reset", "timeoffline", "28", "01f", "32", "enable_ltr_pool", "wa_msys_crypto", "01d", "58", "dtx_freeze_hg_update", "nack_if_rpsi_throttled", "253", "840", "media.famd15-1.fna.whatsapp.net", "media.fbog17-2.fna.whatsapp.net", "media.fcai19-2.fna.whatsapp.net", "media.fcai21-4.fna.whatsapp.net", "media.fesb10-4.fna.whatsapp.net", "media.fesb10-5.fna.whatsapp.net", "media.fmaa12-1.fna.whatsapp.net", "media.fmex11-3.fna.whatsapp.net", "media.fpoa33-1.fna.whatsapp.net", "1050", "021", "clean", "cond_range_ema_packet_loss_pct", "media.fadb6-5.fna.whatsapp.net", "media.faqp4-1.fna.whatsapp.net", "media.fbaq3-1.fna.whatsapp.net", "media.fbel2-1.fna.whatsapp.net", "media.fblr4-2.fna.whatsapp.net", "media.fclo8-1.fna.whatsapp.net", "media.fcoo1-2.fna.whatsapp.net", "media.ffjr1-4.fna.whatsapp.net", "media.ffor9-1.fna.whatsapp.net", "media.fisb3-1.fna.whatsapp.net", "media.fkhi2-2.fna.whatsapp.net", "media.fkhi4-1.fna.whatsapp.net", "media.fpbc1-2.fna.whatsapp.net", "media.fruh2-2.fna.whatsapp.net", "media.fruh5-1.fna.whatsapp.net", "media.fsub3-1.fna.whatsapp.net", "payments_transaction_limit", "252", "27", "29", "tintagel", "01e", "237", "780", "callee_updated_payload", "020", "257", "price", "025", "239", "payments_cs_phone_number", "mediaretry", "w:auth:backup:token", "Glass.caf", "max_bitrate", "240", "251", "660", "media.fbog16-1.fna.whatsapp.net", "media.fcgh21-1.fna.whatsapp.net", "media.fkul19-2.fna.whatsapp.net", "media.flim21-2.fna.whatsapp.net", "media.fmex10-4.fna.whatsapp.net", "64", "33", "34", "35", "interruption", "media.fabv3-1.fna.whatsapp.net", "media.fadb6-1.fna.whatsapp.net", "media.fagr1-1.fna.whatsapp.net", "media.famd1-1.fna.whatsapp.net", "media.famm6-1.fna.whatsapp.net", "media.faqp2-3.fna.whatsapp.net"]; +export const DICTIONARIES = [DICTIONARY_0_TOKEN, DICTIONARY_1_TOKEN, DICTIONARY_2_TOKEN, DICTIONARY_3_TOKEN]; + +export const buildMap = (data) => { + const map = new Map(); + for (let r = 0; r < data.length; r++) { + map.set(data[r], r); + } + + return map; +} + +export const SINGLE_BYTE_TOKEN_MAP = buildMap(SINGLE_BYTE_TOKEN); +export const DICTIONARIES_MAP = DICTIONARIES.map((dict) => buildMap(dict)) \ No newline at end of file diff --git a/WABinary/HexHelper.js b/WABinary/HexHelper.js new file mode 100644 index 0000000..3ecadb8 --- /dev/null +++ b/WABinary/HexHelper.js @@ -0,0 +1,117 @@ +import * as Crypto from "crypto"; + +const r = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70], + a = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102]; + +const i = (e) => { + for (var t = [], a = 0; a < e.length; a++) { + var i = e[a]; + t.push(r[i >> 4], r[15 & i]); + } + return String.fromCharCode.apply(String, t); +}; + +const n = (e, t) => { + var r = e.charCodeAt(t); + return r <= 57 ? r - 48 : r <= 70 ? 10 + r - 65 : 10 + r - 97; +}; + +const s = (e) => { + if (/[^0-9a-fA-F]/.test(e)) throw new Error(`"${e}" is not a valid hex`); + return e; +}; + +const o = (e, t) => { + for (var r = t - e.length, a = e, i = 0; i < r; i++) a = "0" + a; + return a; +}; + +const l = (e) => { + return "-" === e[0]; +}; + +const d = (e) => { + if (e > 4294967295 || e < -4294967296) + throw new Error("uint32ToLowerCaseHex given number over 32 bits"); + return o((e >= 0 ? e : 4294967296 + e).toString(16), 8); +}; + +export const NUM_HEX_IN_LONG = 16; +export const HEX_LOWER = a; + +export const randomHex = function (e) { + var t = new Uint8Array(e); + var bytes = Crypto.randomBytes(t.length); + t.set(bytes); + return i(t); +}; + +export const toHex = i; + +export const toLowerCaseHex = function (e) { + for (var t = [], r = 0; r < e.length; r++) { + var i = e[r]; + t.push(a[i >> 4], a[15 & i]); + } + return String.fromCharCode.apply(String, t); +}; + +export const parseHex = function (e) { + var t = s(e); + if (t.length % 2 != 0) + throw new Error( + `parseHex given hex "${t}" which is not a multiple of 8-bits.` + ); + for ( + var r = new Uint8Array(t.length >> 1), a = 0, i = 0; + a < t.length; + a += 2, i++ + ) + r[i] = (n(t, a) << 4) | n(t, a + 1); + return r.buffer; +}; + +export const hexAt = n; +export const hexOrThrow = s; +export const bytesToBuffer = function (e) { + var t = e.buffer; + return 0 === e.byteOffset && e.length === t.byteLength + ? t + : t.slice(e.byteOffset, e.byteOffset + e.length); +}; + +export const bytesToDebugString = function (e) { + var t = !0, + r = e.length; + for (; t && r; ) { + var a = e[--r]; + t = 32 <= a && a < 127; + } + return t ? JSON.stringify(String.fromCharCode.apply(String, e)) : i(e); +}; + +export const createHexLong = function (e, t = !1) { + var r = s(e); + return ( + (function (e, t) { + if (e.length > t) throw new Error(`"${e}" is longer than ${4 * t} bits.`); + })(r, 16), + `${t ? "-" : ""}0x${o(r, 16)}` + ); +}; + +export const createHexLongFrom32Bits = function (e, t, r = !1) { + var a = d(e), + i = d(t); + return `${r ? "-" : ""}0x${a}${i}`; +}; + +export const hexLongToHex = function (e) { + return e.substring(e.indexOf("0x") + 2); +}; + +export const hexLongIsNegative = l; + +export const negateHexLong = function (e) { + return l(e) ? e.slice(1) : "-" + e; +}; diff --git a/WABinary/readme.md b/WABinary/readme.md new file mode 100644 index 0000000..267c69d --- /dev/null +++ b/WABinary/readme.md @@ -0,0 +1,15 @@ +# WABinary + +Contains the raw JS code to parse WA binary messages. WA uses a tree like structure to encode information, the type for which is written below: + +``` ts +export type BinaryNode = { + tag: string + attrs: Attributes + content?: BinaryNode[] | string | Uint8Array +} +``` + +Do note, the multi-device binary format is very similar to the one on WA Web, though they are not backwards compatible. + +Originally from [pokearaujo/multidevice](https://github.com/pokearaujo/multidevice) \ No newline at end of file diff --git a/src/BinaryNode/GenerateStatics.sh b/WAProto/GenerateStatics.sh similarity index 50% rename from src/BinaryNode/GenerateStatics.sh rename to WAProto/GenerateStatics.sh index 295f6bb..7d77a28 100644 --- a/src/BinaryNode/GenerateStatics.sh +++ b/WAProto/GenerateStatics.sh @@ -1,4 +1,4 @@ -yarn pbjs -t static-module -w commonjs -o ./WAMessage/index.js ./src/BinaryNode/WAMessage.proto; -yarn pbts -o ./WAMessage/index.d.ts ./WAMessage/index.js; +yarn pbjs -t static-module -w commonjs -o ./WAProto/index.js ./WAProto/WAProto.proto; +yarn pbts -o ./WAProto/index.d.ts ./WAProto/index.js; #protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_opt=env=node,useOptionals=true,forceLong=long --ts_proto_out=. ./src/Binary/WAMessage.proto; \ No newline at end of file diff --git a/src/BinaryNode/WAMessage.proto b/WAProto/WAProto.proto similarity index 69% rename from src/BinaryNode/WAMessage.proto rename to WAProto/WAProto.proto index 98cd6ec..1bedf04 100644 --- a/src/BinaryNode/WAMessage.proto +++ b/WAProto/WAProto.proto @@ -1,11 +1,621 @@ syntax = "proto2"; package proto; -message MessageKey { - optional string remoteJid = 1; - optional bool fromMe = 2; - optional string id = 3; - optional string participant = 4; +message AppVersion { + optional uint32 primary = 1; + optional uint32 secondary = 2; + optional uint32 tertiary = 3; + optional uint32 quaternary = 4; + optional uint32 quinary = 5; +} + +message UserAgent { + enum UserAgentPlatform { + ANDROID = 0; + IOS = 1; + WINDOWS_PHONE = 2; + BLACKBERRY = 3; + BLACKBERRYX = 4; + S40 = 5; + S60 = 6; + PYTHON_CLIENT = 7; + TIZEN = 8; + ENTERPRISE = 9; + SMB_ANDROID = 10; + KAIOS = 11; + SMB_IOS = 12; + WINDOWS = 13; + WEB = 14; + PORTAL = 15; + GREEN_ANDROID = 16; + GREEN_IPHONE = 17; + BLUE_ANDROID = 18; + BLUE_IPHONE = 19; + FBLITE_ANDROID = 20; + MLITE_ANDROID = 21; + IGLITE_ANDROID = 22; + PAGE = 23; + MACOS = 24; + VR = 25; + } + optional UserAgentPlatform platform = 1; + optional AppVersion appVersion = 2; + optional string mcc = 3; + optional string mnc = 4; + optional string osVersion = 5; + optional string manufacturer = 6; + optional string device = 7; + optional string osBuildNumber = 8; + optional string phoneId = 9; + enum UserAgentReleaseChannel { + RELEASE = 0; + BETA = 1; + ALPHA = 2; + DEBUG = 3; + } + optional UserAgentReleaseChannel releaseChannel = 10; + optional string localeLanguageIso6391 = 11; + optional string localeCountryIso31661Alpha2 = 12; + optional string deviceBoard = 13; +} + +message WebdPayload { + optional bool usesParticipantInKey = 1; + optional bool supportsStarredMessages = 2; + optional bool supportsDocumentMessages = 3; + optional bool supportsUrlMessages = 4; + optional bool supportsMediaRetry = 5; + optional bool supportsE2EImage = 6; + optional bool supportsE2EVideo = 7; + optional bool supportsE2EAudio = 8; + optional bool supportsE2EDocument = 9; + optional string documentTypes = 10; + optional bytes features = 11; +} + +message WebInfo { + optional string refToken = 1; + optional string version = 2; + optional WebdPayload webdPayload = 3; + enum WebInfoWebSubPlatform { + WEB_BROWSER = 0; + APP_STORE = 1; + WIN_STORE = 2; + DARWIN = 3; + WIN32 = 4; + } + optional WebInfoWebSubPlatform webSubPlatform = 4; +} + +message DNSSource { + enum DNSSourceDNSResolutionMethod { + SYSTEM = 0; + GOOGLE = 1; + HARDCODED = 2; + OVERRIDE = 3; + FALLBACK = 4; + } + optional DNSSourceDNSResolutionMethod dnsMethod = 15; + optional bool appCached = 16; +} + +message CompanionRegData { + optional bytes eRegid = 1; + optional bytes eKeytype = 2; + optional bytes eIdent = 3; + optional bytes eSkeyId = 4; + optional bytes eSkeyVal = 5; + optional bytes eSkeySig = 6; + optional bytes buildHash = 7; + optional bytes companionProps = 8; +} + +message ClientPayload { + optional uint64 username = 1; + optional bool passive = 3; + enum ClientPayloadClientFeature { + NONE = 0; + } + repeated ClientPayloadClientFeature clientFeatures = 4; + optional UserAgent userAgent = 5; + optional WebInfo webInfo = 6; + optional string pushName = 7; + optional sfixed32 sessionId = 9; + optional bool shortConnect = 10; + enum ClientPayloadIOSAppExtension { + SHARE_EXTENSION = 0; + SERVICE_EXTENSION = 1; + INTENTS_EXTENSION = 2; + } + optional ClientPayloadIOSAppExtension iosAppExtension = 30; + enum ClientPayloadConnectType { + CELLULAR_UNKNOWN = 0; + WIFI_UNKNOWN = 1; + CELLULAR_EDGE = 100; + CELLULAR_IDEN = 101; + CELLULAR_UMTS = 102; + CELLULAR_EVDO = 103; + CELLULAR_GPRS = 104; + CELLULAR_HSDPA = 105; + CELLULAR_HSUPA = 106; + CELLULAR_HSPA = 107; + CELLULAR_CDMA = 108; + CELLULAR_1XRTT = 109; + CELLULAR_EHRPD = 110; + CELLULAR_LTE = 111; + CELLULAR_HSPAP = 112; + } + optional ClientPayloadConnectType connectType = 12; + enum ClientPayloadConnectReason { + PUSH = 0; + USER_ACTIVATED = 1; + SCHEDULED = 2; + ERROR_RECONNECT = 3; + NETWORK_SWITCH = 4; + PING_RECONNECT = 5; + } + optional ClientPayloadConnectReason connectReason = 13; + repeated int32 shards = 14; + optional DNSSource dnsSource = 15; + optional uint32 connectAttemptCount = 16; + optional uint32 agent = 17; + optional uint32 device = 18; + optional CompanionRegData regData = 19; + enum ClientPayloadProduct { + WHATSAPP = 0; + MESSENGER = 1; + } + optional ClientPayloadProduct product = 20; + optional bytes fbCat = 21; + optional bytes fbUserAgent = 22; + optional bool oc = 23; +} + +message Details { + optional uint32 serial = 1; + optional string issuer = 2; + optional uint64 expires = 3; + optional string subject = 4; + optional bytes key = 5; +} + +message NoiseCertificate { + optional bytes details = 1; + optional bytes signature = 2; +} + +message ClientHello { + optional bytes ephemeral = 1; + optional bytes static = 2; + optional bytes payload = 3; +} + +message ServerHello { + optional bytes ephemeral = 1; + optional bytes static = 2; + optional bytes payload = 3; +} + +message ClientFinish { + optional bytes static = 1; + optional bytes payload = 2; +} + +message HandshakeMessage { + optional ClientHello clientHello = 2; + optional ServerHello serverHello = 3; + optional ClientFinish clientFinish = 4; +} + +message BizIdentityInfo { + enum BizIdentityInfoVerifiedLevelValue { + UNKNOWN = 0; + LOW = 1; + HIGH = 2; + } + optional BizIdentityInfoVerifiedLevelValue vlevel = 1; + optional VerifiedNameCertificate vnameCert = 2; + optional bool signed = 3; + optional bool revoked = 4; + enum BizIdentityInfoHostStorageType { + ON_PREMISE = 0; + FACEBOOK = 1; + } + optional BizIdentityInfoHostStorageType hostStorage = 5; + enum BizIdentityInfoActualActorsType { + SELF = 0; + BSP = 1; + } + optional BizIdentityInfoActualActorsType actualActors = 6; + optional uint64 privacyModeTs = 7; +} + +message BizAccountLinkInfo { + optional uint64 whatsappBizAcctFbid = 1; + optional string whatsappAcctNumber = 2; + optional uint64 issueTime = 3; + enum BizAccountLinkInfoHostStorageType { + ON_PREMISE = 0; + FACEBOOK = 1; + } + optional BizAccountLinkInfoHostStorageType hostStorage = 4; + enum BizAccountLinkInfoAccountType { + ENTERPRISE = 0; + PAGE = 1; + } + optional BizAccountLinkInfoAccountType accountType = 5; +} + +message BizAccountPayload { + optional VerifiedNameCertificate vnameCert = 1; + optional bytes bizAcctLinkInfo = 2; +} + +//message Details { +// optional uint64 serial = 1; +// optional string issuer = 2; +// optional string verifiedName = 4; +// repeated LocalizedName localizedNames = 8; +// optional uint64 issueTime = 10; +//} + +message VerifiedNameCertificate { + optional bytes details = 1; + optional bytes signature = 2; + optional bytes serverSignature = 3; +} + +message LocalizedName { + optional string lg = 1; + optional string lc = 2; + optional string verifiedName = 3; +} + +message SyncActionData { + optional bytes index = 1; + optional SyncActionValue value = 2; + optional bytes padding = 3; + optional int32 version = 4; +} + +message StarAction { + optional bool starred = 1; +} + +message ContactAction { + optional string fullName = 1; + optional string firstName = 2; +} + +message MuteAction { + optional bool muted = 1; + optional int64 muteEndTimestamp = 2; +} + +message PinAction { + optional bool pinned = 1; +} + +message SecurityNotificationSetting { + optional bool showNotification = 1; +} + +message PushNameSetting { + optional string name = 1; +} + +message LocaleSetting { + optional string locale = 1; +} + +message QuickReplyAction { + optional string shortcut = 1; + optional string message = 2; + repeated string keywords = 3; + optional int32 count = 4; + optional bool deleted = 5; +} + +message LabelAssociationAction { + optional bool labeled = 1; +} + +message LabelEditAction { + optional string name = 1; + optional int32 color = 2; + optional int32 predefinedId = 3; + optional bool deleted = 4; +} + +message RecentStickerWeightsAction { + repeated RecentStickerWeight weights = 1; +} + +message RecentStickerMetadata { + optional string directPath = 1; + optional string encFilehash = 2; + optional string mediaKey = 3; + optional string stanzaId = 4; + optional string chatJid = 5; + optional string participant = 6; + optional bool isSentByMe = 7; +} + +message RecentEmojiWeightsAction { + repeated RecentEmojiWeight weights = 1; +} + +message ArchiveChatAction { + optional bool archived = 1; + optional SyncActionMessageRange messageRange = 2; +} + +message DeleteMessageForMeAction { + optional bool deleteMedia = 1; + optional int64 messageTimestamp = 2; +} + +message MarkChatAsReadAction { + optional bool read = 1; + optional SyncActionMessageRange messageRange = 2; +} + +message ClearChatAction { + optional SyncActionMessageRange messageRange = 1; +} + +message DeleteChatAction { + optional SyncActionMessageRange messageRange = 1; +} + +message UnarchiveChatsSetting { + optional bool unarchiveChats = 1; +} + +message SyncActionMessageRange { + optional int64 lastMessageTimestamp = 1; + optional int64 lastSystemMessageTimestamp = 2; + repeated SyncActionMessage messages = 3; +} + +message SyncActionMessage { + optional MessageKey key = 1; + optional int64 timestamp = 2; +} + +message KeyExpiration { + optional int32 expiredKeyEpoch = 1; +} + +message SyncActionValue { + optional int64 timestamp = 1; + optional StarAction starAction = 2; + optional ContactAction contactAction = 3; + optional MuteAction muteAction = 4; + optional PinAction pinAction = 5; + optional SecurityNotificationSetting securityNotificationSetting = 6; + optional PushNameSetting pushNameSetting = 7; + optional QuickReplyAction quickReplyAction = 8; + optional RecentStickerWeightsAction recentStickerWeightsAction = 9; + optional RecentStickerMetadata recentStickerMetadata = 10; + optional RecentEmojiWeightsAction recentEmojiWeightsAction = 11; + optional LabelEditAction labelEditAction = 14; + optional LabelAssociationAction labelAssociationAction = 15; + optional LocaleSetting localeSetting = 16; + optional ArchiveChatAction archiveChatAction = 17; + optional DeleteMessageForMeAction deleteMessageForMeAction = 18; + optional KeyExpiration keyExpiration = 19; + optional MarkChatAsReadAction markChatAsReadAction = 20; + optional ClearChatAction clearChatAction = 21; + optional DeleteChatAction deleteChatAction = 22; + optional UnarchiveChatsSetting unarchiveChatsSetting = 23; +} + +message RecentEmojiWeight { + optional string emoji = 1; + optional float weight = 2; +} + +message RecentStickerWeight { + optional string filehash = 1; + optional float weight = 2; +} + +message SyncdPatch { + optional SyncdVersion version = 1; + repeated SyncdMutation mutations = 2; + optional ExternalBlobReference externalMutations = 3; + optional bytes snapshotMac = 4; + optional bytes patchMac = 5; + optional KeyId keyId = 6; + optional ExitCode exitCode = 7; + optional uint32 deviceIndex = 8; +} + +message SyncdMutation { + enum SyncdMutationSyncdOperation { + SET = 0; + REMOVE = 1; + } + optional SyncdMutationSyncdOperation operation = 1; + optional SyncdRecord record = 2; +} + +message SyncdMutations { + repeated SyncdMutation mutations = 1; +} + +message SyncdSnapshot { + optional SyncdVersion version = 1; + repeated SyncdRecord records = 2; + optional bytes mac = 3; + optional KeyId keyId = 4; +} + +message ExternalBlobReference { + optional bytes mediaKey = 1; + optional string directPath = 2; + optional string handle = 3; + optional uint64 fileSizeBytes = 4; + optional bytes fileSha256 = 5; + optional bytes fileEncSha256 = 6; +} + +message SyncdRecord { + optional SyncdIndex index = 1; + optional SyncdValue value = 2; + optional KeyId keyId = 3; +} + +message KeyId { + optional bytes id = 1; +} + +message SyncdValue { + optional bytes blob = 1; +} + +message SyncdIndex { + optional bytes blob = 1; +} + +message ExitCode { + optional uint64 code = 1; + optional string text = 2; +} + +message SyncdVersion { + optional uint64 version = 1; +} + +message ServerErrorReceipt { + optional string stanzaId = 1; +} + +message MediaRetryNotification { + optional string stanzaId = 1; + optional string directPath = 2; + enum MediaRetryNotificationResultType { + GENERAL_ERROR = 0; + SUCCESS = 1; + NOT_FOUND = 2; + DECRYPTION_ERROR = 3; + } + optional MediaRetryNotificationResultType result = 3; +} + +message MsgOpaqueData { + optional string body = 1; + optional string caption = 3; + optional string clientUrl = 4; +// optional string loc = 4; + optional double lng = 5; + optional double lat = 7; + optional int32 paymentAmount1000 = 8; + optional string paymentNoteMsgBody = 9; + optional string canonicalUrl = 10; + optional string matchedText = 11; + optional string title = 12; + optional string description = 13; +} + +message MsgRowOpaqueData { + optional MsgOpaqueData currentMsg = 1; + optional MsgOpaqueData quotedMsg = 2; +} + +message Pushname { + optional string id = 1; + optional string pushname = 2; +} + +message HistorySyncMsg { + optional WebMessageInfo message = 1; + optional uint64 msgOrderId = 2; +} + +message Conversation { + required string id = 1; + repeated HistorySyncMsg messages = 2; + optional string newJid = 3; + optional string oldJid = 4; + optional uint64 lastMsgTimestamp = 5; + optional uint32 unreadCount = 6; + optional bool readOnly = 7; + optional bool endOfHistoryTransfer = 8; + optional uint32 ephemeralExpiration = 9; + optional int64 ephemeralSettingTimestamp = 10; + enum ConversationEndOfHistoryTransferType { + COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY = 0; + COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY = 1; + } + optional ConversationEndOfHistoryTransferType endOfHistoryTransferType = 11; + optional uint64 conversationTimestamp = 12; + optional string name = 13; + optional string pHash = 14; + optional bool notSpam = 15; +} + +message HistorySync { + enum HistorySyncHistorySyncType { + INITIAL_BOOTSTRAP = 0; + INITIAL_STATUS_V3 = 1; + FULL = 2; + RECENT = 3; + PUSH_NAME = 4; + } + required HistorySyncHistorySyncType syncType = 1; + repeated Conversation conversations = 2; + repeated WebMessageInfo statusV3Messages = 3; + optional uint32 chunkOrder = 5; + optional uint32 progress = 6; + repeated Pushname pushnames = 7; +} + +message EphemeralSetting { + optional sfixed32 duration = 1; + optional sfixed64 timestamp = 2; +} + +message PaymentBackground { + optional string id = 1; + optional string fileLength = 2; + optional uint32 width = 3; + optional uint32 height = 4; + optional string mimetype = 5; + optional fixed32 placeholderArgb = 6; + optional fixed32 textArgb = 7; + optional fixed32 subtextArgb = 8; +} + +message Money { + optional int64 value = 1; + optional uint32 offset = 2; + optional string currencyCode = 3; +} + +message HydratedQuickReplyButton { + optional string displayText = 1; + optional string id = 2; +} + +message HydratedURLButton { + optional string displayText = 1; + optional string url = 2; +} + +message HydratedCallButton { + optional string displayText = 1; + optional string phoneNumber = 2; +} + +message HydratedTemplateButton { + optional uint32 index = 4; + oneof hydratedButton { + HydratedQuickReplyButton quickReplyButton = 1; + HydratedURLButton urlButton = 2; + HydratedCallButton callButton = 3; + } } message QuickReplyButton { @@ -115,7 +725,6 @@ message ContextInfo { optional string entryPointConversionSource = 29; optional string entryPointConversionApp = 30; optional uint32 entryPointConversionDelaySeconds = 31; - optional DisappearingMode disappearingMode = 32; } message SenderKeyDistributionMessage { @@ -149,7 +758,6 @@ message ImageMessage { optional string thumbnailDirectPath = 26; optional bytes thumbnailSha256 = 27; optional bytes thumbnailEncSha256 = 28; - optional string staticUrl = 29; } message InvoiceMessage { @@ -289,7 +897,6 @@ message VideoMessage { optional string thumbnailDirectPath = 21; optional bytes thumbnailSha256 = 22; optional bytes thumbnailEncSha256 = 23; - optional string staticUrl = 24; } message Call { @@ -325,7 +932,6 @@ message ProtocolMessage { optional AppStateSyncKeyRequest appStateSyncKeyRequest = 8; optional InitialSecurityNotificationSettingSync initialSecurityNotificationSettingSync = 9; optional AppStateFatalExceptionNotification appStateFatalExceptionNotification = 10; - optional DisappearingMode disappearingMode = 11; } message HistorySyncNotification { @@ -669,59 +1275,6 @@ message ListResponseMessage { optional string description = 5; } -message Header { - optional string title = 1; - optional string subtitle = 2; - oneof media { - DocumentMessage documentMessage = 3; - ImageMessage imageMessage = 4; - } -} - -message Body { - optional string text = 1; -} - -message Footer { - optional string text = 1; -} - -message ShopsMessage { - optional string id = 1; - enum ShopsMessageSurface { - UNKNOWN_SURFACE = 0; - FB = 1; - IG = 2; - WA = 3; - } - optional ShopsMessageSurface surface = 2; - enum ShopsMessageType { - UNKNOWN_TYPE = 0; - PRODUCT = 1; - STOREFRONT = 2; - COLLECTION = 3; - } - optional ShopsMessageType type = 3; - optional int32 messageVersion = 4; -} - -message CollectionMessage { - optional string bizJid = 1; - optional string id = 2; - optional int32 messageVersion = 3; -} - -message InteractiveMessage { - optional Header header = 1; - optional Body body = 2; - optional Footer footer = 3; - optional ContextInfo contextInfo = 15; - oneof interactiveMessage { - ShopsMessage shopsMessage = 4; - CollectionMessage collectionMessage = 5; - } -} - message GroupInviteMessage { optional string groupJid = 1; optional string inviteCode = 2; @@ -837,66 +1390,65 @@ message Message { optional ButtonsMessage buttonsMessage = 42; optional ButtonsResponseMessage buttonsResponseMessage = 43; optional PaymentInviteMessage paymentInviteMessage = 44; - optional InteractiveMessage interactiveMessage = 45; } -message DisappearingMode { - enum DisappearingModeInitiator { - CHANGED_IN_CHAT = 0; - INITIATED_BY_ME = 1; - INITIATED_BY_OTHER = 2; +message CompanionProps { + optional string os = 1; + optional AppVersion version = 2; + enum CompanionPropsPlatformType { + UNKNOWN = 0; + CHROME = 1; + FIREFOX = 2; + IE = 3; + OPERA = 4; + SAFARI = 5; + EDGE = 6; + DESKTOP = 7; + IPAD = 8; + ANDROID_TABLET = 9; + OHANA = 10; + ALOHA = 11; + CATALINA = 12; } - optional DisappearingModeInitiator initiator = 1; + optional CompanionPropsPlatformType platformType = 3; + optional bool requireFullSync = 4; } -message PaymentBackground { - optional string id = 1; - optional uint64 fileLength = 2; - optional uint32 width = 3; - optional uint32 height = 4; - optional string mimetype = 5; - optional fixed32 placeholderArgb = 6; - optional fixed32 textArgb = 7; - optional fixed32 subtextArgb = 8; +message ADVSignedDeviceIdentityHMAC { + optional bytes details = 1; + optional bytes hmac = 2; } -message Money { - optional int64 value = 1; - optional uint32 offset = 2; - optional string currencyCode = 3; +message ADVSignedDeviceIdentity { + optional bytes details = 1; + optional bytes accountSignatureKey = 2; + optional bytes accountSignature = 3; + optional bytes deviceSignature = 4; } -message HydratedQuickReplyButton { - optional string displayText = 1; - optional string id = 2; +message ADVDeviceIdentity { + optional uint32 rawId = 1; + optional uint64 timestamp = 2; + optional uint32 keyIndex = 3; } -message HydratedURLButton { - optional string displayText = 1; - optional string url = 2; +message ADVSignedKeyIndexList { + optional bytes details = 1; + optional bytes accountSignature = 2; } -message HydratedCallButton { - optional string displayText = 1; - optional string phoneNumber = 2; +message ADVKeyIndexList { + optional uint32 rawId = 1; + optional uint64 timestamp = 2; + optional uint32 currentIndex = 3; + repeated uint32 validIndexes = 4 [packed=true]; } -message HydratedTemplateButton { - optional uint32 index = 4; - oneof hydratedButton { - HydratedQuickReplyButton quickReplyButton = 1; - HydratedURLButton urlButton = 2; - HydratedCallButton callButton = 3; - } -} - -message UserReceipt { - required string userJid = 1; - optional int64 receiptTimestamp = 2; - optional int64 readTimestamp = 3; - optional int64 playedTimestamp = 4; - repeated string pendingDeviceJid = 5; - repeated string deliveredDeviceJid = 6; +message MessageKey { + optional string remoteJid = 1; + optional bool fromMe = 2; + optional string id = 3; + optional string participant = 4; } message PhotoChange { @@ -958,7 +1510,6 @@ message WebFeatures { optional WebFeaturesFlag ephemeralAllowGroupMembers = 44; optional WebFeaturesFlag ephemeral24HDuration = 45; optional WebFeaturesFlag mdForceUpgrade = 46; - optional WebFeaturesFlag disappearingMode = 47; } message NotificationMessageInfo { @@ -1194,7 +1745,6 @@ message WebMessageInfo { BIZ_PRIVACY_MODE_INIT_BSP = 127; BIZ_PRIVACY_MODE_TO_FB = 128; BIZ_PRIVACY_MODE_TO_BSP = 129; - DISAPPEARING_MODE = 130; } optional WebMessageInfoStubType messageStubType = 24; optional bool clearMedia = 25; @@ -1218,5 +1768,4 @@ message WebMessageInfo { optional string verifiedBizName = 37; optional MediaData mediaData = 38; optional PhotoChange photoChange = 39; - repeated UserReceipt userReceipt = 40; -} +} \ No newline at end of file diff --git a/WAMessage/index.d.ts b/WAProto/index.d.ts similarity index 60% rename from WAMessage/index.d.ts rename to WAProto/index.d.ts index 5412364..9299a7b 100644 --- a/WAMessage/index.d.ts +++ b/WAProto/index.d.ts @@ -2,109 +2,7691 @@ import * as $protobuf from "protobufjs"; /** Namespace proto. */ export namespace proto { - /** Properties of a MessageKey. */ - interface IMessageKey { + /** Properties of an AppVersion. */ + interface IAppVersion { - /** MessageKey remoteJid */ - remoteJid?: (string|null); + /** AppVersion primary */ + primary?: (number|null); - /** MessageKey fromMe */ - fromMe?: (boolean|null); + /** AppVersion secondary */ + secondary?: (number|null); - /** MessageKey id */ - id?: (string|null); + /** AppVersion tertiary */ + tertiary?: (number|null); - /** MessageKey participant */ - participant?: (string|null); + /** AppVersion quaternary */ + quaternary?: (number|null); + + /** AppVersion quinary */ + quinary?: (number|null); } - /** Represents a MessageKey. */ - class MessageKey implements IMessageKey { + /** Represents an AppVersion. */ + class AppVersion implements IAppVersion { /** - * Constructs a new MessageKey. + * Constructs a new AppVersion. * @param [properties] Properties to set */ - constructor(properties?: proto.IMessageKey); + constructor(properties?: proto.IAppVersion); - /** MessageKey remoteJid. */ - public remoteJid: string; + /** AppVersion primary. */ + public primary: number; - /** MessageKey fromMe. */ - public fromMe: boolean; + /** AppVersion secondary. */ + public secondary: number; - /** MessageKey id. */ - public id: string; + /** AppVersion tertiary. */ + public tertiary: number; - /** MessageKey participant. */ - public participant: string; + /** AppVersion quaternary. */ + public quaternary: number; + + /** AppVersion quinary. */ + public quinary: number; /** - * Creates a new MessageKey instance using the specified properties. + * Creates a new AppVersion instance using the specified properties. * @param [properties] Properties to set - * @returns MessageKey instance + * @returns AppVersion instance */ - public static create(properties?: proto.IMessageKey): proto.MessageKey; + public static create(properties?: proto.IAppVersion): proto.AppVersion; /** - * Encodes the specified MessageKey message. Does not implicitly {@link proto.MessageKey.verify|verify} messages. - * @param message MessageKey message or plain object to encode + * Encodes the specified AppVersion message. Does not implicitly {@link proto.AppVersion.verify|verify} messages. + * @param message AppVersion message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encode(message: proto.IMessageKey, writer?: $protobuf.Writer): $protobuf.Writer; + public static encode(message: proto.IAppVersion, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Encodes the specified MessageKey message, length delimited. Does not implicitly {@link proto.MessageKey.verify|verify} messages. - * @param message MessageKey message or plain object to encode + * Encodes the specified AppVersion message, length delimited. Does not implicitly {@link proto.AppVersion.verify|verify} messages. + * @param message AppVersion message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encodeDelimited(message: proto.IMessageKey, writer?: $protobuf.Writer): $protobuf.Writer; + public static encodeDelimited(message: proto.IAppVersion, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Decodes a MessageKey message from the specified reader or buffer. + * Decodes an AppVersion message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns MessageKey + * @returns AppVersion * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MessageKey; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.AppVersion; /** - * Decodes a MessageKey message from the specified reader or buffer, length delimited. + * Decodes an AppVersion message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns MessageKey + * @returns AppVersion * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MessageKey; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.AppVersion; /** - * Verifies a MessageKey message. + * Verifies an AppVersion message. * @param message Plain object to verify * @returns `null` if valid, otherwise the reason why it is not */ public static verify(message: { [k: string]: any }): (string|null); /** - * Creates a MessageKey message from a plain object. Also converts values to their respective internal types. + * Creates an AppVersion message from a plain object. Also converts values to their respective internal types. * @param object Plain object - * @returns MessageKey + * @returns AppVersion */ - public static fromObject(object: { [k: string]: any }): proto.MessageKey; + public static fromObject(object: { [k: string]: any }): proto.AppVersion; /** - * Creates a plain object from a MessageKey message. Also converts values to other types if specified. - * @param message MessageKey + * Creates a plain object from an AppVersion message. Also converts values to other types if specified. + * @param message AppVersion * @param [options] Conversion options * @returns Plain object */ - public static toObject(message: proto.MessageKey, options?: $protobuf.IConversionOptions): { [k: string]: any }; + public static toObject(message: proto.AppVersion, options?: $protobuf.IConversionOptions): { [k: string]: any }; /** - * Converts this MessageKey to JSON. + * Converts this AppVersion to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a UserAgent. */ + interface IUserAgent { + + /** UserAgent platform */ + platform?: (proto.UserAgent.UserAgentPlatform|null); + + /** UserAgent appVersion */ + appVersion?: (proto.IAppVersion|null); + + /** UserAgent mcc */ + mcc?: (string|null); + + /** UserAgent mnc */ + mnc?: (string|null); + + /** UserAgent osVersion */ + osVersion?: (string|null); + + /** UserAgent manufacturer */ + manufacturer?: (string|null); + + /** UserAgent device */ + device?: (string|null); + + /** UserAgent osBuildNumber */ + osBuildNumber?: (string|null); + + /** UserAgent phoneId */ + phoneId?: (string|null); + + /** UserAgent releaseChannel */ + releaseChannel?: (proto.UserAgent.UserAgentReleaseChannel|null); + + /** UserAgent localeLanguageIso6391 */ + localeLanguageIso6391?: (string|null); + + /** UserAgent localeCountryIso31661Alpha2 */ + localeCountryIso31661Alpha2?: (string|null); + + /** UserAgent deviceBoard */ + deviceBoard?: (string|null); + } + + /** Represents a UserAgent. */ + class UserAgent implements IUserAgent { + + /** + * Constructs a new UserAgent. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IUserAgent); + + /** UserAgent platform. */ + public platform: proto.UserAgent.UserAgentPlatform; + + /** UserAgent appVersion. */ + public appVersion?: (proto.IAppVersion|null); + + /** UserAgent mcc. */ + public mcc: string; + + /** UserAgent mnc. */ + public mnc: string; + + /** UserAgent osVersion. */ + public osVersion: string; + + /** UserAgent manufacturer. */ + public manufacturer: string; + + /** UserAgent device. */ + public device: string; + + /** UserAgent osBuildNumber. */ + public osBuildNumber: string; + + /** UserAgent phoneId. */ + public phoneId: string; + + /** UserAgent releaseChannel. */ + public releaseChannel: proto.UserAgent.UserAgentReleaseChannel; + + /** UserAgent localeLanguageIso6391. */ + public localeLanguageIso6391: string; + + /** UserAgent localeCountryIso31661Alpha2. */ + public localeCountryIso31661Alpha2: string; + + /** UserAgent deviceBoard. */ + public deviceBoard: string; + + /** + * Creates a new UserAgent instance using the specified properties. + * @param [properties] Properties to set + * @returns UserAgent instance + */ + public static create(properties?: proto.IUserAgent): proto.UserAgent; + + /** + * Encodes the specified UserAgent message. Does not implicitly {@link proto.UserAgent.verify|verify} messages. + * @param message UserAgent message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IUserAgent, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified UserAgent message, length delimited. Does not implicitly {@link proto.UserAgent.verify|verify} messages. + * @param message UserAgent message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IUserAgent, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a UserAgent message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns UserAgent + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.UserAgent; + + /** + * Decodes a UserAgent message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns UserAgent + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.UserAgent; + + /** + * Verifies a UserAgent message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a UserAgent message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns UserAgent + */ + public static fromObject(object: { [k: string]: any }): proto.UserAgent; + + /** + * Creates a plain object from a UserAgent message. Also converts values to other types if specified. + * @param message UserAgent + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.UserAgent, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this UserAgent to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace UserAgent { + + /** UserAgentPlatform enum. */ + enum UserAgentPlatform { + ANDROID = 0, + IOS = 1, + WINDOWS_PHONE = 2, + BLACKBERRY = 3, + BLACKBERRYX = 4, + S40 = 5, + S60 = 6, + PYTHON_CLIENT = 7, + TIZEN = 8, + ENTERPRISE = 9, + SMB_ANDROID = 10, + KAIOS = 11, + SMB_IOS = 12, + WINDOWS = 13, + WEB = 14, + PORTAL = 15, + GREEN_ANDROID = 16, + GREEN_IPHONE = 17, + BLUE_ANDROID = 18, + BLUE_IPHONE = 19, + FBLITE_ANDROID = 20, + MLITE_ANDROID = 21, + IGLITE_ANDROID = 22, + PAGE = 23, + MACOS = 24, + VR = 25 + } + + /** UserAgentReleaseChannel enum. */ + enum UserAgentReleaseChannel { + RELEASE = 0, + BETA = 1, + ALPHA = 2, + DEBUG = 3 + } + } + + /** Properties of a WebdPayload. */ + interface IWebdPayload { + + /** WebdPayload usesParticipantInKey */ + usesParticipantInKey?: (boolean|null); + + /** WebdPayload supportsStarredMessages */ + supportsStarredMessages?: (boolean|null); + + /** WebdPayload supportsDocumentMessages */ + supportsDocumentMessages?: (boolean|null); + + /** WebdPayload supportsUrlMessages */ + supportsUrlMessages?: (boolean|null); + + /** WebdPayload supportsMediaRetry */ + supportsMediaRetry?: (boolean|null); + + /** WebdPayload supportsE2EImage */ + supportsE2EImage?: (boolean|null); + + /** WebdPayload supportsE2EVideo */ + supportsE2EVideo?: (boolean|null); + + /** WebdPayload supportsE2EAudio */ + supportsE2EAudio?: (boolean|null); + + /** WebdPayload supportsE2EDocument */ + supportsE2EDocument?: (boolean|null); + + /** WebdPayload documentTypes */ + documentTypes?: (string|null); + + /** WebdPayload features */ + features?: (Uint8Array|null); + } + + /** Represents a WebdPayload. */ + class WebdPayload implements IWebdPayload { + + /** + * Constructs a new WebdPayload. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IWebdPayload); + + /** WebdPayload usesParticipantInKey. */ + public usesParticipantInKey: boolean; + + /** WebdPayload supportsStarredMessages. */ + public supportsStarredMessages: boolean; + + /** WebdPayload supportsDocumentMessages. */ + public supportsDocumentMessages: boolean; + + /** WebdPayload supportsUrlMessages. */ + public supportsUrlMessages: boolean; + + /** WebdPayload supportsMediaRetry. */ + public supportsMediaRetry: boolean; + + /** WebdPayload supportsE2EImage. */ + public supportsE2EImage: boolean; + + /** WebdPayload supportsE2EVideo. */ + public supportsE2EVideo: boolean; + + /** WebdPayload supportsE2EAudio. */ + public supportsE2EAudio: boolean; + + /** WebdPayload supportsE2EDocument. */ + public supportsE2EDocument: boolean; + + /** WebdPayload documentTypes. */ + public documentTypes: string; + + /** WebdPayload features. */ + public features: Uint8Array; + + /** + * Creates a new WebdPayload instance using the specified properties. + * @param [properties] Properties to set + * @returns WebdPayload instance + */ + public static create(properties?: proto.IWebdPayload): proto.WebdPayload; + + /** + * Encodes the specified WebdPayload message. Does not implicitly {@link proto.WebdPayload.verify|verify} messages. + * @param message WebdPayload message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IWebdPayload, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified WebdPayload message, length delimited. Does not implicitly {@link proto.WebdPayload.verify|verify} messages. + * @param message WebdPayload message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IWebdPayload, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a WebdPayload message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns WebdPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WebdPayload; + + /** + * Decodes a WebdPayload message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns WebdPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WebdPayload; + + /** + * Verifies a WebdPayload message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a WebdPayload message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns WebdPayload + */ + public static fromObject(object: { [k: string]: any }): proto.WebdPayload; + + /** + * Creates a plain object from a WebdPayload message. Also converts values to other types if specified. + * @param message WebdPayload + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.WebdPayload, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this WebdPayload to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a WebInfo. */ + interface IWebInfo { + + /** WebInfo refToken */ + refToken?: (string|null); + + /** WebInfo version */ + version?: (string|null); + + /** WebInfo webdPayload */ + webdPayload?: (proto.IWebdPayload|null); + + /** WebInfo webSubPlatform */ + webSubPlatform?: (proto.WebInfo.WebInfoWebSubPlatform|null); + } + + /** Represents a WebInfo. */ + class WebInfo implements IWebInfo { + + /** + * Constructs a new WebInfo. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IWebInfo); + + /** WebInfo refToken. */ + public refToken: string; + + /** WebInfo version. */ + public version: string; + + /** WebInfo webdPayload. */ + public webdPayload?: (proto.IWebdPayload|null); + + /** WebInfo webSubPlatform. */ + public webSubPlatform: proto.WebInfo.WebInfoWebSubPlatform; + + /** + * Creates a new WebInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns WebInfo instance + */ + public static create(properties?: proto.IWebInfo): proto.WebInfo; + + /** + * Encodes the specified WebInfo message. Does not implicitly {@link proto.WebInfo.verify|verify} messages. + * @param message WebInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IWebInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified WebInfo message, length delimited. Does not implicitly {@link proto.WebInfo.verify|verify} messages. + * @param message WebInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IWebInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a WebInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns WebInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WebInfo; + + /** + * Decodes a WebInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns WebInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WebInfo; + + /** + * Verifies a WebInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a WebInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns WebInfo + */ + public static fromObject(object: { [k: string]: any }): proto.WebInfo; + + /** + * Creates a plain object from a WebInfo message. Also converts values to other types if specified. + * @param message WebInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.WebInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this WebInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace WebInfo { + + /** WebInfoWebSubPlatform enum. */ + enum WebInfoWebSubPlatform { + WEB_BROWSER = 0, + APP_STORE = 1, + WIN_STORE = 2, + DARWIN = 3, + WIN32 = 4 + } + } + + /** Properties of a DNSSource. */ + interface IDNSSource { + + /** DNSSource dnsMethod */ + dnsMethod?: (proto.DNSSource.DNSSourceDNSResolutionMethod|null); + + /** DNSSource appCached */ + appCached?: (boolean|null); + } + + /** Represents a DNSSource. */ + class DNSSource implements IDNSSource { + + /** + * Constructs a new DNSSource. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IDNSSource); + + /** DNSSource dnsMethod. */ + public dnsMethod: proto.DNSSource.DNSSourceDNSResolutionMethod; + + /** DNSSource appCached. */ + public appCached: boolean; + + /** + * Creates a new DNSSource instance using the specified properties. + * @param [properties] Properties to set + * @returns DNSSource instance + */ + public static create(properties?: proto.IDNSSource): proto.DNSSource; + + /** + * Encodes the specified DNSSource message. Does not implicitly {@link proto.DNSSource.verify|verify} messages. + * @param message DNSSource message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IDNSSource, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified DNSSource message, length delimited. Does not implicitly {@link proto.DNSSource.verify|verify} messages. + * @param message DNSSource message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IDNSSource, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a DNSSource message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns DNSSource + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DNSSource; + + /** + * Decodes a DNSSource message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns DNSSource + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DNSSource; + + /** + * Verifies a DNSSource message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a DNSSource message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns DNSSource + */ + public static fromObject(object: { [k: string]: any }): proto.DNSSource; + + /** + * Creates a plain object from a DNSSource message. Also converts values to other types if specified. + * @param message DNSSource + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.DNSSource, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this DNSSource to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace DNSSource { + + /** DNSSourceDNSResolutionMethod enum. */ + enum DNSSourceDNSResolutionMethod { + SYSTEM = 0, + GOOGLE = 1, + HARDCODED = 2, + OVERRIDE = 3, + FALLBACK = 4 + } + } + + /** Properties of a CompanionRegData. */ + interface ICompanionRegData { + + /** CompanionRegData eRegid */ + eRegid?: (Uint8Array|null); + + /** CompanionRegData eKeytype */ + eKeytype?: (Uint8Array|null); + + /** CompanionRegData eIdent */ + eIdent?: (Uint8Array|null); + + /** CompanionRegData eSkeyId */ + eSkeyId?: (Uint8Array|null); + + /** CompanionRegData eSkeyVal */ + eSkeyVal?: (Uint8Array|null); + + /** CompanionRegData eSkeySig */ + eSkeySig?: (Uint8Array|null); + + /** CompanionRegData buildHash */ + buildHash?: (Uint8Array|null); + + /** CompanionRegData companionProps */ + companionProps?: (Uint8Array|null); + } + + /** Represents a CompanionRegData. */ + class CompanionRegData implements ICompanionRegData { + + /** + * Constructs a new CompanionRegData. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ICompanionRegData); + + /** CompanionRegData eRegid. */ + public eRegid: Uint8Array; + + /** CompanionRegData eKeytype. */ + public eKeytype: Uint8Array; + + /** CompanionRegData eIdent. */ + public eIdent: Uint8Array; + + /** CompanionRegData eSkeyId. */ + public eSkeyId: Uint8Array; + + /** CompanionRegData eSkeyVal. */ + public eSkeyVal: Uint8Array; + + /** CompanionRegData eSkeySig. */ + public eSkeySig: Uint8Array; + + /** CompanionRegData buildHash. */ + public buildHash: Uint8Array; + + /** CompanionRegData companionProps. */ + public companionProps: Uint8Array; + + /** + * Creates a new CompanionRegData instance using the specified properties. + * @param [properties] Properties to set + * @returns CompanionRegData instance + */ + public static create(properties?: proto.ICompanionRegData): proto.CompanionRegData; + + /** + * Encodes the specified CompanionRegData message. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages. + * @param message CompanionRegData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ICompanionRegData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified CompanionRegData message, length delimited. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages. + * @param message CompanionRegData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ICompanionRegData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a CompanionRegData message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns CompanionRegData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.CompanionRegData; + + /** + * Decodes a CompanionRegData message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns CompanionRegData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.CompanionRegData; + + /** + * Verifies a CompanionRegData message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a CompanionRegData message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns CompanionRegData + */ + public static fromObject(object: { [k: string]: any }): proto.CompanionRegData; + + /** + * Creates a plain object from a CompanionRegData message. Also converts values to other types if specified. + * @param message CompanionRegData + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.CompanionRegData, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this CompanionRegData to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ClientPayload. */ + interface IClientPayload { + + /** ClientPayload username */ + username?: (number|Long|null); + + /** ClientPayload passive */ + passive?: (boolean|null); + + /** ClientPayload clientFeatures */ + clientFeatures?: (proto.ClientPayload.ClientPayloadClientFeature[]|null); + + /** ClientPayload userAgent */ + userAgent?: (proto.IUserAgent|null); + + /** ClientPayload webInfo */ + webInfo?: (proto.IWebInfo|null); + + /** ClientPayload pushName */ + pushName?: (string|null); + + /** ClientPayload sessionId */ + sessionId?: (number|null); + + /** ClientPayload shortConnect */ + shortConnect?: (boolean|null); + + /** ClientPayload iosAppExtension */ + iosAppExtension?: (proto.ClientPayload.ClientPayloadIOSAppExtension|null); + + /** ClientPayload connectType */ + connectType?: (proto.ClientPayload.ClientPayloadConnectType|null); + + /** ClientPayload connectReason */ + connectReason?: (proto.ClientPayload.ClientPayloadConnectReason|null); + + /** ClientPayload shards */ + shards?: (number[]|null); + + /** ClientPayload dnsSource */ + dnsSource?: (proto.IDNSSource|null); + + /** ClientPayload connectAttemptCount */ + connectAttemptCount?: (number|null); + + /** ClientPayload agent */ + agent?: (number|null); + + /** ClientPayload device */ + device?: (number|null); + + /** ClientPayload regData */ + regData?: (proto.ICompanionRegData|null); + + /** ClientPayload product */ + product?: (proto.ClientPayload.ClientPayloadProduct|null); + + /** ClientPayload fbCat */ + fbCat?: (Uint8Array|null); + + /** ClientPayload fbUserAgent */ + fbUserAgent?: (Uint8Array|null); + + /** ClientPayload oc */ + oc?: (boolean|null); + } + + /** Represents a ClientPayload. */ + class ClientPayload implements IClientPayload { + + /** + * Constructs a new ClientPayload. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IClientPayload); + + /** ClientPayload username. */ + public username: (number|Long); + + /** ClientPayload passive. */ + public passive: boolean; + + /** ClientPayload clientFeatures. */ + public clientFeatures: proto.ClientPayload.ClientPayloadClientFeature[]; + + /** ClientPayload userAgent. */ + public userAgent?: (proto.IUserAgent|null); + + /** ClientPayload webInfo. */ + public webInfo?: (proto.IWebInfo|null); + + /** ClientPayload pushName. */ + public pushName: string; + + /** ClientPayload sessionId. */ + public sessionId: number; + + /** ClientPayload shortConnect. */ + public shortConnect: boolean; + + /** ClientPayload iosAppExtension. */ + public iosAppExtension: proto.ClientPayload.ClientPayloadIOSAppExtension; + + /** ClientPayload connectType. */ + public connectType: proto.ClientPayload.ClientPayloadConnectType; + + /** ClientPayload connectReason. */ + public connectReason: proto.ClientPayload.ClientPayloadConnectReason; + + /** ClientPayload shards. */ + public shards: number[]; + + /** ClientPayload dnsSource. */ + public dnsSource?: (proto.IDNSSource|null); + + /** ClientPayload connectAttemptCount. */ + public connectAttemptCount: number; + + /** ClientPayload agent. */ + public agent: number; + + /** ClientPayload device. */ + public device: number; + + /** ClientPayload regData. */ + public regData?: (proto.ICompanionRegData|null); + + /** ClientPayload product. */ + public product: proto.ClientPayload.ClientPayloadProduct; + + /** ClientPayload fbCat. */ + public fbCat: Uint8Array; + + /** ClientPayload fbUserAgent. */ + public fbUserAgent: Uint8Array; + + /** ClientPayload oc. */ + public oc: boolean; + + /** + * Creates a new ClientPayload instance using the specified properties. + * @param [properties] Properties to set + * @returns ClientPayload instance + */ + public static create(properties?: proto.IClientPayload): proto.ClientPayload; + + /** + * Encodes the specified ClientPayload message. Does not implicitly {@link proto.ClientPayload.verify|verify} messages. + * @param message ClientPayload message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IClientPayload, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ClientPayload message, length delimited. Does not implicitly {@link proto.ClientPayload.verify|verify} messages. + * @param message ClientPayload message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IClientPayload, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ClientPayload message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ClientPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ClientPayload; + + /** + * Decodes a ClientPayload message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ClientPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ClientPayload; + + /** + * Verifies a ClientPayload message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ClientPayload message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ClientPayload + */ + public static fromObject(object: { [k: string]: any }): proto.ClientPayload; + + /** + * Creates a plain object from a ClientPayload message. Also converts values to other types if specified. + * @param message ClientPayload + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ClientPayload, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ClientPayload to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace ClientPayload { + + /** ClientPayloadClientFeature enum. */ + enum ClientPayloadClientFeature { + NONE = 0 + } + + /** ClientPayloadIOSAppExtension enum. */ + enum ClientPayloadIOSAppExtension { + SHARE_EXTENSION = 0, + SERVICE_EXTENSION = 1, + INTENTS_EXTENSION = 2 + } + + /** ClientPayloadConnectType enum. */ + enum ClientPayloadConnectType { + CELLULAR_UNKNOWN = 0, + WIFI_UNKNOWN = 1, + CELLULAR_EDGE = 100, + CELLULAR_IDEN = 101, + CELLULAR_UMTS = 102, + CELLULAR_EVDO = 103, + CELLULAR_GPRS = 104, + CELLULAR_HSDPA = 105, + CELLULAR_HSUPA = 106, + CELLULAR_HSPA = 107, + CELLULAR_CDMA = 108, + CELLULAR_1XRTT = 109, + CELLULAR_EHRPD = 110, + CELLULAR_LTE = 111, + CELLULAR_HSPAP = 112 + } + + /** ClientPayloadConnectReason enum. */ + enum ClientPayloadConnectReason { + PUSH = 0, + USER_ACTIVATED = 1, + SCHEDULED = 2, + ERROR_RECONNECT = 3, + NETWORK_SWITCH = 4, + PING_RECONNECT = 5 + } + + /** ClientPayloadProduct enum. */ + enum ClientPayloadProduct { + WHATSAPP = 0, + MESSENGER = 1 + } + } + + /** Properties of a Details. */ + interface IDetails { + + /** Details serial */ + serial?: (number|null); + + /** Details issuer */ + issuer?: (string|null); + + /** Details expires */ + expires?: (number|Long|null); + + /** Details subject */ + subject?: (string|null); + + /** Details key */ + key?: (Uint8Array|null); + } + + /** Represents a Details. */ + class Details implements IDetails { + + /** + * Constructs a new Details. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IDetails); + + /** Details serial. */ + public serial: number; + + /** Details issuer. */ + public issuer: string; + + /** Details expires. */ + public expires: (number|Long); + + /** Details subject. */ + public subject: string; + + /** Details key. */ + public key: Uint8Array; + + /** + * Creates a new Details instance using the specified properties. + * @param [properties] Properties to set + * @returns Details instance + */ + public static create(properties?: proto.IDetails): proto.Details; + + /** + * Encodes the specified Details message. Does not implicitly {@link proto.Details.verify|verify} messages. + * @param message Details message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IDetails, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Details message, length delimited. Does not implicitly {@link proto.Details.verify|verify} messages. + * @param message Details message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IDetails, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Details message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Details + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Details; + + /** + * Decodes a Details message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Details + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Details; + + /** + * Verifies a Details message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Details message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Details + */ + public static fromObject(object: { [k: string]: any }): proto.Details; + + /** + * Creates a plain object from a Details message. Also converts values to other types if specified. + * @param message Details + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Details, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Details to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a NoiseCertificate. */ + interface INoiseCertificate { + + /** NoiseCertificate details */ + details?: (Uint8Array|null); + + /** NoiseCertificate signature */ + signature?: (Uint8Array|null); + } + + /** Represents a NoiseCertificate. */ + class NoiseCertificate implements INoiseCertificate { + + /** + * Constructs a new NoiseCertificate. + * @param [properties] Properties to set + */ + constructor(properties?: proto.INoiseCertificate); + + /** NoiseCertificate details. */ + public details: Uint8Array; + + /** NoiseCertificate signature. */ + public signature: Uint8Array; + + /** + * Creates a new NoiseCertificate instance using the specified properties. + * @param [properties] Properties to set + * @returns NoiseCertificate instance + */ + public static create(properties?: proto.INoiseCertificate): proto.NoiseCertificate; + + /** + * Encodes the specified NoiseCertificate message. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages. + * @param message NoiseCertificate message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.INoiseCertificate, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified NoiseCertificate message, length delimited. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages. + * @param message NoiseCertificate message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.INoiseCertificate, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a NoiseCertificate message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns NoiseCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.NoiseCertificate; + + /** + * Decodes a NoiseCertificate message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns NoiseCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.NoiseCertificate; + + /** + * Verifies a NoiseCertificate message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a NoiseCertificate message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns NoiseCertificate + */ + public static fromObject(object: { [k: string]: any }): proto.NoiseCertificate; + + /** + * Creates a plain object from a NoiseCertificate message. Also converts values to other types if specified. + * @param message NoiseCertificate + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.NoiseCertificate, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this NoiseCertificate to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ClientHello. */ + interface IClientHello { + + /** ClientHello ephemeral */ + ephemeral?: (Uint8Array|null); + + /** ClientHello static */ + "static"?: (Uint8Array|null); + + /** ClientHello payload */ + payload?: (Uint8Array|null); + } + + /** Represents a ClientHello. */ + class ClientHello implements IClientHello { + + /** + * Constructs a new ClientHello. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IClientHello); + + /** ClientHello ephemeral. */ + public ephemeral: Uint8Array; + + /** ClientHello static. */ + public static: Uint8Array; + + /** ClientHello payload. */ + public payload: Uint8Array; + + /** + * Creates a new ClientHello instance using the specified properties. + * @param [properties] Properties to set + * @returns ClientHello instance + */ + public static create(properties?: proto.IClientHello): proto.ClientHello; + + /** + * Encodes the specified ClientHello message. Does not implicitly {@link proto.ClientHello.verify|verify} messages. + * @param message ClientHello message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IClientHello, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ClientHello message, length delimited. Does not implicitly {@link proto.ClientHello.verify|verify} messages. + * @param message ClientHello message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IClientHello, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ClientHello message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ClientHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ClientHello; + + /** + * Decodes a ClientHello message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ClientHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ClientHello; + + /** + * Verifies a ClientHello message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ClientHello message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ClientHello + */ + public static fromObject(object: { [k: string]: any }): proto.ClientHello; + + /** + * Creates a plain object from a ClientHello message. Also converts values to other types if specified. + * @param message ClientHello + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ClientHello, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ClientHello to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ServerHello. */ + interface IServerHello { + + /** ServerHello ephemeral */ + ephemeral?: (Uint8Array|null); + + /** ServerHello static */ + "static"?: (Uint8Array|null); + + /** ServerHello payload */ + payload?: (Uint8Array|null); + } + + /** Represents a ServerHello. */ + class ServerHello implements IServerHello { + + /** + * Constructs a new ServerHello. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IServerHello); + + /** ServerHello ephemeral. */ + public ephemeral: Uint8Array; + + /** ServerHello static. */ + public static: Uint8Array; + + /** ServerHello payload. */ + public payload: Uint8Array; + + /** + * Creates a new ServerHello instance using the specified properties. + * @param [properties] Properties to set + * @returns ServerHello instance + */ + public static create(properties?: proto.IServerHello): proto.ServerHello; + + /** + * Encodes the specified ServerHello message. Does not implicitly {@link proto.ServerHello.verify|verify} messages. + * @param message ServerHello message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IServerHello, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ServerHello message, length delimited. Does not implicitly {@link proto.ServerHello.verify|verify} messages. + * @param message ServerHello message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IServerHello, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ServerHello message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ServerHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ServerHello; + + /** + * Decodes a ServerHello message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ServerHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ServerHello; + + /** + * Verifies a ServerHello message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ServerHello message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ServerHello + */ + public static fromObject(object: { [k: string]: any }): proto.ServerHello; + + /** + * Creates a plain object from a ServerHello message. Also converts values to other types if specified. + * @param message ServerHello + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ServerHello, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ServerHello to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ClientFinish. */ + interface IClientFinish { + + /** ClientFinish static */ + "static"?: (Uint8Array|null); + + /** ClientFinish payload */ + payload?: (Uint8Array|null); + } + + /** Represents a ClientFinish. */ + class ClientFinish implements IClientFinish { + + /** + * Constructs a new ClientFinish. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IClientFinish); + + /** ClientFinish static. */ + public static: Uint8Array; + + /** ClientFinish payload. */ + public payload: Uint8Array; + + /** + * Creates a new ClientFinish instance using the specified properties. + * @param [properties] Properties to set + * @returns ClientFinish instance + */ + public static create(properties?: proto.IClientFinish): proto.ClientFinish; + + /** + * Encodes the specified ClientFinish message. Does not implicitly {@link proto.ClientFinish.verify|verify} messages. + * @param message ClientFinish message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IClientFinish, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ClientFinish message, length delimited. Does not implicitly {@link proto.ClientFinish.verify|verify} messages. + * @param message ClientFinish message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IClientFinish, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ClientFinish message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ClientFinish + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ClientFinish; + + /** + * Decodes a ClientFinish message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ClientFinish + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ClientFinish; + + /** + * Verifies a ClientFinish message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ClientFinish message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ClientFinish + */ + public static fromObject(object: { [k: string]: any }): proto.ClientFinish; + + /** + * Creates a plain object from a ClientFinish message. Also converts values to other types if specified. + * @param message ClientFinish + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ClientFinish, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ClientFinish to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HandshakeMessage. */ + interface IHandshakeMessage { + + /** HandshakeMessage clientHello */ + clientHello?: (proto.IClientHello|null); + + /** HandshakeMessage serverHello */ + serverHello?: (proto.IServerHello|null); + + /** HandshakeMessage clientFinish */ + clientFinish?: (proto.IClientFinish|null); + } + + /** Represents a HandshakeMessage. */ + class HandshakeMessage implements IHandshakeMessage { + + /** + * Constructs a new HandshakeMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHandshakeMessage); + + /** HandshakeMessage clientHello. */ + public clientHello?: (proto.IClientHello|null); + + /** HandshakeMessage serverHello. */ + public serverHello?: (proto.IServerHello|null); + + /** HandshakeMessage clientFinish. */ + public clientFinish?: (proto.IClientFinish|null); + + /** + * Creates a new HandshakeMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns HandshakeMessage instance + */ + public static create(properties?: proto.IHandshakeMessage): proto.HandshakeMessage; + + /** + * Encodes the specified HandshakeMessage message. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages. + * @param message HandshakeMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHandshakeMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HandshakeMessage message, length delimited. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages. + * @param message HandshakeMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHandshakeMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HandshakeMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HandshakeMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HandshakeMessage; + + /** + * Decodes a HandshakeMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HandshakeMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HandshakeMessage; + + /** + * Verifies a HandshakeMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HandshakeMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HandshakeMessage + */ + public static fromObject(object: { [k: string]: any }): proto.HandshakeMessage; + + /** + * Creates a plain object from a HandshakeMessage message. Also converts values to other types if specified. + * @param message HandshakeMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HandshakeMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HandshakeMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a BizIdentityInfo. */ + interface IBizIdentityInfo { + + /** BizIdentityInfo vlevel */ + vlevel?: (proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue|null); + + /** BizIdentityInfo vnameCert */ + vnameCert?: (proto.IVerifiedNameCertificate|null); + + /** BizIdentityInfo signed */ + signed?: (boolean|null); + + /** BizIdentityInfo revoked */ + revoked?: (boolean|null); + + /** BizIdentityInfo hostStorage */ + hostStorage?: (proto.BizIdentityInfo.BizIdentityInfoHostStorageType|null); + + /** BizIdentityInfo actualActors */ + actualActors?: (proto.BizIdentityInfo.BizIdentityInfoActualActorsType|null); + + /** BizIdentityInfo privacyModeTs */ + privacyModeTs?: (number|Long|null); + } + + /** Represents a BizIdentityInfo. */ + class BizIdentityInfo implements IBizIdentityInfo { + + /** + * Constructs a new BizIdentityInfo. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IBizIdentityInfo); + + /** BizIdentityInfo vlevel. */ + public vlevel: proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue; + + /** BizIdentityInfo vnameCert. */ + public vnameCert?: (proto.IVerifiedNameCertificate|null); + + /** BizIdentityInfo signed. */ + public signed: boolean; + + /** BizIdentityInfo revoked. */ + public revoked: boolean; + + /** BizIdentityInfo hostStorage. */ + public hostStorage: proto.BizIdentityInfo.BizIdentityInfoHostStorageType; + + /** BizIdentityInfo actualActors. */ + public actualActors: proto.BizIdentityInfo.BizIdentityInfoActualActorsType; + + /** BizIdentityInfo privacyModeTs. */ + public privacyModeTs: (number|Long); + + /** + * Creates a new BizIdentityInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns BizIdentityInfo instance + */ + public static create(properties?: proto.IBizIdentityInfo): proto.BizIdentityInfo; + + /** + * Encodes the specified BizIdentityInfo message. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages. + * @param message BizIdentityInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IBizIdentityInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified BizIdentityInfo message, length delimited. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages. + * @param message BizIdentityInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IBizIdentityInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a BizIdentityInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns BizIdentityInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.BizIdentityInfo; + + /** + * Decodes a BizIdentityInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns BizIdentityInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.BizIdentityInfo; + + /** + * Verifies a BizIdentityInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a BizIdentityInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns BizIdentityInfo + */ + public static fromObject(object: { [k: string]: any }): proto.BizIdentityInfo; + + /** + * Creates a plain object from a BizIdentityInfo message. Also converts values to other types if specified. + * @param message BizIdentityInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.BizIdentityInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this BizIdentityInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace BizIdentityInfo { + + /** BizIdentityInfoVerifiedLevelValue enum. */ + enum BizIdentityInfoVerifiedLevelValue { + UNKNOWN = 0, + LOW = 1, + HIGH = 2 + } + + /** BizIdentityInfoHostStorageType enum. */ + enum BizIdentityInfoHostStorageType { + ON_PREMISE = 0, + FACEBOOK = 1 + } + + /** BizIdentityInfoActualActorsType enum. */ + enum BizIdentityInfoActualActorsType { + SELF = 0, + BSP = 1 + } + } + + /** Properties of a BizAccountLinkInfo. */ + interface IBizAccountLinkInfo { + + /** BizAccountLinkInfo whatsappBizAcctFbid */ + whatsappBizAcctFbid?: (number|Long|null); + + /** BizAccountLinkInfo whatsappAcctNumber */ + whatsappAcctNumber?: (string|null); + + /** BizAccountLinkInfo issueTime */ + issueTime?: (number|Long|null); + + /** BizAccountLinkInfo hostStorage */ + hostStorage?: (proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType|null); + + /** BizAccountLinkInfo accountType */ + accountType?: (proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType|null); + } + + /** Represents a BizAccountLinkInfo. */ + class BizAccountLinkInfo implements IBizAccountLinkInfo { + + /** + * Constructs a new BizAccountLinkInfo. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IBizAccountLinkInfo); + + /** BizAccountLinkInfo whatsappBizAcctFbid. */ + public whatsappBizAcctFbid: (number|Long); + + /** BizAccountLinkInfo whatsappAcctNumber. */ + public whatsappAcctNumber: string; + + /** BizAccountLinkInfo issueTime. */ + public issueTime: (number|Long); + + /** BizAccountLinkInfo hostStorage. */ + public hostStorage: proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType; + + /** BizAccountLinkInfo accountType. */ + public accountType: proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType; + + /** + * Creates a new BizAccountLinkInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns BizAccountLinkInfo instance + */ + public static create(properties?: proto.IBizAccountLinkInfo): proto.BizAccountLinkInfo; + + /** + * Encodes the specified BizAccountLinkInfo message. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages. + * @param message BizAccountLinkInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IBizAccountLinkInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified BizAccountLinkInfo message, length delimited. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages. + * @param message BizAccountLinkInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IBizAccountLinkInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a BizAccountLinkInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns BizAccountLinkInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.BizAccountLinkInfo; + + /** + * Decodes a BizAccountLinkInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns BizAccountLinkInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.BizAccountLinkInfo; + + /** + * Verifies a BizAccountLinkInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a BizAccountLinkInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns BizAccountLinkInfo + */ + public static fromObject(object: { [k: string]: any }): proto.BizAccountLinkInfo; + + /** + * Creates a plain object from a BizAccountLinkInfo message. Also converts values to other types if specified. + * @param message BizAccountLinkInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.BizAccountLinkInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this BizAccountLinkInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace BizAccountLinkInfo { + + /** BizAccountLinkInfoHostStorageType enum. */ + enum BizAccountLinkInfoHostStorageType { + ON_PREMISE = 0, + FACEBOOK = 1 + } + + /** BizAccountLinkInfoAccountType enum. */ + enum BizAccountLinkInfoAccountType { + ENTERPRISE = 0, + PAGE = 1 + } + } + + /** Properties of a BizAccountPayload. */ + interface IBizAccountPayload { + + /** BizAccountPayload vnameCert */ + vnameCert?: (proto.IVerifiedNameCertificate|null); + + /** BizAccountPayload bizAcctLinkInfo */ + bizAcctLinkInfo?: (Uint8Array|null); + } + + /** Represents a BizAccountPayload. */ + class BizAccountPayload implements IBizAccountPayload { + + /** + * Constructs a new BizAccountPayload. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IBizAccountPayload); + + /** BizAccountPayload vnameCert. */ + public vnameCert?: (proto.IVerifiedNameCertificate|null); + + /** BizAccountPayload bizAcctLinkInfo. */ + public bizAcctLinkInfo: Uint8Array; + + /** + * Creates a new BizAccountPayload instance using the specified properties. + * @param [properties] Properties to set + * @returns BizAccountPayload instance + */ + public static create(properties?: proto.IBizAccountPayload): proto.BizAccountPayload; + + /** + * Encodes the specified BizAccountPayload message. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages. + * @param message BizAccountPayload message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IBizAccountPayload, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified BizAccountPayload message, length delimited. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages. + * @param message BizAccountPayload message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IBizAccountPayload, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a BizAccountPayload message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns BizAccountPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.BizAccountPayload; + + /** + * Decodes a BizAccountPayload message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns BizAccountPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.BizAccountPayload; + + /** + * Verifies a BizAccountPayload message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a BizAccountPayload message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns BizAccountPayload + */ + public static fromObject(object: { [k: string]: any }): proto.BizAccountPayload; + + /** + * Creates a plain object from a BizAccountPayload message. Also converts values to other types if specified. + * @param message BizAccountPayload + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.BizAccountPayload, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this BizAccountPayload to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a VerifiedNameCertificate. */ + interface IVerifiedNameCertificate { + + /** VerifiedNameCertificate details */ + details?: (Uint8Array|null); + + /** VerifiedNameCertificate signature */ + signature?: (Uint8Array|null); + + /** VerifiedNameCertificate serverSignature */ + serverSignature?: (Uint8Array|null); + } + + /** Represents a VerifiedNameCertificate. */ + class VerifiedNameCertificate implements IVerifiedNameCertificate { + + /** + * Constructs a new VerifiedNameCertificate. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IVerifiedNameCertificate); + + /** VerifiedNameCertificate details. */ + public details: Uint8Array; + + /** VerifiedNameCertificate signature. */ + public signature: Uint8Array; + + /** VerifiedNameCertificate serverSignature. */ + public serverSignature: Uint8Array; + + /** + * Creates a new VerifiedNameCertificate instance using the specified properties. + * @param [properties] Properties to set + * @returns VerifiedNameCertificate instance + */ + public static create(properties?: proto.IVerifiedNameCertificate): proto.VerifiedNameCertificate; + + /** + * Encodes the specified VerifiedNameCertificate message. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages. + * @param message VerifiedNameCertificate message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IVerifiedNameCertificate, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified VerifiedNameCertificate message, length delimited. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages. + * @param message VerifiedNameCertificate message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IVerifiedNameCertificate, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a VerifiedNameCertificate message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns VerifiedNameCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.VerifiedNameCertificate; + + /** + * Decodes a VerifiedNameCertificate message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns VerifiedNameCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.VerifiedNameCertificate; + + /** + * Verifies a VerifiedNameCertificate message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a VerifiedNameCertificate message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns VerifiedNameCertificate + */ + public static fromObject(object: { [k: string]: any }): proto.VerifiedNameCertificate; + + /** + * Creates a plain object from a VerifiedNameCertificate message. Also converts values to other types if specified. + * @param message VerifiedNameCertificate + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.VerifiedNameCertificate, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this VerifiedNameCertificate to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a LocalizedName. */ + interface ILocalizedName { + + /** LocalizedName lg */ + lg?: (string|null); + + /** LocalizedName lc */ + lc?: (string|null); + + /** LocalizedName verifiedName */ + verifiedName?: (string|null); + } + + /** Represents a LocalizedName. */ + class LocalizedName implements ILocalizedName { + + /** + * Constructs a new LocalizedName. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ILocalizedName); + + /** LocalizedName lg. */ + public lg: string; + + /** LocalizedName lc. */ + public lc: string; + + /** LocalizedName verifiedName. */ + public verifiedName: string; + + /** + * Creates a new LocalizedName instance using the specified properties. + * @param [properties] Properties to set + * @returns LocalizedName instance + */ + public static create(properties?: proto.ILocalizedName): proto.LocalizedName; + + /** + * Encodes the specified LocalizedName message. Does not implicitly {@link proto.LocalizedName.verify|verify} messages. + * @param message LocalizedName message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ILocalizedName, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified LocalizedName message, length delimited. Does not implicitly {@link proto.LocalizedName.verify|verify} messages. + * @param message LocalizedName message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ILocalizedName, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a LocalizedName message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns LocalizedName + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.LocalizedName; + + /** + * Decodes a LocalizedName message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns LocalizedName + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.LocalizedName; + + /** + * Verifies a LocalizedName message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a LocalizedName message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns LocalizedName + */ + public static fromObject(object: { [k: string]: any }): proto.LocalizedName; + + /** + * Creates a plain object from a LocalizedName message. Also converts values to other types if specified. + * @param message LocalizedName + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.LocalizedName, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this LocalizedName to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncActionData. */ + interface ISyncActionData { + + /** SyncActionData index */ + index?: (Uint8Array|null); + + /** SyncActionData value */ + value?: (proto.ISyncActionValue|null); + + /** SyncActionData padding */ + padding?: (Uint8Array|null); + + /** SyncActionData version */ + version?: (number|null); + } + + /** Represents a SyncActionData. */ + class SyncActionData implements ISyncActionData { + + /** + * Constructs a new SyncActionData. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncActionData); + + /** SyncActionData index. */ + public index: Uint8Array; + + /** SyncActionData value. */ + public value?: (proto.ISyncActionValue|null); + + /** SyncActionData padding. */ + public padding: Uint8Array; + + /** SyncActionData version. */ + public version: number; + + /** + * Creates a new SyncActionData instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncActionData instance + */ + public static create(properties?: proto.ISyncActionData): proto.SyncActionData; + + /** + * Encodes the specified SyncActionData message. Does not implicitly {@link proto.SyncActionData.verify|verify} messages. + * @param message SyncActionData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncActionData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncActionData message, length delimited. Does not implicitly {@link proto.SyncActionData.verify|verify} messages. + * @param message SyncActionData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncActionData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncActionData message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncActionData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncActionData; + + /** + * Decodes a SyncActionData message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncActionData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncActionData; + + /** + * Verifies a SyncActionData message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncActionData message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncActionData + */ + public static fromObject(object: { [k: string]: any }): proto.SyncActionData; + + /** + * Creates a plain object from a SyncActionData message. Also converts values to other types if specified. + * @param message SyncActionData + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncActionData, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncActionData to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a StarAction. */ + interface IStarAction { + + /** StarAction starred */ + starred?: (boolean|null); + } + + /** Represents a StarAction. */ + class StarAction implements IStarAction { + + /** + * Constructs a new StarAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IStarAction); + + /** StarAction starred. */ + public starred: boolean; + + /** + * Creates a new StarAction instance using the specified properties. + * @param [properties] Properties to set + * @returns StarAction instance + */ + public static create(properties?: proto.IStarAction): proto.StarAction; + + /** + * Encodes the specified StarAction message. Does not implicitly {@link proto.StarAction.verify|verify} messages. + * @param message StarAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IStarAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified StarAction message, length delimited. Does not implicitly {@link proto.StarAction.verify|verify} messages. + * @param message StarAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IStarAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a StarAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns StarAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.StarAction; + + /** + * Decodes a StarAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns StarAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.StarAction; + + /** + * Verifies a StarAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a StarAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns StarAction + */ + public static fromObject(object: { [k: string]: any }): proto.StarAction; + + /** + * Creates a plain object from a StarAction message. Also converts values to other types if specified. + * @param message StarAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.StarAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this StarAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ContactAction. */ + interface IContactAction { + + /** ContactAction fullName */ + fullName?: (string|null); + + /** ContactAction firstName */ + firstName?: (string|null); + } + + /** Represents a ContactAction. */ + class ContactAction implements IContactAction { + + /** + * Constructs a new ContactAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IContactAction); + + /** ContactAction fullName. */ + public fullName: string; + + /** ContactAction firstName. */ + public firstName: string; + + /** + * Creates a new ContactAction instance using the specified properties. + * @param [properties] Properties to set + * @returns ContactAction instance + */ + public static create(properties?: proto.IContactAction): proto.ContactAction; + + /** + * Encodes the specified ContactAction message. Does not implicitly {@link proto.ContactAction.verify|verify} messages. + * @param message ContactAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IContactAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ContactAction message, length delimited. Does not implicitly {@link proto.ContactAction.verify|verify} messages. + * @param message ContactAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IContactAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ContactAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ContactAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ContactAction; + + /** + * Decodes a ContactAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ContactAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ContactAction; + + /** + * Verifies a ContactAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ContactAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ContactAction + */ + public static fromObject(object: { [k: string]: any }): proto.ContactAction; + + /** + * Creates a plain object from a ContactAction message. Also converts values to other types if specified. + * @param message ContactAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ContactAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ContactAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a MuteAction. */ + interface IMuteAction { + + /** MuteAction muted */ + muted?: (boolean|null); + + /** MuteAction muteEndTimestamp */ + muteEndTimestamp?: (number|Long|null); + } + + /** Represents a MuteAction. */ + class MuteAction implements IMuteAction { + + /** + * Constructs a new MuteAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMuteAction); + + /** MuteAction muted. */ + public muted: boolean; + + /** MuteAction muteEndTimestamp. */ + public muteEndTimestamp: (number|Long); + + /** + * Creates a new MuteAction instance using the specified properties. + * @param [properties] Properties to set + * @returns MuteAction instance + */ + public static create(properties?: proto.IMuteAction): proto.MuteAction; + + /** + * Encodes the specified MuteAction message. Does not implicitly {@link proto.MuteAction.verify|verify} messages. + * @param message MuteAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMuteAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MuteAction message, length delimited. Does not implicitly {@link proto.MuteAction.verify|verify} messages. + * @param message MuteAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMuteAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MuteAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MuteAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MuteAction; + + /** + * Decodes a MuteAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MuteAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MuteAction; + + /** + * Verifies a MuteAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MuteAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MuteAction + */ + public static fromObject(object: { [k: string]: any }): proto.MuteAction; + + /** + * Creates a plain object from a MuteAction message. Also converts values to other types if specified. + * @param message MuteAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MuteAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MuteAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a PinAction. */ + interface IPinAction { + + /** PinAction pinned */ + pinned?: (boolean|null); + } + + /** Represents a PinAction. */ + class PinAction implements IPinAction { + + /** + * Constructs a new PinAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPinAction); + + /** PinAction pinned. */ + public pinned: boolean; + + /** + * Creates a new PinAction instance using the specified properties. + * @param [properties] Properties to set + * @returns PinAction instance + */ + public static create(properties?: proto.IPinAction): proto.PinAction; + + /** + * Encodes the specified PinAction message. Does not implicitly {@link proto.PinAction.verify|verify} messages. + * @param message PinAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPinAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified PinAction message, length delimited. Does not implicitly {@link proto.PinAction.verify|verify} messages. + * @param message PinAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPinAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a PinAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns PinAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PinAction; + + /** + * Decodes a PinAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns PinAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PinAction; + + /** + * Verifies a PinAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a PinAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns PinAction + */ + public static fromObject(object: { [k: string]: any }): proto.PinAction; + + /** + * Creates a plain object from a PinAction message. Also converts values to other types if specified. + * @param message PinAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.PinAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this PinAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SecurityNotificationSetting. */ + interface ISecurityNotificationSetting { + + /** SecurityNotificationSetting showNotification */ + showNotification?: (boolean|null); + } + + /** Represents a SecurityNotificationSetting. */ + class SecurityNotificationSetting implements ISecurityNotificationSetting { + + /** + * Constructs a new SecurityNotificationSetting. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISecurityNotificationSetting); + + /** SecurityNotificationSetting showNotification. */ + public showNotification: boolean; + + /** + * Creates a new SecurityNotificationSetting instance using the specified properties. + * @param [properties] Properties to set + * @returns SecurityNotificationSetting instance + */ + public static create(properties?: proto.ISecurityNotificationSetting): proto.SecurityNotificationSetting; + + /** + * Encodes the specified SecurityNotificationSetting message. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages. + * @param message SecurityNotificationSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISecurityNotificationSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SecurityNotificationSetting message, length delimited. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages. + * @param message SecurityNotificationSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISecurityNotificationSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SecurityNotificationSetting message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SecurityNotificationSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SecurityNotificationSetting; + + /** + * Decodes a SecurityNotificationSetting message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SecurityNotificationSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SecurityNotificationSetting; + + /** + * Verifies a SecurityNotificationSetting message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SecurityNotificationSetting message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SecurityNotificationSetting + */ + public static fromObject(object: { [k: string]: any }): proto.SecurityNotificationSetting; + + /** + * Creates a plain object from a SecurityNotificationSetting message. Also converts values to other types if specified. + * @param message SecurityNotificationSetting + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SecurityNotificationSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SecurityNotificationSetting to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a PushNameSetting. */ + interface IPushNameSetting { + + /** PushNameSetting name */ + name?: (string|null); + } + + /** Represents a PushNameSetting. */ + class PushNameSetting implements IPushNameSetting { + + /** + * Constructs a new PushNameSetting. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPushNameSetting); + + /** PushNameSetting name. */ + public name: string; + + /** + * Creates a new PushNameSetting instance using the specified properties. + * @param [properties] Properties to set + * @returns PushNameSetting instance + */ + public static create(properties?: proto.IPushNameSetting): proto.PushNameSetting; + + /** + * Encodes the specified PushNameSetting message. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages. + * @param message PushNameSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPushNameSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified PushNameSetting message, length delimited. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages. + * @param message PushNameSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPushNameSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a PushNameSetting message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns PushNameSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PushNameSetting; + + /** + * Decodes a PushNameSetting message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns PushNameSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PushNameSetting; + + /** + * Verifies a PushNameSetting message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a PushNameSetting message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns PushNameSetting + */ + public static fromObject(object: { [k: string]: any }): proto.PushNameSetting; + + /** + * Creates a plain object from a PushNameSetting message. Also converts values to other types if specified. + * @param message PushNameSetting + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.PushNameSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this PushNameSetting to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a LocaleSetting. */ + interface ILocaleSetting { + + /** LocaleSetting locale */ + locale?: (string|null); + } + + /** Represents a LocaleSetting. */ + class LocaleSetting implements ILocaleSetting { + + /** + * Constructs a new LocaleSetting. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ILocaleSetting); + + /** LocaleSetting locale. */ + public locale: string; + + /** + * Creates a new LocaleSetting instance using the specified properties. + * @param [properties] Properties to set + * @returns LocaleSetting instance + */ + public static create(properties?: proto.ILocaleSetting): proto.LocaleSetting; + + /** + * Encodes the specified LocaleSetting message. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages. + * @param message LocaleSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ILocaleSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified LocaleSetting message, length delimited. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages. + * @param message LocaleSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ILocaleSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a LocaleSetting message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns LocaleSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.LocaleSetting; + + /** + * Decodes a LocaleSetting message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns LocaleSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.LocaleSetting; + + /** + * Verifies a LocaleSetting message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a LocaleSetting message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns LocaleSetting + */ + public static fromObject(object: { [k: string]: any }): proto.LocaleSetting; + + /** + * Creates a plain object from a LocaleSetting message. Also converts values to other types if specified. + * @param message LocaleSetting + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.LocaleSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this LocaleSetting to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a QuickReplyAction. */ + interface IQuickReplyAction { + + /** QuickReplyAction shortcut */ + shortcut?: (string|null); + + /** QuickReplyAction message */ + message?: (string|null); + + /** QuickReplyAction keywords */ + keywords?: (string[]|null); + + /** QuickReplyAction count */ + count?: (number|null); + + /** QuickReplyAction deleted */ + deleted?: (boolean|null); + } + + /** Represents a QuickReplyAction. */ + class QuickReplyAction implements IQuickReplyAction { + + /** + * Constructs a new QuickReplyAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IQuickReplyAction); + + /** QuickReplyAction shortcut. */ + public shortcut: string; + + /** QuickReplyAction message. */ + public message: string; + + /** QuickReplyAction keywords. */ + public keywords: string[]; + + /** QuickReplyAction count. */ + public count: number; + + /** QuickReplyAction deleted. */ + public deleted: boolean; + + /** + * Creates a new QuickReplyAction instance using the specified properties. + * @param [properties] Properties to set + * @returns QuickReplyAction instance + */ + public static create(properties?: proto.IQuickReplyAction): proto.QuickReplyAction; + + /** + * Encodes the specified QuickReplyAction message. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages. + * @param message QuickReplyAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IQuickReplyAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified QuickReplyAction message, length delimited. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages. + * @param message QuickReplyAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IQuickReplyAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a QuickReplyAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns QuickReplyAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.QuickReplyAction; + + /** + * Decodes a QuickReplyAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns QuickReplyAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.QuickReplyAction; + + /** + * Verifies a QuickReplyAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a QuickReplyAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns QuickReplyAction + */ + public static fromObject(object: { [k: string]: any }): proto.QuickReplyAction; + + /** + * Creates a plain object from a QuickReplyAction message. Also converts values to other types if specified. + * @param message QuickReplyAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.QuickReplyAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this QuickReplyAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a LabelAssociationAction. */ + interface ILabelAssociationAction { + + /** LabelAssociationAction labeled */ + labeled?: (boolean|null); + } + + /** Represents a LabelAssociationAction. */ + class LabelAssociationAction implements ILabelAssociationAction { + + /** + * Constructs a new LabelAssociationAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ILabelAssociationAction); + + /** LabelAssociationAction labeled. */ + public labeled: boolean; + + /** + * Creates a new LabelAssociationAction instance using the specified properties. + * @param [properties] Properties to set + * @returns LabelAssociationAction instance + */ + public static create(properties?: proto.ILabelAssociationAction): proto.LabelAssociationAction; + + /** + * Encodes the specified LabelAssociationAction message. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages. + * @param message LabelAssociationAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ILabelAssociationAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified LabelAssociationAction message, length delimited. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages. + * @param message LabelAssociationAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ILabelAssociationAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a LabelAssociationAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns LabelAssociationAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.LabelAssociationAction; + + /** + * Decodes a LabelAssociationAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns LabelAssociationAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.LabelAssociationAction; + + /** + * Verifies a LabelAssociationAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a LabelAssociationAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns LabelAssociationAction + */ + public static fromObject(object: { [k: string]: any }): proto.LabelAssociationAction; + + /** + * Creates a plain object from a LabelAssociationAction message. Also converts values to other types if specified. + * @param message LabelAssociationAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.LabelAssociationAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this LabelAssociationAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a LabelEditAction. */ + interface ILabelEditAction { + + /** LabelEditAction name */ + name?: (string|null); + + /** LabelEditAction color */ + color?: (number|null); + + /** LabelEditAction predefinedId */ + predefinedId?: (number|null); + + /** LabelEditAction deleted */ + deleted?: (boolean|null); + } + + /** Represents a LabelEditAction. */ + class LabelEditAction implements ILabelEditAction { + + /** + * Constructs a new LabelEditAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ILabelEditAction); + + /** LabelEditAction name. */ + public name: string; + + /** LabelEditAction color. */ + public color: number; + + /** LabelEditAction predefinedId. */ + public predefinedId: number; + + /** LabelEditAction deleted. */ + public deleted: boolean; + + /** + * Creates a new LabelEditAction instance using the specified properties. + * @param [properties] Properties to set + * @returns LabelEditAction instance + */ + public static create(properties?: proto.ILabelEditAction): proto.LabelEditAction; + + /** + * Encodes the specified LabelEditAction message. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages. + * @param message LabelEditAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ILabelEditAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified LabelEditAction message, length delimited. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages. + * @param message LabelEditAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ILabelEditAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a LabelEditAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns LabelEditAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.LabelEditAction; + + /** + * Decodes a LabelEditAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns LabelEditAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.LabelEditAction; + + /** + * Verifies a LabelEditAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a LabelEditAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns LabelEditAction + */ + public static fromObject(object: { [k: string]: any }): proto.LabelEditAction; + + /** + * Creates a plain object from a LabelEditAction message. Also converts values to other types if specified. + * @param message LabelEditAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.LabelEditAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this LabelEditAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RecentStickerWeightsAction. */ + interface IRecentStickerWeightsAction { + + /** RecentStickerWeightsAction weights */ + weights?: (proto.IRecentStickerWeight[]|null); + } + + /** Represents a RecentStickerWeightsAction. */ + class RecentStickerWeightsAction implements IRecentStickerWeightsAction { + + /** + * Constructs a new RecentStickerWeightsAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IRecentStickerWeightsAction); + + /** RecentStickerWeightsAction weights. */ + public weights: proto.IRecentStickerWeight[]; + + /** + * Creates a new RecentStickerWeightsAction instance using the specified properties. + * @param [properties] Properties to set + * @returns RecentStickerWeightsAction instance + */ + public static create(properties?: proto.IRecentStickerWeightsAction): proto.RecentStickerWeightsAction; + + /** + * Encodes the specified RecentStickerWeightsAction message. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages. + * @param message RecentStickerWeightsAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IRecentStickerWeightsAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RecentStickerWeightsAction message, length delimited. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages. + * @param message RecentStickerWeightsAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IRecentStickerWeightsAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RecentStickerWeightsAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RecentStickerWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentStickerWeightsAction; + + /** + * Decodes a RecentStickerWeightsAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RecentStickerWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentStickerWeightsAction; + + /** + * Verifies a RecentStickerWeightsAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RecentStickerWeightsAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RecentStickerWeightsAction + */ + public static fromObject(object: { [k: string]: any }): proto.RecentStickerWeightsAction; + + /** + * Creates a plain object from a RecentStickerWeightsAction message. Also converts values to other types if specified. + * @param message RecentStickerWeightsAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.RecentStickerWeightsAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RecentStickerWeightsAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RecentStickerMetadata. */ + interface IRecentStickerMetadata { + + /** RecentStickerMetadata directPath */ + directPath?: (string|null); + + /** RecentStickerMetadata encFilehash */ + encFilehash?: (string|null); + + /** RecentStickerMetadata mediaKey */ + mediaKey?: (string|null); + + /** RecentStickerMetadata stanzaId */ + stanzaId?: (string|null); + + /** RecentStickerMetadata chatJid */ + chatJid?: (string|null); + + /** RecentStickerMetadata participant */ + participant?: (string|null); + + /** RecentStickerMetadata isSentByMe */ + isSentByMe?: (boolean|null); + } + + /** Represents a RecentStickerMetadata. */ + class RecentStickerMetadata implements IRecentStickerMetadata { + + /** + * Constructs a new RecentStickerMetadata. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IRecentStickerMetadata); + + /** RecentStickerMetadata directPath. */ + public directPath: string; + + /** RecentStickerMetadata encFilehash. */ + public encFilehash: string; + + /** RecentStickerMetadata mediaKey. */ + public mediaKey: string; + + /** RecentStickerMetadata stanzaId. */ + public stanzaId: string; + + /** RecentStickerMetadata chatJid. */ + public chatJid: string; + + /** RecentStickerMetadata participant. */ + public participant: string; + + /** RecentStickerMetadata isSentByMe. */ + public isSentByMe: boolean; + + /** + * Creates a new RecentStickerMetadata instance using the specified properties. + * @param [properties] Properties to set + * @returns RecentStickerMetadata instance + */ + public static create(properties?: proto.IRecentStickerMetadata): proto.RecentStickerMetadata; + + /** + * Encodes the specified RecentStickerMetadata message. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages. + * @param message RecentStickerMetadata message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IRecentStickerMetadata, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RecentStickerMetadata message, length delimited. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages. + * @param message RecentStickerMetadata message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IRecentStickerMetadata, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RecentStickerMetadata message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RecentStickerMetadata + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentStickerMetadata; + + /** + * Decodes a RecentStickerMetadata message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RecentStickerMetadata + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentStickerMetadata; + + /** + * Verifies a RecentStickerMetadata message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RecentStickerMetadata message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RecentStickerMetadata + */ + public static fromObject(object: { [k: string]: any }): proto.RecentStickerMetadata; + + /** + * Creates a plain object from a RecentStickerMetadata message. Also converts values to other types if specified. + * @param message RecentStickerMetadata + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.RecentStickerMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RecentStickerMetadata to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RecentEmojiWeightsAction. */ + interface IRecentEmojiWeightsAction { + + /** RecentEmojiWeightsAction weights */ + weights?: (proto.IRecentEmojiWeight[]|null); + } + + /** Represents a RecentEmojiWeightsAction. */ + class RecentEmojiWeightsAction implements IRecentEmojiWeightsAction { + + /** + * Constructs a new RecentEmojiWeightsAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IRecentEmojiWeightsAction); + + /** RecentEmojiWeightsAction weights. */ + public weights: proto.IRecentEmojiWeight[]; + + /** + * Creates a new RecentEmojiWeightsAction instance using the specified properties. + * @param [properties] Properties to set + * @returns RecentEmojiWeightsAction instance + */ + public static create(properties?: proto.IRecentEmojiWeightsAction): proto.RecentEmojiWeightsAction; + + /** + * Encodes the specified RecentEmojiWeightsAction message. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages. + * @param message RecentEmojiWeightsAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IRecentEmojiWeightsAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RecentEmojiWeightsAction message, length delimited. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages. + * @param message RecentEmojiWeightsAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IRecentEmojiWeightsAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RecentEmojiWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentEmojiWeightsAction; + + /** + * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RecentEmojiWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentEmojiWeightsAction; + + /** + * Verifies a RecentEmojiWeightsAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RecentEmojiWeightsAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RecentEmojiWeightsAction + */ + public static fromObject(object: { [k: string]: any }): proto.RecentEmojiWeightsAction; + + /** + * Creates a plain object from a RecentEmojiWeightsAction message. Also converts values to other types if specified. + * @param message RecentEmojiWeightsAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.RecentEmojiWeightsAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RecentEmojiWeightsAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an ArchiveChatAction. */ + interface IArchiveChatAction { + + /** ArchiveChatAction archived */ + archived?: (boolean|null); + + /** ArchiveChatAction messageRange */ + messageRange?: (proto.ISyncActionMessageRange|null); + } + + /** Represents an ArchiveChatAction. */ + class ArchiveChatAction implements IArchiveChatAction { + + /** + * Constructs a new ArchiveChatAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IArchiveChatAction); + + /** ArchiveChatAction archived. */ + public archived: boolean; + + /** ArchiveChatAction messageRange. */ + public messageRange?: (proto.ISyncActionMessageRange|null); + + /** + * Creates a new ArchiveChatAction instance using the specified properties. + * @param [properties] Properties to set + * @returns ArchiveChatAction instance + */ + public static create(properties?: proto.IArchiveChatAction): proto.ArchiveChatAction; + + /** + * Encodes the specified ArchiveChatAction message. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages. + * @param message ArchiveChatAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IArchiveChatAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ArchiveChatAction message, length delimited. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages. + * @param message ArchiveChatAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IArchiveChatAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an ArchiveChatAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ArchiveChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ArchiveChatAction; + + /** + * Decodes an ArchiveChatAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ArchiveChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ArchiveChatAction; + + /** + * Verifies an ArchiveChatAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an ArchiveChatAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ArchiveChatAction + */ + public static fromObject(object: { [k: string]: any }): proto.ArchiveChatAction; + + /** + * Creates a plain object from an ArchiveChatAction message. Also converts values to other types if specified. + * @param message ArchiveChatAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ArchiveChatAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ArchiveChatAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a DeleteMessageForMeAction. */ + interface IDeleteMessageForMeAction { + + /** DeleteMessageForMeAction deleteMedia */ + deleteMedia?: (boolean|null); + + /** DeleteMessageForMeAction messageTimestamp */ + messageTimestamp?: (number|Long|null); + } + + /** Represents a DeleteMessageForMeAction. */ + class DeleteMessageForMeAction implements IDeleteMessageForMeAction { + + /** + * Constructs a new DeleteMessageForMeAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IDeleteMessageForMeAction); + + /** DeleteMessageForMeAction deleteMedia. */ + public deleteMedia: boolean; + + /** DeleteMessageForMeAction messageTimestamp. */ + public messageTimestamp: (number|Long); + + /** + * Creates a new DeleteMessageForMeAction instance using the specified properties. + * @param [properties] Properties to set + * @returns DeleteMessageForMeAction instance + */ + public static create(properties?: proto.IDeleteMessageForMeAction): proto.DeleteMessageForMeAction; + + /** + * Encodes the specified DeleteMessageForMeAction message. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages. + * @param message DeleteMessageForMeAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IDeleteMessageForMeAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified DeleteMessageForMeAction message, length delimited. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages. + * @param message DeleteMessageForMeAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IDeleteMessageForMeAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a DeleteMessageForMeAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns DeleteMessageForMeAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DeleteMessageForMeAction; + + /** + * Decodes a DeleteMessageForMeAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns DeleteMessageForMeAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DeleteMessageForMeAction; + + /** + * Verifies a DeleteMessageForMeAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a DeleteMessageForMeAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns DeleteMessageForMeAction + */ + public static fromObject(object: { [k: string]: any }): proto.DeleteMessageForMeAction; + + /** + * Creates a plain object from a DeleteMessageForMeAction message. Also converts values to other types if specified. + * @param message DeleteMessageForMeAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.DeleteMessageForMeAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this DeleteMessageForMeAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a MarkChatAsReadAction. */ + interface IMarkChatAsReadAction { + + /** MarkChatAsReadAction read */ + read?: (boolean|null); + + /** MarkChatAsReadAction messageRange */ + messageRange?: (proto.ISyncActionMessageRange|null); + } + + /** Represents a MarkChatAsReadAction. */ + class MarkChatAsReadAction implements IMarkChatAsReadAction { + + /** + * Constructs a new MarkChatAsReadAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMarkChatAsReadAction); + + /** MarkChatAsReadAction read. */ + public read: boolean; + + /** MarkChatAsReadAction messageRange. */ + public messageRange?: (proto.ISyncActionMessageRange|null); + + /** + * Creates a new MarkChatAsReadAction instance using the specified properties. + * @param [properties] Properties to set + * @returns MarkChatAsReadAction instance + */ + public static create(properties?: proto.IMarkChatAsReadAction): proto.MarkChatAsReadAction; + + /** + * Encodes the specified MarkChatAsReadAction message. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages. + * @param message MarkChatAsReadAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMarkChatAsReadAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MarkChatAsReadAction message, length delimited. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages. + * @param message MarkChatAsReadAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMarkChatAsReadAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MarkChatAsReadAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MarkChatAsReadAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MarkChatAsReadAction; + + /** + * Decodes a MarkChatAsReadAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MarkChatAsReadAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MarkChatAsReadAction; + + /** + * Verifies a MarkChatAsReadAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MarkChatAsReadAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MarkChatAsReadAction + */ + public static fromObject(object: { [k: string]: any }): proto.MarkChatAsReadAction; + + /** + * Creates a plain object from a MarkChatAsReadAction message. Also converts values to other types if specified. + * @param message MarkChatAsReadAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MarkChatAsReadAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MarkChatAsReadAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ClearChatAction. */ + interface IClearChatAction { + + /** ClearChatAction messageRange */ + messageRange?: (proto.ISyncActionMessageRange|null); + } + + /** Represents a ClearChatAction. */ + class ClearChatAction implements IClearChatAction { + + /** + * Constructs a new ClearChatAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IClearChatAction); + + /** ClearChatAction messageRange. */ + public messageRange?: (proto.ISyncActionMessageRange|null); + + /** + * Creates a new ClearChatAction instance using the specified properties. + * @param [properties] Properties to set + * @returns ClearChatAction instance + */ + public static create(properties?: proto.IClearChatAction): proto.ClearChatAction; + + /** + * Encodes the specified ClearChatAction message. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages. + * @param message ClearChatAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IClearChatAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ClearChatAction message, length delimited. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages. + * @param message ClearChatAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IClearChatAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ClearChatAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ClearChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ClearChatAction; + + /** + * Decodes a ClearChatAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ClearChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ClearChatAction; + + /** + * Verifies a ClearChatAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ClearChatAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ClearChatAction + */ + public static fromObject(object: { [k: string]: any }): proto.ClearChatAction; + + /** + * Creates a plain object from a ClearChatAction message. Also converts values to other types if specified. + * @param message ClearChatAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ClearChatAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ClearChatAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a DeleteChatAction. */ + interface IDeleteChatAction { + + /** DeleteChatAction messageRange */ + messageRange?: (proto.ISyncActionMessageRange|null); + } + + /** Represents a DeleteChatAction. */ + class DeleteChatAction implements IDeleteChatAction { + + /** + * Constructs a new DeleteChatAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IDeleteChatAction); + + /** DeleteChatAction messageRange. */ + public messageRange?: (proto.ISyncActionMessageRange|null); + + /** + * Creates a new DeleteChatAction instance using the specified properties. + * @param [properties] Properties to set + * @returns DeleteChatAction instance + */ + public static create(properties?: proto.IDeleteChatAction): proto.DeleteChatAction; + + /** + * Encodes the specified DeleteChatAction message. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages. + * @param message DeleteChatAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IDeleteChatAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified DeleteChatAction message, length delimited. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages. + * @param message DeleteChatAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IDeleteChatAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a DeleteChatAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns DeleteChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DeleteChatAction; + + /** + * Decodes a DeleteChatAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns DeleteChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DeleteChatAction; + + /** + * Verifies a DeleteChatAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a DeleteChatAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns DeleteChatAction + */ + public static fromObject(object: { [k: string]: any }): proto.DeleteChatAction; + + /** + * Creates a plain object from a DeleteChatAction message. Also converts values to other types if specified. + * @param message DeleteChatAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.DeleteChatAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this DeleteChatAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an UnarchiveChatsSetting. */ + interface IUnarchiveChatsSetting { + + /** UnarchiveChatsSetting unarchiveChats */ + unarchiveChats?: (boolean|null); + } + + /** Represents an UnarchiveChatsSetting. */ + class UnarchiveChatsSetting implements IUnarchiveChatsSetting { + + /** + * Constructs a new UnarchiveChatsSetting. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IUnarchiveChatsSetting); + + /** UnarchiveChatsSetting unarchiveChats. */ + public unarchiveChats: boolean; + + /** + * Creates a new UnarchiveChatsSetting instance using the specified properties. + * @param [properties] Properties to set + * @returns UnarchiveChatsSetting instance + */ + public static create(properties?: proto.IUnarchiveChatsSetting): proto.UnarchiveChatsSetting; + + /** + * Encodes the specified UnarchiveChatsSetting message. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages. + * @param message UnarchiveChatsSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IUnarchiveChatsSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified UnarchiveChatsSetting message, length delimited. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages. + * @param message UnarchiveChatsSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IUnarchiveChatsSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an UnarchiveChatsSetting message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns UnarchiveChatsSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.UnarchiveChatsSetting; + + /** + * Decodes an UnarchiveChatsSetting message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns UnarchiveChatsSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.UnarchiveChatsSetting; + + /** + * Verifies an UnarchiveChatsSetting message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an UnarchiveChatsSetting message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns UnarchiveChatsSetting + */ + public static fromObject(object: { [k: string]: any }): proto.UnarchiveChatsSetting; + + /** + * Creates a plain object from an UnarchiveChatsSetting message. Also converts values to other types if specified. + * @param message UnarchiveChatsSetting + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.UnarchiveChatsSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this UnarchiveChatsSetting to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncActionMessageRange. */ + interface ISyncActionMessageRange { + + /** SyncActionMessageRange lastMessageTimestamp */ + lastMessageTimestamp?: (number|Long|null); + + /** SyncActionMessageRange lastSystemMessageTimestamp */ + lastSystemMessageTimestamp?: (number|Long|null); + + /** SyncActionMessageRange messages */ + messages?: (proto.ISyncActionMessage[]|null); + } + + /** Represents a SyncActionMessageRange. */ + class SyncActionMessageRange implements ISyncActionMessageRange { + + /** + * Constructs a new SyncActionMessageRange. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncActionMessageRange); + + /** SyncActionMessageRange lastMessageTimestamp. */ + public lastMessageTimestamp: (number|Long); + + /** SyncActionMessageRange lastSystemMessageTimestamp. */ + public lastSystemMessageTimestamp: (number|Long); + + /** SyncActionMessageRange messages. */ + public messages: proto.ISyncActionMessage[]; + + /** + * Creates a new SyncActionMessageRange instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncActionMessageRange instance + */ + public static create(properties?: proto.ISyncActionMessageRange): proto.SyncActionMessageRange; + + /** + * Encodes the specified SyncActionMessageRange message. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages. + * @param message SyncActionMessageRange message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncActionMessageRange, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncActionMessageRange message, length delimited. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages. + * @param message SyncActionMessageRange message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncActionMessageRange, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncActionMessageRange message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncActionMessageRange + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncActionMessageRange; + + /** + * Decodes a SyncActionMessageRange message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncActionMessageRange + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncActionMessageRange; + + /** + * Verifies a SyncActionMessageRange message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncActionMessageRange message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncActionMessageRange + */ + public static fromObject(object: { [k: string]: any }): proto.SyncActionMessageRange; + + /** + * Creates a plain object from a SyncActionMessageRange message. Also converts values to other types if specified. + * @param message SyncActionMessageRange + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncActionMessageRange, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncActionMessageRange to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncActionMessage. */ + interface ISyncActionMessage { + + /** SyncActionMessage key */ + key?: (proto.IMessageKey|null); + + /** SyncActionMessage timestamp */ + timestamp?: (number|Long|null); + } + + /** Represents a SyncActionMessage. */ + class SyncActionMessage implements ISyncActionMessage { + + /** + * Constructs a new SyncActionMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncActionMessage); + + /** SyncActionMessage key. */ + public key?: (proto.IMessageKey|null); + + /** SyncActionMessage timestamp. */ + public timestamp: (number|Long); + + /** + * Creates a new SyncActionMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncActionMessage instance + */ + public static create(properties?: proto.ISyncActionMessage): proto.SyncActionMessage; + + /** + * Encodes the specified SyncActionMessage message. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages. + * @param message SyncActionMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncActionMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncActionMessage message, length delimited. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages. + * @param message SyncActionMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncActionMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncActionMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncActionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncActionMessage; + + /** + * Decodes a SyncActionMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncActionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncActionMessage; + + /** + * Verifies a SyncActionMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncActionMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncActionMessage + */ + public static fromObject(object: { [k: string]: any }): proto.SyncActionMessage; + + /** + * Creates a plain object from a SyncActionMessage message. Also converts values to other types if specified. + * @param message SyncActionMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncActionMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncActionMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a KeyExpiration. */ + interface IKeyExpiration { + + /** KeyExpiration expiredKeyEpoch */ + expiredKeyEpoch?: (number|null); + } + + /** Represents a KeyExpiration. */ + class KeyExpiration implements IKeyExpiration { + + /** + * Constructs a new KeyExpiration. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IKeyExpiration); + + /** KeyExpiration expiredKeyEpoch. */ + public expiredKeyEpoch: number; + + /** + * Creates a new KeyExpiration instance using the specified properties. + * @param [properties] Properties to set + * @returns KeyExpiration instance + */ + public static create(properties?: proto.IKeyExpiration): proto.KeyExpiration; + + /** + * Encodes the specified KeyExpiration message. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages. + * @param message KeyExpiration message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IKeyExpiration, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified KeyExpiration message, length delimited. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages. + * @param message KeyExpiration message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IKeyExpiration, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a KeyExpiration message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns KeyExpiration + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.KeyExpiration; + + /** + * Decodes a KeyExpiration message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns KeyExpiration + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.KeyExpiration; + + /** + * Verifies a KeyExpiration message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a KeyExpiration message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns KeyExpiration + */ + public static fromObject(object: { [k: string]: any }): proto.KeyExpiration; + + /** + * Creates a plain object from a KeyExpiration message. Also converts values to other types if specified. + * @param message KeyExpiration + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.KeyExpiration, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this KeyExpiration to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncActionValue. */ + interface ISyncActionValue { + + /** SyncActionValue timestamp */ + timestamp?: (number|Long|null); + + /** SyncActionValue starAction */ + starAction?: (proto.IStarAction|null); + + /** SyncActionValue contactAction */ + contactAction?: (proto.IContactAction|null); + + /** SyncActionValue muteAction */ + muteAction?: (proto.IMuteAction|null); + + /** SyncActionValue pinAction */ + pinAction?: (proto.IPinAction|null); + + /** SyncActionValue securityNotificationSetting */ + securityNotificationSetting?: (proto.ISecurityNotificationSetting|null); + + /** SyncActionValue pushNameSetting */ + pushNameSetting?: (proto.IPushNameSetting|null); + + /** SyncActionValue quickReplyAction */ + quickReplyAction?: (proto.IQuickReplyAction|null); + + /** SyncActionValue recentStickerWeightsAction */ + recentStickerWeightsAction?: (proto.IRecentStickerWeightsAction|null); + + /** SyncActionValue recentStickerMetadata */ + recentStickerMetadata?: (proto.IRecentStickerMetadata|null); + + /** SyncActionValue recentEmojiWeightsAction */ + recentEmojiWeightsAction?: (proto.IRecentEmojiWeightsAction|null); + + /** SyncActionValue labelEditAction */ + labelEditAction?: (proto.ILabelEditAction|null); + + /** SyncActionValue labelAssociationAction */ + labelAssociationAction?: (proto.ILabelAssociationAction|null); + + /** SyncActionValue localeSetting */ + localeSetting?: (proto.ILocaleSetting|null); + + /** SyncActionValue archiveChatAction */ + archiveChatAction?: (proto.IArchiveChatAction|null); + + /** SyncActionValue deleteMessageForMeAction */ + deleteMessageForMeAction?: (proto.IDeleteMessageForMeAction|null); + + /** SyncActionValue keyExpiration */ + keyExpiration?: (proto.IKeyExpiration|null); + + /** SyncActionValue markChatAsReadAction */ + markChatAsReadAction?: (proto.IMarkChatAsReadAction|null); + + /** SyncActionValue clearChatAction */ + clearChatAction?: (proto.IClearChatAction|null); + + /** SyncActionValue deleteChatAction */ + deleteChatAction?: (proto.IDeleteChatAction|null); + + /** SyncActionValue unarchiveChatsSetting */ + unarchiveChatsSetting?: (proto.IUnarchiveChatsSetting|null); + } + + /** Represents a SyncActionValue. */ + class SyncActionValue implements ISyncActionValue { + + /** + * Constructs a new SyncActionValue. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncActionValue); + + /** SyncActionValue timestamp. */ + public timestamp: (number|Long); + + /** SyncActionValue starAction. */ + public starAction?: (proto.IStarAction|null); + + /** SyncActionValue contactAction. */ + public contactAction?: (proto.IContactAction|null); + + /** SyncActionValue muteAction. */ + public muteAction?: (proto.IMuteAction|null); + + /** SyncActionValue pinAction. */ + public pinAction?: (proto.IPinAction|null); + + /** SyncActionValue securityNotificationSetting. */ + public securityNotificationSetting?: (proto.ISecurityNotificationSetting|null); + + /** SyncActionValue pushNameSetting. */ + public pushNameSetting?: (proto.IPushNameSetting|null); + + /** SyncActionValue quickReplyAction. */ + public quickReplyAction?: (proto.IQuickReplyAction|null); + + /** SyncActionValue recentStickerWeightsAction. */ + public recentStickerWeightsAction?: (proto.IRecentStickerWeightsAction|null); + + /** SyncActionValue recentStickerMetadata. */ + public recentStickerMetadata?: (proto.IRecentStickerMetadata|null); + + /** SyncActionValue recentEmojiWeightsAction. */ + public recentEmojiWeightsAction?: (proto.IRecentEmojiWeightsAction|null); + + /** SyncActionValue labelEditAction. */ + public labelEditAction?: (proto.ILabelEditAction|null); + + /** SyncActionValue labelAssociationAction. */ + public labelAssociationAction?: (proto.ILabelAssociationAction|null); + + /** SyncActionValue localeSetting. */ + public localeSetting?: (proto.ILocaleSetting|null); + + /** SyncActionValue archiveChatAction. */ + public archiveChatAction?: (proto.IArchiveChatAction|null); + + /** SyncActionValue deleteMessageForMeAction. */ + public deleteMessageForMeAction?: (proto.IDeleteMessageForMeAction|null); + + /** SyncActionValue keyExpiration. */ + public keyExpiration?: (proto.IKeyExpiration|null); + + /** SyncActionValue markChatAsReadAction. */ + public markChatAsReadAction?: (proto.IMarkChatAsReadAction|null); + + /** SyncActionValue clearChatAction. */ + public clearChatAction?: (proto.IClearChatAction|null); + + /** SyncActionValue deleteChatAction. */ + public deleteChatAction?: (proto.IDeleteChatAction|null); + + /** SyncActionValue unarchiveChatsSetting. */ + public unarchiveChatsSetting?: (proto.IUnarchiveChatsSetting|null); + + /** + * Creates a new SyncActionValue instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncActionValue instance + */ + public static create(properties?: proto.ISyncActionValue): proto.SyncActionValue; + + /** + * Encodes the specified SyncActionValue message. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages. + * @param message SyncActionValue message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncActionValue, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncActionValue message, length delimited. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages. + * @param message SyncActionValue message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncActionValue, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncActionValue message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncActionValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncActionValue; + + /** + * Decodes a SyncActionValue message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncActionValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncActionValue; + + /** + * Verifies a SyncActionValue message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncActionValue message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncActionValue + */ + public static fromObject(object: { [k: string]: any }): proto.SyncActionValue; + + /** + * Creates a plain object from a SyncActionValue message. Also converts values to other types if specified. + * @param message SyncActionValue + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncActionValue, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncActionValue to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RecentEmojiWeight. */ + interface IRecentEmojiWeight { + + /** RecentEmojiWeight emoji */ + emoji?: (string|null); + + /** RecentEmojiWeight weight */ + weight?: (number|null); + } + + /** Represents a RecentEmojiWeight. */ + class RecentEmojiWeight implements IRecentEmojiWeight { + + /** + * Constructs a new RecentEmojiWeight. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IRecentEmojiWeight); + + /** RecentEmojiWeight emoji. */ + public emoji: string; + + /** RecentEmojiWeight weight. */ + public weight: number; + + /** + * Creates a new RecentEmojiWeight instance using the specified properties. + * @param [properties] Properties to set + * @returns RecentEmojiWeight instance + */ + public static create(properties?: proto.IRecentEmojiWeight): proto.RecentEmojiWeight; + + /** + * Encodes the specified RecentEmojiWeight message. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages. + * @param message RecentEmojiWeight message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IRecentEmojiWeight, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RecentEmojiWeight message, length delimited. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages. + * @param message RecentEmojiWeight message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IRecentEmojiWeight, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RecentEmojiWeight message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RecentEmojiWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentEmojiWeight; + + /** + * Decodes a RecentEmojiWeight message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RecentEmojiWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentEmojiWeight; + + /** + * Verifies a RecentEmojiWeight message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RecentEmojiWeight message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RecentEmojiWeight + */ + public static fromObject(object: { [k: string]: any }): proto.RecentEmojiWeight; + + /** + * Creates a plain object from a RecentEmojiWeight message. Also converts values to other types if specified. + * @param message RecentEmojiWeight + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.RecentEmojiWeight, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RecentEmojiWeight to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RecentStickerWeight. */ + interface IRecentStickerWeight { + + /** RecentStickerWeight filehash */ + filehash?: (string|null); + + /** RecentStickerWeight weight */ + weight?: (number|null); + } + + /** Represents a RecentStickerWeight. */ + class RecentStickerWeight implements IRecentStickerWeight { + + /** + * Constructs a new RecentStickerWeight. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IRecentStickerWeight); + + /** RecentStickerWeight filehash. */ + public filehash: string; + + /** RecentStickerWeight weight. */ + public weight: number; + + /** + * Creates a new RecentStickerWeight instance using the specified properties. + * @param [properties] Properties to set + * @returns RecentStickerWeight instance + */ + public static create(properties?: proto.IRecentStickerWeight): proto.RecentStickerWeight; + + /** + * Encodes the specified RecentStickerWeight message. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages. + * @param message RecentStickerWeight message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IRecentStickerWeight, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RecentStickerWeight message, length delimited. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages. + * @param message RecentStickerWeight message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IRecentStickerWeight, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RecentStickerWeight message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RecentStickerWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.RecentStickerWeight; + + /** + * Decodes a RecentStickerWeight message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RecentStickerWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.RecentStickerWeight; + + /** + * Verifies a RecentStickerWeight message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RecentStickerWeight message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RecentStickerWeight + */ + public static fromObject(object: { [k: string]: any }): proto.RecentStickerWeight; + + /** + * Creates a plain object from a RecentStickerWeight message. Also converts values to other types if specified. + * @param message RecentStickerWeight + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.RecentStickerWeight, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RecentStickerWeight to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdPatch. */ + interface ISyncdPatch { + + /** SyncdPatch version */ + version?: (proto.ISyncdVersion|null); + + /** SyncdPatch mutations */ + mutations?: (proto.ISyncdMutation[]|null); + + /** SyncdPatch externalMutations */ + externalMutations?: (proto.IExternalBlobReference|null); + + /** SyncdPatch snapshotMac */ + snapshotMac?: (Uint8Array|null); + + /** SyncdPatch patchMac */ + patchMac?: (Uint8Array|null); + + /** SyncdPatch keyId */ + keyId?: (proto.IKeyId|null); + + /** SyncdPatch exitCode */ + exitCode?: (proto.IExitCode|null); + + /** SyncdPatch deviceIndex */ + deviceIndex?: (number|null); + } + + /** Represents a SyncdPatch. */ + class SyncdPatch implements ISyncdPatch { + + /** + * Constructs a new SyncdPatch. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdPatch); + + /** SyncdPatch version. */ + public version?: (proto.ISyncdVersion|null); + + /** SyncdPatch mutations. */ + public mutations: proto.ISyncdMutation[]; + + /** SyncdPatch externalMutations. */ + public externalMutations?: (proto.IExternalBlobReference|null); + + /** SyncdPatch snapshotMac. */ + public snapshotMac: Uint8Array; + + /** SyncdPatch patchMac. */ + public patchMac: Uint8Array; + + /** SyncdPatch keyId. */ + public keyId?: (proto.IKeyId|null); + + /** SyncdPatch exitCode. */ + public exitCode?: (proto.IExitCode|null); + + /** SyncdPatch deviceIndex. */ + public deviceIndex: number; + + /** + * Creates a new SyncdPatch instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdPatch instance + */ + public static create(properties?: proto.ISyncdPatch): proto.SyncdPatch; + + /** + * Encodes the specified SyncdPatch message. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages. + * @param message SyncdPatch message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdPatch, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdPatch message, length delimited. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages. + * @param message SyncdPatch message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdPatch, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdPatch message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdPatch + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdPatch; + + /** + * Decodes a SyncdPatch message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdPatch + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdPatch; + + /** + * Verifies a SyncdPatch message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdPatch message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdPatch + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdPatch; + + /** + * Creates a plain object from a SyncdPatch message. Also converts values to other types if specified. + * @param message SyncdPatch + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdPatch, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdPatch to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdMutation. */ + interface ISyncdMutation { + + /** SyncdMutation operation */ + operation?: (proto.SyncdMutation.SyncdMutationSyncdOperation|null); + + /** SyncdMutation record */ + record?: (proto.ISyncdRecord|null); + } + + /** Represents a SyncdMutation. */ + class SyncdMutation implements ISyncdMutation { + + /** + * Constructs a new SyncdMutation. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdMutation); + + /** SyncdMutation operation. */ + public operation: proto.SyncdMutation.SyncdMutationSyncdOperation; + + /** SyncdMutation record. */ + public record?: (proto.ISyncdRecord|null); + + /** + * Creates a new SyncdMutation instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdMutation instance + */ + public static create(properties?: proto.ISyncdMutation): proto.SyncdMutation; + + /** + * Encodes the specified SyncdMutation message. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages. + * @param message SyncdMutation message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdMutation, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdMutation message, length delimited. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages. + * @param message SyncdMutation message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdMutation, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdMutation message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdMutation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdMutation; + + /** + * Decodes a SyncdMutation message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdMutation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdMutation; + + /** + * Verifies a SyncdMutation message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdMutation message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdMutation + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdMutation; + + /** + * Creates a plain object from a SyncdMutation message. Also converts values to other types if specified. + * @param message SyncdMutation + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdMutation, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdMutation to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace SyncdMutation { + + /** SyncdMutationSyncdOperation enum. */ + enum SyncdMutationSyncdOperation { + SET = 0, + REMOVE = 1 + } + } + + /** Properties of a SyncdMutations. */ + interface ISyncdMutations { + + /** SyncdMutations mutations */ + mutations?: (proto.ISyncdMutation[]|null); + } + + /** Represents a SyncdMutations. */ + class SyncdMutations implements ISyncdMutations { + + /** + * Constructs a new SyncdMutations. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdMutations); + + /** SyncdMutations mutations. */ + public mutations: proto.ISyncdMutation[]; + + /** + * Creates a new SyncdMutations instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdMutations instance + */ + public static create(properties?: proto.ISyncdMutations): proto.SyncdMutations; + + /** + * Encodes the specified SyncdMutations message. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages. + * @param message SyncdMutations message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdMutations, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdMutations message, length delimited. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages. + * @param message SyncdMutations message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdMutations, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdMutations message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdMutations + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdMutations; + + /** + * Decodes a SyncdMutations message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdMutations + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdMutations; + + /** + * Verifies a SyncdMutations message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdMutations message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdMutations + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdMutations; + + /** + * Creates a plain object from a SyncdMutations message. Also converts values to other types if specified. + * @param message SyncdMutations + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdMutations, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdMutations to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdSnapshot. */ + interface ISyncdSnapshot { + + /** SyncdSnapshot version */ + version?: (proto.ISyncdVersion|null); + + /** SyncdSnapshot records */ + records?: (proto.ISyncdRecord[]|null); + + /** SyncdSnapshot mac */ + mac?: (Uint8Array|null); + + /** SyncdSnapshot keyId */ + keyId?: (proto.IKeyId|null); + } + + /** Represents a SyncdSnapshot. */ + class SyncdSnapshot implements ISyncdSnapshot { + + /** + * Constructs a new SyncdSnapshot. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdSnapshot); + + /** SyncdSnapshot version. */ + public version?: (proto.ISyncdVersion|null); + + /** SyncdSnapshot records. */ + public records: proto.ISyncdRecord[]; + + /** SyncdSnapshot mac. */ + public mac: Uint8Array; + + /** SyncdSnapshot keyId. */ + public keyId?: (proto.IKeyId|null); + + /** + * Creates a new SyncdSnapshot instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdSnapshot instance + */ + public static create(properties?: proto.ISyncdSnapshot): proto.SyncdSnapshot; + + /** + * Encodes the specified SyncdSnapshot message. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages. + * @param message SyncdSnapshot message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdSnapshot, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdSnapshot message, length delimited. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages. + * @param message SyncdSnapshot message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdSnapshot, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdSnapshot message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdSnapshot + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdSnapshot; + + /** + * Decodes a SyncdSnapshot message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdSnapshot + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdSnapshot; + + /** + * Verifies a SyncdSnapshot message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdSnapshot message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdSnapshot + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdSnapshot; + + /** + * Creates a plain object from a SyncdSnapshot message. Also converts values to other types if specified. + * @param message SyncdSnapshot + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdSnapshot, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdSnapshot to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an ExternalBlobReference. */ + interface IExternalBlobReference { + + /** ExternalBlobReference mediaKey */ + mediaKey?: (Uint8Array|null); + + /** ExternalBlobReference directPath */ + directPath?: (string|null); + + /** ExternalBlobReference handle */ + handle?: (string|null); + + /** ExternalBlobReference fileSizeBytes */ + fileSizeBytes?: (number|Long|null); + + /** ExternalBlobReference fileSha256 */ + fileSha256?: (Uint8Array|null); + + /** ExternalBlobReference fileEncSha256 */ + fileEncSha256?: (Uint8Array|null); + } + + /** Represents an ExternalBlobReference. */ + class ExternalBlobReference implements IExternalBlobReference { + + /** + * Constructs a new ExternalBlobReference. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IExternalBlobReference); + + /** ExternalBlobReference mediaKey. */ + public mediaKey: Uint8Array; + + /** ExternalBlobReference directPath. */ + public directPath: string; + + /** ExternalBlobReference handle. */ + public handle: string; + + /** ExternalBlobReference fileSizeBytes. */ + public fileSizeBytes: (number|Long); + + /** ExternalBlobReference fileSha256. */ + public fileSha256: Uint8Array; + + /** ExternalBlobReference fileEncSha256. */ + public fileEncSha256: Uint8Array; + + /** + * Creates a new ExternalBlobReference instance using the specified properties. + * @param [properties] Properties to set + * @returns ExternalBlobReference instance + */ + public static create(properties?: proto.IExternalBlobReference): proto.ExternalBlobReference; + + /** + * Encodes the specified ExternalBlobReference message. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages. + * @param message ExternalBlobReference message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IExternalBlobReference, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ExternalBlobReference message, length delimited. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages. + * @param message ExternalBlobReference message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IExternalBlobReference, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an ExternalBlobReference message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ExternalBlobReference + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ExternalBlobReference; + + /** + * Decodes an ExternalBlobReference message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ExternalBlobReference + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ExternalBlobReference; + + /** + * Verifies an ExternalBlobReference message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an ExternalBlobReference message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ExternalBlobReference + */ + public static fromObject(object: { [k: string]: any }): proto.ExternalBlobReference; + + /** + * Creates a plain object from an ExternalBlobReference message. Also converts values to other types if specified. + * @param message ExternalBlobReference + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ExternalBlobReference, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ExternalBlobReference to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdRecord. */ + interface ISyncdRecord { + + /** SyncdRecord index */ + index?: (proto.ISyncdIndex|null); + + /** SyncdRecord value */ + value?: (proto.ISyncdValue|null); + + /** SyncdRecord keyId */ + keyId?: (proto.IKeyId|null); + } + + /** Represents a SyncdRecord. */ + class SyncdRecord implements ISyncdRecord { + + /** + * Constructs a new SyncdRecord. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdRecord); + + /** SyncdRecord index. */ + public index?: (proto.ISyncdIndex|null); + + /** SyncdRecord value. */ + public value?: (proto.ISyncdValue|null); + + /** SyncdRecord keyId. */ + public keyId?: (proto.IKeyId|null); + + /** + * Creates a new SyncdRecord instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdRecord instance + */ + public static create(properties?: proto.ISyncdRecord): proto.SyncdRecord; + + /** + * Encodes the specified SyncdRecord message. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages. + * @param message SyncdRecord message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdRecord, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdRecord message, length delimited. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages. + * @param message SyncdRecord message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdRecord, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdRecord message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdRecord + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdRecord; + + /** + * Decodes a SyncdRecord message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdRecord + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdRecord; + + /** + * Verifies a SyncdRecord message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdRecord message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdRecord + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdRecord; + + /** + * Creates a plain object from a SyncdRecord message. Also converts values to other types if specified. + * @param message SyncdRecord + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdRecord, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdRecord to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a KeyId. */ + interface IKeyId { + + /** KeyId id */ + id?: (Uint8Array|null); + } + + /** Represents a KeyId. */ + class KeyId implements IKeyId { + + /** + * Constructs a new KeyId. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IKeyId); + + /** KeyId id. */ + public id: Uint8Array; + + /** + * Creates a new KeyId instance using the specified properties. + * @param [properties] Properties to set + * @returns KeyId instance + */ + public static create(properties?: proto.IKeyId): proto.KeyId; + + /** + * Encodes the specified KeyId message. Does not implicitly {@link proto.KeyId.verify|verify} messages. + * @param message KeyId message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IKeyId, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified KeyId message, length delimited. Does not implicitly {@link proto.KeyId.verify|verify} messages. + * @param message KeyId message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IKeyId, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a KeyId message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns KeyId + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.KeyId; + + /** + * Decodes a KeyId message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns KeyId + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.KeyId; + + /** + * Verifies a KeyId message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a KeyId message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns KeyId + */ + public static fromObject(object: { [k: string]: any }): proto.KeyId; + + /** + * Creates a plain object from a KeyId message. Also converts values to other types if specified. + * @param message KeyId + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.KeyId, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this KeyId to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdValue. */ + interface ISyncdValue { + + /** SyncdValue blob */ + blob?: (Uint8Array|null); + } + + /** Represents a SyncdValue. */ + class SyncdValue implements ISyncdValue { + + /** + * Constructs a new SyncdValue. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdValue); + + /** SyncdValue blob. */ + public blob: Uint8Array; + + /** + * Creates a new SyncdValue instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdValue instance + */ + public static create(properties?: proto.ISyncdValue): proto.SyncdValue; + + /** + * Encodes the specified SyncdValue message. Does not implicitly {@link proto.SyncdValue.verify|verify} messages. + * @param message SyncdValue message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdValue, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdValue message, length delimited. Does not implicitly {@link proto.SyncdValue.verify|verify} messages. + * @param message SyncdValue message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdValue, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdValue message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdValue; + + /** + * Decodes a SyncdValue message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdValue; + + /** + * Verifies a SyncdValue message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdValue message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdValue + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdValue; + + /** + * Creates a plain object from a SyncdValue message. Also converts values to other types if specified. + * @param message SyncdValue + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdValue, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdValue to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdIndex. */ + interface ISyncdIndex { + + /** SyncdIndex blob */ + blob?: (Uint8Array|null); + } + + /** Represents a SyncdIndex. */ + class SyncdIndex implements ISyncdIndex { + + /** + * Constructs a new SyncdIndex. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdIndex); + + /** SyncdIndex blob. */ + public blob: Uint8Array; + + /** + * Creates a new SyncdIndex instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdIndex instance + */ + public static create(properties?: proto.ISyncdIndex): proto.SyncdIndex; + + /** + * Encodes the specified SyncdIndex message. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages. + * @param message SyncdIndex message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdIndex, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdIndex message, length delimited. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages. + * @param message SyncdIndex message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdIndex, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdIndex message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdIndex + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdIndex; + + /** + * Decodes a SyncdIndex message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdIndex + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdIndex; + + /** + * Verifies a SyncdIndex message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdIndex message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdIndex + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdIndex; + + /** + * Creates a plain object from a SyncdIndex message. Also converts values to other types if specified. + * @param message SyncdIndex + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdIndex, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdIndex to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an ExitCode. */ + interface IExitCode { + + /** ExitCode code */ + code?: (number|Long|null); + + /** ExitCode text */ + text?: (string|null); + } + + /** Represents an ExitCode. */ + class ExitCode implements IExitCode { + + /** + * Constructs a new ExitCode. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IExitCode); + + /** ExitCode code. */ + public code: (number|Long); + + /** ExitCode text. */ + public text: string; + + /** + * Creates a new ExitCode instance using the specified properties. + * @param [properties] Properties to set + * @returns ExitCode instance + */ + public static create(properties?: proto.IExitCode): proto.ExitCode; + + /** + * Encodes the specified ExitCode message. Does not implicitly {@link proto.ExitCode.verify|verify} messages. + * @param message ExitCode message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IExitCode, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ExitCode message, length delimited. Does not implicitly {@link proto.ExitCode.verify|verify} messages. + * @param message ExitCode message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IExitCode, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an ExitCode message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ExitCode + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ExitCode; + + /** + * Decodes an ExitCode message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ExitCode + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ExitCode; + + /** + * Verifies an ExitCode message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an ExitCode message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ExitCode + */ + public static fromObject(object: { [k: string]: any }): proto.ExitCode; + + /** + * Creates a plain object from an ExitCode message. Also converts values to other types if specified. + * @param message ExitCode + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ExitCode, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ExitCode to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a SyncdVersion. */ + interface ISyncdVersion { + + /** SyncdVersion version */ + version?: (number|Long|null); + } + + /** Represents a SyncdVersion. */ + class SyncdVersion implements ISyncdVersion { + + /** + * Constructs a new SyncdVersion. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ISyncdVersion); + + /** SyncdVersion version. */ + public version: (number|Long); + + /** + * Creates a new SyncdVersion instance using the specified properties. + * @param [properties] Properties to set + * @returns SyncdVersion instance + */ + public static create(properties?: proto.ISyncdVersion): proto.SyncdVersion; + + /** + * Encodes the specified SyncdVersion message. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages. + * @param message SyncdVersion message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ISyncdVersion, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SyncdVersion message, length delimited. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages. + * @param message SyncdVersion message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ISyncdVersion, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SyncdVersion message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SyncdVersion + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.SyncdVersion; + + /** + * Decodes a SyncdVersion message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SyncdVersion + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.SyncdVersion; + + /** + * Verifies a SyncdVersion message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SyncdVersion message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SyncdVersion + */ + public static fromObject(object: { [k: string]: any }): proto.SyncdVersion; + + /** + * Creates a plain object from a SyncdVersion message. Also converts values to other types if specified. + * @param message SyncdVersion + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.SyncdVersion, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SyncdVersion to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ServerErrorReceipt. */ + interface IServerErrorReceipt { + + /** ServerErrorReceipt stanzaId */ + stanzaId?: (string|null); + } + + /** Represents a ServerErrorReceipt. */ + class ServerErrorReceipt implements IServerErrorReceipt { + + /** + * Constructs a new ServerErrorReceipt. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IServerErrorReceipt); + + /** ServerErrorReceipt stanzaId. */ + public stanzaId: string; + + /** + * Creates a new ServerErrorReceipt instance using the specified properties. + * @param [properties] Properties to set + * @returns ServerErrorReceipt instance + */ + public static create(properties?: proto.IServerErrorReceipt): proto.ServerErrorReceipt; + + /** + * Encodes the specified ServerErrorReceipt message. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages. + * @param message ServerErrorReceipt message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IServerErrorReceipt, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ServerErrorReceipt message, length delimited. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages. + * @param message ServerErrorReceipt message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IServerErrorReceipt, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ServerErrorReceipt message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ServerErrorReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ServerErrorReceipt; + + /** + * Decodes a ServerErrorReceipt message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ServerErrorReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ServerErrorReceipt; + + /** + * Verifies a ServerErrorReceipt message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ServerErrorReceipt message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ServerErrorReceipt + */ + public static fromObject(object: { [k: string]: any }): proto.ServerErrorReceipt; + + /** + * Creates a plain object from a ServerErrorReceipt message. Also converts values to other types if specified. + * @param message ServerErrorReceipt + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ServerErrorReceipt, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ServerErrorReceipt to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a MediaRetryNotification. */ + interface IMediaRetryNotification { + + /** MediaRetryNotification stanzaId */ + stanzaId?: (string|null); + + /** MediaRetryNotification directPath */ + directPath?: (string|null); + + /** MediaRetryNotification result */ + result?: (proto.MediaRetryNotification.MediaRetryNotificationResultType|null); + } + + /** Represents a MediaRetryNotification. */ + class MediaRetryNotification implements IMediaRetryNotification { + + /** + * Constructs a new MediaRetryNotification. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMediaRetryNotification); + + /** MediaRetryNotification stanzaId. */ + public stanzaId: string; + + /** MediaRetryNotification directPath. */ + public directPath: string; + + /** MediaRetryNotification result. */ + public result: proto.MediaRetryNotification.MediaRetryNotificationResultType; + + /** + * Creates a new MediaRetryNotification instance using the specified properties. + * @param [properties] Properties to set + * @returns MediaRetryNotification instance + */ + public static create(properties?: proto.IMediaRetryNotification): proto.MediaRetryNotification; + + /** + * Encodes the specified MediaRetryNotification message. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages. + * @param message MediaRetryNotification message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMediaRetryNotification, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MediaRetryNotification message, length delimited. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages. + * @param message MediaRetryNotification message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMediaRetryNotification, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MediaRetryNotification message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MediaRetryNotification + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MediaRetryNotification; + + /** + * Decodes a MediaRetryNotification message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MediaRetryNotification + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MediaRetryNotification; + + /** + * Verifies a MediaRetryNotification message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MediaRetryNotification message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MediaRetryNotification + */ + public static fromObject(object: { [k: string]: any }): proto.MediaRetryNotification; + + /** + * Creates a plain object from a MediaRetryNotification message. Also converts values to other types if specified. + * @param message MediaRetryNotification + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MediaRetryNotification, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MediaRetryNotification to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace MediaRetryNotification { + + /** MediaRetryNotificationResultType enum. */ + enum MediaRetryNotificationResultType { + GENERAL_ERROR = 0, + SUCCESS = 1, + NOT_FOUND = 2, + DECRYPTION_ERROR = 3 + } + } + + /** Properties of a MsgOpaqueData. */ + interface IMsgOpaqueData { + + /** MsgOpaqueData body */ + body?: (string|null); + + /** MsgOpaqueData caption */ + caption?: (string|null); + + /** MsgOpaqueData clientUrl */ + clientUrl?: (string|null); + + /** MsgOpaqueData lng */ + lng?: (number|null); + + /** MsgOpaqueData lat */ + lat?: (number|null); + + /** MsgOpaqueData paymentAmount1000 */ + paymentAmount1000?: (number|null); + + /** MsgOpaqueData paymentNoteMsgBody */ + paymentNoteMsgBody?: (string|null); + + /** MsgOpaqueData canonicalUrl */ + canonicalUrl?: (string|null); + + /** MsgOpaqueData matchedText */ + matchedText?: (string|null); + + /** MsgOpaqueData title */ + title?: (string|null); + + /** MsgOpaqueData description */ + description?: (string|null); + } + + /** Represents a MsgOpaqueData. */ + class MsgOpaqueData implements IMsgOpaqueData { + + /** + * Constructs a new MsgOpaqueData. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMsgOpaqueData); + + /** MsgOpaqueData body. */ + public body: string; + + /** MsgOpaqueData caption. */ + public caption: string; + + /** MsgOpaqueData clientUrl. */ + public clientUrl: string; + + /** MsgOpaqueData lng. */ + public lng: number; + + /** MsgOpaqueData lat. */ + public lat: number; + + /** MsgOpaqueData paymentAmount1000. */ + public paymentAmount1000: number; + + /** MsgOpaqueData paymentNoteMsgBody. */ + public paymentNoteMsgBody: string; + + /** MsgOpaqueData canonicalUrl. */ + public canonicalUrl: string; + + /** MsgOpaqueData matchedText. */ + public matchedText: string; + + /** MsgOpaqueData title. */ + public title: string; + + /** MsgOpaqueData description. */ + public description: string; + + /** + * Creates a new MsgOpaqueData instance using the specified properties. + * @param [properties] Properties to set + * @returns MsgOpaqueData instance + */ + public static create(properties?: proto.IMsgOpaqueData): proto.MsgOpaqueData; + + /** + * Encodes the specified MsgOpaqueData message. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages. + * @param message MsgOpaqueData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMsgOpaqueData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MsgOpaqueData message, length delimited. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages. + * @param message MsgOpaqueData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMsgOpaqueData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MsgOpaqueData message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MsgOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MsgOpaqueData; + + /** + * Decodes a MsgOpaqueData message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MsgOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MsgOpaqueData; + + /** + * Verifies a MsgOpaqueData message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MsgOpaqueData message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MsgOpaqueData + */ + public static fromObject(object: { [k: string]: any }): proto.MsgOpaqueData; + + /** + * Creates a plain object from a MsgOpaqueData message. Also converts values to other types if specified. + * @param message MsgOpaqueData + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MsgOpaqueData, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MsgOpaqueData to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a MsgRowOpaqueData. */ + interface IMsgRowOpaqueData { + + /** MsgRowOpaqueData currentMsg */ + currentMsg?: (proto.IMsgOpaqueData|null); + + /** MsgRowOpaqueData quotedMsg */ + quotedMsg?: (proto.IMsgOpaqueData|null); + } + + /** Represents a MsgRowOpaqueData. */ + class MsgRowOpaqueData implements IMsgRowOpaqueData { + + /** + * Constructs a new MsgRowOpaqueData. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMsgRowOpaqueData); + + /** MsgRowOpaqueData currentMsg. */ + public currentMsg?: (proto.IMsgOpaqueData|null); + + /** MsgRowOpaqueData quotedMsg. */ + public quotedMsg?: (proto.IMsgOpaqueData|null); + + /** + * Creates a new MsgRowOpaqueData instance using the specified properties. + * @param [properties] Properties to set + * @returns MsgRowOpaqueData instance + */ + public static create(properties?: proto.IMsgRowOpaqueData): proto.MsgRowOpaqueData; + + /** + * Encodes the specified MsgRowOpaqueData message. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages. + * @param message MsgRowOpaqueData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMsgRowOpaqueData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MsgRowOpaqueData message, length delimited. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages. + * @param message MsgRowOpaqueData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMsgRowOpaqueData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MsgRowOpaqueData message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MsgRowOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MsgRowOpaqueData; + + /** + * Decodes a MsgRowOpaqueData message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MsgRowOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MsgRowOpaqueData; + + /** + * Verifies a MsgRowOpaqueData message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MsgRowOpaqueData message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MsgRowOpaqueData + */ + public static fromObject(object: { [k: string]: any }): proto.MsgRowOpaqueData; + + /** + * Creates a plain object from a MsgRowOpaqueData message. Also converts values to other types if specified. + * @param message MsgRowOpaqueData + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MsgRowOpaqueData, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MsgRowOpaqueData to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Pushname. */ + interface IPushname { + + /** Pushname id */ + id?: (string|null); + + /** Pushname pushname */ + pushname?: (string|null); + } + + /** Represents a Pushname. */ + class Pushname implements IPushname { + + /** + * Constructs a new Pushname. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPushname); + + /** Pushname id. */ + public id: string; + + /** Pushname pushname. */ + public pushname: string; + + /** + * Creates a new Pushname instance using the specified properties. + * @param [properties] Properties to set + * @returns Pushname instance + */ + public static create(properties?: proto.IPushname): proto.Pushname; + + /** + * Encodes the specified Pushname message. Does not implicitly {@link proto.Pushname.verify|verify} messages. + * @param message Pushname message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPushname, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Pushname message, length delimited. Does not implicitly {@link proto.Pushname.verify|verify} messages. + * @param message Pushname message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPushname, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Pushname message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Pushname + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Pushname; + + /** + * Decodes a Pushname message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Pushname + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Pushname; + + /** + * Verifies a Pushname message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Pushname message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Pushname + */ + public static fromObject(object: { [k: string]: any }): proto.Pushname; + + /** + * Creates a plain object from a Pushname message. Also converts values to other types if specified. + * @param message Pushname + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Pushname, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Pushname to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HistorySyncMsg. */ + interface IHistorySyncMsg { + + /** HistorySyncMsg message */ + message?: (proto.IWebMessageInfo|null); + + /** HistorySyncMsg msgOrderId */ + msgOrderId?: (number|Long|null); + } + + /** Represents a HistorySyncMsg. */ + class HistorySyncMsg implements IHistorySyncMsg { + + /** + * Constructs a new HistorySyncMsg. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHistorySyncMsg); + + /** HistorySyncMsg message. */ + public message?: (proto.IWebMessageInfo|null); + + /** HistorySyncMsg msgOrderId. */ + public msgOrderId: (number|Long); + + /** + * Creates a new HistorySyncMsg instance using the specified properties. + * @param [properties] Properties to set + * @returns HistorySyncMsg instance + */ + public static create(properties?: proto.IHistorySyncMsg): proto.HistorySyncMsg; + + /** + * Encodes the specified HistorySyncMsg message. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages. + * @param message HistorySyncMsg message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHistorySyncMsg, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HistorySyncMsg message, length delimited. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages. + * @param message HistorySyncMsg message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHistorySyncMsg, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HistorySyncMsg message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HistorySyncMsg + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HistorySyncMsg; + + /** + * Decodes a HistorySyncMsg message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HistorySyncMsg + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HistorySyncMsg; + + /** + * Verifies a HistorySyncMsg message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HistorySyncMsg message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HistorySyncMsg + */ + public static fromObject(object: { [k: string]: any }): proto.HistorySyncMsg; + + /** + * Creates a plain object from a HistorySyncMsg message. Also converts values to other types if specified. + * @param message HistorySyncMsg + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HistorySyncMsg, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HistorySyncMsg to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Conversation. */ + interface IConversation { + + /** Conversation id */ + id: string; + + /** Conversation messages */ + messages?: (proto.IHistorySyncMsg[]|null); + + /** Conversation newJid */ + newJid?: (string|null); + + /** Conversation oldJid */ + oldJid?: (string|null); + + /** Conversation lastMsgTimestamp */ + lastMsgTimestamp?: (number|Long|null); + + /** Conversation unreadCount */ + unreadCount?: (number|null); + + /** Conversation readOnly */ + readOnly?: (boolean|null); + + /** Conversation endOfHistoryTransfer */ + endOfHistoryTransfer?: (boolean|null); + + /** Conversation ephemeralExpiration */ + ephemeralExpiration?: (number|null); + + /** Conversation ephemeralSettingTimestamp */ + ephemeralSettingTimestamp?: (number|Long|null); + + /** Conversation endOfHistoryTransferType */ + endOfHistoryTransferType?: (proto.Conversation.ConversationEndOfHistoryTransferType|null); + + /** Conversation conversationTimestamp */ + conversationTimestamp?: (number|Long|null); + + /** Conversation name */ + name?: (string|null); + + /** Conversation pHash */ + pHash?: (string|null); + + /** Conversation notSpam */ + notSpam?: (boolean|null); + } + + /** Represents a Conversation. */ + class Conversation implements IConversation { + + /** + * Constructs a new Conversation. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IConversation); + + /** Conversation id. */ + public id: string; + + /** Conversation messages. */ + public messages: proto.IHistorySyncMsg[]; + + /** Conversation newJid. */ + public newJid: string; + + /** Conversation oldJid. */ + public oldJid: string; + + /** Conversation lastMsgTimestamp. */ + public lastMsgTimestamp: (number|Long); + + /** Conversation unreadCount. */ + public unreadCount: number; + + /** Conversation readOnly. */ + public readOnly: boolean; + + /** Conversation endOfHistoryTransfer. */ + public endOfHistoryTransfer: boolean; + + /** Conversation ephemeralExpiration. */ + public ephemeralExpiration: number; + + /** Conversation ephemeralSettingTimestamp. */ + public ephemeralSettingTimestamp: (number|Long); + + /** Conversation endOfHistoryTransferType. */ + public endOfHistoryTransferType: proto.Conversation.ConversationEndOfHistoryTransferType; + + /** Conversation conversationTimestamp. */ + public conversationTimestamp: (number|Long); + + /** Conversation name. */ + public name: string; + + /** Conversation pHash. */ + public pHash: string; + + /** Conversation notSpam. */ + public notSpam: boolean; + + /** + * Creates a new Conversation instance using the specified properties. + * @param [properties] Properties to set + * @returns Conversation instance + */ + public static create(properties?: proto.IConversation): proto.Conversation; + + /** + * Encodes the specified Conversation message. Does not implicitly {@link proto.Conversation.verify|verify} messages. + * @param message Conversation message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IConversation, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Conversation message, length delimited. Does not implicitly {@link proto.Conversation.verify|verify} messages. + * @param message Conversation message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IConversation, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Conversation message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Conversation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Conversation; + + /** + * Decodes a Conversation message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Conversation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Conversation; + + /** + * Verifies a Conversation message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Conversation message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Conversation + */ + public static fromObject(object: { [k: string]: any }): proto.Conversation; + + /** + * Creates a plain object from a Conversation message. Also converts values to other types if specified. + * @param message Conversation + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Conversation, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Conversation to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace Conversation { + + /** ConversationEndOfHistoryTransferType enum. */ + enum ConversationEndOfHistoryTransferType { + COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY = 0, + COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY = 1 + } + } + + /** Properties of a HistorySync. */ + interface IHistorySync { + + /** HistorySync syncType */ + syncType: proto.HistorySync.HistorySyncHistorySyncType; + + /** HistorySync conversations */ + conversations?: (proto.IConversation[]|null); + + /** HistorySync statusV3Messages */ + statusV3Messages?: (proto.IWebMessageInfo[]|null); + + /** HistorySync chunkOrder */ + chunkOrder?: (number|null); + + /** HistorySync progress */ + progress?: (number|null); + + /** HistorySync pushnames */ + pushnames?: (proto.IPushname[]|null); + } + + /** Represents a HistorySync. */ + class HistorySync implements IHistorySync { + + /** + * Constructs a new HistorySync. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHistorySync); + + /** HistorySync syncType. */ + public syncType: proto.HistorySync.HistorySyncHistorySyncType; + + /** HistorySync conversations. */ + public conversations: proto.IConversation[]; + + /** HistorySync statusV3Messages. */ + public statusV3Messages: proto.IWebMessageInfo[]; + + /** HistorySync chunkOrder. */ + public chunkOrder: number; + + /** HistorySync progress. */ + public progress: number; + + /** HistorySync pushnames. */ + public pushnames: proto.IPushname[]; + + /** + * Creates a new HistorySync instance using the specified properties. + * @param [properties] Properties to set + * @returns HistorySync instance + */ + public static create(properties?: proto.IHistorySync): proto.HistorySync; + + /** + * Encodes the specified HistorySync message. Does not implicitly {@link proto.HistorySync.verify|verify} messages. + * @param message HistorySync message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHistorySync, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HistorySync message, length delimited. Does not implicitly {@link proto.HistorySync.verify|verify} messages. + * @param message HistorySync message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHistorySync, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HistorySync message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HistorySync + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HistorySync; + + /** + * Decodes a HistorySync message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HistorySync + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HistorySync; + + /** + * Verifies a HistorySync message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HistorySync message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HistorySync + */ + public static fromObject(object: { [k: string]: any }): proto.HistorySync; + + /** + * Creates a plain object from a HistorySync message. Also converts values to other types if specified. + * @param message HistorySync + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HistorySync, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HistorySync to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace HistorySync { + + /** HistorySyncHistorySyncType enum. */ + enum HistorySyncHistorySyncType { + INITIAL_BOOTSTRAP = 0, + INITIAL_STATUS_V3 = 1, + FULL = 2, + RECENT = 3, + PUSH_NAME = 4 + } + } + + /** Properties of an EphemeralSetting. */ + interface IEphemeralSetting { + + /** EphemeralSetting duration */ + duration?: (number|null); + + /** EphemeralSetting timestamp */ + timestamp?: (number|Long|null); + } + + /** Represents an EphemeralSetting. */ + class EphemeralSetting implements IEphemeralSetting { + + /** + * Constructs a new EphemeralSetting. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IEphemeralSetting); + + /** EphemeralSetting duration. */ + public duration: number; + + /** EphemeralSetting timestamp. */ + public timestamp: (number|Long); + + /** + * Creates a new EphemeralSetting instance using the specified properties. + * @param [properties] Properties to set + * @returns EphemeralSetting instance + */ + public static create(properties?: proto.IEphemeralSetting): proto.EphemeralSetting; + + /** + * Encodes the specified EphemeralSetting message. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. + * @param message EphemeralSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IEphemeralSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified EphemeralSetting message, length delimited. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. + * @param message EphemeralSetting message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IEphemeralSetting, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an EphemeralSetting message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns EphemeralSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.EphemeralSetting; + + /** + * Decodes an EphemeralSetting message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns EphemeralSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.EphemeralSetting; + + /** + * Verifies an EphemeralSetting message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an EphemeralSetting message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns EphemeralSetting + */ + public static fromObject(object: { [k: string]: any }): proto.EphemeralSetting; + + /** + * Creates a plain object from an EphemeralSetting message. Also converts values to other types if specified. + * @param message EphemeralSetting + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.EphemeralSetting, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this EphemeralSetting to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a PaymentBackground. */ + interface IPaymentBackground { + + /** PaymentBackground id */ + id?: (string|null); + + /** PaymentBackground fileLength */ + fileLength?: (string|null); + + /** PaymentBackground width */ + width?: (number|null); + + /** PaymentBackground height */ + height?: (number|null); + + /** PaymentBackground mimetype */ + mimetype?: (string|null); + + /** PaymentBackground placeholderArgb */ + placeholderArgb?: (number|null); + + /** PaymentBackground textArgb */ + textArgb?: (number|null); + + /** PaymentBackground subtextArgb */ + subtextArgb?: (number|null); + } + + /** Represents a PaymentBackground. */ + class PaymentBackground implements IPaymentBackground { + + /** + * Constructs a new PaymentBackground. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPaymentBackground); + + /** PaymentBackground id. */ + public id: string; + + /** PaymentBackground fileLength. */ + public fileLength: string; + + /** PaymentBackground width. */ + public width: number; + + /** PaymentBackground height. */ + public height: number; + + /** PaymentBackground mimetype. */ + public mimetype: string; + + /** PaymentBackground placeholderArgb. */ + public placeholderArgb: number; + + /** PaymentBackground textArgb. */ + public textArgb: number; + + /** PaymentBackground subtextArgb. */ + public subtextArgb: number; + + /** + * Creates a new PaymentBackground instance using the specified properties. + * @param [properties] Properties to set + * @returns PaymentBackground instance + */ + public static create(properties?: proto.IPaymentBackground): proto.PaymentBackground; + + /** + * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @param message PaymentBackground message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @param message PaymentBackground message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a PaymentBackground message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns PaymentBackground + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PaymentBackground; + + /** + * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns PaymentBackground + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PaymentBackground; + + /** + * Verifies a PaymentBackground message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns PaymentBackground + */ + public static fromObject(object: { [k: string]: any }): proto.PaymentBackground; + + /** + * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. + * @param message PaymentBackground + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.PaymentBackground, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this PaymentBackground to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Money. */ + interface IMoney { + + /** Money value */ + value?: (number|Long|null); + + /** Money offset */ + offset?: (number|null); + + /** Money currencyCode */ + currencyCode?: (string|null); + } + + /** Represents a Money. */ + class Money implements IMoney { + + /** + * Constructs a new Money. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMoney); + + /** Money value. */ + public value: (number|Long); + + /** Money offset. */ + public offset: number; + + /** Money currencyCode. */ + public currencyCode: string; + + /** + * Creates a new Money instance using the specified properties. + * @param [properties] Properties to set + * @returns Money instance + */ + public static create(properties?: proto.IMoney): proto.Money; + + /** + * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. + * @param message Money message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. + * @param message Money message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Money message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Money; + + /** + * Decodes a Money message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Money; + + /** + * Verifies a Money message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Money message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Money + */ + public static fromObject(object: { [k: string]: any }): proto.Money; + + /** + * Creates a plain object from a Money message. Also converts values to other types if specified. + * @param message Money + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Money, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Money to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HydratedQuickReplyButton. */ + interface IHydratedQuickReplyButton { + + /** HydratedQuickReplyButton displayText */ + displayText?: (string|null); + + /** HydratedQuickReplyButton id */ + id?: (string|null); + } + + /** Represents a HydratedQuickReplyButton. */ + class HydratedQuickReplyButton implements IHydratedQuickReplyButton { + + /** + * Constructs a new HydratedQuickReplyButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHydratedQuickReplyButton); + + /** HydratedQuickReplyButton displayText. */ + public displayText: string; + + /** HydratedQuickReplyButton id. */ + public id: string; + + /** + * Creates a new HydratedQuickReplyButton instance using the specified properties. + * @param [properties] Properties to set + * @returns HydratedQuickReplyButton instance + */ + public static create(properties?: proto.IHydratedQuickReplyButton): proto.HydratedQuickReplyButton; + + /** + * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * @param message HydratedQuickReplyButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHydratedQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * @param message HydratedQuickReplyButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHydratedQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HydratedQuickReplyButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HydratedQuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedQuickReplyButton; + + /** + * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HydratedQuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedQuickReplyButton; + + /** + * Verifies a HydratedQuickReplyButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HydratedQuickReplyButton + */ + public static fromObject(object: { [k: string]: any }): proto.HydratedQuickReplyButton; + + /** + * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified. + * @param message HydratedQuickReplyButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HydratedQuickReplyButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HydratedQuickReplyButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HydratedURLButton. */ + interface IHydratedURLButton { + + /** HydratedURLButton displayText */ + displayText?: (string|null); + + /** HydratedURLButton url */ + url?: (string|null); + } + + /** Represents a HydratedURLButton. */ + class HydratedURLButton implements IHydratedURLButton { + + /** + * Constructs a new HydratedURLButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHydratedURLButton); + + /** HydratedURLButton displayText. */ + public displayText: string; + + /** HydratedURLButton url. */ + public url: string; + + /** + * Creates a new HydratedURLButton instance using the specified properties. + * @param [properties] Properties to set + * @returns HydratedURLButton instance + */ + public static create(properties?: proto.IHydratedURLButton): proto.HydratedURLButton; + + /** + * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. + * @param message HydratedURLButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHydratedURLButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. + * @param message HydratedURLButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHydratedURLButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HydratedURLButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HydratedURLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedURLButton; + + /** + * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HydratedURLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedURLButton; + + /** + * Verifies a HydratedURLButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HydratedURLButton + */ + public static fromObject(object: { [k: string]: any }): proto.HydratedURLButton; + + /** + * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified. + * @param message HydratedURLButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HydratedURLButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HydratedURLButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HydratedCallButton. */ + interface IHydratedCallButton { + + /** HydratedCallButton displayText */ + displayText?: (string|null); + + /** HydratedCallButton phoneNumber */ + phoneNumber?: (string|null); + } + + /** Represents a HydratedCallButton. */ + class HydratedCallButton implements IHydratedCallButton { + + /** + * Constructs a new HydratedCallButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHydratedCallButton); + + /** HydratedCallButton displayText. */ + public displayText: string; + + /** HydratedCallButton phoneNumber. */ + public phoneNumber: string; + + /** + * Creates a new HydratedCallButton instance using the specified properties. + * @param [properties] Properties to set + * @returns HydratedCallButton instance + */ + public static create(properties?: proto.IHydratedCallButton): proto.HydratedCallButton; + + /** + * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. + * @param message HydratedCallButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHydratedCallButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. + * @param message HydratedCallButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHydratedCallButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HydratedCallButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HydratedCallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedCallButton; + + /** + * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HydratedCallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedCallButton; + + /** + * Verifies a HydratedCallButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HydratedCallButton + */ + public static fromObject(object: { [k: string]: any }): proto.HydratedCallButton; + + /** + * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified. + * @param message HydratedCallButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HydratedCallButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HydratedCallButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HydratedTemplateButton. */ + interface IHydratedTemplateButton { + + /** HydratedTemplateButton index */ + index?: (number|null); + + /** HydratedTemplateButton quickReplyButton */ + quickReplyButton?: (proto.IHydratedQuickReplyButton|null); + + /** HydratedTemplateButton urlButton */ + urlButton?: (proto.IHydratedURLButton|null); + + /** HydratedTemplateButton callButton */ + callButton?: (proto.IHydratedCallButton|null); + } + + /** Represents a HydratedTemplateButton. */ + class HydratedTemplateButton implements IHydratedTemplateButton { + + /** + * Constructs a new HydratedTemplateButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHydratedTemplateButton); + + /** HydratedTemplateButton index. */ + public index: number; + + /** HydratedTemplateButton quickReplyButton. */ + public quickReplyButton?: (proto.IHydratedQuickReplyButton|null); + + /** HydratedTemplateButton urlButton. */ + public urlButton?: (proto.IHydratedURLButton|null); + + /** HydratedTemplateButton callButton. */ + public callButton?: (proto.IHydratedCallButton|null); + + /** HydratedTemplateButton hydratedButton. */ + public hydratedButton?: ("quickReplyButton"|"urlButton"|"callButton"); + + /** + * Creates a new HydratedTemplateButton instance using the specified properties. + * @param [properties] Properties to set + * @returns HydratedTemplateButton instance + */ + public static create(properties?: proto.IHydratedTemplateButton): proto.HydratedTemplateButton; + + /** + * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. + * @param message HydratedTemplateButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHydratedTemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. + * @param message HydratedTemplateButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHydratedTemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HydratedTemplateButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HydratedTemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedTemplateButton; + + /** + * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HydratedTemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedTemplateButton; + + /** + * Verifies a HydratedTemplateButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HydratedTemplateButton + */ + public static fromObject(object: { [k: string]: any }): proto.HydratedTemplateButton; + + /** + * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified. + * @param message HydratedTemplateButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HydratedTemplateButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HydratedTemplateButton to JSON. * @returns JSON object */ public toJSON(): { [k: string]: any }; @@ -1359,9 +8941,6 @@ export namespace proto { /** ContextInfo entryPointConversionDelaySeconds */ entryPointConversionDelaySeconds?: (number|null); - - /** ContextInfo disappearingMode */ - disappearingMode?: (proto.IDisappearingMode|null); } /** Represents a ContextInfo. */ @@ -1430,9 +9009,6 @@ export namespace proto { /** ContextInfo entryPointConversionDelaySeconds. */ public entryPointConversionDelaySeconds: number; - /** ContextInfo disappearingMode. */ - public disappearingMode?: (proto.IDisappearingMode|null); - /** * Creates a new ContextInfo instance using the specified properties. * @param [properties] Properties to set @@ -1677,9 +9253,6 @@ export namespace proto { /** ImageMessage thumbnailEncSha256 */ thumbnailEncSha256?: (Uint8Array|null); - - /** ImageMessage staticUrl */ - staticUrl?: (string|null); } /** Represents an ImageMessage. */ @@ -1766,9 +9339,6 @@ export namespace proto { /** ImageMessage thumbnailEncSha256. */ public thumbnailEncSha256: Uint8Array; - /** ImageMessage staticUrl. */ - public staticUrl: string; - /** * Creates a new ImageMessage instance using the specified properties. * @param [properties] Properties to set @@ -2890,9 +10460,6 @@ export namespace proto { /** VideoMessage thumbnailEncSha256 */ thumbnailEncSha256?: (Uint8Array|null); - - /** VideoMessage staticUrl */ - staticUrl?: (string|null); } /** Represents a VideoMessage. */ @@ -2970,9 +10537,6 @@ export namespace proto { /** VideoMessage thumbnailEncSha256. */ public thumbnailEncSha256: Uint8Array; - /** VideoMessage staticUrl. */ - public staticUrl: string; - /** * Creates a new VideoMessage instance using the specified properties. * @param [properties] Properties to set @@ -3287,9 +10851,6 @@ export namespace proto { /** ProtocolMessage appStateFatalExceptionNotification */ appStateFatalExceptionNotification?: (proto.IAppStateFatalExceptionNotification|null); - - /** ProtocolMessage disappearingMode */ - disappearingMode?: (proto.IDisappearingMode|null); } /** Represents a ProtocolMessage. */ @@ -3328,9 +10889,6 @@ export namespace proto { /** ProtocolMessage appStateFatalExceptionNotification. */ public appStateFatalExceptionNotification?: (proto.IAppStateFatalExceptionNotification|null); - /** ProtocolMessage disappearingMode. */ - public disappearingMode?: (proto.IDisappearingMode|null); - /** * Creates a new ProtocolMessage instance using the specified properties. * @param [properties] Properties to set @@ -7888,649 +15446,6 @@ export namespace proto { } } - /** Properties of a Header. */ - interface IHeader { - - /** Header title */ - title?: (string|null); - - /** Header subtitle */ - subtitle?: (string|null); - - /** Header documentMessage */ - documentMessage?: (proto.IDocumentMessage|null); - - /** Header imageMessage */ - imageMessage?: (proto.IImageMessage|null); - } - - /** Represents a Header. */ - class Header implements IHeader { - - /** - * Constructs a new Header. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHeader); - - /** Header title. */ - public title: string; - - /** Header subtitle. */ - public subtitle: string; - - /** Header documentMessage. */ - public documentMessage?: (proto.IDocumentMessage|null); - - /** Header imageMessage. */ - public imageMessage?: (proto.IImageMessage|null); - - /** Header media. */ - public media?: ("documentMessage"|"imageMessage"); - - /** - * Creates a new Header instance using the specified properties. - * @param [properties] Properties to set - * @returns Header instance - */ - public static create(properties?: proto.IHeader): proto.Header; - - /** - * Encodes the specified Header message. Does not implicitly {@link proto.Header.verify|verify} messages. - * @param message Header message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHeader, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified Header message, length delimited. Does not implicitly {@link proto.Header.verify|verify} messages. - * @param message Header message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHeader, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a Header message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns Header - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Header; - - /** - * Decodes a Header message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns Header - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Header; - - /** - * Verifies a Header message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a Header message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns Header - */ - public static fromObject(object: { [k: string]: any }): proto.Header; - - /** - * Creates a plain object from a Header message. Also converts values to other types if specified. - * @param message Header - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.Header, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this Header to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a Body. */ - interface IBody { - - /** Body text */ - text?: (string|null); - } - - /** Represents a Body. */ - class Body implements IBody { - - /** - * Constructs a new Body. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IBody); - - /** Body text. */ - public text: string; - - /** - * Creates a new Body instance using the specified properties. - * @param [properties] Properties to set - * @returns Body instance - */ - public static create(properties?: proto.IBody): proto.Body; - - /** - * Encodes the specified Body message. Does not implicitly {@link proto.Body.verify|verify} messages. - * @param message Body message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IBody, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified Body message, length delimited. Does not implicitly {@link proto.Body.verify|verify} messages. - * @param message Body message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IBody, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a Body message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns Body - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Body; - - /** - * Decodes a Body message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns Body - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Body; - - /** - * Verifies a Body message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a Body message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns Body - */ - public static fromObject(object: { [k: string]: any }): proto.Body; - - /** - * Creates a plain object from a Body message. Also converts values to other types if specified. - * @param message Body - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.Body, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this Body to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a Footer. */ - interface IFooter { - - /** Footer text */ - text?: (string|null); - } - - /** Represents a Footer. */ - class Footer implements IFooter { - - /** - * Constructs a new Footer. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IFooter); - - /** Footer text. */ - public text: string; - - /** - * Creates a new Footer instance using the specified properties. - * @param [properties] Properties to set - * @returns Footer instance - */ - public static create(properties?: proto.IFooter): proto.Footer; - - /** - * Encodes the specified Footer message. Does not implicitly {@link proto.Footer.verify|verify} messages. - * @param message Footer message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IFooter, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified Footer message, length delimited. Does not implicitly {@link proto.Footer.verify|verify} messages. - * @param message Footer message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IFooter, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a Footer message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns Footer - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Footer; - - /** - * Decodes a Footer message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns Footer - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Footer; - - /** - * Verifies a Footer message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a Footer message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns Footer - */ - public static fromObject(object: { [k: string]: any }): proto.Footer; - - /** - * Creates a plain object from a Footer message. Also converts values to other types if specified. - * @param message Footer - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.Footer, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this Footer to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a ShopsMessage. */ - interface IShopsMessage { - - /** ShopsMessage id */ - id?: (string|null); - - /** ShopsMessage surface */ - surface?: (proto.ShopsMessage.ShopsMessageSurface|null); - - /** ShopsMessage type */ - type?: (proto.ShopsMessage.ShopsMessageType|null); - - /** ShopsMessage messageVersion */ - messageVersion?: (number|null); - } - - /** Represents a ShopsMessage. */ - class ShopsMessage implements IShopsMessage { - - /** - * Constructs a new ShopsMessage. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IShopsMessage); - - /** ShopsMessage id. */ - public id: string; - - /** ShopsMessage surface. */ - public surface: proto.ShopsMessage.ShopsMessageSurface; - - /** ShopsMessage type. */ - public type: proto.ShopsMessage.ShopsMessageType; - - /** ShopsMessage messageVersion. */ - public messageVersion: number; - - /** - * Creates a new ShopsMessage instance using the specified properties. - * @param [properties] Properties to set - * @returns ShopsMessage instance - */ - public static create(properties?: proto.IShopsMessage): proto.ShopsMessage; - - /** - * Encodes the specified ShopsMessage message. Does not implicitly {@link proto.ShopsMessage.verify|verify} messages. - * @param message ShopsMessage message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IShopsMessage, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ShopsMessage message, length delimited. Does not implicitly {@link proto.ShopsMessage.verify|verify} messages. - * @param message ShopsMessage message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IShopsMessage, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a ShopsMessage message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ShopsMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ShopsMessage; - - /** - * Decodes a ShopsMessage message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ShopsMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ShopsMessage; - - /** - * Verifies a ShopsMessage message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a ShopsMessage message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ShopsMessage - */ - public static fromObject(object: { [k: string]: any }): proto.ShopsMessage; - - /** - * Creates a plain object from a ShopsMessage message. Also converts values to other types if specified. - * @param message ShopsMessage - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.ShopsMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ShopsMessage to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - namespace ShopsMessage { - - /** ShopsMessageSurface enum. */ - enum ShopsMessageSurface { - UNKNOWN_SURFACE = 0, - FB = 1, - IG = 2, - WA = 3 - } - - /** ShopsMessageType enum. */ - enum ShopsMessageType { - UNKNOWN_TYPE = 0, - PRODUCT = 1, - STOREFRONT = 2, - COLLECTION = 3 - } - } - - /** Properties of a CollectionMessage. */ - interface ICollectionMessage { - - /** CollectionMessage bizJid */ - bizJid?: (string|null); - - /** CollectionMessage id */ - id?: (string|null); - - /** CollectionMessage messageVersion */ - messageVersion?: (number|null); - } - - /** Represents a CollectionMessage. */ - class CollectionMessage implements ICollectionMessage { - - /** - * Constructs a new CollectionMessage. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ICollectionMessage); - - /** CollectionMessage bizJid. */ - public bizJid: string; - - /** CollectionMessage id. */ - public id: string; - - /** CollectionMessage messageVersion. */ - public messageVersion: number; - - /** - * Creates a new CollectionMessage instance using the specified properties. - * @param [properties] Properties to set - * @returns CollectionMessage instance - */ - public static create(properties?: proto.ICollectionMessage): proto.CollectionMessage; - - /** - * Encodes the specified CollectionMessage message. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages. - * @param message CollectionMessage message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ICollectionMessage, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified CollectionMessage message, length delimited. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages. - * @param message CollectionMessage message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ICollectionMessage, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a CollectionMessage message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns CollectionMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.CollectionMessage; - - /** - * Decodes a CollectionMessage message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns CollectionMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.CollectionMessage; - - /** - * Verifies a CollectionMessage message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a CollectionMessage message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns CollectionMessage - */ - public static fromObject(object: { [k: string]: any }): proto.CollectionMessage; - - /** - * Creates a plain object from a CollectionMessage message. Also converts values to other types if specified. - * @param message CollectionMessage - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.CollectionMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this CollectionMessage to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of an InteractiveMessage. */ - interface IInteractiveMessage { - - /** InteractiveMessage header */ - header?: (proto.IHeader|null); - - /** InteractiveMessage body */ - body?: (proto.IBody|null); - - /** InteractiveMessage footer */ - footer?: (proto.IFooter|null); - - /** InteractiveMessage contextInfo */ - contextInfo?: (proto.IContextInfo|null); - - /** InteractiveMessage shopsMessage */ - shopsMessage?: (proto.IShopsMessage|null); - - /** InteractiveMessage collectionMessage */ - collectionMessage?: (proto.ICollectionMessage|null); - } - - /** Represents an InteractiveMessage. */ - class InteractiveMessage implements IInteractiveMessage { - - /** - * Constructs a new InteractiveMessage. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IInteractiveMessage); - - /** InteractiveMessage header. */ - public header?: (proto.IHeader|null); - - /** InteractiveMessage body. */ - public body?: (proto.IBody|null); - - /** InteractiveMessage footer. */ - public footer?: (proto.IFooter|null); - - /** InteractiveMessage contextInfo. */ - public contextInfo?: (proto.IContextInfo|null); - - /** InteractiveMessage shopsMessage. */ - public shopsMessage?: (proto.IShopsMessage|null); - - /** InteractiveMessage collectionMessage. */ - public collectionMessage?: (proto.ICollectionMessage|null); - - /** InteractiveMessage interactiveMessage. */ - public interactiveMessage?: ("shopsMessage"|"collectionMessage"); - - /** - * Creates a new InteractiveMessage instance using the specified properties. - * @param [properties] Properties to set - * @returns InteractiveMessage instance - */ - public static create(properties?: proto.IInteractiveMessage): proto.InteractiveMessage; - - /** - * Encodes the specified InteractiveMessage message. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages. - * @param message InteractiveMessage message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IInteractiveMessage, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified InteractiveMessage message, length delimited. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages. - * @param message InteractiveMessage message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IInteractiveMessage, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes an InteractiveMessage message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns InteractiveMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.InteractiveMessage; - - /** - * Decodes an InteractiveMessage message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns InteractiveMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.InteractiveMessage; - - /** - * Verifies an InteractiveMessage message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates an InteractiveMessage message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns InteractiveMessage - */ - public static fromObject(object: { [k: string]: any }): proto.InteractiveMessage; - - /** - * Creates a plain object from an InteractiveMessage message. Also converts values to other types if specified. - * @param message InteractiveMessage - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.InteractiveMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this InteractiveMessage to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - /** Properties of a GroupInviteMessage. */ interface IGroupInviteMessage { @@ -9544,9 +16459,6 @@ export namespace proto { /** Message paymentInviteMessage */ paymentInviteMessage?: (proto.IPaymentInviteMessage|null); - - /** Message interactiveMessage */ - interactiveMessage?: (proto.IInteractiveMessage|null); } /** Represents a Message. */ @@ -9666,9 +16578,6 @@ export namespace proto { /** Message paymentInviteMessage. */ public paymentInviteMessage?: (proto.IPaymentInviteMessage|null); - /** Message interactiveMessage. */ - public interactiveMessage?: (proto.IInteractiveMessage|null); - /** * Creates a new Message instance using the specified properties. * @param [properties] Properties to set @@ -9740,854 +16649,747 @@ export namespace proto { public toJSON(): { [k: string]: any }; } - /** Properties of a DisappearingMode. */ - interface IDisappearingMode { + /** Properties of a CompanionProps. */ + interface ICompanionProps { - /** DisappearingMode initiator */ - initiator?: (proto.DisappearingMode.DisappearingModeInitiator|null); + /** CompanionProps os */ + os?: (string|null); + + /** CompanionProps version */ + version?: (proto.IAppVersion|null); + + /** CompanionProps platformType */ + platformType?: (proto.CompanionProps.CompanionPropsPlatformType|null); + + /** CompanionProps requireFullSync */ + requireFullSync?: (boolean|null); } - /** Represents a DisappearingMode. */ - class DisappearingMode implements IDisappearingMode { + /** Represents a CompanionProps. */ + class CompanionProps implements ICompanionProps { /** - * Constructs a new DisappearingMode. + * Constructs a new CompanionProps. * @param [properties] Properties to set */ - constructor(properties?: proto.IDisappearingMode); + constructor(properties?: proto.ICompanionProps); - /** DisappearingMode initiator. */ - public initiator: proto.DisappearingMode.DisappearingModeInitiator; + /** CompanionProps os. */ + public os: string; + + /** CompanionProps version. */ + public version?: (proto.IAppVersion|null); + + /** CompanionProps platformType. */ + public platformType: proto.CompanionProps.CompanionPropsPlatformType; + + /** CompanionProps requireFullSync. */ + public requireFullSync: boolean; /** - * Creates a new DisappearingMode instance using the specified properties. + * Creates a new CompanionProps instance using the specified properties. * @param [properties] Properties to set - * @returns DisappearingMode instance + * @returns CompanionProps instance */ - public static create(properties?: proto.IDisappearingMode): proto.DisappearingMode; + public static create(properties?: proto.ICompanionProps): proto.CompanionProps; /** - * Encodes the specified DisappearingMode message. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages. - * @param message DisappearingMode message or plain object to encode + * Encodes the specified CompanionProps message. Does not implicitly {@link proto.CompanionProps.verify|verify} messages. + * @param message CompanionProps message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encode(message: proto.IDisappearingMode, writer?: $protobuf.Writer): $protobuf.Writer; + public static encode(message: proto.ICompanionProps, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Encodes the specified DisappearingMode message, length delimited. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages. - * @param message DisappearingMode message or plain object to encode + * Encodes the specified CompanionProps message, length delimited. Does not implicitly {@link proto.CompanionProps.verify|verify} messages. + * @param message CompanionProps message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encodeDelimited(message: proto.IDisappearingMode, writer?: $protobuf.Writer): $protobuf.Writer; + public static encodeDelimited(message: proto.ICompanionProps, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Decodes a DisappearingMode message from the specified reader or buffer. + * Decodes a CompanionProps message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns DisappearingMode + * @returns CompanionProps * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DisappearingMode; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.CompanionProps; /** - * Decodes a DisappearingMode message from the specified reader or buffer, length delimited. + * Decodes a CompanionProps message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns DisappearingMode + * @returns CompanionProps * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DisappearingMode; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.CompanionProps; /** - * Verifies a DisappearingMode message. + * Verifies a CompanionProps message. * @param message Plain object to verify * @returns `null` if valid, otherwise the reason why it is not */ public static verify(message: { [k: string]: any }): (string|null); /** - * Creates a DisappearingMode message from a plain object. Also converts values to their respective internal types. + * Creates a CompanionProps message from a plain object. Also converts values to their respective internal types. * @param object Plain object - * @returns DisappearingMode + * @returns CompanionProps */ - public static fromObject(object: { [k: string]: any }): proto.DisappearingMode; + public static fromObject(object: { [k: string]: any }): proto.CompanionProps; /** - * Creates a plain object from a DisappearingMode message. Also converts values to other types if specified. - * @param message DisappearingMode + * Creates a plain object from a CompanionProps message. Also converts values to other types if specified. + * @param message CompanionProps * @param [options] Conversion options * @returns Plain object */ - public static toObject(message: proto.DisappearingMode, options?: $protobuf.IConversionOptions): { [k: string]: any }; + public static toObject(message: proto.CompanionProps, options?: $protobuf.IConversionOptions): { [k: string]: any }; /** - * Converts this DisappearingMode to JSON. + * Converts this CompanionProps to JSON. * @returns JSON object */ public toJSON(): { [k: string]: any }; } - namespace DisappearingMode { + namespace CompanionProps { - /** DisappearingModeInitiator enum. */ - enum DisappearingModeInitiator { - CHANGED_IN_CHAT = 0, - INITIATED_BY_ME = 1, - INITIATED_BY_OTHER = 2 + /** CompanionPropsPlatformType enum. */ + enum CompanionPropsPlatformType { + UNKNOWN = 0, + CHROME = 1, + FIREFOX = 2, + IE = 3, + OPERA = 4, + SAFARI = 5, + EDGE = 6, + DESKTOP = 7, + IPAD = 8, + ANDROID_TABLET = 9, + OHANA = 10, + ALOHA = 11, + CATALINA = 12 } } - /** Properties of a PaymentBackground. */ - interface IPaymentBackground { + /** Properties of a ADVSignedDeviceIdentityHMAC. */ + interface IADVSignedDeviceIdentityHMAC { - /** PaymentBackground id */ + /** ADVSignedDeviceIdentityHMAC details */ + details?: (Uint8Array|null); + + /** ADVSignedDeviceIdentityHMAC hmac */ + hmac?: (Uint8Array|null); + } + + /** Represents a ADVSignedDeviceIdentityHMAC. */ + class ADVSignedDeviceIdentityHMAC implements IADVSignedDeviceIdentityHMAC { + + /** + * Constructs a new ADVSignedDeviceIdentityHMAC. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IADVSignedDeviceIdentityHMAC); + + /** ADVSignedDeviceIdentityHMAC details. */ + public details: Uint8Array; + + /** ADVSignedDeviceIdentityHMAC hmac. */ + public hmac: Uint8Array; + + /** + * Creates a new ADVSignedDeviceIdentityHMAC instance using the specified properties. + * @param [properties] Properties to set + * @returns ADVSignedDeviceIdentityHMAC instance + */ + public static create(properties?: proto.IADVSignedDeviceIdentityHMAC): proto.ADVSignedDeviceIdentityHMAC; + + /** + * Encodes the specified ADVSignedDeviceIdentityHMAC message. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages. + * @param message ADVSignedDeviceIdentityHMAC message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IADVSignedDeviceIdentityHMAC, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ADVSignedDeviceIdentityHMAC message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages. + * @param message ADVSignedDeviceIdentityHMAC message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IADVSignedDeviceIdentityHMAC, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ADVSignedDeviceIdentityHMAC + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVSignedDeviceIdentityHMAC; + + /** + * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ADVSignedDeviceIdentityHMAC + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVSignedDeviceIdentityHMAC; + + /** + * Verifies a ADVSignedDeviceIdentityHMAC message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ADVSignedDeviceIdentityHMAC message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ADVSignedDeviceIdentityHMAC + */ + public static fromObject(object: { [k: string]: any }): proto.ADVSignedDeviceIdentityHMAC; + + /** + * Creates a plain object from a ADVSignedDeviceIdentityHMAC message. Also converts values to other types if specified. + * @param message ADVSignedDeviceIdentityHMAC + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ADVSignedDeviceIdentityHMAC, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ADVSignedDeviceIdentityHMAC to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ADVSignedDeviceIdentity. */ + interface IADVSignedDeviceIdentity { + + /** ADVSignedDeviceIdentity details */ + details?: (Uint8Array|null); + + /** ADVSignedDeviceIdentity accountSignatureKey */ + accountSignatureKey?: (Uint8Array|null); + + /** ADVSignedDeviceIdentity accountSignature */ + accountSignature?: (Uint8Array|null); + + /** ADVSignedDeviceIdentity deviceSignature */ + deviceSignature?: (Uint8Array|null); + } + + /** Represents a ADVSignedDeviceIdentity. */ + class ADVSignedDeviceIdentity implements IADVSignedDeviceIdentity { + + /** + * Constructs a new ADVSignedDeviceIdentity. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IADVSignedDeviceIdentity); + + /** ADVSignedDeviceIdentity details. */ + public details: Uint8Array; + + /** ADVSignedDeviceIdentity accountSignatureKey. */ + public accountSignatureKey: Uint8Array; + + /** ADVSignedDeviceIdentity accountSignature. */ + public accountSignature: Uint8Array; + + /** ADVSignedDeviceIdentity deviceSignature. */ + public deviceSignature: Uint8Array; + + /** + * Creates a new ADVSignedDeviceIdentity instance using the specified properties. + * @param [properties] Properties to set + * @returns ADVSignedDeviceIdentity instance + */ + public static create(properties?: proto.IADVSignedDeviceIdentity): proto.ADVSignedDeviceIdentity; + + /** + * Encodes the specified ADVSignedDeviceIdentity message. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages. + * @param message ADVSignedDeviceIdentity message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IADVSignedDeviceIdentity, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ADVSignedDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages. + * @param message ADVSignedDeviceIdentity message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IADVSignedDeviceIdentity, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ADVSignedDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVSignedDeviceIdentity; + + /** + * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ADVSignedDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVSignedDeviceIdentity; + + /** + * Verifies a ADVSignedDeviceIdentity message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ADVSignedDeviceIdentity message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ADVSignedDeviceIdentity + */ + public static fromObject(object: { [k: string]: any }): proto.ADVSignedDeviceIdentity; + + /** + * Creates a plain object from a ADVSignedDeviceIdentity message. Also converts values to other types if specified. + * @param message ADVSignedDeviceIdentity + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ADVSignedDeviceIdentity, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ADVSignedDeviceIdentity to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ADVDeviceIdentity. */ + interface IADVDeviceIdentity { + + /** ADVDeviceIdentity rawId */ + rawId?: (number|null); + + /** ADVDeviceIdentity timestamp */ + timestamp?: (number|Long|null); + + /** ADVDeviceIdentity keyIndex */ + keyIndex?: (number|null); + } + + /** Represents a ADVDeviceIdentity. */ + class ADVDeviceIdentity implements IADVDeviceIdentity { + + /** + * Constructs a new ADVDeviceIdentity. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IADVDeviceIdentity); + + /** ADVDeviceIdentity rawId. */ + public rawId: number; + + /** ADVDeviceIdentity timestamp. */ + public timestamp: (number|Long); + + /** ADVDeviceIdentity keyIndex. */ + public keyIndex: number; + + /** + * Creates a new ADVDeviceIdentity instance using the specified properties. + * @param [properties] Properties to set + * @returns ADVDeviceIdentity instance + */ + public static create(properties?: proto.IADVDeviceIdentity): proto.ADVDeviceIdentity; + + /** + * Encodes the specified ADVDeviceIdentity message. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages. + * @param message ADVDeviceIdentity message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IADVDeviceIdentity, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ADVDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages. + * @param message ADVDeviceIdentity message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IADVDeviceIdentity, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ADVDeviceIdentity message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ADVDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVDeviceIdentity; + + /** + * Decodes a ADVDeviceIdentity message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ADVDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVDeviceIdentity; + + /** + * Verifies a ADVDeviceIdentity message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ADVDeviceIdentity message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ADVDeviceIdentity + */ + public static fromObject(object: { [k: string]: any }): proto.ADVDeviceIdentity; + + /** + * Creates a plain object from a ADVDeviceIdentity message. Also converts values to other types if specified. + * @param message ADVDeviceIdentity + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ADVDeviceIdentity, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ADVDeviceIdentity to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ADVSignedKeyIndexList. */ + interface IADVSignedKeyIndexList { + + /** ADVSignedKeyIndexList details */ + details?: (Uint8Array|null); + + /** ADVSignedKeyIndexList accountSignature */ + accountSignature?: (Uint8Array|null); + } + + /** Represents a ADVSignedKeyIndexList. */ + class ADVSignedKeyIndexList implements IADVSignedKeyIndexList { + + /** + * Constructs a new ADVSignedKeyIndexList. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IADVSignedKeyIndexList); + + /** ADVSignedKeyIndexList details. */ + public details: Uint8Array; + + /** ADVSignedKeyIndexList accountSignature. */ + public accountSignature: Uint8Array; + + /** + * Creates a new ADVSignedKeyIndexList instance using the specified properties. + * @param [properties] Properties to set + * @returns ADVSignedKeyIndexList instance + */ + public static create(properties?: proto.IADVSignedKeyIndexList): proto.ADVSignedKeyIndexList; + + /** + * Encodes the specified ADVSignedKeyIndexList message. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages. + * @param message ADVSignedKeyIndexList message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IADVSignedKeyIndexList, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ADVSignedKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages. + * @param message ADVSignedKeyIndexList message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IADVSignedKeyIndexList, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ADVSignedKeyIndexList + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVSignedKeyIndexList; + + /** + * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ADVSignedKeyIndexList + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVSignedKeyIndexList; + + /** + * Verifies a ADVSignedKeyIndexList message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ADVSignedKeyIndexList message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ADVSignedKeyIndexList + */ + public static fromObject(object: { [k: string]: any }): proto.ADVSignedKeyIndexList; + + /** + * Creates a plain object from a ADVSignedKeyIndexList message. Also converts values to other types if specified. + * @param message ADVSignedKeyIndexList + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ADVSignedKeyIndexList, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ADVSignedKeyIndexList to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ADVKeyIndexList. */ + interface IADVKeyIndexList { + + /** ADVKeyIndexList rawId */ + rawId?: (number|null); + + /** ADVKeyIndexList timestamp */ + timestamp?: (number|Long|null); + + /** ADVKeyIndexList currentIndex */ + currentIndex?: (number|null); + + /** ADVKeyIndexList validIndexes */ + validIndexes?: (number[]|null); + } + + /** Represents a ADVKeyIndexList. */ + class ADVKeyIndexList implements IADVKeyIndexList { + + /** + * Constructs a new ADVKeyIndexList. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IADVKeyIndexList); + + /** ADVKeyIndexList rawId. */ + public rawId: number; + + /** ADVKeyIndexList timestamp. */ + public timestamp: (number|Long); + + /** ADVKeyIndexList currentIndex. */ + public currentIndex: number; + + /** ADVKeyIndexList validIndexes. */ + public validIndexes: number[]; + + /** + * Creates a new ADVKeyIndexList instance using the specified properties. + * @param [properties] Properties to set + * @returns ADVKeyIndexList instance + */ + public static create(properties?: proto.IADVKeyIndexList): proto.ADVKeyIndexList; + + /** + * Encodes the specified ADVKeyIndexList message. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages. + * @param message ADVKeyIndexList message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IADVKeyIndexList, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ADVKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages. + * @param message ADVKeyIndexList message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IADVKeyIndexList, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ADVKeyIndexList message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ADVKeyIndexList + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ADVKeyIndexList; + + /** + * Decodes a ADVKeyIndexList message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ADVKeyIndexList + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ADVKeyIndexList; + + /** + * Verifies a ADVKeyIndexList message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ADVKeyIndexList message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ADVKeyIndexList + */ + public static fromObject(object: { [k: string]: any }): proto.ADVKeyIndexList; + + /** + * Creates a plain object from a ADVKeyIndexList message. Also converts values to other types if specified. + * @param message ADVKeyIndexList + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ADVKeyIndexList, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ADVKeyIndexList to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a MessageKey. */ + interface IMessageKey { + + /** MessageKey remoteJid */ + remoteJid?: (string|null); + + /** MessageKey fromMe */ + fromMe?: (boolean|null); + + /** MessageKey id */ id?: (string|null); - /** PaymentBackground fileLength */ - fileLength?: (number|Long|null); - - /** PaymentBackground width */ - width?: (number|null); - - /** PaymentBackground height */ - height?: (number|null); - - /** PaymentBackground mimetype */ - mimetype?: (string|null); - - /** PaymentBackground placeholderArgb */ - placeholderArgb?: (number|null); - - /** PaymentBackground textArgb */ - textArgb?: (number|null); - - /** PaymentBackground subtextArgb */ - subtextArgb?: (number|null); + /** MessageKey participant */ + participant?: (string|null); } - /** Represents a PaymentBackground. */ - class PaymentBackground implements IPaymentBackground { + /** Represents a MessageKey. */ + class MessageKey implements IMessageKey { /** - * Constructs a new PaymentBackground. + * Constructs a new MessageKey. * @param [properties] Properties to set */ - constructor(properties?: proto.IPaymentBackground); + constructor(properties?: proto.IMessageKey); - /** PaymentBackground id. */ + /** MessageKey remoteJid. */ + public remoteJid: string; + + /** MessageKey fromMe. */ + public fromMe: boolean; + + /** MessageKey id. */ public id: string; - /** PaymentBackground fileLength. */ - public fileLength: (number|Long); - - /** PaymentBackground width. */ - public width: number; - - /** PaymentBackground height. */ - public height: number; - - /** PaymentBackground mimetype. */ - public mimetype: string; - - /** PaymentBackground placeholderArgb. */ - public placeholderArgb: number; - - /** PaymentBackground textArgb. */ - public textArgb: number; - - /** PaymentBackground subtextArgb. */ - public subtextArgb: number; + /** MessageKey participant. */ + public participant: string; /** - * Creates a new PaymentBackground instance using the specified properties. + * Creates a new MessageKey instance using the specified properties. * @param [properties] Properties to set - * @returns PaymentBackground instance + * @returns MessageKey instance */ - public static create(properties?: proto.IPaymentBackground): proto.PaymentBackground; + public static create(properties?: proto.IMessageKey): proto.MessageKey; /** - * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. - * @param message PaymentBackground message or plain object to encode + * Encodes the specified MessageKey message. Does not implicitly {@link proto.MessageKey.verify|verify} messages. + * @param message MessageKey message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encode(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; + public static encode(message: proto.IMessageKey, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. - * @param message PaymentBackground message or plain object to encode + * Encodes the specified MessageKey message, length delimited. Does not implicitly {@link proto.MessageKey.verify|verify} messages. + * @param message MessageKey message or plain object to encode * @param [writer] Writer to encode to * @returns Writer */ - public static encodeDelimited(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; + public static encodeDelimited(message: proto.IMessageKey, writer?: $protobuf.Writer): $protobuf.Writer; /** - * Decodes a PaymentBackground message from the specified reader or buffer. + * Decodes a MessageKey message from the specified reader or buffer. * @param reader Reader or buffer to decode from * @param [length] Message length if known beforehand - * @returns PaymentBackground + * @returns MessageKey * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PaymentBackground; + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MessageKey; /** - * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. + * Decodes a MessageKey message from the specified reader or buffer, length delimited. * @param reader Reader or buffer to decode from - * @returns PaymentBackground + * @returns MessageKey * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PaymentBackground; + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MessageKey; /** - * Verifies a PaymentBackground message. + * Verifies a MessageKey message. * @param message Plain object to verify * @returns `null` if valid, otherwise the reason why it is not */ public static verify(message: { [k: string]: any }): (string|null); /** - * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. + * Creates a MessageKey message from a plain object. Also converts values to their respective internal types. * @param object Plain object - * @returns PaymentBackground + * @returns MessageKey */ - public static fromObject(object: { [k: string]: any }): proto.PaymentBackground; + public static fromObject(object: { [k: string]: any }): proto.MessageKey; /** - * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. - * @param message PaymentBackground + * Creates a plain object from a MessageKey message. Also converts values to other types if specified. + * @param message MessageKey * @param [options] Conversion options * @returns Plain object */ - public static toObject(message: proto.PaymentBackground, options?: $protobuf.IConversionOptions): { [k: string]: any }; + public static toObject(message: proto.MessageKey, options?: $protobuf.IConversionOptions): { [k: string]: any }; /** - * Converts this PaymentBackground to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a Money. */ - interface IMoney { - - /** Money value */ - value?: (number|Long|null); - - /** Money offset */ - offset?: (number|null); - - /** Money currencyCode */ - currencyCode?: (string|null); - } - - /** Represents a Money. */ - class Money implements IMoney { - - /** - * Constructs a new Money. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IMoney); - - /** Money value. */ - public value: (number|Long); - - /** Money offset. */ - public offset: number; - - /** Money currencyCode. */ - public currencyCode: string; - - /** - * Creates a new Money instance using the specified properties. - * @param [properties] Properties to set - * @returns Money instance - */ - public static create(properties?: proto.IMoney): proto.Money; - - /** - * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. - * @param message Money message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. - * @param message Money message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a Money message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns Money - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Money; - - /** - * Decodes a Money message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns Money - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Money; - - /** - * Verifies a Money message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a Money message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns Money - */ - public static fromObject(object: { [k: string]: any }): proto.Money; - - /** - * Creates a plain object from a Money message. Also converts values to other types if specified. - * @param message Money - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.Money, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this Money to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HydratedQuickReplyButton. */ - interface IHydratedQuickReplyButton { - - /** HydratedQuickReplyButton displayText */ - displayText?: (string|null); - - /** HydratedQuickReplyButton id */ - id?: (string|null); - } - - /** Represents a HydratedQuickReplyButton. */ - class HydratedQuickReplyButton implements IHydratedQuickReplyButton { - - /** - * Constructs a new HydratedQuickReplyButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHydratedQuickReplyButton); - - /** HydratedQuickReplyButton displayText. */ - public displayText: string; - - /** HydratedQuickReplyButton id. */ - public id: string; - - /** - * Creates a new HydratedQuickReplyButton instance using the specified properties. - * @param [properties] Properties to set - * @returns HydratedQuickReplyButton instance - */ - public static create(properties?: proto.IHydratedQuickReplyButton): proto.HydratedQuickReplyButton; - - /** - * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. - * @param message HydratedQuickReplyButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHydratedQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. - * @param message HydratedQuickReplyButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHydratedQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HydratedQuickReplyButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HydratedQuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedQuickReplyButton; - - /** - * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HydratedQuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedQuickReplyButton; - - /** - * Verifies a HydratedQuickReplyButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HydratedQuickReplyButton - */ - public static fromObject(object: { [k: string]: any }): proto.HydratedQuickReplyButton; - - /** - * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified. - * @param message HydratedQuickReplyButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HydratedQuickReplyButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HydratedQuickReplyButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HydratedURLButton. */ - interface IHydratedURLButton { - - /** HydratedURLButton displayText */ - displayText?: (string|null); - - /** HydratedURLButton url */ - url?: (string|null); - } - - /** Represents a HydratedURLButton. */ - class HydratedURLButton implements IHydratedURLButton { - - /** - * Constructs a new HydratedURLButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHydratedURLButton); - - /** HydratedURLButton displayText. */ - public displayText: string; - - /** HydratedURLButton url. */ - public url: string; - - /** - * Creates a new HydratedURLButton instance using the specified properties. - * @param [properties] Properties to set - * @returns HydratedURLButton instance - */ - public static create(properties?: proto.IHydratedURLButton): proto.HydratedURLButton; - - /** - * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. - * @param message HydratedURLButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHydratedURLButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. - * @param message HydratedURLButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHydratedURLButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HydratedURLButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HydratedURLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedURLButton; - - /** - * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HydratedURLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedURLButton; - - /** - * Verifies a HydratedURLButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HydratedURLButton - */ - public static fromObject(object: { [k: string]: any }): proto.HydratedURLButton; - - /** - * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified. - * @param message HydratedURLButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HydratedURLButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HydratedURLButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HydratedCallButton. */ - interface IHydratedCallButton { - - /** HydratedCallButton displayText */ - displayText?: (string|null); - - /** HydratedCallButton phoneNumber */ - phoneNumber?: (string|null); - } - - /** Represents a HydratedCallButton. */ - class HydratedCallButton implements IHydratedCallButton { - - /** - * Constructs a new HydratedCallButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHydratedCallButton); - - /** HydratedCallButton displayText. */ - public displayText: string; - - /** HydratedCallButton phoneNumber. */ - public phoneNumber: string; - - /** - * Creates a new HydratedCallButton instance using the specified properties. - * @param [properties] Properties to set - * @returns HydratedCallButton instance - */ - public static create(properties?: proto.IHydratedCallButton): proto.HydratedCallButton; - - /** - * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. - * @param message HydratedCallButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHydratedCallButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. - * @param message HydratedCallButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHydratedCallButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HydratedCallButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HydratedCallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedCallButton; - - /** - * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HydratedCallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedCallButton; - - /** - * Verifies a HydratedCallButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HydratedCallButton - */ - public static fromObject(object: { [k: string]: any }): proto.HydratedCallButton; - - /** - * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified. - * @param message HydratedCallButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HydratedCallButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HydratedCallButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HydratedTemplateButton. */ - interface IHydratedTemplateButton { - - /** HydratedTemplateButton index */ - index?: (number|null); - - /** HydratedTemplateButton quickReplyButton */ - quickReplyButton?: (proto.IHydratedQuickReplyButton|null); - - /** HydratedTemplateButton urlButton */ - urlButton?: (proto.IHydratedURLButton|null); - - /** HydratedTemplateButton callButton */ - callButton?: (proto.IHydratedCallButton|null); - } - - /** Represents a HydratedTemplateButton. */ - class HydratedTemplateButton implements IHydratedTemplateButton { - - /** - * Constructs a new HydratedTemplateButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHydratedTemplateButton); - - /** HydratedTemplateButton index. */ - public index: number; - - /** HydratedTemplateButton quickReplyButton. */ - public quickReplyButton?: (proto.IHydratedQuickReplyButton|null); - - /** HydratedTemplateButton urlButton. */ - public urlButton?: (proto.IHydratedURLButton|null); - - /** HydratedTemplateButton callButton. */ - public callButton?: (proto.IHydratedCallButton|null); - - /** HydratedTemplateButton hydratedButton. */ - public hydratedButton?: ("quickReplyButton"|"urlButton"|"callButton"); - - /** - * Creates a new HydratedTemplateButton instance using the specified properties. - * @param [properties] Properties to set - * @returns HydratedTemplateButton instance - */ - public static create(properties?: proto.IHydratedTemplateButton): proto.HydratedTemplateButton; - - /** - * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. - * @param message HydratedTemplateButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHydratedTemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. - * @param message HydratedTemplateButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHydratedTemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HydratedTemplateButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HydratedTemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedTemplateButton; - - /** - * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HydratedTemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedTemplateButton; - - /** - * Verifies a HydratedTemplateButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HydratedTemplateButton - */ - public static fromObject(object: { [k: string]: any }): proto.HydratedTemplateButton; - - /** - * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified. - * @param message HydratedTemplateButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HydratedTemplateButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HydratedTemplateButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a UserReceipt. */ - interface IUserReceipt { - - /** UserReceipt userJid */ - userJid: string; - - /** UserReceipt receiptTimestamp */ - receiptTimestamp?: (number|Long|null); - - /** UserReceipt readTimestamp */ - readTimestamp?: (number|Long|null); - - /** UserReceipt playedTimestamp */ - playedTimestamp?: (number|Long|null); - - /** UserReceipt pendingDeviceJid */ - pendingDeviceJid?: (string[]|null); - - /** UserReceipt deliveredDeviceJid */ - deliveredDeviceJid?: (string[]|null); - } - - /** Represents a UserReceipt. */ - class UserReceipt implements IUserReceipt { - - /** - * Constructs a new UserReceipt. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IUserReceipt); - - /** UserReceipt userJid. */ - public userJid: string; - - /** UserReceipt receiptTimestamp. */ - public receiptTimestamp: (number|Long); - - /** UserReceipt readTimestamp. */ - public readTimestamp: (number|Long); - - /** UserReceipt playedTimestamp. */ - public playedTimestamp: (number|Long); - - /** UserReceipt pendingDeviceJid. */ - public pendingDeviceJid: string[]; - - /** UserReceipt deliveredDeviceJid. */ - public deliveredDeviceJid: string[]; - - /** - * Creates a new UserReceipt instance using the specified properties. - * @param [properties] Properties to set - * @returns UserReceipt instance - */ - public static create(properties?: proto.IUserReceipt): proto.UserReceipt; - - /** - * Encodes the specified UserReceipt message. Does not implicitly {@link proto.UserReceipt.verify|verify} messages. - * @param message UserReceipt message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IUserReceipt, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified UserReceipt message, length delimited. Does not implicitly {@link proto.UserReceipt.verify|verify} messages. - * @param message UserReceipt message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IUserReceipt, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a UserReceipt message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns UserReceipt - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.UserReceipt; - - /** - * Decodes a UserReceipt message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns UserReceipt - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.UserReceipt; - - /** - * Verifies a UserReceipt message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a UserReceipt message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns UserReceipt - */ - public static fromObject(object: { [k: string]: any }): proto.UserReceipt; - - /** - * Creates a plain object from a UserReceipt message. Also converts values to other types if specified. - * @param message UserReceipt - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.UserReceipt, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this UserReceipt to JSON. + * Converts this MessageKey to JSON. * @returns JSON object */ public toJSON(): { [k: string]: any }; @@ -10913,9 +17715,6 @@ export namespace proto { /** WebFeatures mdForceUpgrade */ mdForceUpgrade?: (proto.WebFeatures.WebFeaturesFlag|null); - - /** WebFeatures disappearingMode */ - disappearingMode?: (proto.WebFeatures.WebFeaturesFlag|null); } /** Represents a WebFeatures. */ @@ -11053,9 +17852,6 @@ export namespace proto { /** WebFeatures mdForceUpgrade. */ public mdForceUpgrade: proto.WebFeatures.WebFeaturesFlag; - /** WebFeatures disappearingMode. */ - public disappearingMode: proto.WebFeatures.WebFeaturesFlag; - /** * Creates a new WebFeatures instance using the specified properties. * @param [properties] Properties to set @@ -11666,9 +18462,6 @@ export namespace proto { /** WebMessageInfo photoChange */ photoChange?: (proto.IPhotoChange|null); - - /** WebMessageInfo userReceipt */ - userReceipt?: (proto.IUserReceipt[]|null); } /** Represents a WebMessageInfo. */ @@ -11770,9 +18563,6 @@ export namespace proto { /** WebMessageInfo photoChange. */ public photoChange?: (proto.IPhotoChange|null); - /** WebMessageInfo userReceipt. */ - public userReceipt: proto.IUserReceipt[]; - /** * Creates a new WebMessageInfo instance using the specified properties. * @param [properties] Properties to set @@ -11987,8 +18777,7 @@ export namespace proto { BIZ_PRIVACY_MODE_INIT_FB = 126, BIZ_PRIVACY_MODE_INIT_BSP = 127, BIZ_PRIVACY_MODE_TO_FB = 128, - BIZ_PRIVACY_MODE_TO_BSP = 129, - DISAPPEARING_MODE = 130 + BIZ_PRIVACY_MODE_TO_BSP = 129 } /** WebMessageInfoBizPrivacyStatus enum. */ diff --git a/WAMessage/index.js b/WAProto/index.js similarity index 65% rename from WAMessage/index.js rename to WAProto/index.js index 5f73b72..c2604c7 100644 --- a/WAMessage/index.js +++ b/WAProto/index.js @@ -18,27 +18,28 @@ $root.proto = (function() { */ var proto = {}; - proto.MessageKey = (function() { + proto.AppVersion = (function() { /** - * Properties of a MessageKey. + * Properties of an AppVersion. * @memberof proto - * @interface IMessageKey - * @property {string|null} [remoteJid] MessageKey remoteJid - * @property {boolean|null} [fromMe] MessageKey fromMe - * @property {string|null} [id] MessageKey id - * @property {string|null} [participant] MessageKey participant + * @interface IAppVersion + * @property {number|null} [primary] AppVersion primary + * @property {number|null} [secondary] AppVersion secondary + * @property {number|null} [tertiary] AppVersion tertiary + * @property {number|null} [quaternary] AppVersion quaternary + * @property {number|null} [quinary] AppVersion quinary */ /** - * Constructs a new MessageKey. + * Constructs a new AppVersion. * @memberof proto - * @classdesc Represents a MessageKey. - * @implements IMessageKey + * @classdesc Represents an AppVersion. + * @implements IAppVersion * @constructor - * @param {proto.IMessageKey=} [properties] Properties to set + * @param {proto.IAppVersion=} [properties] Properties to set */ - function MessageKey(properties) { + function AppVersion(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -46,114 +47,127 @@ $root.proto = (function() { } /** - * MessageKey remoteJid. - * @member {string} remoteJid - * @memberof proto.MessageKey + * AppVersion primary. + * @member {number} primary + * @memberof proto.AppVersion * @instance */ - MessageKey.prototype.remoteJid = ""; + AppVersion.prototype.primary = 0; /** - * MessageKey fromMe. - * @member {boolean} fromMe - * @memberof proto.MessageKey + * AppVersion secondary. + * @member {number} secondary + * @memberof proto.AppVersion * @instance */ - MessageKey.prototype.fromMe = false; + AppVersion.prototype.secondary = 0; /** - * MessageKey id. - * @member {string} id - * @memberof proto.MessageKey + * AppVersion tertiary. + * @member {number} tertiary + * @memberof proto.AppVersion * @instance */ - MessageKey.prototype.id = ""; + AppVersion.prototype.tertiary = 0; /** - * MessageKey participant. - * @member {string} participant - * @memberof proto.MessageKey + * AppVersion quaternary. + * @member {number} quaternary + * @memberof proto.AppVersion * @instance */ - MessageKey.prototype.participant = ""; + AppVersion.prototype.quaternary = 0; /** - * Creates a new MessageKey instance using the specified properties. + * AppVersion quinary. + * @member {number} quinary + * @memberof proto.AppVersion + * @instance + */ + AppVersion.prototype.quinary = 0; + + /** + * Creates a new AppVersion instance using the specified properties. * @function create - * @memberof proto.MessageKey + * @memberof proto.AppVersion * @static - * @param {proto.IMessageKey=} [properties] Properties to set - * @returns {proto.MessageKey} MessageKey instance + * @param {proto.IAppVersion=} [properties] Properties to set + * @returns {proto.AppVersion} AppVersion instance */ - MessageKey.create = function create(properties) { - return new MessageKey(properties); + AppVersion.create = function create(properties) { + return new AppVersion(properties); }; /** - * Encodes the specified MessageKey message. Does not implicitly {@link proto.MessageKey.verify|verify} messages. + * Encodes the specified AppVersion message. Does not implicitly {@link proto.AppVersion.verify|verify} messages. * @function encode - * @memberof proto.MessageKey + * @memberof proto.AppVersion * @static - * @param {proto.IMessageKey} message MessageKey message or plain object to encode + * @param {proto.IAppVersion} message AppVersion message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - MessageKey.encode = function encode(message, writer) { + AppVersion.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.remoteJid != null && Object.hasOwnProperty.call(message, "remoteJid")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.remoteJid); - if (message.fromMe != null && Object.hasOwnProperty.call(message, "fromMe")) - writer.uint32(/* id 2, wireType 0 =*/16).bool(message.fromMe); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.id); - if (message.participant != null && Object.hasOwnProperty.call(message, "participant")) - writer.uint32(/* id 4, wireType 2 =*/34).string(message.participant); + if (message.primary != null && Object.hasOwnProperty.call(message, "primary")) + writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.primary); + if (message.secondary != null && Object.hasOwnProperty.call(message, "secondary")) + writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.secondary); + if (message.tertiary != null && Object.hasOwnProperty.call(message, "tertiary")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.tertiary); + if (message.quaternary != null && Object.hasOwnProperty.call(message, "quaternary")) + writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.quaternary); + if (message.quinary != null && Object.hasOwnProperty.call(message, "quinary")) + writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.quinary); return writer; }; /** - * Encodes the specified MessageKey message, length delimited. Does not implicitly {@link proto.MessageKey.verify|verify} messages. + * Encodes the specified AppVersion message, length delimited. Does not implicitly {@link proto.AppVersion.verify|verify} messages. * @function encodeDelimited - * @memberof proto.MessageKey + * @memberof proto.AppVersion * @static - * @param {proto.IMessageKey} message MessageKey message or plain object to encode + * @param {proto.IAppVersion} message AppVersion message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - MessageKey.encodeDelimited = function encodeDelimited(message, writer) { + AppVersion.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; /** - * Decodes a MessageKey message from the specified reader or buffer. + * Decodes an AppVersion message from the specified reader or buffer. * @function decode - * @memberof proto.MessageKey + * @memberof proto.AppVersion * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from * @param {number} [length] Message length if known beforehand - * @returns {proto.MessageKey} MessageKey + * @returns {proto.AppVersion} AppVersion * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - MessageKey.decode = function decode(reader, length) { + AppVersion.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MessageKey(); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AppVersion(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.remoteJid = reader.string(); + message.primary = reader.uint32(); break; case 2: - message.fromMe = reader.bool(); + message.secondary = reader.uint32(); break; case 3: - message.id = reader.string(); + message.tertiary = reader.uint32(); break; case 4: - message.participant = reader.string(); + message.quaternary = reader.uint32(); + break; + case 5: + message.quinary = reader.uint32(); break; default: reader.skipType(tag & 7); @@ -164,112 +178,19425 @@ $root.proto = (function() { }; /** - * Decodes a MessageKey message from the specified reader or buffer, length delimited. + * Decodes an AppVersion message from the specified reader or buffer, length delimited. * @function decodeDelimited - * @memberof proto.MessageKey + * @memberof proto.AppVersion * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.MessageKey} MessageKey + * @returns {proto.AppVersion} AppVersion * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - MessageKey.decodeDelimited = function decodeDelimited(reader) { + AppVersion.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; /** - * Verifies a MessageKey message. + * Verifies an AppVersion message. * @function verify - * @memberof proto.MessageKey + * @memberof proto.AppVersion * @static * @param {Object.} message Plain object to verify * @returns {string|null} `null` if valid, otherwise the reason why it is not */ - MessageKey.verify = function verify(message) { + AppVersion.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.remoteJid != null && message.hasOwnProperty("remoteJid")) - if (!$util.isString(message.remoteJid)) - return "remoteJid: string expected"; - if (message.fromMe != null && message.hasOwnProperty("fromMe")) - if (typeof message.fromMe !== "boolean") - return "fromMe: boolean expected"; - if (message.id != null && message.hasOwnProperty("id")) - if (!$util.isString(message.id)) - return "id: string expected"; - if (message.participant != null && message.hasOwnProperty("participant")) - if (!$util.isString(message.participant)) - return "participant: string expected"; + if (message.primary != null && message.hasOwnProperty("primary")) + if (!$util.isInteger(message.primary)) + return "primary: integer expected"; + if (message.secondary != null && message.hasOwnProperty("secondary")) + if (!$util.isInteger(message.secondary)) + return "secondary: integer expected"; + if (message.tertiary != null && message.hasOwnProperty("tertiary")) + if (!$util.isInteger(message.tertiary)) + return "tertiary: integer expected"; + if (message.quaternary != null && message.hasOwnProperty("quaternary")) + if (!$util.isInteger(message.quaternary)) + return "quaternary: integer expected"; + if (message.quinary != null && message.hasOwnProperty("quinary")) + if (!$util.isInteger(message.quinary)) + return "quinary: integer expected"; return null; }; /** - * Creates a MessageKey message from a plain object. Also converts values to their respective internal types. + * Creates an AppVersion message from a plain object. Also converts values to their respective internal types. * @function fromObject - * @memberof proto.MessageKey + * @memberof proto.AppVersion * @static * @param {Object.} object Plain object - * @returns {proto.MessageKey} MessageKey + * @returns {proto.AppVersion} AppVersion */ - MessageKey.fromObject = function fromObject(object) { - if (object instanceof $root.proto.MessageKey) + AppVersion.fromObject = function fromObject(object) { + if (object instanceof $root.proto.AppVersion) return object; - var message = new $root.proto.MessageKey(); - if (object.remoteJid != null) - message.remoteJid = String(object.remoteJid); - if (object.fromMe != null) - message.fromMe = Boolean(object.fromMe); - if (object.id != null) - message.id = String(object.id); - if (object.participant != null) - message.participant = String(object.participant); + var message = new $root.proto.AppVersion(); + if (object.primary != null) + message.primary = object.primary >>> 0; + if (object.secondary != null) + message.secondary = object.secondary >>> 0; + if (object.tertiary != null) + message.tertiary = object.tertiary >>> 0; + if (object.quaternary != null) + message.quaternary = object.quaternary >>> 0; + if (object.quinary != null) + message.quinary = object.quinary >>> 0; return message; }; /** - * Creates a plain object from a MessageKey message. Also converts values to other types if specified. + * Creates a plain object from an AppVersion message. Also converts values to other types if specified. * @function toObject - * @memberof proto.MessageKey + * @memberof proto.AppVersion * @static - * @param {proto.MessageKey} message MessageKey + * @param {proto.AppVersion} message AppVersion * @param {$protobuf.IConversionOptions} [options] Conversion options * @returns {Object.} Plain object */ - MessageKey.toObject = function toObject(message, options) { + AppVersion.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { - object.remoteJid = ""; - object.fromMe = false; - object.id = ""; - object.participant = ""; + object.primary = 0; + object.secondary = 0; + object.tertiary = 0; + object.quaternary = 0; + object.quinary = 0; } - if (message.remoteJid != null && message.hasOwnProperty("remoteJid")) - object.remoteJid = message.remoteJid; - if (message.fromMe != null && message.hasOwnProperty("fromMe")) - object.fromMe = message.fromMe; - if (message.id != null && message.hasOwnProperty("id")) - object.id = message.id; - if (message.participant != null && message.hasOwnProperty("participant")) - object.participant = message.participant; + if (message.primary != null && message.hasOwnProperty("primary")) + object.primary = message.primary; + if (message.secondary != null && message.hasOwnProperty("secondary")) + object.secondary = message.secondary; + if (message.tertiary != null && message.hasOwnProperty("tertiary")) + object.tertiary = message.tertiary; + if (message.quaternary != null && message.hasOwnProperty("quaternary")) + object.quaternary = message.quaternary; + if (message.quinary != null && message.hasOwnProperty("quinary")) + object.quinary = message.quinary; return object; }; /** - * Converts this MessageKey to JSON. + * Converts this AppVersion to JSON. * @function toJSON - * @memberof proto.MessageKey + * @memberof proto.AppVersion * @instance * @returns {Object.} JSON object */ - MessageKey.prototype.toJSON = function toJSON() { + AppVersion.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - return MessageKey; + return AppVersion; + })(); + + proto.UserAgent = (function() { + + /** + * Properties of a UserAgent. + * @memberof proto + * @interface IUserAgent + * @property {proto.UserAgent.UserAgentPlatform|null} [platform] UserAgent platform + * @property {proto.IAppVersion|null} [appVersion] UserAgent appVersion + * @property {string|null} [mcc] UserAgent mcc + * @property {string|null} [mnc] UserAgent mnc + * @property {string|null} [osVersion] UserAgent osVersion + * @property {string|null} [manufacturer] UserAgent manufacturer + * @property {string|null} [device] UserAgent device + * @property {string|null} [osBuildNumber] UserAgent osBuildNumber + * @property {string|null} [phoneId] UserAgent phoneId + * @property {proto.UserAgent.UserAgentReleaseChannel|null} [releaseChannel] UserAgent releaseChannel + * @property {string|null} [localeLanguageIso6391] UserAgent localeLanguageIso6391 + * @property {string|null} [localeCountryIso31661Alpha2] UserAgent localeCountryIso31661Alpha2 + * @property {string|null} [deviceBoard] UserAgent deviceBoard + */ + + /** + * Constructs a new UserAgent. + * @memberof proto + * @classdesc Represents a UserAgent. + * @implements IUserAgent + * @constructor + * @param {proto.IUserAgent=} [properties] Properties to set + */ + function UserAgent(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * UserAgent platform. + * @member {proto.UserAgent.UserAgentPlatform} platform + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.platform = 0; + + /** + * UserAgent appVersion. + * @member {proto.IAppVersion|null|undefined} appVersion + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.appVersion = null; + + /** + * UserAgent mcc. + * @member {string} mcc + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.mcc = ""; + + /** + * UserAgent mnc. + * @member {string} mnc + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.mnc = ""; + + /** + * UserAgent osVersion. + * @member {string} osVersion + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.osVersion = ""; + + /** + * UserAgent manufacturer. + * @member {string} manufacturer + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.manufacturer = ""; + + /** + * UserAgent device. + * @member {string} device + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.device = ""; + + /** + * UserAgent osBuildNumber. + * @member {string} osBuildNumber + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.osBuildNumber = ""; + + /** + * UserAgent phoneId. + * @member {string} phoneId + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.phoneId = ""; + + /** + * UserAgent releaseChannel. + * @member {proto.UserAgent.UserAgentReleaseChannel} releaseChannel + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.releaseChannel = 0; + + /** + * UserAgent localeLanguageIso6391. + * @member {string} localeLanguageIso6391 + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.localeLanguageIso6391 = ""; + + /** + * UserAgent localeCountryIso31661Alpha2. + * @member {string} localeCountryIso31661Alpha2 + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.localeCountryIso31661Alpha2 = ""; + + /** + * UserAgent deviceBoard. + * @member {string} deviceBoard + * @memberof proto.UserAgent + * @instance + */ + UserAgent.prototype.deviceBoard = ""; + + /** + * Creates a new UserAgent instance using the specified properties. + * @function create + * @memberof proto.UserAgent + * @static + * @param {proto.IUserAgent=} [properties] Properties to set + * @returns {proto.UserAgent} UserAgent instance + */ + UserAgent.create = function create(properties) { + return new UserAgent(properties); + }; + + /** + * Encodes the specified UserAgent message. Does not implicitly {@link proto.UserAgent.verify|verify} messages. + * @function encode + * @memberof proto.UserAgent + * @static + * @param {proto.IUserAgent} message UserAgent message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UserAgent.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.platform != null && Object.hasOwnProperty.call(message, "platform")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.platform); + if (message.appVersion != null && Object.hasOwnProperty.call(message, "appVersion")) + $root.proto.AppVersion.encode(message.appVersion, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.mcc != null && Object.hasOwnProperty.call(message, "mcc")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.mcc); + if (message.mnc != null && Object.hasOwnProperty.call(message, "mnc")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.mnc); + if (message.osVersion != null && Object.hasOwnProperty.call(message, "osVersion")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.osVersion); + if (message.manufacturer != null && Object.hasOwnProperty.call(message, "manufacturer")) + writer.uint32(/* id 6, wireType 2 =*/50).string(message.manufacturer); + if (message.device != null && Object.hasOwnProperty.call(message, "device")) + writer.uint32(/* id 7, wireType 2 =*/58).string(message.device); + if (message.osBuildNumber != null && Object.hasOwnProperty.call(message, "osBuildNumber")) + writer.uint32(/* id 8, wireType 2 =*/66).string(message.osBuildNumber); + if (message.phoneId != null && Object.hasOwnProperty.call(message, "phoneId")) + writer.uint32(/* id 9, wireType 2 =*/74).string(message.phoneId); + if (message.releaseChannel != null && Object.hasOwnProperty.call(message, "releaseChannel")) + writer.uint32(/* id 10, wireType 0 =*/80).int32(message.releaseChannel); + if (message.localeLanguageIso6391 != null && Object.hasOwnProperty.call(message, "localeLanguageIso6391")) + writer.uint32(/* id 11, wireType 2 =*/90).string(message.localeLanguageIso6391); + if (message.localeCountryIso31661Alpha2 != null && Object.hasOwnProperty.call(message, "localeCountryIso31661Alpha2")) + writer.uint32(/* id 12, wireType 2 =*/98).string(message.localeCountryIso31661Alpha2); + if (message.deviceBoard != null && Object.hasOwnProperty.call(message, "deviceBoard")) + writer.uint32(/* id 13, wireType 2 =*/106).string(message.deviceBoard); + return writer; + }; + + /** + * Encodes the specified UserAgent message, length delimited. Does not implicitly {@link proto.UserAgent.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.UserAgent + * @static + * @param {proto.IUserAgent} message UserAgent message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UserAgent.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a UserAgent message from the specified reader or buffer. + * @function decode + * @memberof proto.UserAgent + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.UserAgent} UserAgent + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UserAgent.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.UserAgent(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.platform = reader.int32(); + break; + case 2: + message.appVersion = $root.proto.AppVersion.decode(reader, reader.uint32()); + break; + case 3: + message.mcc = reader.string(); + break; + case 4: + message.mnc = reader.string(); + break; + case 5: + message.osVersion = reader.string(); + break; + case 6: + message.manufacturer = reader.string(); + break; + case 7: + message.device = reader.string(); + break; + case 8: + message.osBuildNumber = reader.string(); + break; + case 9: + message.phoneId = reader.string(); + break; + case 10: + message.releaseChannel = reader.int32(); + break; + case 11: + message.localeLanguageIso6391 = reader.string(); + break; + case 12: + message.localeCountryIso31661Alpha2 = reader.string(); + break; + case 13: + message.deviceBoard = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a UserAgent message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.UserAgent + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.UserAgent} UserAgent + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UserAgent.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a UserAgent message. + * @function verify + * @memberof proto.UserAgent + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + UserAgent.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.platform != null && message.hasOwnProperty("platform")) + switch (message.platform) { + default: + return "platform: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + break; + } + if (message.appVersion != null && message.hasOwnProperty("appVersion")) { + var error = $root.proto.AppVersion.verify(message.appVersion); + if (error) + return "appVersion." + error; + } + if (message.mcc != null && message.hasOwnProperty("mcc")) + if (!$util.isString(message.mcc)) + return "mcc: string expected"; + if (message.mnc != null && message.hasOwnProperty("mnc")) + if (!$util.isString(message.mnc)) + return "mnc: string expected"; + if (message.osVersion != null && message.hasOwnProperty("osVersion")) + if (!$util.isString(message.osVersion)) + return "osVersion: string expected"; + if (message.manufacturer != null && message.hasOwnProperty("manufacturer")) + if (!$util.isString(message.manufacturer)) + return "manufacturer: string expected"; + if (message.device != null && message.hasOwnProperty("device")) + if (!$util.isString(message.device)) + return "device: string expected"; + if (message.osBuildNumber != null && message.hasOwnProperty("osBuildNumber")) + if (!$util.isString(message.osBuildNumber)) + return "osBuildNumber: string expected"; + if (message.phoneId != null && message.hasOwnProperty("phoneId")) + if (!$util.isString(message.phoneId)) + return "phoneId: string expected"; + if (message.releaseChannel != null && message.hasOwnProperty("releaseChannel")) + switch (message.releaseChannel) { + default: + return "releaseChannel: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.localeLanguageIso6391 != null && message.hasOwnProperty("localeLanguageIso6391")) + if (!$util.isString(message.localeLanguageIso6391)) + return "localeLanguageIso6391: string expected"; + if (message.localeCountryIso31661Alpha2 != null && message.hasOwnProperty("localeCountryIso31661Alpha2")) + if (!$util.isString(message.localeCountryIso31661Alpha2)) + return "localeCountryIso31661Alpha2: string expected"; + if (message.deviceBoard != null && message.hasOwnProperty("deviceBoard")) + if (!$util.isString(message.deviceBoard)) + return "deviceBoard: string expected"; + return null; + }; + + /** + * Creates a UserAgent message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.UserAgent + * @static + * @param {Object.} object Plain object + * @returns {proto.UserAgent} UserAgent + */ + UserAgent.fromObject = function fromObject(object) { + if (object instanceof $root.proto.UserAgent) + return object; + var message = new $root.proto.UserAgent(); + switch (object.platform) { + case "ANDROID": + case 0: + message.platform = 0; + break; + case "IOS": + case 1: + message.platform = 1; + break; + case "WINDOWS_PHONE": + case 2: + message.platform = 2; + break; + case "BLACKBERRY": + case 3: + message.platform = 3; + break; + case "BLACKBERRYX": + case 4: + message.platform = 4; + break; + case "S40": + case 5: + message.platform = 5; + break; + case "S60": + case 6: + message.platform = 6; + break; + case "PYTHON_CLIENT": + case 7: + message.platform = 7; + break; + case "TIZEN": + case 8: + message.platform = 8; + break; + case "ENTERPRISE": + case 9: + message.platform = 9; + break; + case "SMB_ANDROID": + case 10: + message.platform = 10; + break; + case "KAIOS": + case 11: + message.platform = 11; + break; + case "SMB_IOS": + case 12: + message.platform = 12; + break; + case "WINDOWS": + case 13: + message.platform = 13; + break; + case "WEB": + case 14: + message.platform = 14; + break; + case "PORTAL": + case 15: + message.platform = 15; + break; + case "GREEN_ANDROID": + case 16: + message.platform = 16; + break; + case "GREEN_IPHONE": + case 17: + message.platform = 17; + break; + case "BLUE_ANDROID": + case 18: + message.platform = 18; + break; + case "BLUE_IPHONE": + case 19: + message.platform = 19; + break; + case "FBLITE_ANDROID": + case 20: + message.platform = 20; + break; + case "MLITE_ANDROID": + case 21: + message.platform = 21; + break; + case "IGLITE_ANDROID": + case 22: + message.platform = 22; + break; + case "PAGE": + case 23: + message.platform = 23; + break; + case "MACOS": + case 24: + message.platform = 24; + break; + case "VR": + case 25: + message.platform = 25; + break; + } + if (object.appVersion != null) { + if (typeof object.appVersion !== "object") + throw TypeError(".proto.UserAgent.appVersion: object expected"); + message.appVersion = $root.proto.AppVersion.fromObject(object.appVersion); + } + if (object.mcc != null) + message.mcc = String(object.mcc); + if (object.mnc != null) + message.mnc = String(object.mnc); + if (object.osVersion != null) + message.osVersion = String(object.osVersion); + if (object.manufacturer != null) + message.manufacturer = String(object.manufacturer); + if (object.device != null) + message.device = String(object.device); + if (object.osBuildNumber != null) + message.osBuildNumber = String(object.osBuildNumber); + if (object.phoneId != null) + message.phoneId = String(object.phoneId); + switch (object.releaseChannel) { + case "RELEASE": + case 0: + message.releaseChannel = 0; + break; + case "BETA": + case 1: + message.releaseChannel = 1; + break; + case "ALPHA": + case 2: + message.releaseChannel = 2; + break; + case "DEBUG": + case 3: + message.releaseChannel = 3; + break; + } + if (object.localeLanguageIso6391 != null) + message.localeLanguageIso6391 = String(object.localeLanguageIso6391); + if (object.localeCountryIso31661Alpha2 != null) + message.localeCountryIso31661Alpha2 = String(object.localeCountryIso31661Alpha2); + if (object.deviceBoard != null) + message.deviceBoard = String(object.deviceBoard); + return message; + }; + + /** + * Creates a plain object from a UserAgent message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.UserAgent + * @static + * @param {proto.UserAgent} message UserAgent + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + UserAgent.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.platform = options.enums === String ? "ANDROID" : 0; + object.appVersion = null; + object.mcc = ""; + object.mnc = ""; + object.osVersion = ""; + object.manufacturer = ""; + object.device = ""; + object.osBuildNumber = ""; + object.phoneId = ""; + object.releaseChannel = options.enums === String ? "RELEASE" : 0; + object.localeLanguageIso6391 = ""; + object.localeCountryIso31661Alpha2 = ""; + object.deviceBoard = ""; + } + if (message.platform != null && message.hasOwnProperty("platform")) + object.platform = options.enums === String ? $root.proto.UserAgent.UserAgentPlatform[message.platform] : message.platform; + if (message.appVersion != null && message.hasOwnProperty("appVersion")) + object.appVersion = $root.proto.AppVersion.toObject(message.appVersion, options); + if (message.mcc != null && message.hasOwnProperty("mcc")) + object.mcc = message.mcc; + if (message.mnc != null && message.hasOwnProperty("mnc")) + object.mnc = message.mnc; + if (message.osVersion != null && message.hasOwnProperty("osVersion")) + object.osVersion = message.osVersion; + if (message.manufacturer != null && message.hasOwnProperty("manufacturer")) + object.manufacturer = message.manufacturer; + if (message.device != null && message.hasOwnProperty("device")) + object.device = message.device; + if (message.osBuildNumber != null && message.hasOwnProperty("osBuildNumber")) + object.osBuildNumber = message.osBuildNumber; + if (message.phoneId != null && message.hasOwnProperty("phoneId")) + object.phoneId = message.phoneId; + if (message.releaseChannel != null && message.hasOwnProperty("releaseChannel")) + object.releaseChannel = options.enums === String ? $root.proto.UserAgent.UserAgentReleaseChannel[message.releaseChannel] : message.releaseChannel; + if (message.localeLanguageIso6391 != null && message.hasOwnProperty("localeLanguageIso6391")) + object.localeLanguageIso6391 = message.localeLanguageIso6391; + if (message.localeCountryIso31661Alpha2 != null && message.hasOwnProperty("localeCountryIso31661Alpha2")) + object.localeCountryIso31661Alpha2 = message.localeCountryIso31661Alpha2; + if (message.deviceBoard != null && message.hasOwnProperty("deviceBoard")) + object.deviceBoard = message.deviceBoard; + return object; + }; + + /** + * Converts this UserAgent to JSON. + * @function toJSON + * @memberof proto.UserAgent + * @instance + * @returns {Object.} JSON object + */ + UserAgent.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * UserAgentPlatform enum. + * @name proto.UserAgent.UserAgentPlatform + * @enum {number} + * @property {number} ANDROID=0 ANDROID value + * @property {number} IOS=1 IOS value + * @property {number} WINDOWS_PHONE=2 WINDOWS_PHONE value + * @property {number} BLACKBERRY=3 BLACKBERRY value + * @property {number} BLACKBERRYX=4 BLACKBERRYX value + * @property {number} S40=5 S40 value + * @property {number} S60=6 S60 value + * @property {number} PYTHON_CLIENT=7 PYTHON_CLIENT value + * @property {number} TIZEN=8 TIZEN value + * @property {number} ENTERPRISE=9 ENTERPRISE value + * @property {number} SMB_ANDROID=10 SMB_ANDROID value + * @property {number} KAIOS=11 KAIOS value + * @property {number} SMB_IOS=12 SMB_IOS value + * @property {number} WINDOWS=13 WINDOWS value + * @property {number} WEB=14 WEB value + * @property {number} PORTAL=15 PORTAL value + * @property {number} GREEN_ANDROID=16 GREEN_ANDROID value + * @property {number} GREEN_IPHONE=17 GREEN_IPHONE value + * @property {number} BLUE_ANDROID=18 BLUE_ANDROID value + * @property {number} BLUE_IPHONE=19 BLUE_IPHONE value + * @property {number} FBLITE_ANDROID=20 FBLITE_ANDROID value + * @property {number} MLITE_ANDROID=21 MLITE_ANDROID value + * @property {number} IGLITE_ANDROID=22 IGLITE_ANDROID value + * @property {number} PAGE=23 PAGE value + * @property {number} MACOS=24 MACOS value + * @property {number} VR=25 VR value + */ + UserAgent.UserAgentPlatform = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "ANDROID"] = 0; + values[valuesById[1] = "IOS"] = 1; + values[valuesById[2] = "WINDOWS_PHONE"] = 2; + values[valuesById[3] = "BLACKBERRY"] = 3; + values[valuesById[4] = "BLACKBERRYX"] = 4; + values[valuesById[5] = "S40"] = 5; + values[valuesById[6] = "S60"] = 6; + values[valuesById[7] = "PYTHON_CLIENT"] = 7; + values[valuesById[8] = "TIZEN"] = 8; + values[valuesById[9] = "ENTERPRISE"] = 9; + values[valuesById[10] = "SMB_ANDROID"] = 10; + values[valuesById[11] = "KAIOS"] = 11; + values[valuesById[12] = "SMB_IOS"] = 12; + values[valuesById[13] = "WINDOWS"] = 13; + values[valuesById[14] = "WEB"] = 14; + values[valuesById[15] = "PORTAL"] = 15; + values[valuesById[16] = "GREEN_ANDROID"] = 16; + values[valuesById[17] = "GREEN_IPHONE"] = 17; + values[valuesById[18] = "BLUE_ANDROID"] = 18; + values[valuesById[19] = "BLUE_IPHONE"] = 19; + values[valuesById[20] = "FBLITE_ANDROID"] = 20; + values[valuesById[21] = "MLITE_ANDROID"] = 21; + values[valuesById[22] = "IGLITE_ANDROID"] = 22; + values[valuesById[23] = "PAGE"] = 23; + values[valuesById[24] = "MACOS"] = 24; + values[valuesById[25] = "VR"] = 25; + return values; + })(); + + /** + * UserAgentReleaseChannel enum. + * @name proto.UserAgent.UserAgentReleaseChannel + * @enum {number} + * @property {number} RELEASE=0 RELEASE value + * @property {number} BETA=1 BETA value + * @property {number} ALPHA=2 ALPHA value + * @property {number} DEBUG=3 DEBUG value + */ + UserAgent.UserAgentReleaseChannel = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "RELEASE"] = 0; + values[valuesById[1] = "BETA"] = 1; + values[valuesById[2] = "ALPHA"] = 2; + values[valuesById[3] = "DEBUG"] = 3; + return values; + })(); + + return UserAgent; + })(); + + proto.WebdPayload = (function() { + + /** + * Properties of a WebdPayload. + * @memberof proto + * @interface IWebdPayload + * @property {boolean|null} [usesParticipantInKey] WebdPayload usesParticipantInKey + * @property {boolean|null} [supportsStarredMessages] WebdPayload supportsStarredMessages + * @property {boolean|null} [supportsDocumentMessages] WebdPayload supportsDocumentMessages + * @property {boolean|null} [supportsUrlMessages] WebdPayload supportsUrlMessages + * @property {boolean|null} [supportsMediaRetry] WebdPayload supportsMediaRetry + * @property {boolean|null} [supportsE2EImage] WebdPayload supportsE2EImage + * @property {boolean|null} [supportsE2EVideo] WebdPayload supportsE2EVideo + * @property {boolean|null} [supportsE2EAudio] WebdPayload supportsE2EAudio + * @property {boolean|null} [supportsE2EDocument] WebdPayload supportsE2EDocument + * @property {string|null} [documentTypes] WebdPayload documentTypes + * @property {Uint8Array|null} [features] WebdPayload features + */ + + /** + * Constructs a new WebdPayload. + * @memberof proto + * @classdesc Represents a WebdPayload. + * @implements IWebdPayload + * @constructor + * @param {proto.IWebdPayload=} [properties] Properties to set + */ + function WebdPayload(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * WebdPayload usesParticipantInKey. + * @member {boolean} usesParticipantInKey + * @memberof proto.WebdPayload + * @instance + */ + WebdPayload.prototype.usesParticipantInKey = false; + + /** + * WebdPayload supportsStarredMessages. + * @member {boolean} supportsStarredMessages + * @memberof proto.WebdPayload + * @instance + */ + WebdPayload.prototype.supportsStarredMessages = false; + + /** + * WebdPayload supportsDocumentMessages. + * @member {boolean} supportsDocumentMessages + * @memberof proto.WebdPayload + * @instance + */ + WebdPayload.prototype.supportsDocumentMessages = false; + + /** + * WebdPayload supportsUrlMessages. + * @member {boolean} supportsUrlMessages + * @memberof proto.WebdPayload + * @instance + */ + WebdPayload.prototype.supportsUrlMessages = false; + + /** + * WebdPayload supportsMediaRetry. + * @member {boolean} supportsMediaRetry + * @memberof proto.WebdPayload + * @instance + */ + WebdPayload.prototype.supportsMediaRetry = false; + + /** + * WebdPayload supportsE2EImage. + * @member {boolean} supportsE2EImage + * @memberof proto.WebdPayload + * @instance + */ + WebdPayload.prototype.supportsE2EImage = false; + + /** + * WebdPayload supportsE2EVideo. + * @member {boolean} supportsE2EVideo + * @memberof proto.WebdPayload + * @instance + */ + WebdPayload.prototype.supportsE2EVideo = false; + + /** + * WebdPayload supportsE2EAudio. + * @member {boolean} supportsE2EAudio + * @memberof proto.WebdPayload + * @instance + */ + WebdPayload.prototype.supportsE2EAudio = false; + + /** + * WebdPayload supportsE2EDocument. + * @member {boolean} supportsE2EDocument + * @memberof proto.WebdPayload + * @instance + */ + WebdPayload.prototype.supportsE2EDocument = false; + + /** + * WebdPayload documentTypes. + * @member {string} documentTypes + * @memberof proto.WebdPayload + * @instance + */ + WebdPayload.prototype.documentTypes = ""; + + /** + * WebdPayload features. + * @member {Uint8Array} features + * @memberof proto.WebdPayload + * @instance + */ + WebdPayload.prototype.features = $util.newBuffer([]); + + /** + * Creates a new WebdPayload instance using the specified properties. + * @function create + * @memberof proto.WebdPayload + * @static + * @param {proto.IWebdPayload=} [properties] Properties to set + * @returns {proto.WebdPayload} WebdPayload instance + */ + WebdPayload.create = function create(properties) { + return new WebdPayload(properties); + }; + + /** + * Encodes the specified WebdPayload message. Does not implicitly {@link proto.WebdPayload.verify|verify} messages. + * @function encode + * @memberof proto.WebdPayload + * @static + * @param {proto.IWebdPayload} message WebdPayload message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WebdPayload.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.usesParticipantInKey != null && Object.hasOwnProperty.call(message, "usesParticipantInKey")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.usesParticipantInKey); + if (message.supportsStarredMessages != null && Object.hasOwnProperty.call(message, "supportsStarredMessages")) + writer.uint32(/* id 2, wireType 0 =*/16).bool(message.supportsStarredMessages); + if (message.supportsDocumentMessages != null && Object.hasOwnProperty.call(message, "supportsDocumentMessages")) + writer.uint32(/* id 3, wireType 0 =*/24).bool(message.supportsDocumentMessages); + if (message.supportsUrlMessages != null && Object.hasOwnProperty.call(message, "supportsUrlMessages")) + writer.uint32(/* id 4, wireType 0 =*/32).bool(message.supportsUrlMessages); + if (message.supportsMediaRetry != null && Object.hasOwnProperty.call(message, "supportsMediaRetry")) + writer.uint32(/* id 5, wireType 0 =*/40).bool(message.supportsMediaRetry); + if (message.supportsE2EImage != null && Object.hasOwnProperty.call(message, "supportsE2EImage")) + writer.uint32(/* id 6, wireType 0 =*/48).bool(message.supportsE2EImage); + if (message.supportsE2EVideo != null && Object.hasOwnProperty.call(message, "supportsE2EVideo")) + writer.uint32(/* id 7, wireType 0 =*/56).bool(message.supportsE2EVideo); + if (message.supportsE2EAudio != null && Object.hasOwnProperty.call(message, "supportsE2EAudio")) + writer.uint32(/* id 8, wireType 0 =*/64).bool(message.supportsE2EAudio); + if (message.supportsE2EDocument != null && Object.hasOwnProperty.call(message, "supportsE2EDocument")) + writer.uint32(/* id 9, wireType 0 =*/72).bool(message.supportsE2EDocument); + if (message.documentTypes != null && Object.hasOwnProperty.call(message, "documentTypes")) + writer.uint32(/* id 10, wireType 2 =*/82).string(message.documentTypes); + if (message.features != null && Object.hasOwnProperty.call(message, "features")) + writer.uint32(/* id 11, wireType 2 =*/90).bytes(message.features); + return writer; + }; + + /** + * Encodes the specified WebdPayload message, length delimited. Does not implicitly {@link proto.WebdPayload.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.WebdPayload + * @static + * @param {proto.IWebdPayload} message WebdPayload message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WebdPayload.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a WebdPayload message from the specified reader or buffer. + * @function decode + * @memberof proto.WebdPayload + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.WebdPayload} WebdPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebdPayload.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebdPayload(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.usesParticipantInKey = reader.bool(); + break; + case 2: + message.supportsStarredMessages = reader.bool(); + break; + case 3: + message.supportsDocumentMessages = reader.bool(); + break; + case 4: + message.supportsUrlMessages = reader.bool(); + break; + case 5: + message.supportsMediaRetry = reader.bool(); + break; + case 6: + message.supportsE2EImage = reader.bool(); + break; + case 7: + message.supportsE2EVideo = reader.bool(); + break; + case 8: + message.supportsE2EAudio = reader.bool(); + break; + case 9: + message.supportsE2EDocument = reader.bool(); + break; + case 10: + message.documentTypes = reader.string(); + break; + case 11: + message.features = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a WebdPayload message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.WebdPayload + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.WebdPayload} WebdPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebdPayload.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a WebdPayload message. + * @function verify + * @memberof proto.WebdPayload + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + WebdPayload.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.usesParticipantInKey != null && message.hasOwnProperty("usesParticipantInKey")) + if (typeof message.usesParticipantInKey !== "boolean") + return "usesParticipantInKey: boolean expected"; + if (message.supportsStarredMessages != null && message.hasOwnProperty("supportsStarredMessages")) + if (typeof message.supportsStarredMessages !== "boolean") + return "supportsStarredMessages: boolean expected"; + if (message.supportsDocumentMessages != null && message.hasOwnProperty("supportsDocumentMessages")) + if (typeof message.supportsDocumentMessages !== "boolean") + return "supportsDocumentMessages: boolean expected"; + if (message.supportsUrlMessages != null && message.hasOwnProperty("supportsUrlMessages")) + if (typeof message.supportsUrlMessages !== "boolean") + return "supportsUrlMessages: boolean expected"; + if (message.supportsMediaRetry != null && message.hasOwnProperty("supportsMediaRetry")) + if (typeof message.supportsMediaRetry !== "boolean") + return "supportsMediaRetry: boolean expected"; + if (message.supportsE2EImage != null && message.hasOwnProperty("supportsE2EImage")) + if (typeof message.supportsE2EImage !== "boolean") + return "supportsE2EImage: boolean expected"; + if (message.supportsE2EVideo != null && message.hasOwnProperty("supportsE2EVideo")) + if (typeof message.supportsE2EVideo !== "boolean") + return "supportsE2EVideo: boolean expected"; + if (message.supportsE2EAudio != null && message.hasOwnProperty("supportsE2EAudio")) + if (typeof message.supportsE2EAudio !== "boolean") + return "supportsE2EAudio: boolean expected"; + if (message.supportsE2EDocument != null && message.hasOwnProperty("supportsE2EDocument")) + if (typeof message.supportsE2EDocument !== "boolean") + return "supportsE2EDocument: boolean expected"; + if (message.documentTypes != null && message.hasOwnProperty("documentTypes")) + if (!$util.isString(message.documentTypes)) + return "documentTypes: string expected"; + if (message.features != null && message.hasOwnProperty("features")) + if (!(message.features && typeof message.features.length === "number" || $util.isString(message.features))) + return "features: buffer expected"; + return null; + }; + + /** + * Creates a WebdPayload message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.WebdPayload + * @static + * @param {Object.} object Plain object + * @returns {proto.WebdPayload} WebdPayload + */ + WebdPayload.fromObject = function fromObject(object) { + if (object instanceof $root.proto.WebdPayload) + return object; + var message = new $root.proto.WebdPayload(); + if (object.usesParticipantInKey != null) + message.usesParticipantInKey = Boolean(object.usesParticipantInKey); + if (object.supportsStarredMessages != null) + message.supportsStarredMessages = Boolean(object.supportsStarredMessages); + if (object.supportsDocumentMessages != null) + message.supportsDocumentMessages = Boolean(object.supportsDocumentMessages); + if (object.supportsUrlMessages != null) + message.supportsUrlMessages = Boolean(object.supportsUrlMessages); + if (object.supportsMediaRetry != null) + message.supportsMediaRetry = Boolean(object.supportsMediaRetry); + if (object.supportsE2EImage != null) + message.supportsE2EImage = Boolean(object.supportsE2EImage); + if (object.supportsE2EVideo != null) + message.supportsE2EVideo = Boolean(object.supportsE2EVideo); + if (object.supportsE2EAudio != null) + message.supportsE2EAudio = Boolean(object.supportsE2EAudio); + if (object.supportsE2EDocument != null) + message.supportsE2EDocument = Boolean(object.supportsE2EDocument); + if (object.documentTypes != null) + message.documentTypes = String(object.documentTypes); + if (object.features != null) + if (typeof object.features === "string") + $util.base64.decode(object.features, message.features = $util.newBuffer($util.base64.length(object.features)), 0); + else if (object.features.length) + message.features = object.features; + return message; + }; + + /** + * Creates a plain object from a WebdPayload message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.WebdPayload + * @static + * @param {proto.WebdPayload} message WebdPayload + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + WebdPayload.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.usesParticipantInKey = false; + object.supportsStarredMessages = false; + object.supportsDocumentMessages = false; + object.supportsUrlMessages = false; + object.supportsMediaRetry = false; + object.supportsE2EImage = false; + object.supportsE2EVideo = false; + object.supportsE2EAudio = false; + object.supportsE2EDocument = false; + object.documentTypes = ""; + if (options.bytes === String) + object.features = ""; + else { + object.features = []; + if (options.bytes !== Array) + object.features = $util.newBuffer(object.features); + } + } + if (message.usesParticipantInKey != null && message.hasOwnProperty("usesParticipantInKey")) + object.usesParticipantInKey = message.usesParticipantInKey; + if (message.supportsStarredMessages != null && message.hasOwnProperty("supportsStarredMessages")) + object.supportsStarredMessages = message.supportsStarredMessages; + if (message.supportsDocumentMessages != null && message.hasOwnProperty("supportsDocumentMessages")) + object.supportsDocumentMessages = message.supportsDocumentMessages; + if (message.supportsUrlMessages != null && message.hasOwnProperty("supportsUrlMessages")) + object.supportsUrlMessages = message.supportsUrlMessages; + if (message.supportsMediaRetry != null && message.hasOwnProperty("supportsMediaRetry")) + object.supportsMediaRetry = message.supportsMediaRetry; + if (message.supportsE2EImage != null && message.hasOwnProperty("supportsE2EImage")) + object.supportsE2EImage = message.supportsE2EImage; + if (message.supportsE2EVideo != null && message.hasOwnProperty("supportsE2EVideo")) + object.supportsE2EVideo = message.supportsE2EVideo; + if (message.supportsE2EAudio != null && message.hasOwnProperty("supportsE2EAudio")) + object.supportsE2EAudio = message.supportsE2EAudio; + if (message.supportsE2EDocument != null && message.hasOwnProperty("supportsE2EDocument")) + object.supportsE2EDocument = message.supportsE2EDocument; + if (message.documentTypes != null && message.hasOwnProperty("documentTypes")) + object.documentTypes = message.documentTypes; + if (message.features != null && message.hasOwnProperty("features")) + object.features = options.bytes === String ? $util.base64.encode(message.features, 0, message.features.length) : options.bytes === Array ? Array.prototype.slice.call(message.features) : message.features; + return object; + }; + + /** + * Converts this WebdPayload to JSON. + * @function toJSON + * @memberof proto.WebdPayload + * @instance + * @returns {Object.} JSON object + */ + WebdPayload.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return WebdPayload; + })(); + + proto.WebInfo = (function() { + + /** + * Properties of a WebInfo. + * @memberof proto + * @interface IWebInfo + * @property {string|null} [refToken] WebInfo refToken + * @property {string|null} [version] WebInfo version + * @property {proto.IWebdPayload|null} [webdPayload] WebInfo webdPayload + * @property {proto.WebInfo.WebInfoWebSubPlatform|null} [webSubPlatform] WebInfo webSubPlatform + */ + + /** + * Constructs a new WebInfo. + * @memberof proto + * @classdesc Represents a WebInfo. + * @implements IWebInfo + * @constructor + * @param {proto.IWebInfo=} [properties] Properties to set + */ + function WebInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * WebInfo refToken. + * @member {string} refToken + * @memberof proto.WebInfo + * @instance + */ + WebInfo.prototype.refToken = ""; + + /** + * WebInfo version. + * @member {string} version + * @memberof proto.WebInfo + * @instance + */ + WebInfo.prototype.version = ""; + + /** + * WebInfo webdPayload. + * @member {proto.IWebdPayload|null|undefined} webdPayload + * @memberof proto.WebInfo + * @instance + */ + WebInfo.prototype.webdPayload = null; + + /** + * WebInfo webSubPlatform. + * @member {proto.WebInfo.WebInfoWebSubPlatform} webSubPlatform + * @memberof proto.WebInfo + * @instance + */ + WebInfo.prototype.webSubPlatform = 0; + + /** + * Creates a new WebInfo instance using the specified properties. + * @function create + * @memberof proto.WebInfo + * @static + * @param {proto.IWebInfo=} [properties] Properties to set + * @returns {proto.WebInfo} WebInfo instance + */ + WebInfo.create = function create(properties) { + return new WebInfo(properties); + }; + + /** + * Encodes the specified WebInfo message. Does not implicitly {@link proto.WebInfo.verify|verify} messages. + * @function encode + * @memberof proto.WebInfo + * @static + * @param {proto.IWebInfo} message WebInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WebInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.refToken != null && Object.hasOwnProperty.call(message, "refToken")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.refToken); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.version); + if (message.webdPayload != null && Object.hasOwnProperty.call(message, "webdPayload")) + $root.proto.WebdPayload.encode(message.webdPayload, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.webSubPlatform != null && Object.hasOwnProperty.call(message, "webSubPlatform")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.webSubPlatform); + return writer; + }; + + /** + * Encodes the specified WebInfo message, length delimited. Does not implicitly {@link proto.WebInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.WebInfo + * @static + * @param {proto.IWebInfo} message WebInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WebInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a WebInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.WebInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.WebInfo} WebInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.refToken = reader.string(); + break; + case 2: + message.version = reader.string(); + break; + case 3: + message.webdPayload = $root.proto.WebdPayload.decode(reader, reader.uint32()); + break; + case 4: + message.webSubPlatform = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a WebInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.WebInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.WebInfo} WebInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WebInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a WebInfo message. + * @function verify + * @memberof proto.WebInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + WebInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.refToken != null && message.hasOwnProperty("refToken")) + if (!$util.isString(message.refToken)) + return "refToken: string expected"; + if (message.version != null && message.hasOwnProperty("version")) + if (!$util.isString(message.version)) + return "version: string expected"; + if (message.webdPayload != null && message.hasOwnProperty("webdPayload")) { + var error = $root.proto.WebdPayload.verify(message.webdPayload); + if (error) + return "webdPayload." + error; + } + if (message.webSubPlatform != null && message.hasOwnProperty("webSubPlatform")) + switch (message.webSubPlatform) { + default: + return "webSubPlatform: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + break; + } + return null; + }; + + /** + * Creates a WebInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.WebInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.WebInfo} WebInfo + */ + WebInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.WebInfo) + return object; + var message = new $root.proto.WebInfo(); + if (object.refToken != null) + message.refToken = String(object.refToken); + if (object.version != null) + message.version = String(object.version); + if (object.webdPayload != null) { + if (typeof object.webdPayload !== "object") + throw TypeError(".proto.WebInfo.webdPayload: object expected"); + message.webdPayload = $root.proto.WebdPayload.fromObject(object.webdPayload); + } + switch (object.webSubPlatform) { + case "WEB_BROWSER": + case 0: + message.webSubPlatform = 0; + break; + case "APP_STORE": + case 1: + message.webSubPlatform = 1; + break; + case "WIN_STORE": + case 2: + message.webSubPlatform = 2; + break; + case "DARWIN": + case 3: + message.webSubPlatform = 3; + break; + case "WIN32": + case 4: + message.webSubPlatform = 4; + break; + } + return message; + }; + + /** + * Creates a plain object from a WebInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.WebInfo + * @static + * @param {proto.WebInfo} message WebInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + WebInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.refToken = ""; + object.version = ""; + object.webdPayload = null; + object.webSubPlatform = options.enums === String ? "WEB_BROWSER" : 0; + } + if (message.refToken != null && message.hasOwnProperty("refToken")) + object.refToken = message.refToken; + if (message.version != null && message.hasOwnProperty("version")) + object.version = message.version; + if (message.webdPayload != null && message.hasOwnProperty("webdPayload")) + object.webdPayload = $root.proto.WebdPayload.toObject(message.webdPayload, options); + if (message.webSubPlatform != null && message.hasOwnProperty("webSubPlatform")) + object.webSubPlatform = options.enums === String ? $root.proto.WebInfo.WebInfoWebSubPlatform[message.webSubPlatform] : message.webSubPlatform; + return object; + }; + + /** + * Converts this WebInfo to JSON. + * @function toJSON + * @memberof proto.WebInfo + * @instance + * @returns {Object.} JSON object + */ + WebInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * WebInfoWebSubPlatform enum. + * @name proto.WebInfo.WebInfoWebSubPlatform + * @enum {number} + * @property {number} WEB_BROWSER=0 WEB_BROWSER value + * @property {number} APP_STORE=1 APP_STORE value + * @property {number} WIN_STORE=2 WIN_STORE value + * @property {number} DARWIN=3 DARWIN value + * @property {number} WIN32=4 WIN32 value + */ + WebInfo.WebInfoWebSubPlatform = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "WEB_BROWSER"] = 0; + values[valuesById[1] = "APP_STORE"] = 1; + values[valuesById[2] = "WIN_STORE"] = 2; + values[valuesById[3] = "DARWIN"] = 3; + values[valuesById[4] = "WIN32"] = 4; + return values; + })(); + + return WebInfo; + })(); + + proto.DNSSource = (function() { + + /** + * Properties of a DNSSource. + * @memberof proto + * @interface IDNSSource + * @property {proto.DNSSource.DNSSourceDNSResolutionMethod|null} [dnsMethod] DNSSource dnsMethod + * @property {boolean|null} [appCached] DNSSource appCached + */ + + /** + * Constructs a new DNSSource. + * @memberof proto + * @classdesc Represents a DNSSource. + * @implements IDNSSource + * @constructor + * @param {proto.IDNSSource=} [properties] Properties to set + */ + function DNSSource(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * DNSSource dnsMethod. + * @member {proto.DNSSource.DNSSourceDNSResolutionMethod} dnsMethod + * @memberof proto.DNSSource + * @instance + */ + DNSSource.prototype.dnsMethod = 0; + + /** + * DNSSource appCached. + * @member {boolean} appCached + * @memberof proto.DNSSource + * @instance + */ + DNSSource.prototype.appCached = false; + + /** + * Creates a new DNSSource instance using the specified properties. + * @function create + * @memberof proto.DNSSource + * @static + * @param {proto.IDNSSource=} [properties] Properties to set + * @returns {proto.DNSSource} DNSSource instance + */ + DNSSource.create = function create(properties) { + return new DNSSource(properties); + }; + + /** + * Encodes the specified DNSSource message. Does not implicitly {@link proto.DNSSource.verify|verify} messages. + * @function encode + * @memberof proto.DNSSource + * @static + * @param {proto.IDNSSource} message DNSSource message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DNSSource.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.dnsMethod != null && Object.hasOwnProperty.call(message, "dnsMethod")) + writer.uint32(/* id 15, wireType 0 =*/120).int32(message.dnsMethod); + if (message.appCached != null && Object.hasOwnProperty.call(message, "appCached")) + writer.uint32(/* id 16, wireType 0 =*/128).bool(message.appCached); + return writer; + }; + + /** + * Encodes the specified DNSSource message, length delimited. Does not implicitly {@link proto.DNSSource.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.DNSSource + * @static + * @param {proto.IDNSSource} message DNSSource message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DNSSource.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a DNSSource message from the specified reader or buffer. + * @function decode + * @memberof proto.DNSSource + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.DNSSource} DNSSource + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DNSSource.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DNSSource(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 15: + message.dnsMethod = reader.int32(); + break; + case 16: + message.appCached = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a DNSSource message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.DNSSource + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.DNSSource} DNSSource + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DNSSource.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a DNSSource message. + * @function verify + * @memberof proto.DNSSource + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + DNSSource.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.dnsMethod != null && message.hasOwnProperty("dnsMethod")) + switch (message.dnsMethod) { + default: + return "dnsMethod: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + break; + } + if (message.appCached != null && message.hasOwnProperty("appCached")) + if (typeof message.appCached !== "boolean") + return "appCached: boolean expected"; + return null; + }; + + /** + * Creates a DNSSource message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.DNSSource + * @static + * @param {Object.} object Plain object + * @returns {proto.DNSSource} DNSSource + */ + DNSSource.fromObject = function fromObject(object) { + if (object instanceof $root.proto.DNSSource) + return object; + var message = new $root.proto.DNSSource(); + switch (object.dnsMethod) { + case "SYSTEM": + case 0: + message.dnsMethod = 0; + break; + case "GOOGLE": + case 1: + message.dnsMethod = 1; + break; + case "HARDCODED": + case 2: + message.dnsMethod = 2; + break; + case "OVERRIDE": + case 3: + message.dnsMethod = 3; + break; + case "FALLBACK": + case 4: + message.dnsMethod = 4; + break; + } + if (object.appCached != null) + message.appCached = Boolean(object.appCached); + return message; + }; + + /** + * Creates a plain object from a DNSSource message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.DNSSource + * @static + * @param {proto.DNSSource} message DNSSource + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + DNSSource.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.dnsMethod = options.enums === String ? "SYSTEM" : 0; + object.appCached = false; + } + if (message.dnsMethod != null && message.hasOwnProperty("dnsMethod")) + object.dnsMethod = options.enums === String ? $root.proto.DNSSource.DNSSourceDNSResolutionMethod[message.dnsMethod] : message.dnsMethod; + if (message.appCached != null && message.hasOwnProperty("appCached")) + object.appCached = message.appCached; + return object; + }; + + /** + * Converts this DNSSource to JSON. + * @function toJSON + * @memberof proto.DNSSource + * @instance + * @returns {Object.} JSON object + */ + DNSSource.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * DNSSourceDNSResolutionMethod enum. + * @name proto.DNSSource.DNSSourceDNSResolutionMethod + * @enum {number} + * @property {number} SYSTEM=0 SYSTEM value + * @property {number} GOOGLE=1 GOOGLE value + * @property {number} HARDCODED=2 HARDCODED value + * @property {number} OVERRIDE=3 OVERRIDE value + * @property {number} FALLBACK=4 FALLBACK value + */ + DNSSource.DNSSourceDNSResolutionMethod = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "SYSTEM"] = 0; + values[valuesById[1] = "GOOGLE"] = 1; + values[valuesById[2] = "HARDCODED"] = 2; + values[valuesById[3] = "OVERRIDE"] = 3; + values[valuesById[4] = "FALLBACK"] = 4; + return values; + })(); + + return DNSSource; + })(); + + proto.CompanionRegData = (function() { + + /** + * Properties of a CompanionRegData. + * @memberof proto + * @interface ICompanionRegData + * @property {Uint8Array|null} [eRegid] CompanionRegData eRegid + * @property {Uint8Array|null} [eKeytype] CompanionRegData eKeytype + * @property {Uint8Array|null} [eIdent] CompanionRegData eIdent + * @property {Uint8Array|null} [eSkeyId] CompanionRegData eSkeyId + * @property {Uint8Array|null} [eSkeyVal] CompanionRegData eSkeyVal + * @property {Uint8Array|null} [eSkeySig] CompanionRegData eSkeySig + * @property {Uint8Array|null} [buildHash] CompanionRegData buildHash + * @property {Uint8Array|null} [companionProps] CompanionRegData companionProps + */ + + /** + * Constructs a new CompanionRegData. + * @memberof proto + * @classdesc Represents a CompanionRegData. + * @implements ICompanionRegData + * @constructor + * @param {proto.ICompanionRegData=} [properties] Properties to set + */ + function CompanionRegData(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * CompanionRegData eRegid. + * @member {Uint8Array} eRegid + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.eRegid = $util.newBuffer([]); + + /** + * CompanionRegData eKeytype. + * @member {Uint8Array} eKeytype + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.eKeytype = $util.newBuffer([]); + + /** + * CompanionRegData eIdent. + * @member {Uint8Array} eIdent + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.eIdent = $util.newBuffer([]); + + /** + * CompanionRegData eSkeyId. + * @member {Uint8Array} eSkeyId + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.eSkeyId = $util.newBuffer([]); + + /** + * CompanionRegData eSkeyVal. + * @member {Uint8Array} eSkeyVal + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.eSkeyVal = $util.newBuffer([]); + + /** + * CompanionRegData eSkeySig. + * @member {Uint8Array} eSkeySig + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.eSkeySig = $util.newBuffer([]); + + /** + * CompanionRegData buildHash. + * @member {Uint8Array} buildHash + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.buildHash = $util.newBuffer([]); + + /** + * CompanionRegData companionProps. + * @member {Uint8Array} companionProps + * @memberof proto.CompanionRegData + * @instance + */ + CompanionRegData.prototype.companionProps = $util.newBuffer([]); + + /** + * Creates a new CompanionRegData instance using the specified properties. + * @function create + * @memberof proto.CompanionRegData + * @static + * @param {proto.ICompanionRegData=} [properties] Properties to set + * @returns {proto.CompanionRegData} CompanionRegData instance + */ + CompanionRegData.create = function create(properties) { + return new CompanionRegData(properties); + }; + + /** + * Encodes the specified CompanionRegData message. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages. + * @function encode + * @memberof proto.CompanionRegData + * @static + * @param {proto.ICompanionRegData} message CompanionRegData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CompanionRegData.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.eRegid != null && Object.hasOwnProperty.call(message, "eRegid")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.eRegid); + if (message.eKeytype != null && Object.hasOwnProperty.call(message, "eKeytype")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.eKeytype); + if (message.eIdent != null && Object.hasOwnProperty.call(message, "eIdent")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.eIdent); + if (message.eSkeyId != null && Object.hasOwnProperty.call(message, "eSkeyId")) + writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.eSkeyId); + if (message.eSkeyVal != null && Object.hasOwnProperty.call(message, "eSkeyVal")) + writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.eSkeyVal); + if (message.eSkeySig != null && Object.hasOwnProperty.call(message, "eSkeySig")) + writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.eSkeySig); + if (message.buildHash != null && Object.hasOwnProperty.call(message, "buildHash")) + writer.uint32(/* id 7, wireType 2 =*/58).bytes(message.buildHash); + if (message.companionProps != null && Object.hasOwnProperty.call(message, "companionProps")) + writer.uint32(/* id 8, wireType 2 =*/66).bytes(message.companionProps); + return writer; + }; + + /** + * Encodes the specified CompanionRegData message, length delimited. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.CompanionRegData + * @static + * @param {proto.ICompanionRegData} message CompanionRegData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CompanionRegData.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a CompanionRegData message from the specified reader or buffer. + * @function decode + * @memberof proto.CompanionRegData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.CompanionRegData} CompanionRegData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CompanionRegData.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CompanionRegData(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.eRegid = reader.bytes(); + break; + case 2: + message.eKeytype = reader.bytes(); + break; + case 3: + message.eIdent = reader.bytes(); + break; + case 4: + message.eSkeyId = reader.bytes(); + break; + case 5: + message.eSkeyVal = reader.bytes(); + break; + case 6: + message.eSkeySig = reader.bytes(); + break; + case 7: + message.buildHash = reader.bytes(); + break; + case 8: + message.companionProps = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a CompanionRegData message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.CompanionRegData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.CompanionRegData} CompanionRegData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CompanionRegData.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a CompanionRegData message. + * @function verify + * @memberof proto.CompanionRegData + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + CompanionRegData.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.eRegid != null && message.hasOwnProperty("eRegid")) + if (!(message.eRegid && typeof message.eRegid.length === "number" || $util.isString(message.eRegid))) + return "eRegid: buffer expected"; + if (message.eKeytype != null && message.hasOwnProperty("eKeytype")) + if (!(message.eKeytype && typeof message.eKeytype.length === "number" || $util.isString(message.eKeytype))) + return "eKeytype: buffer expected"; + if (message.eIdent != null && message.hasOwnProperty("eIdent")) + if (!(message.eIdent && typeof message.eIdent.length === "number" || $util.isString(message.eIdent))) + return "eIdent: buffer expected"; + if (message.eSkeyId != null && message.hasOwnProperty("eSkeyId")) + if (!(message.eSkeyId && typeof message.eSkeyId.length === "number" || $util.isString(message.eSkeyId))) + return "eSkeyId: buffer expected"; + if (message.eSkeyVal != null && message.hasOwnProperty("eSkeyVal")) + if (!(message.eSkeyVal && typeof message.eSkeyVal.length === "number" || $util.isString(message.eSkeyVal))) + return "eSkeyVal: buffer expected"; + if (message.eSkeySig != null && message.hasOwnProperty("eSkeySig")) + if (!(message.eSkeySig && typeof message.eSkeySig.length === "number" || $util.isString(message.eSkeySig))) + return "eSkeySig: buffer expected"; + if (message.buildHash != null && message.hasOwnProperty("buildHash")) + if (!(message.buildHash && typeof message.buildHash.length === "number" || $util.isString(message.buildHash))) + return "buildHash: buffer expected"; + if (message.companionProps != null && message.hasOwnProperty("companionProps")) + if (!(message.companionProps && typeof message.companionProps.length === "number" || $util.isString(message.companionProps))) + return "companionProps: buffer expected"; + return null; + }; + + /** + * Creates a CompanionRegData message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.CompanionRegData + * @static + * @param {Object.} object Plain object + * @returns {proto.CompanionRegData} CompanionRegData + */ + CompanionRegData.fromObject = function fromObject(object) { + if (object instanceof $root.proto.CompanionRegData) + return object; + var message = new $root.proto.CompanionRegData(); + if (object.eRegid != null) + if (typeof object.eRegid === "string") + $util.base64.decode(object.eRegid, message.eRegid = $util.newBuffer($util.base64.length(object.eRegid)), 0); + else if (object.eRegid.length) + message.eRegid = object.eRegid; + if (object.eKeytype != null) + if (typeof object.eKeytype === "string") + $util.base64.decode(object.eKeytype, message.eKeytype = $util.newBuffer($util.base64.length(object.eKeytype)), 0); + else if (object.eKeytype.length) + message.eKeytype = object.eKeytype; + if (object.eIdent != null) + if (typeof object.eIdent === "string") + $util.base64.decode(object.eIdent, message.eIdent = $util.newBuffer($util.base64.length(object.eIdent)), 0); + else if (object.eIdent.length) + message.eIdent = object.eIdent; + if (object.eSkeyId != null) + if (typeof object.eSkeyId === "string") + $util.base64.decode(object.eSkeyId, message.eSkeyId = $util.newBuffer($util.base64.length(object.eSkeyId)), 0); + else if (object.eSkeyId.length) + message.eSkeyId = object.eSkeyId; + if (object.eSkeyVal != null) + if (typeof object.eSkeyVal === "string") + $util.base64.decode(object.eSkeyVal, message.eSkeyVal = $util.newBuffer($util.base64.length(object.eSkeyVal)), 0); + else if (object.eSkeyVal.length) + message.eSkeyVal = object.eSkeyVal; + if (object.eSkeySig != null) + if (typeof object.eSkeySig === "string") + $util.base64.decode(object.eSkeySig, message.eSkeySig = $util.newBuffer($util.base64.length(object.eSkeySig)), 0); + else if (object.eSkeySig.length) + message.eSkeySig = object.eSkeySig; + if (object.buildHash != null) + if (typeof object.buildHash === "string") + $util.base64.decode(object.buildHash, message.buildHash = $util.newBuffer($util.base64.length(object.buildHash)), 0); + else if (object.buildHash.length) + message.buildHash = object.buildHash; + if (object.companionProps != null) + if (typeof object.companionProps === "string") + $util.base64.decode(object.companionProps, message.companionProps = $util.newBuffer($util.base64.length(object.companionProps)), 0); + else if (object.companionProps.length) + message.companionProps = object.companionProps; + return message; + }; + + /** + * Creates a plain object from a CompanionRegData message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.CompanionRegData + * @static + * @param {proto.CompanionRegData} message CompanionRegData + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + CompanionRegData.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.eRegid = ""; + else { + object.eRegid = []; + if (options.bytes !== Array) + object.eRegid = $util.newBuffer(object.eRegid); + } + if (options.bytes === String) + object.eKeytype = ""; + else { + object.eKeytype = []; + if (options.bytes !== Array) + object.eKeytype = $util.newBuffer(object.eKeytype); + } + if (options.bytes === String) + object.eIdent = ""; + else { + object.eIdent = []; + if (options.bytes !== Array) + object.eIdent = $util.newBuffer(object.eIdent); + } + if (options.bytes === String) + object.eSkeyId = ""; + else { + object.eSkeyId = []; + if (options.bytes !== Array) + object.eSkeyId = $util.newBuffer(object.eSkeyId); + } + if (options.bytes === String) + object.eSkeyVal = ""; + else { + object.eSkeyVal = []; + if (options.bytes !== Array) + object.eSkeyVal = $util.newBuffer(object.eSkeyVal); + } + if (options.bytes === String) + object.eSkeySig = ""; + else { + object.eSkeySig = []; + if (options.bytes !== Array) + object.eSkeySig = $util.newBuffer(object.eSkeySig); + } + if (options.bytes === String) + object.buildHash = ""; + else { + object.buildHash = []; + if (options.bytes !== Array) + object.buildHash = $util.newBuffer(object.buildHash); + } + if (options.bytes === String) + object.companionProps = ""; + else { + object.companionProps = []; + if (options.bytes !== Array) + object.companionProps = $util.newBuffer(object.companionProps); + } + } + if (message.eRegid != null && message.hasOwnProperty("eRegid")) + object.eRegid = options.bytes === String ? $util.base64.encode(message.eRegid, 0, message.eRegid.length) : options.bytes === Array ? Array.prototype.slice.call(message.eRegid) : message.eRegid; + if (message.eKeytype != null && message.hasOwnProperty("eKeytype")) + object.eKeytype = options.bytes === String ? $util.base64.encode(message.eKeytype, 0, message.eKeytype.length) : options.bytes === Array ? Array.prototype.slice.call(message.eKeytype) : message.eKeytype; + if (message.eIdent != null && message.hasOwnProperty("eIdent")) + object.eIdent = options.bytes === String ? $util.base64.encode(message.eIdent, 0, message.eIdent.length) : options.bytes === Array ? Array.prototype.slice.call(message.eIdent) : message.eIdent; + if (message.eSkeyId != null && message.hasOwnProperty("eSkeyId")) + object.eSkeyId = options.bytes === String ? $util.base64.encode(message.eSkeyId, 0, message.eSkeyId.length) : options.bytes === Array ? Array.prototype.slice.call(message.eSkeyId) : message.eSkeyId; + if (message.eSkeyVal != null && message.hasOwnProperty("eSkeyVal")) + object.eSkeyVal = options.bytes === String ? $util.base64.encode(message.eSkeyVal, 0, message.eSkeyVal.length) : options.bytes === Array ? Array.prototype.slice.call(message.eSkeyVal) : message.eSkeyVal; + if (message.eSkeySig != null && message.hasOwnProperty("eSkeySig")) + object.eSkeySig = options.bytes === String ? $util.base64.encode(message.eSkeySig, 0, message.eSkeySig.length) : options.bytes === Array ? Array.prototype.slice.call(message.eSkeySig) : message.eSkeySig; + if (message.buildHash != null && message.hasOwnProperty("buildHash")) + object.buildHash = options.bytes === String ? $util.base64.encode(message.buildHash, 0, message.buildHash.length) : options.bytes === Array ? Array.prototype.slice.call(message.buildHash) : message.buildHash; + if (message.companionProps != null && message.hasOwnProperty("companionProps")) + object.companionProps = options.bytes === String ? $util.base64.encode(message.companionProps, 0, message.companionProps.length) : options.bytes === Array ? Array.prototype.slice.call(message.companionProps) : message.companionProps; + return object; + }; + + /** + * Converts this CompanionRegData to JSON. + * @function toJSON + * @memberof proto.CompanionRegData + * @instance + * @returns {Object.} JSON object + */ + CompanionRegData.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return CompanionRegData; + })(); + + proto.ClientPayload = (function() { + + /** + * Properties of a ClientPayload. + * @memberof proto + * @interface IClientPayload + * @property {number|Long|null} [username] ClientPayload username + * @property {boolean|null} [passive] ClientPayload passive + * @property {Array.|null} [clientFeatures] ClientPayload clientFeatures + * @property {proto.IUserAgent|null} [userAgent] ClientPayload userAgent + * @property {proto.IWebInfo|null} [webInfo] ClientPayload webInfo + * @property {string|null} [pushName] ClientPayload pushName + * @property {number|null} [sessionId] ClientPayload sessionId + * @property {boolean|null} [shortConnect] ClientPayload shortConnect + * @property {proto.ClientPayload.ClientPayloadIOSAppExtension|null} [iosAppExtension] ClientPayload iosAppExtension + * @property {proto.ClientPayload.ClientPayloadConnectType|null} [connectType] ClientPayload connectType + * @property {proto.ClientPayload.ClientPayloadConnectReason|null} [connectReason] ClientPayload connectReason + * @property {Array.|null} [shards] ClientPayload shards + * @property {proto.IDNSSource|null} [dnsSource] ClientPayload dnsSource + * @property {number|null} [connectAttemptCount] ClientPayload connectAttemptCount + * @property {number|null} [agent] ClientPayload agent + * @property {number|null} [device] ClientPayload device + * @property {proto.ICompanionRegData|null} [regData] ClientPayload regData + * @property {proto.ClientPayload.ClientPayloadProduct|null} [product] ClientPayload product + * @property {Uint8Array|null} [fbCat] ClientPayload fbCat + * @property {Uint8Array|null} [fbUserAgent] ClientPayload fbUserAgent + * @property {boolean|null} [oc] ClientPayload oc + */ + + /** + * Constructs a new ClientPayload. + * @memberof proto + * @classdesc Represents a ClientPayload. + * @implements IClientPayload + * @constructor + * @param {proto.IClientPayload=} [properties] Properties to set + */ + function ClientPayload(properties) { + this.clientFeatures = []; + this.shards = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ClientPayload username. + * @member {number|Long} username + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.username = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * ClientPayload passive. + * @member {boolean} passive + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.passive = false; + + /** + * ClientPayload clientFeatures. + * @member {Array.} clientFeatures + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.clientFeatures = $util.emptyArray; + + /** + * ClientPayload userAgent. + * @member {proto.IUserAgent|null|undefined} userAgent + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.userAgent = null; + + /** + * ClientPayload webInfo. + * @member {proto.IWebInfo|null|undefined} webInfo + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.webInfo = null; + + /** + * ClientPayload pushName. + * @member {string} pushName + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.pushName = ""; + + /** + * ClientPayload sessionId. + * @member {number} sessionId + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.sessionId = 0; + + /** + * ClientPayload shortConnect. + * @member {boolean} shortConnect + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.shortConnect = false; + + /** + * ClientPayload iosAppExtension. + * @member {proto.ClientPayload.ClientPayloadIOSAppExtension} iosAppExtension + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.iosAppExtension = 0; + + /** + * ClientPayload connectType. + * @member {proto.ClientPayload.ClientPayloadConnectType} connectType + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.connectType = 0; + + /** + * ClientPayload connectReason. + * @member {proto.ClientPayload.ClientPayloadConnectReason} connectReason + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.connectReason = 0; + + /** + * ClientPayload shards. + * @member {Array.} shards + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.shards = $util.emptyArray; + + /** + * ClientPayload dnsSource. + * @member {proto.IDNSSource|null|undefined} dnsSource + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.dnsSource = null; + + /** + * ClientPayload connectAttemptCount. + * @member {number} connectAttemptCount + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.connectAttemptCount = 0; + + /** + * ClientPayload agent. + * @member {number} agent + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.agent = 0; + + /** + * ClientPayload device. + * @member {number} device + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.device = 0; + + /** + * ClientPayload regData. + * @member {proto.ICompanionRegData|null|undefined} regData + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.regData = null; + + /** + * ClientPayload product. + * @member {proto.ClientPayload.ClientPayloadProduct} product + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.product = 0; + + /** + * ClientPayload fbCat. + * @member {Uint8Array} fbCat + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.fbCat = $util.newBuffer([]); + + /** + * ClientPayload fbUserAgent. + * @member {Uint8Array} fbUserAgent + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.fbUserAgent = $util.newBuffer([]); + + /** + * ClientPayload oc. + * @member {boolean} oc + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.oc = false; + + /** + * Creates a new ClientPayload instance using the specified properties. + * @function create + * @memberof proto.ClientPayload + * @static + * @param {proto.IClientPayload=} [properties] Properties to set + * @returns {proto.ClientPayload} ClientPayload instance + */ + ClientPayload.create = function create(properties) { + return new ClientPayload(properties); + }; + + /** + * Encodes the specified ClientPayload message. Does not implicitly {@link proto.ClientPayload.verify|verify} messages. + * @function encode + * @memberof proto.ClientPayload + * @static + * @param {proto.IClientPayload} message ClientPayload message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClientPayload.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.username != null && Object.hasOwnProperty.call(message, "username")) + writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.username); + if (message.passive != null && Object.hasOwnProperty.call(message, "passive")) + writer.uint32(/* id 3, wireType 0 =*/24).bool(message.passive); + if (message.clientFeatures != null && message.clientFeatures.length) + for (var i = 0; i < message.clientFeatures.length; ++i) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.clientFeatures[i]); + if (message.userAgent != null && Object.hasOwnProperty.call(message, "userAgent")) + $root.proto.UserAgent.encode(message.userAgent, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + if (message.webInfo != null && Object.hasOwnProperty.call(message, "webInfo")) + $root.proto.WebInfo.encode(message.webInfo, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.pushName != null && Object.hasOwnProperty.call(message, "pushName")) + writer.uint32(/* id 7, wireType 2 =*/58).string(message.pushName); + if (message.sessionId != null && Object.hasOwnProperty.call(message, "sessionId")) + writer.uint32(/* id 9, wireType 5 =*/77).sfixed32(message.sessionId); + if (message.shortConnect != null && Object.hasOwnProperty.call(message, "shortConnect")) + writer.uint32(/* id 10, wireType 0 =*/80).bool(message.shortConnect); + if (message.connectType != null && Object.hasOwnProperty.call(message, "connectType")) + writer.uint32(/* id 12, wireType 0 =*/96).int32(message.connectType); + if (message.connectReason != null && Object.hasOwnProperty.call(message, "connectReason")) + writer.uint32(/* id 13, wireType 0 =*/104).int32(message.connectReason); + if (message.shards != null && message.shards.length) + for (var i = 0; i < message.shards.length; ++i) + writer.uint32(/* id 14, wireType 0 =*/112).int32(message.shards[i]); + if (message.dnsSource != null && Object.hasOwnProperty.call(message, "dnsSource")) + $root.proto.DNSSource.encode(message.dnsSource, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim(); + if (message.connectAttemptCount != null && Object.hasOwnProperty.call(message, "connectAttemptCount")) + writer.uint32(/* id 16, wireType 0 =*/128).uint32(message.connectAttemptCount); + if (message.agent != null && Object.hasOwnProperty.call(message, "agent")) + writer.uint32(/* id 17, wireType 0 =*/136).uint32(message.agent); + if (message.device != null && Object.hasOwnProperty.call(message, "device")) + writer.uint32(/* id 18, wireType 0 =*/144).uint32(message.device); + if (message.regData != null && Object.hasOwnProperty.call(message, "regData")) + $root.proto.CompanionRegData.encode(message.regData, writer.uint32(/* id 19, wireType 2 =*/154).fork()).ldelim(); + if (message.product != null && Object.hasOwnProperty.call(message, "product")) + writer.uint32(/* id 20, wireType 0 =*/160).int32(message.product); + if (message.fbCat != null && Object.hasOwnProperty.call(message, "fbCat")) + writer.uint32(/* id 21, wireType 2 =*/170).bytes(message.fbCat); + if (message.fbUserAgent != null && Object.hasOwnProperty.call(message, "fbUserAgent")) + writer.uint32(/* id 22, wireType 2 =*/178).bytes(message.fbUserAgent); + if (message.oc != null && Object.hasOwnProperty.call(message, "oc")) + writer.uint32(/* id 23, wireType 0 =*/184).bool(message.oc); + if (message.iosAppExtension != null && Object.hasOwnProperty.call(message, "iosAppExtension")) + writer.uint32(/* id 30, wireType 0 =*/240).int32(message.iosAppExtension); + return writer; + }; + + /** + * Encodes the specified ClientPayload message, length delimited. Does not implicitly {@link proto.ClientPayload.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ClientPayload + * @static + * @param {proto.IClientPayload} message ClientPayload message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClientPayload.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ClientPayload message from the specified reader or buffer. + * @function decode + * @memberof proto.ClientPayload + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ClientPayload} ClientPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClientPayload.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClientPayload(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.username = reader.uint64(); + break; + case 3: + message.passive = reader.bool(); + break; + case 4: + if (!(message.clientFeatures && message.clientFeatures.length)) + message.clientFeatures = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.clientFeatures.push(reader.int32()); + } else + message.clientFeatures.push(reader.int32()); + break; + case 5: + message.userAgent = $root.proto.UserAgent.decode(reader, reader.uint32()); + break; + case 6: + message.webInfo = $root.proto.WebInfo.decode(reader, reader.uint32()); + break; + case 7: + message.pushName = reader.string(); + break; + case 9: + message.sessionId = reader.sfixed32(); + break; + case 10: + message.shortConnect = reader.bool(); + break; + case 30: + message.iosAppExtension = reader.int32(); + break; + case 12: + message.connectType = reader.int32(); + break; + case 13: + message.connectReason = reader.int32(); + break; + case 14: + if (!(message.shards && message.shards.length)) + message.shards = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.shards.push(reader.int32()); + } else + message.shards.push(reader.int32()); + break; + case 15: + message.dnsSource = $root.proto.DNSSource.decode(reader, reader.uint32()); + break; + case 16: + message.connectAttemptCount = reader.uint32(); + break; + case 17: + message.agent = reader.uint32(); + break; + case 18: + message.device = reader.uint32(); + break; + case 19: + message.regData = $root.proto.CompanionRegData.decode(reader, reader.uint32()); + break; + case 20: + message.product = reader.int32(); + break; + case 21: + message.fbCat = reader.bytes(); + break; + case 22: + message.fbUserAgent = reader.bytes(); + break; + case 23: + message.oc = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ClientPayload message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ClientPayload + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ClientPayload} ClientPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClientPayload.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ClientPayload message. + * @function verify + * @memberof proto.ClientPayload + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ClientPayload.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.username != null && message.hasOwnProperty("username")) + if (!$util.isInteger(message.username) && !(message.username && $util.isInteger(message.username.low) && $util.isInteger(message.username.high))) + return "username: integer|Long expected"; + if (message.passive != null && message.hasOwnProperty("passive")) + if (typeof message.passive !== "boolean") + return "passive: boolean expected"; + if (message.clientFeatures != null && message.hasOwnProperty("clientFeatures")) { + if (!Array.isArray(message.clientFeatures)) + return "clientFeatures: array expected"; + for (var i = 0; i < message.clientFeatures.length; ++i) + switch (message.clientFeatures[i]) { + default: + return "clientFeatures: enum value[] expected"; + case 0: + break; + } + } + if (message.userAgent != null && message.hasOwnProperty("userAgent")) { + var error = $root.proto.UserAgent.verify(message.userAgent); + if (error) + return "userAgent." + error; + } + if (message.webInfo != null && message.hasOwnProperty("webInfo")) { + var error = $root.proto.WebInfo.verify(message.webInfo); + if (error) + return "webInfo." + error; + } + if (message.pushName != null && message.hasOwnProperty("pushName")) + if (!$util.isString(message.pushName)) + return "pushName: string expected"; + if (message.sessionId != null && message.hasOwnProperty("sessionId")) + if (!$util.isInteger(message.sessionId)) + return "sessionId: integer expected"; + if (message.shortConnect != null && message.hasOwnProperty("shortConnect")) + if (typeof message.shortConnect !== "boolean") + return "shortConnect: boolean expected"; + if (message.iosAppExtension != null && message.hasOwnProperty("iosAppExtension")) + switch (message.iosAppExtension) { + default: + return "iosAppExtension: enum value expected"; + case 0: + case 1: + case 2: + break; + } + if (message.connectType != null && message.hasOwnProperty("connectType")) + switch (message.connectType) { + default: + return "connectType: enum value expected"; + case 0: + case 1: + case 100: + case 101: + case 102: + case 103: + case 104: + case 105: + case 106: + case 107: + case 108: + case 109: + case 110: + case 111: + case 112: + break; + } + if (message.connectReason != null && message.hasOwnProperty("connectReason")) + switch (message.connectReason) { + default: + return "connectReason: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + break; + } + if (message.shards != null && message.hasOwnProperty("shards")) { + if (!Array.isArray(message.shards)) + return "shards: array expected"; + for (var i = 0; i < message.shards.length; ++i) + if (!$util.isInteger(message.shards[i])) + return "shards: integer[] expected"; + } + if (message.dnsSource != null && message.hasOwnProperty("dnsSource")) { + var error = $root.proto.DNSSource.verify(message.dnsSource); + if (error) + return "dnsSource." + error; + } + if (message.connectAttemptCount != null && message.hasOwnProperty("connectAttemptCount")) + if (!$util.isInteger(message.connectAttemptCount)) + return "connectAttemptCount: integer expected"; + if (message.agent != null && message.hasOwnProperty("agent")) + if (!$util.isInteger(message.agent)) + return "agent: integer expected"; + if (message.device != null && message.hasOwnProperty("device")) + if (!$util.isInteger(message.device)) + return "device: integer expected"; + if (message.regData != null && message.hasOwnProperty("regData")) { + var error = $root.proto.CompanionRegData.verify(message.regData); + if (error) + return "regData." + error; + } + if (message.product != null && message.hasOwnProperty("product")) + switch (message.product) { + default: + return "product: enum value expected"; + case 0: + case 1: + break; + } + if (message.fbCat != null && message.hasOwnProperty("fbCat")) + if (!(message.fbCat && typeof message.fbCat.length === "number" || $util.isString(message.fbCat))) + return "fbCat: buffer expected"; + if (message.fbUserAgent != null && message.hasOwnProperty("fbUserAgent")) + if (!(message.fbUserAgent && typeof message.fbUserAgent.length === "number" || $util.isString(message.fbUserAgent))) + return "fbUserAgent: buffer expected"; + if (message.oc != null && message.hasOwnProperty("oc")) + if (typeof message.oc !== "boolean") + return "oc: boolean expected"; + return null; + }; + + /** + * Creates a ClientPayload message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ClientPayload + * @static + * @param {Object.} object Plain object + * @returns {proto.ClientPayload} ClientPayload + */ + ClientPayload.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ClientPayload) + return object; + var message = new $root.proto.ClientPayload(); + if (object.username != null) + if ($util.Long) + (message.username = $util.Long.fromValue(object.username)).unsigned = true; + else if (typeof object.username === "string") + message.username = parseInt(object.username, 10); + else if (typeof object.username === "number") + message.username = object.username; + else if (typeof object.username === "object") + message.username = new $util.LongBits(object.username.low >>> 0, object.username.high >>> 0).toNumber(true); + if (object.passive != null) + message.passive = Boolean(object.passive); + if (object.clientFeatures) { + if (!Array.isArray(object.clientFeatures)) + throw TypeError(".proto.ClientPayload.clientFeatures: array expected"); + message.clientFeatures = []; + for (var i = 0; i < object.clientFeatures.length; ++i) + switch (object.clientFeatures[i]) { + default: + case "NONE": + case 0: + message.clientFeatures[i] = 0; + break; + } + } + if (object.userAgent != null) { + if (typeof object.userAgent !== "object") + throw TypeError(".proto.ClientPayload.userAgent: object expected"); + message.userAgent = $root.proto.UserAgent.fromObject(object.userAgent); + } + if (object.webInfo != null) { + if (typeof object.webInfo !== "object") + throw TypeError(".proto.ClientPayload.webInfo: object expected"); + message.webInfo = $root.proto.WebInfo.fromObject(object.webInfo); + } + if (object.pushName != null) + message.pushName = String(object.pushName); + if (object.sessionId != null) + message.sessionId = object.sessionId | 0; + if (object.shortConnect != null) + message.shortConnect = Boolean(object.shortConnect); + switch (object.iosAppExtension) { + case "SHARE_EXTENSION": + case 0: + message.iosAppExtension = 0; + break; + case "SERVICE_EXTENSION": + case 1: + message.iosAppExtension = 1; + break; + case "INTENTS_EXTENSION": + case 2: + message.iosAppExtension = 2; + break; + } + switch (object.connectType) { + case "CELLULAR_UNKNOWN": + case 0: + message.connectType = 0; + break; + case "WIFI_UNKNOWN": + case 1: + message.connectType = 1; + break; + case "CELLULAR_EDGE": + case 100: + message.connectType = 100; + break; + case "CELLULAR_IDEN": + case 101: + message.connectType = 101; + break; + case "CELLULAR_UMTS": + case 102: + message.connectType = 102; + break; + case "CELLULAR_EVDO": + case 103: + message.connectType = 103; + break; + case "CELLULAR_GPRS": + case 104: + message.connectType = 104; + break; + case "CELLULAR_HSDPA": + case 105: + message.connectType = 105; + break; + case "CELLULAR_HSUPA": + case 106: + message.connectType = 106; + break; + case "CELLULAR_HSPA": + case 107: + message.connectType = 107; + break; + case "CELLULAR_CDMA": + case 108: + message.connectType = 108; + break; + case "CELLULAR_1XRTT": + case 109: + message.connectType = 109; + break; + case "CELLULAR_EHRPD": + case 110: + message.connectType = 110; + break; + case "CELLULAR_LTE": + case 111: + message.connectType = 111; + break; + case "CELLULAR_HSPAP": + case 112: + message.connectType = 112; + break; + } + switch (object.connectReason) { + case "PUSH": + case 0: + message.connectReason = 0; + break; + case "USER_ACTIVATED": + case 1: + message.connectReason = 1; + break; + case "SCHEDULED": + case 2: + message.connectReason = 2; + break; + case "ERROR_RECONNECT": + case 3: + message.connectReason = 3; + break; + case "NETWORK_SWITCH": + case 4: + message.connectReason = 4; + break; + case "PING_RECONNECT": + case 5: + message.connectReason = 5; + break; + } + if (object.shards) { + if (!Array.isArray(object.shards)) + throw TypeError(".proto.ClientPayload.shards: array expected"); + message.shards = []; + for (var i = 0; i < object.shards.length; ++i) + message.shards[i] = object.shards[i] | 0; + } + if (object.dnsSource != null) { + if (typeof object.dnsSource !== "object") + throw TypeError(".proto.ClientPayload.dnsSource: object expected"); + message.dnsSource = $root.proto.DNSSource.fromObject(object.dnsSource); + } + if (object.connectAttemptCount != null) + message.connectAttemptCount = object.connectAttemptCount >>> 0; + if (object.agent != null) + message.agent = object.agent >>> 0; + if (object.device != null) + message.device = object.device >>> 0; + if (object.regData != null) { + if (typeof object.regData !== "object") + throw TypeError(".proto.ClientPayload.regData: object expected"); + message.regData = $root.proto.CompanionRegData.fromObject(object.regData); + } + switch (object.product) { + case "WHATSAPP": + case 0: + message.product = 0; + break; + case "MESSENGER": + case 1: + message.product = 1; + break; + } + if (object.fbCat != null) + if (typeof object.fbCat === "string") + $util.base64.decode(object.fbCat, message.fbCat = $util.newBuffer($util.base64.length(object.fbCat)), 0); + else if (object.fbCat.length) + message.fbCat = object.fbCat; + if (object.fbUserAgent != null) + if (typeof object.fbUserAgent === "string") + $util.base64.decode(object.fbUserAgent, message.fbUserAgent = $util.newBuffer($util.base64.length(object.fbUserAgent)), 0); + else if (object.fbUserAgent.length) + message.fbUserAgent = object.fbUserAgent; + if (object.oc != null) + message.oc = Boolean(object.oc); + return message; + }; + + /** + * Creates a plain object from a ClientPayload message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ClientPayload + * @static + * @param {proto.ClientPayload} message ClientPayload + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ClientPayload.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.clientFeatures = []; + object.shards = []; + } + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.username = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.username = options.longs === String ? "0" : 0; + object.passive = false; + object.userAgent = null; + object.webInfo = null; + object.pushName = ""; + object.sessionId = 0; + object.shortConnect = false; + object.connectType = options.enums === String ? "CELLULAR_UNKNOWN" : 0; + object.connectReason = options.enums === String ? "PUSH" : 0; + object.dnsSource = null; + object.connectAttemptCount = 0; + object.agent = 0; + object.device = 0; + object.regData = null; + object.product = options.enums === String ? "WHATSAPP" : 0; + if (options.bytes === String) + object.fbCat = ""; + else { + object.fbCat = []; + if (options.bytes !== Array) + object.fbCat = $util.newBuffer(object.fbCat); + } + if (options.bytes === String) + object.fbUserAgent = ""; + else { + object.fbUserAgent = []; + if (options.bytes !== Array) + object.fbUserAgent = $util.newBuffer(object.fbUserAgent); + } + object.oc = false; + object.iosAppExtension = options.enums === String ? "SHARE_EXTENSION" : 0; + } + if (message.username != null && message.hasOwnProperty("username")) + if (typeof message.username === "number") + object.username = options.longs === String ? String(message.username) : message.username; + else + object.username = options.longs === String ? $util.Long.prototype.toString.call(message.username) : options.longs === Number ? new $util.LongBits(message.username.low >>> 0, message.username.high >>> 0).toNumber(true) : message.username; + if (message.passive != null && message.hasOwnProperty("passive")) + object.passive = message.passive; + if (message.clientFeatures && message.clientFeatures.length) { + object.clientFeatures = []; + for (var j = 0; j < message.clientFeatures.length; ++j) + object.clientFeatures[j] = options.enums === String ? $root.proto.ClientPayload.ClientPayloadClientFeature[message.clientFeatures[j]] : message.clientFeatures[j]; + } + if (message.userAgent != null && message.hasOwnProperty("userAgent")) + object.userAgent = $root.proto.UserAgent.toObject(message.userAgent, options); + if (message.webInfo != null && message.hasOwnProperty("webInfo")) + object.webInfo = $root.proto.WebInfo.toObject(message.webInfo, options); + if (message.pushName != null && message.hasOwnProperty("pushName")) + object.pushName = message.pushName; + if (message.sessionId != null && message.hasOwnProperty("sessionId")) + object.sessionId = message.sessionId; + if (message.shortConnect != null && message.hasOwnProperty("shortConnect")) + object.shortConnect = message.shortConnect; + if (message.connectType != null && message.hasOwnProperty("connectType")) + object.connectType = options.enums === String ? $root.proto.ClientPayload.ClientPayloadConnectType[message.connectType] : message.connectType; + if (message.connectReason != null && message.hasOwnProperty("connectReason")) + object.connectReason = options.enums === String ? $root.proto.ClientPayload.ClientPayloadConnectReason[message.connectReason] : message.connectReason; + if (message.shards && message.shards.length) { + object.shards = []; + for (var j = 0; j < message.shards.length; ++j) + object.shards[j] = message.shards[j]; + } + if (message.dnsSource != null && message.hasOwnProperty("dnsSource")) + object.dnsSource = $root.proto.DNSSource.toObject(message.dnsSource, options); + if (message.connectAttemptCount != null && message.hasOwnProperty("connectAttemptCount")) + object.connectAttemptCount = message.connectAttemptCount; + if (message.agent != null && message.hasOwnProperty("agent")) + object.agent = message.agent; + if (message.device != null && message.hasOwnProperty("device")) + object.device = message.device; + if (message.regData != null && message.hasOwnProperty("regData")) + object.regData = $root.proto.CompanionRegData.toObject(message.regData, options); + if (message.product != null && message.hasOwnProperty("product")) + object.product = options.enums === String ? $root.proto.ClientPayload.ClientPayloadProduct[message.product] : message.product; + if (message.fbCat != null && message.hasOwnProperty("fbCat")) + object.fbCat = options.bytes === String ? $util.base64.encode(message.fbCat, 0, message.fbCat.length) : options.bytes === Array ? Array.prototype.slice.call(message.fbCat) : message.fbCat; + if (message.fbUserAgent != null && message.hasOwnProperty("fbUserAgent")) + object.fbUserAgent = options.bytes === String ? $util.base64.encode(message.fbUserAgent, 0, message.fbUserAgent.length) : options.bytes === Array ? Array.prototype.slice.call(message.fbUserAgent) : message.fbUserAgent; + if (message.oc != null && message.hasOwnProperty("oc")) + object.oc = message.oc; + if (message.iosAppExtension != null && message.hasOwnProperty("iosAppExtension")) + object.iosAppExtension = options.enums === String ? $root.proto.ClientPayload.ClientPayloadIOSAppExtension[message.iosAppExtension] : message.iosAppExtension; + return object; + }; + + /** + * Converts this ClientPayload to JSON. + * @function toJSON + * @memberof proto.ClientPayload + * @instance + * @returns {Object.} JSON object + */ + ClientPayload.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * ClientPayloadClientFeature enum. + * @name proto.ClientPayload.ClientPayloadClientFeature + * @enum {number} + * @property {number} NONE=0 NONE value + */ + ClientPayload.ClientPayloadClientFeature = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "NONE"] = 0; + return values; + })(); + + /** + * ClientPayloadIOSAppExtension enum. + * @name proto.ClientPayload.ClientPayloadIOSAppExtension + * @enum {number} + * @property {number} SHARE_EXTENSION=0 SHARE_EXTENSION value + * @property {number} SERVICE_EXTENSION=1 SERVICE_EXTENSION value + * @property {number} INTENTS_EXTENSION=2 INTENTS_EXTENSION value + */ + ClientPayload.ClientPayloadIOSAppExtension = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "SHARE_EXTENSION"] = 0; + values[valuesById[1] = "SERVICE_EXTENSION"] = 1; + values[valuesById[2] = "INTENTS_EXTENSION"] = 2; + return values; + })(); + + /** + * ClientPayloadConnectType enum. + * @name proto.ClientPayload.ClientPayloadConnectType + * @enum {number} + * @property {number} CELLULAR_UNKNOWN=0 CELLULAR_UNKNOWN value + * @property {number} WIFI_UNKNOWN=1 WIFI_UNKNOWN value + * @property {number} CELLULAR_EDGE=100 CELLULAR_EDGE value + * @property {number} CELLULAR_IDEN=101 CELLULAR_IDEN value + * @property {number} CELLULAR_UMTS=102 CELLULAR_UMTS value + * @property {number} CELLULAR_EVDO=103 CELLULAR_EVDO value + * @property {number} CELLULAR_GPRS=104 CELLULAR_GPRS value + * @property {number} CELLULAR_HSDPA=105 CELLULAR_HSDPA value + * @property {number} CELLULAR_HSUPA=106 CELLULAR_HSUPA value + * @property {number} CELLULAR_HSPA=107 CELLULAR_HSPA value + * @property {number} CELLULAR_CDMA=108 CELLULAR_CDMA value + * @property {number} CELLULAR_1XRTT=109 CELLULAR_1XRTT value + * @property {number} CELLULAR_EHRPD=110 CELLULAR_EHRPD value + * @property {number} CELLULAR_LTE=111 CELLULAR_LTE value + * @property {number} CELLULAR_HSPAP=112 CELLULAR_HSPAP value + */ + ClientPayload.ClientPayloadConnectType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "CELLULAR_UNKNOWN"] = 0; + values[valuesById[1] = "WIFI_UNKNOWN"] = 1; + values[valuesById[100] = "CELLULAR_EDGE"] = 100; + values[valuesById[101] = "CELLULAR_IDEN"] = 101; + values[valuesById[102] = "CELLULAR_UMTS"] = 102; + values[valuesById[103] = "CELLULAR_EVDO"] = 103; + values[valuesById[104] = "CELLULAR_GPRS"] = 104; + values[valuesById[105] = "CELLULAR_HSDPA"] = 105; + values[valuesById[106] = "CELLULAR_HSUPA"] = 106; + values[valuesById[107] = "CELLULAR_HSPA"] = 107; + values[valuesById[108] = "CELLULAR_CDMA"] = 108; + values[valuesById[109] = "CELLULAR_1XRTT"] = 109; + values[valuesById[110] = "CELLULAR_EHRPD"] = 110; + values[valuesById[111] = "CELLULAR_LTE"] = 111; + values[valuesById[112] = "CELLULAR_HSPAP"] = 112; + return values; + })(); + + /** + * ClientPayloadConnectReason enum. + * @name proto.ClientPayload.ClientPayloadConnectReason + * @enum {number} + * @property {number} PUSH=0 PUSH value + * @property {number} USER_ACTIVATED=1 USER_ACTIVATED value + * @property {number} SCHEDULED=2 SCHEDULED value + * @property {number} ERROR_RECONNECT=3 ERROR_RECONNECT value + * @property {number} NETWORK_SWITCH=4 NETWORK_SWITCH value + * @property {number} PING_RECONNECT=5 PING_RECONNECT value + */ + ClientPayload.ClientPayloadConnectReason = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "PUSH"] = 0; + values[valuesById[1] = "USER_ACTIVATED"] = 1; + values[valuesById[2] = "SCHEDULED"] = 2; + values[valuesById[3] = "ERROR_RECONNECT"] = 3; + values[valuesById[4] = "NETWORK_SWITCH"] = 4; + values[valuesById[5] = "PING_RECONNECT"] = 5; + return values; + })(); + + /** + * ClientPayloadProduct enum. + * @name proto.ClientPayload.ClientPayloadProduct + * @enum {number} + * @property {number} WHATSAPP=0 WHATSAPP value + * @property {number} MESSENGER=1 MESSENGER value + */ + ClientPayload.ClientPayloadProduct = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "WHATSAPP"] = 0; + values[valuesById[1] = "MESSENGER"] = 1; + return values; + })(); + + return ClientPayload; + })(); + + proto.Details = (function() { + + /** + * Properties of a Details. + * @memberof proto + * @interface IDetails + * @property {number|null} [serial] Details serial + * @property {string|null} [issuer] Details issuer + * @property {number|Long|null} [expires] Details expires + * @property {string|null} [subject] Details subject + * @property {Uint8Array|null} [key] Details key + */ + + /** + * Constructs a new Details. + * @memberof proto + * @classdesc Represents a Details. + * @implements IDetails + * @constructor + * @param {proto.IDetails=} [properties] Properties to set + */ + function Details(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Details serial. + * @member {number} serial + * @memberof proto.Details + * @instance + */ + Details.prototype.serial = 0; + + /** + * Details issuer. + * @member {string} issuer + * @memberof proto.Details + * @instance + */ + Details.prototype.issuer = ""; + + /** + * Details expires. + * @member {number|Long} expires + * @memberof proto.Details + * @instance + */ + Details.prototype.expires = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Details subject. + * @member {string} subject + * @memberof proto.Details + * @instance + */ + Details.prototype.subject = ""; + + /** + * Details key. + * @member {Uint8Array} key + * @memberof proto.Details + * @instance + */ + Details.prototype.key = $util.newBuffer([]); + + /** + * Creates a new Details instance using the specified properties. + * @function create + * @memberof proto.Details + * @static + * @param {proto.IDetails=} [properties] Properties to set + * @returns {proto.Details} Details instance + */ + Details.create = function create(properties) { + return new Details(properties); + }; + + /** + * Encodes the specified Details message. Does not implicitly {@link proto.Details.verify|verify} messages. + * @function encode + * @memberof proto.Details + * @static + * @param {proto.IDetails} message Details message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Details.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.serial != null && Object.hasOwnProperty.call(message, "serial")) + writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.serial); + if (message.issuer != null && Object.hasOwnProperty.call(message, "issuer")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.issuer); + if (message.expires != null && Object.hasOwnProperty.call(message, "expires")) + writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.expires); + if (message.subject != null && Object.hasOwnProperty.call(message, "subject")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.subject); + if (message.key != null && Object.hasOwnProperty.call(message, "key")) + writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.key); + return writer; + }; + + /** + * Encodes the specified Details message, length delimited. Does not implicitly {@link proto.Details.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Details + * @static + * @param {proto.IDetails} message Details message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Details.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Details message from the specified reader or buffer. + * @function decode + * @memberof proto.Details + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Details} Details + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Details.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Details(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.serial = reader.uint32(); + break; + case 2: + message.issuer = reader.string(); + break; + case 3: + message.expires = reader.uint64(); + break; + case 4: + message.subject = reader.string(); + break; + case 5: + message.key = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Details message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Details + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Details} Details + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Details.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Details message. + * @function verify + * @memberof proto.Details + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Details.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.serial != null && message.hasOwnProperty("serial")) + if (!$util.isInteger(message.serial)) + return "serial: integer expected"; + if (message.issuer != null && message.hasOwnProperty("issuer")) + if (!$util.isString(message.issuer)) + return "issuer: string expected"; + if (message.expires != null && message.hasOwnProperty("expires")) + if (!$util.isInteger(message.expires) && !(message.expires && $util.isInteger(message.expires.low) && $util.isInteger(message.expires.high))) + return "expires: integer|Long expected"; + if (message.subject != null && message.hasOwnProperty("subject")) + if (!$util.isString(message.subject)) + return "subject: string expected"; + if (message.key != null && message.hasOwnProperty("key")) + if (!(message.key && typeof message.key.length === "number" || $util.isString(message.key))) + return "key: buffer expected"; + return null; + }; + + /** + * Creates a Details message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Details + * @static + * @param {Object.} object Plain object + * @returns {proto.Details} Details + */ + Details.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Details) + return object; + var message = new $root.proto.Details(); + if (object.serial != null) + message.serial = object.serial >>> 0; + if (object.issuer != null) + message.issuer = String(object.issuer); + if (object.expires != null) + if ($util.Long) + (message.expires = $util.Long.fromValue(object.expires)).unsigned = true; + else if (typeof object.expires === "string") + message.expires = parseInt(object.expires, 10); + else if (typeof object.expires === "number") + message.expires = object.expires; + else if (typeof object.expires === "object") + message.expires = new $util.LongBits(object.expires.low >>> 0, object.expires.high >>> 0).toNumber(true); + if (object.subject != null) + message.subject = String(object.subject); + if (object.key != null) + if (typeof object.key === "string") + $util.base64.decode(object.key, message.key = $util.newBuffer($util.base64.length(object.key)), 0); + else if (object.key.length) + message.key = object.key; + return message; + }; + + /** + * Creates a plain object from a Details message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Details + * @static + * @param {proto.Details} message Details + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Details.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.serial = 0; + object.issuer = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.expires = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.expires = options.longs === String ? "0" : 0; + object.subject = ""; + if (options.bytes === String) + object.key = ""; + else { + object.key = []; + if (options.bytes !== Array) + object.key = $util.newBuffer(object.key); + } + } + if (message.serial != null && message.hasOwnProperty("serial")) + object.serial = message.serial; + if (message.issuer != null && message.hasOwnProperty("issuer")) + object.issuer = message.issuer; + if (message.expires != null && message.hasOwnProperty("expires")) + if (typeof message.expires === "number") + object.expires = options.longs === String ? String(message.expires) : message.expires; + else + object.expires = options.longs === String ? $util.Long.prototype.toString.call(message.expires) : options.longs === Number ? new $util.LongBits(message.expires.low >>> 0, message.expires.high >>> 0).toNumber(true) : message.expires; + if (message.subject != null && message.hasOwnProperty("subject")) + object.subject = message.subject; + if (message.key != null && message.hasOwnProperty("key")) + object.key = options.bytes === String ? $util.base64.encode(message.key, 0, message.key.length) : options.bytes === Array ? Array.prototype.slice.call(message.key) : message.key; + return object; + }; + + /** + * Converts this Details to JSON. + * @function toJSON + * @memberof proto.Details + * @instance + * @returns {Object.} JSON object + */ + Details.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Details; + })(); + + proto.NoiseCertificate = (function() { + + /** + * Properties of a NoiseCertificate. + * @memberof proto + * @interface INoiseCertificate + * @property {Uint8Array|null} [details] NoiseCertificate details + * @property {Uint8Array|null} [signature] NoiseCertificate signature + */ + + /** + * Constructs a new NoiseCertificate. + * @memberof proto + * @classdesc Represents a NoiseCertificate. + * @implements INoiseCertificate + * @constructor + * @param {proto.INoiseCertificate=} [properties] Properties to set + */ + function NoiseCertificate(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * NoiseCertificate details. + * @member {Uint8Array} details + * @memberof proto.NoiseCertificate + * @instance + */ + NoiseCertificate.prototype.details = $util.newBuffer([]); + + /** + * NoiseCertificate signature. + * @member {Uint8Array} signature + * @memberof proto.NoiseCertificate + * @instance + */ + NoiseCertificate.prototype.signature = $util.newBuffer([]); + + /** + * Creates a new NoiseCertificate instance using the specified properties. + * @function create + * @memberof proto.NoiseCertificate + * @static + * @param {proto.INoiseCertificate=} [properties] Properties to set + * @returns {proto.NoiseCertificate} NoiseCertificate instance + */ + NoiseCertificate.create = function create(properties) { + return new NoiseCertificate(properties); + }; + + /** + * Encodes the specified NoiseCertificate message. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages. + * @function encode + * @memberof proto.NoiseCertificate + * @static + * @param {proto.INoiseCertificate} message NoiseCertificate message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + NoiseCertificate.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.details != null && Object.hasOwnProperty.call(message, "details")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); + if (message.signature != null && Object.hasOwnProperty.call(message, "signature")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.signature); + return writer; + }; + + /** + * Encodes the specified NoiseCertificate message, length delimited. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.NoiseCertificate + * @static + * @param {proto.INoiseCertificate} message NoiseCertificate message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + NoiseCertificate.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a NoiseCertificate message from the specified reader or buffer. + * @function decode + * @memberof proto.NoiseCertificate + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.NoiseCertificate} NoiseCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + NoiseCertificate.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NoiseCertificate(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.details = reader.bytes(); + break; + case 2: + message.signature = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a NoiseCertificate message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.NoiseCertificate + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.NoiseCertificate} NoiseCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + NoiseCertificate.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a NoiseCertificate message. + * @function verify + * @memberof proto.NoiseCertificate + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + NoiseCertificate.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.details != null && message.hasOwnProperty("details")) + if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) + return "details: buffer expected"; + if (message.signature != null && message.hasOwnProperty("signature")) + if (!(message.signature && typeof message.signature.length === "number" || $util.isString(message.signature))) + return "signature: buffer expected"; + return null; + }; + + /** + * Creates a NoiseCertificate message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.NoiseCertificate + * @static + * @param {Object.} object Plain object + * @returns {proto.NoiseCertificate} NoiseCertificate + */ + NoiseCertificate.fromObject = function fromObject(object) { + if (object instanceof $root.proto.NoiseCertificate) + return object; + var message = new $root.proto.NoiseCertificate(); + if (object.details != null) + if (typeof object.details === "string") + $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); + else if (object.details.length) + message.details = object.details; + if (object.signature != null) + if (typeof object.signature === "string") + $util.base64.decode(object.signature, message.signature = $util.newBuffer($util.base64.length(object.signature)), 0); + else if (object.signature.length) + message.signature = object.signature; + return message; + }; + + /** + * Creates a plain object from a NoiseCertificate message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.NoiseCertificate + * @static + * @param {proto.NoiseCertificate} message NoiseCertificate + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + NoiseCertificate.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.details = ""; + else { + object.details = []; + if (options.bytes !== Array) + object.details = $util.newBuffer(object.details); + } + if (options.bytes === String) + object.signature = ""; + else { + object.signature = []; + if (options.bytes !== Array) + object.signature = $util.newBuffer(object.signature); + } + } + if (message.details != null && message.hasOwnProperty("details")) + object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; + if (message.signature != null && message.hasOwnProperty("signature")) + object.signature = options.bytes === String ? $util.base64.encode(message.signature, 0, message.signature.length) : options.bytes === Array ? Array.prototype.slice.call(message.signature) : message.signature; + return object; + }; + + /** + * Converts this NoiseCertificate to JSON. + * @function toJSON + * @memberof proto.NoiseCertificate + * @instance + * @returns {Object.} JSON object + */ + NoiseCertificate.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return NoiseCertificate; + })(); + + proto.ClientHello = (function() { + + /** + * Properties of a ClientHello. + * @memberof proto + * @interface IClientHello + * @property {Uint8Array|null} [ephemeral] ClientHello ephemeral + * @property {Uint8Array|null} ["static"] ClientHello static + * @property {Uint8Array|null} [payload] ClientHello payload + */ + + /** + * Constructs a new ClientHello. + * @memberof proto + * @classdesc Represents a ClientHello. + * @implements IClientHello + * @constructor + * @param {proto.IClientHello=} [properties] Properties to set + */ + function ClientHello(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ClientHello ephemeral. + * @member {Uint8Array} ephemeral + * @memberof proto.ClientHello + * @instance + */ + ClientHello.prototype.ephemeral = $util.newBuffer([]); + + /** + * ClientHello static. + * @member {Uint8Array} static + * @memberof proto.ClientHello + * @instance + */ + ClientHello.prototype["static"] = $util.newBuffer([]); + + /** + * ClientHello payload. + * @member {Uint8Array} payload + * @memberof proto.ClientHello + * @instance + */ + ClientHello.prototype.payload = $util.newBuffer([]); + + /** + * Creates a new ClientHello instance using the specified properties. + * @function create + * @memberof proto.ClientHello + * @static + * @param {proto.IClientHello=} [properties] Properties to set + * @returns {proto.ClientHello} ClientHello instance + */ + ClientHello.create = function create(properties) { + return new ClientHello(properties); + }; + + /** + * Encodes the specified ClientHello message. Does not implicitly {@link proto.ClientHello.verify|verify} messages. + * @function encode + * @memberof proto.ClientHello + * @static + * @param {proto.IClientHello} message ClientHello message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClientHello.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.ephemeral != null && Object.hasOwnProperty.call(message, "ephemeral")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.ephemeral); + if (message["static"] != null && Object.hasOwnProperty.call(message, "static")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message["static"]); + if (message.payload != null && Object.hasOwnProperty.call(message, "payload")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.payload); + return writer; + }; + + /** + * Encodes the specified ClientHello message, length delimited. Does not implicitly {@link proto.ClientHello.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ClientHello + * @static + * @param {proto.IClientHello} message ClientHello message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClientHello.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ClientHello message from the specified reader or buffer. + * @function decode + * @memberof proto.ClientHello + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ClientHello} ClientHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClientHello.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClientHello(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.ephemeral = reader.bytes(); + break; + case 2: + message["static"] = reader.bytes(); + break; + case 3: + message.payload = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ClientHello message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ClientHello + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ClientHello} ClientHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClientHello.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ClientHello message. + * @function verify + * @memberof proto.ClientHello + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ClientHello.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.ephemeral != null && message.hasOwnProperty("ephemeral")) + if (!(message.ephemeral && typeof message.ephemeral.length === "number" || $util.isString(message.ephemeral))) + return "ephemeral: buffer expected"; + if (message["static"] != null && message.hasOwnProperty("static")) + if (!(message["static"] && typeof message["static"].length === "number" || $util.isString(message["static"]))) + return "static: buffer expected"; + if (message.payload != null && message.hasOwnProperty("payload")) + if (!(message.payload && typeof message.payload.length === "number" || $util.isString(message.payload))) + return "payload: buffer expected"; + return null; + }; + + /** + * Creates a ClientHello message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ClientHello + * @static + * @param {Object.} object Plain object + * @returns {proto.ClientHello} ClientHello + */ + ClientHello.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ClientHello) + return object; + var message = new $root.proto.ClientHello(); + if (object.ephemeral != null) + if (typeof object.ephemeral === "string") + $util.base64.decode(object.ephemeral, message.ephemeral = $util.newBuffer($util.base64.length(object.ephemeral)), 0); + else if (object.ephemeral.length) + message.ephemeral = object.ephemeral; + if (object["static"] != null) + if (typeof object["static"] === "string") + $util.base64.decode(object["static"], message["static"] = $util.newBuffer($util.base64.length(object["static"])), 0); + else if (object["static"].length) + message["static"] = object["static"]; + if (object.payload != null) + if (typeof object.payload === "string") + $util.base64.decode(object.payload, message.payload = $util.newBuffer($util.base64.length(object.payload)), 0); + else if (object.payload.length) + message.payload = object.payload; + return message; + }; + + /** + * Creates a plain object from a ClientHello message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ClientHello + * @static + * @param {proto.ClientHello} message ClientHello + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ClientHello.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.ephemeral = ""; + else { + object.ephemeral = []; + if (options.bytes !== Array) + object.ephemeral = $util.newBuffer(object.ephemeral); + } + if (options.bytes === String) + object["static"] = ""; + else { + object["static"] = []; + if (options.bytes !== Array) + object["static"] = $util.newBuffer(object["static"]); + } + if (options.bytes === String) + object.payload = ""; + else { + object.payload = []; + if (options.bytes !== Array) + object.payload = $util.newBuffer(object.payload); + } + } + if (message.ephemeral != null && message.hasOwnProperty("ephemeral")) + object.ephemeral = options.bytes === String ? $util.base64.encode(message.ephemeral, 0, message.ephemeral.length) : options.bytes === Array ? Array.prototype.slice.call(message.ephemeral) : message.ephemeral; + if (message["static"] != null && message.hasOwnProperty("static")) + object["static"] = options.bytes === String ? $util.base64.encode(message["static"], 0, message["static"].length) : options.bytes === Array ? Array.prototype.slice.call(message["static"]) : message["static"]; + if (message.payload != null && message.hasOwnProperty("payload")) + object.payload = options.bytes === String ? $util.base64.encode(message.payload, 0, message.payload.length) : options.bytes === Array ? Array.prototype.slice.call(message.payload) : message.payload; + return object; + }; + + /** + * Converts this ClientHello to JSON. + * @function toJSON + * @memberof proto.ClientHello + * @instance + * @returns {Object.} JSON object + */ + ClientHello.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ClientHello; + })(); + + proto.ServerHello = (function() { + + /** + * Properties of a ServerHello. + * @memberof proto + * @interface IServerHello + * @property {Uint8Array|null} [ephemeral] ServerHello ephemeral + * @property {Uint8Array|null} ["static"] ServerHello static + * @property {Uint8Array|null} [payload] ServerHello payload + */ + + /** + * Constructs a new ServerHello. + * @memberof proto + * @classdesc Represents a ServerHello. + * @implements IServerHello + * @constructor + * @param {proto.IServerHello=} [properties] Properties to set + */ + function ServerHello(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ServerHello ephemeral. + * @member {Uint8Array} ephemeral + * @memberof proto.ServerHello + * @instance + */ + ServerHello.prototype.ephemeral = $util.newBuffer([]); + + /** + * ServerHello static. + * @member {Uint8Array} static + * @memberof proto.ServerHello + * @instance + */ + ServerHello.prototype["static"] = $util.newBuffer([]); + + /** + * ServerHello payload. + * @member {Uint8Array} payload + * @memberof proto.ServerHello + * @instance + */ + ServerHello.prototype.payload = $util.newBuffer([]); + + /** + * Creates a new ServerHello instance using the specified properties. + * @function create + * @memberof proto.ServerHello + * @static + * @param {proto.IServerHello=} [properties] Properties to set + * @returns {proto.ServerHello} ServerHello instance + */ + ServerHello.create = function create(properties) { + return new ServerHello(properties); + }; + + /** + * Encodes the specified ServerHello message. Does not implicitly {@link proto.ServerHello.verify|verify} messages. + * @function encode + * @memberof proto.ServerHello + * @static + * @param {proto.IServerHello} message ServerHello message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ServerHello.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.ephemeral != null && Object.hasOwnProperty.call(message, "ephemeral")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.ephemeral); + if (message["static"] != null && Object.hasOwnProperty.call(message, "static")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message["static"]); + if (message.payload != null && Object.hasOwnProperty.call(message, "payload")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.payload); + return writer; + }; + + /** + * Encodes the specified ServerHello message, length delimited. Does not implicitly {@link proto.ServerHello.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ServerHello + * @static + * @param {proto.IServerHello} message ServerHello message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ServerHello.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ServerHello message from the specified reader or buffer. + * @function decode + * @memberof proto.ServerHello + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ServerHello} ServerHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ServerHello.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ServerHello(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.ephemeral = reader.bytes(); + break; + case 2: + message["static"] = reader.bytes(); + break; + case 3: + message.payload = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ServerHello message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ServerHello + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ServerHello} ServerHello + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ServerHello.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ServerHello message. + * @function verify + * @memberof proto.ServerHello + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ServerHello.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.ephemeral != null && message.hasOwnProperty("ephemeral")) + if (!(message.ephemeral && typeof message.ephemeral.length === "number" || $util.isString(message.ephemeral))) + return "ephemeral: buffer expected"; + if (message["static"] != null && message.hasOwnProperty("static")) + if (!(message["static"] && typeof message["static"].length === "number" || $util.isString(message["static"]))) + return "static: buffer expected"; + if (message.payload != null && message.hasOwnProperty("payload")) + if (!(message.payload && typeof message.payload.length === "number" || $util.isString(message.payload))) + return "payload: buffer expected"; + return null; + }; + + /** + * Creates a ServerHello message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ServerHello + * @static + * @param {Object.} object Plain object + * @returns {proto.ServerHello} ServerHello + */ + ServerHello.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ServerHello) + return object; + var message = new $root.proto.ServerHello(); + if (object.ephemeral != null) + if (typeof object.ephemeral === "string") + $util.base64.decode(object.ephemeral, message.ephemeral = $util.newBuffer($util.base64.length(object.ephemeral)), 0); + else if (object.ephemeral.length) + message.ephemeral = object.ephemeral; + if (object["static"] != null) + if (typeof object["static"] === "string") + $util.base64.decode(object["static"], message["static"] = $util.newBuffer($util.base64.length(object["static"])), 0); + else if (object["static"].length) + message["static"] = object["static"]; + if (object.payload != null) + if (typeof object.payload === "string") + $util.base64.decode(object.payload, message.payload = $util.newBuffer($util.base64.length(object.payload)), 0); + else if (object.payload.length) + message.payload = object.payload; + return message; + }; + + /** + * Creates a plain object from a ServerHello message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ServerHello + * @static + * @param {proto.ServerHello} message ServerHello + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ServerHello.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.ephemeral = ""; + else { + object.ephemeral = []; + if (options.bytes !== Array) + object.ephemeral = $util.newBuffer(object.ephemeral); + } + if (options.bytes === String) + object["static"] = ""; + else { + object["static"] = []; + if (options.bytes !== Array) + object["static"] = $util.newBuffer(object["static"]); + } + if (options.bytes === String) + object.payload = ""; + else { + object.payload = []; + if (options.bytes !== Array) + object.payload = $util.newBuffer(object.payload); + } + } + if (message.ephemeral != null && message.hasOwnProperty("ephemeral")) + object.ephemeral = options.bytes === String ? $util.base64.encode(message.ephemeral, 0, message.ephemeral.length) : options.bytes === Array ? Array.prototype.slice.call(message.ephemeral) : message.ephemeral; + if (message["static"] != null && message.hasOwnProperty("static")) + object["static"] = options.bytes === String ? $util.base64.encode(message["static"], 0, message["static"].length) : options.bytes === Array ? Array.prototype.slice.call(message["static"]) : message["static"]; + if (message.payload != null && message.hasOwnProperty("payload")) + object.payload = options.bytes === String ? $util.base64.encode(message.payload, 0, message.payload.length) : options.bytes === Array ? Array.prototype.slice.call(message.payload) : message.payload; + return object; + }; + + /** + * Converts this ServerHello to JSON. + * @function toJSON + * @memberof proto.ServerHello + * @instance + * @returns {Object.} JSON object + */ + ServerHello.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ServerHello; + })(); + + proto.ClientFinish = (function() { + + /** + * Properties of a ClientFinish. + * @memberof proto + * @interface IClientFinish + * @property {Uint8Array|null} ["static"] ClientFinish static + * @property {Uint8Array|null} [payload] ClientFinish payload + */ + + /** + * Constructs a new ClientFinish. + * @memberof proto + * @classdesc Represents a ClientFinish. + * @implements IClientFinish + * @constructor + * @param {proto.IClientFinish=} [properties] Properties to set + */ + function ClientFinish(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ClientFinish static. + * @member {Uint8Array} static + * @memberof proto.ClientFinish + * @instance + */ + ClientFinish.prototype["static"] = $util.newBuffer([]); + + /** + * ClientFinish payload. + * @member {Uint8Array} payload + * @memberof proto.ClientFinish + * @instance + */ + ClientFinish.prototype.payload = $util.newBuffer([]); + + /** + * Creates a new ClientFinish instance using the specified properties. + * @function create + * @memberof proto.ClientFinish + * @static + * @param {proto.IClientFinish=} [properties] Properties to set + * @returns {proto.ClientFinish} ClientFinish instance + */ + ClientFinish.create = function create(properties) { + return new ClientFinish(properties); + }; + + /** + * Encodes the specified ClientFinish message. Does not implicitly {@link proto.ClientFinish.verify|verify} messages. + * @function encode + * @memberof proto.ClientFinish + * @static + * @param {proto.IClientFinish} message ClientFinish message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClientFinish.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message["static"] != null && Object.hasOwnProperty.call(message, "static")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message["static"]); + if (message.payload != null && Object.hasOwnProperty.call(message, "payload")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.payload); + return writer; + }; + + /** + * Encodes the specified ClientFinish message, length delimited. Does not implicitly {@link proto.ClientFinish.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ClientFinish + * @static + * @param {proto.IClientFinish} message ClientFinish message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClientFinish.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ClientFinish message from the specified reader or buffer. + * @function decode + * @memberof proto.ClientFinish + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ClientFinish} ClientFinish + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClientFinish.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClientFinish(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message["static"] = reader.bytes(); + break; + case 2: + message.payload = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ClientFinish message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ClientFinish + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ClientFinish} ClientFinish + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClientFinish.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ClientFinish message. + * @function verify + * @memberof proto.ClientFinish + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ClientFinish.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message["static"] != null && message.hasOwnProperty("static")) + if (!(message["static"] && typeof message["static"].length === "number" || $util.isString(message["static"]))) + return "static: buffer expected"; + if (message.payload != null && message.hasOwnProperty("payload")) + if (!(message.payload && typeof message.payload.length === "number" || $util.isString(message.payload))) + return "payload: buffer expected"; + return null; + }; + + /** + * Creates a ClientFinish message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ClientFinish + * @static + * @param {Object.} object Plain object + * @returns {proto.ClientFinish} ClientFinish + */ + ClientFinish.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ClientFinish) + return object; + var message = new $root.proto.ClientFinish(); + if (object["static"] != null) + if (typeof object["static"] === "string") + $util.base64.decode(object["static"], message["static"] = $util.newBuffer($util.base64.length(object["static"])), 0); + else if (object["static"].length) + message["static"] = object["static"]; + if (object.payload != null) + if (typeof object.payload === "string") + $util.base64.decode(object.payload, message.payload = $util.newBuffer($util.base64.length(object.payload)), 0); + else if (object.payload.length) + message.payload = object.payload; + return message; + }; + + /** + * Creates a plain object from a ClientFinish message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ClientFinish + * @static + * @param {proto.ClientFinish} message ClientFinish + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ClientFinish.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object["static"] = ""; + else { + object["static"] = []; + if (options.bytes !== Array) + object["static"] = $util.newBuffer(object["static"]); + } + if (options.bytes === String) + object.payload = ""; + else { + object.payload = []; + if (options.bytes !== Array) + object.payload = $util.newBuffer(object.payload); + } + } + if (message["static"] != null && message.hasOwnProperty("static")) + object["static"] = options.bytes === String ? $util.base64.encode(message["static"], 0, message["static"].length) : options.bytes === Array ? Array.prototype.slice.call(message["static"]) : message["static"]; + if (message.payload != null && message.hasOwnProperty("payload")) + object.payload = options.bytes === String ? $util.base64.encode(message.payload, 0, message.payload.length) : options.bytes === Array ? Array.prototype.slice.call(message.payload) : message.payload; + return object; + }; + + /** + * Converts this ClientFinish to JSON. + * @function toJSON + * @memberof proto.ClientFinish + * @instance + * @returns {Object.} JSON object + */ + ClientFinish.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ClientFinish; + })(); + + proto.HandshakeMessage = (function() { + + /** + * Properties of a HandshakeMessage. + * @memberof proto + * @interface IHandshakeMessage + * @property {proto.IClientHello|null} [clientHello] HandshakeMessage clientHello + * @property {proto.IServerHello|null} [serverHello] HandshakeMessage serverHello + * @property {proto.IClientFinish|null} [clientFinish] HandshakeMessage clientFinish + */ + + /** + * Constructs a new HandshakeMessage. + * @memberof proto + * @classdesc Represents a HandshakeMessage. + * @implements IHandshakeMessage + * @constructor + * @param {proto.IHandshakeMessage=} [properties] Properties to set + */ + function HandshakeMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HandshakeMessage clientHello. + * @member {proto.IClientHello|null|undefined} clientHello + * @memberof proto.HandshakeMessage + * @instance + */ + HandshakeMessage.prototype.clientHello = null; + + /** + * HandshakeMessage serverHello. + * @member {proto.IServerHello|null|undefined} serverHello + * @memberof proto.HandshakeMessage + * @instance + */ + HandshakeMessage.prototype.serverHello = null; + + /** + * HandshakeMessage clientFinish. + * @member {proto.IClientFinish|null|undefined} clientFinish + * @memberof proto.HandshakeMessage + * @instance + */ + HandshakeMessage.prototype.clientFinish = null; + + /** + * Creates a new HandshakeMessage instance using the specified properties. + * @function create + * @memberof proto.HandshakeMessage + * @static + * @param {proto.IHandshakeMessage=} [properties] Properties to set + * @returns {proto.HandshakeMessage} HandshakeMessage instance + */ + HandshakeMessage.create = function create(properties) { + return new HandshakeMessage(properties); + }; + + /** + * Encodes the specified HandshakeMessage message. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages. + * @function encode + * @memberof proto.HandshakeMessage + * @static + * @param {proto.IHandshakeMessage} message HandshakeMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HandshakeMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.clientHello != null && Object.hasOwnProperty.call(message, "clientHello")) + $root.proto.ClientHello.encode(message.clientHello, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.serverHello != null && Object.hasOwnProperty.call(message, "serverHello")) + $root.proto.ServerHello.encode(message.serverHello, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.clientFinish != null && Object.hasOwnProperty.call(message, "clientFinish")) + $root.proto.ClientFinish.encode(message.clientFinish, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified HandshakeMessage message, length delimited. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HandshakeMessage + * @static + * @param {proto.IHandshakeMessage} message HandshakeMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HandshakeMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HandshakeMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.HandshakeMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HandshakeMessage} HandshakeMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HandshakeMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HandshakeMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + message.clientHello = $root.proto.ClientHello.decode(reader, reader.uint32()); + break; + case 3: + message.serverHello = $root.proto.ServerHello.decode(reader, reader.uint32()); + break; + case 4: + message.clientFinish = $root.proto.ClientFinish.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HandshakeMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HandshakeMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HandshakeMessage} HandshakeMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HandshakeMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HandshakeMessage message. + * @function verify + * @memberof proto.HandshakeMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HandshakeMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.clientHello != null && message.hasOwnProperty("clientHello")) { + var error = $root.proto.ClientHello.verify(message.clientHello); + if (error) + return "clientHello." + error; + } + if (message.serverHello != null && message.hasOwnProperty("serverHello")) { + var error = $root.proto.ServerHello.verify(message.serverHello); + if (error) + return "serverHello." + error; + } + if (message.clientFinish != null && message.hasOwnProperty("clientFinish")) { + var error = $root.proto.ClientFinish.verify(message.clientFinish); + if (error) + return "clientFinish." + error; + } + return null; + }; + + /** + * Creates a HandshakeMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HandshakeMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.HandshakeMessage} HandshakeMessage + */ + HandshakeMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HandshakeMessage) + return object; + var message = new $root.proto.HandshakeMessage(); + if (object.clientHello != null) { + if (typeof object.clientHello !== "object") + throw TypeError(".proto.HandshakeMessage.clientHello: object expected"); + message.clientHello = $root.proto.ClientHello.fromObject(object.clientHello); + } + if (object.serverHello != null) { + if (typeof object.serverHello !== "object") + throw TypeError(".proto.HandshakeMessage.serverHello: object expected"); + message.serverHello = $root.proto.ServerHello.fromObject(object.serverHello); + } + if (object.clientFinish != null) { + if (typeof object.clientFinish !== "object") + throw TypeError(".proto.HandshakeMessage.clientFinish: object expected"); + message.clientFinish = $root.proto.ClientFinish.fromObject(object.clientFinish); + } + return message; + }; + + /** + * Creates a plain object from a HandshakeMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HandshakeMessage + * @static + * @param {proto.HandshakeMessage} message HandshakeMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HandshakeMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.clientHello = null; + object.serverHello = null; + object.clientFinish = null; + } + if (message.clientHello != null && message.hasOwnProperty("clientHello")) + object.clientHello = $root.proto.ClientHello.toObject(message.clientHello, options); + if (message.serverHello != null && message.hasOwnProperty("serverHello")) + object.serverHello = $root.proto.ServerHello.toObject(message.serverHello, options); + if (message.clientFinish != null && message.hasOwnProperty("clientFinish")) + object.clientFinish = $root.proto.ClientFinish.toObject(message.clientFinish, options); + return object; + }; + + /** + * Converts this HandshakeMessage to JSON. + * @function toJSON + * @memberof proto.HandshakeMessage + * @instance + * @returns {Object.} JSON object + */ + HandshakeMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HandshakeMessage; + })(); + + proto.BizIdentityInfo = (function() { + + /** + * Properties of a BizIdentityInfo. + * @memberof proto + * @interface IBizIdentityInfo + * @property {proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue|null} [vlevel] BizIdentityInfo vlevel + * @property {proto.IVerifiedNameCertificate|null} [vnameCert] BizIdentityInfo vnameCert + * @property {boolean|null} [signed] BizIdentityInfo signed + * @property {boolean|null} [revoked] BizIdentityInfo revoked + * @property {proto.BizIdentityInfo.BizIdentityInfoHostStorageType|null} [hostStorage] BizIdentityInfo hostStorage + * @property {proto.BizIdentityInfo.BizIdentityInfoActualActorsType|null} [actualActors] BizIdentityInfo actualActors + * @property {number|Long|null} [privacyModeTs] BizIdentityInfo privacyModeTs + */ + + /** + * Constructs a new BizIdentityInfo. + * @memberof proto + * @classdesc Represents a BizIdentityInfo. + * @implements IBizIdentityInfo + * @constructor + * @param {proto.IBizIdentityInfo=} [properties] Properties to set + */ + function BizIdentityInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * BizIdentityInfo vlevel. + * @member {proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue} vlevel + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.vlevel = 0; + + /** + * BizIdentityInfo vnameCert. + * @member {proto.IVerifiedNameCertificate|null|undefined} vnameCert + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.vnameCert = null; + + /** + * BizIdentityInfo signed. + * @member {boolean} signed + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.signed = false; + + /** + * BizIdentityInfo revoked. + * @member {boolean} revoked + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.revoked = false; + + /** + * BizIdentityInfo hostStorage. + * @member {proto.BizIdentityInfo.BizIdentityInfoHostStorageType} hostStorage + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.hostStorage = 0; + + /** + * BizIdentityInfo actualActors. + * @member {proto.BizIdentityInfo.BizIdentityInfoActualActorsType} actualActors + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.actualActors = 0; + + /** + * BizIdentityInfo privacyModeTs. + * @member {number|Long} privacyModeTs + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.privacyModeTs = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Creates a new BizIdentityInfo instance using the specified properties. + * @function create + * @memberof proto.BizIdentityInfo + * @static + * @param {proto.IBizIdentityInfo=} [properties] Properties to set + * @returns {proto.BizIdentityInfo} BizIdentityInfo instance + */ + BizIdentityInfo.create = function create(properties) { + return new BizIdentityInfo(properties); + }; + + /** + * Encodes the specified BizIdentityInfo message. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages. + * @function encode + * @memberof proto.BizIdentityInfo + * @static + * @param {proto.IBizIdentityInfo} message BizIdentityInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + BizIdentityInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.vlevel != null && Object.hasOwnProperty.call(message, "vlevel")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.vlevel); + if (message.vnameCert != null && Object.hasOwnProperty.call(message, "vnameCert")) + $root.proto.VerifiedNameCertificate.encode(message.vnameCert, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.signed != null && Object.hasOwnProperty.call(message, "signed")) + writer.uint32(/* id 3, wireType 0 =*/24).bool(message.signed); + if (message.revoked != null && Object.hasOwnProperty.call(message, "revoked")) + writer.uint32(/* id 4, wireType 0 =*/32).bool(message.revoked); + if (message.hostStorage != null && Object.hasOwnProperty.call(message, "hostStorage")) + writer.uint32(/* id 5, wireType 0 =*/40).int32(message.hostStorage); + if (message.actualActors != null && Object.hasOwnProperty.call(message, "actualActors")) + writer.uint32(/* id 6, wireType 0 =*/48).int32(message.actualActors); + if (message.privacyModeTs != null && Object.hasOwnProperty.call(message, "privacyModeTs")) + writer.uint32(/* id 7, wireType 0 =*/56).uint64(message.privacyModeTs); + return writer; + }; + + /** + * Encodes the specified BizIdentityInfo message, length delimited. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.BizIdentityInfo + * @static + * @param {proto.IBizIdentityInfo} message BizIdentityInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + BizIdentityInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a BizIdentityInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.BizIdentityInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.BizIdentityInfo} BizIdentityInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + BizIdentityInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.BizIdentityInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.vlevel = reader.int32(); + break; + case 2: + message.vnameCert = $root.proto.VerifiedNameCertificate.decode(reader, reader.uint32()); + break; + case 3: + message.signed = reader.bool(); + break; + case 4: + message.revoked = reader.bool(); + break; + case 5: + message.hostStorage = reader.int32(); + break; + case 6: + message.actualActors = reader.int32(); + break; + case 7: + message.privacyModeTs = reader.uint64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a BizIdentityInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.BizIdentityInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.BizIdentityInfo} BizIdentityInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + BizIdentityInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a BizIdentityInfo message. + * @function verify + * @memberof proto.BizIdentityInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + BizIdentityInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.vlevel != null && message.hasOwnProperty("vlevel")) + switch (message.vlevel) { + default: + return "vlevel: enum value expected"; + case 0: + case 1: + case 2: + break; + } + if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) { + var error = $root.proto.VerifiedNameCertificate.verify(message.vnameCert); + if (error) + return "vnameCert." + error; + } + if (message.signed != null && message.hasOwnProperty("signed")) + if (typeof message.signed !== "boolean") + return "signed: boolean expected"; + if (message.revoked != null && message.hasOwnProperty("revoked")) + if (typeof message.revoked !== "boolean") + return "revoked: boolean expected"; + if (message.hostStorage != null && message.hasOwnProperty("hostStorage")) + switch (message.hostStorage) { + default: + return "hostStorage: enum value expected"; + case 0: + case 1: + break; + } + if (message.actualActors != null && message.hasOwnProperty("actualActors")) + switch (message.actualActors) { + default: + return "actualActors: enum value expected"; + case 0: + case 1: + break; + } + if (message.privacyModeTs != null && message.hasOwnProperty("privacyModeTs")) + if (!$util.isInteger(message.privacyModeTs) && !(message.privacyModeTs && $util.isInteger(message.privacyModeTs.low) && $util.isInteger(message.privacyModeTs.high))) + return "privacyModeTs: integer|Long expected"; + return null; + }; + + /** + * Creates a BizIdentityInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.BizIdentityInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.BizIdentityInfo} BizIdentityInfo + */ + BizIdentityInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.BizIdentityInfo) + return object; + var message = new $root.proto.BizIdentityInfo(); + switch (object.vlevel) { + case "UNKNOWN": + case 0: + message.vlevel = 0; + break; + case "LOW": + case 1: + message.vlevel = 1; + break; + case "HIGH": + case 2: + message.vlevel = 2; + break; + } + if (object.vnameCert != null) { + if (typeof object.vnameCert !== "object") + throw TypeError(".proto.BizIdentityInfo.vnameCert: object expected"); + message.vnameCert = $root.proto.VerifiedNameCertificate.fromObject(object.vnameCert); + } + if (object.signed != null) + message.signed = Boolean(object.signed); + if (object.revoked != null) + message.revoked = Boolean(object.revoked); + switch (object.hostStorage) { + case "ON_PREMISE": + case 0: + message.hostStorage = 0; + break; + case "FACEBOOK": + case 1: + message.hostStorage = 1; + break; + } + switch (object.actualActors) { + case "SELF": + case 0: + message.actualActors = 0; + break; + case "BSP": + case 1: + message.actualActors = 1; + break; + } + if (object.privacyModeTs != null) + if ($util.Long) + (message.privacyModeTs = $util.Long.fromValue(object.privacyModeTs)).unsigned = true; + else if (typeof object.privacyModeTs === "string") + message.privacyModeTs = parseInt(object.privacyModeTs, 10); + else if (typeof object.privacyModeTs === "number") + message.privacyModeTs = object.privacyModeTs; + else if (typeof object.privacyModeTs === "object") + message.privacyModeTs = new $util.LongBits(object.privacyModeTs.low >>> 0, object.privacyModeTs.high >>> 0).toNumber(true); + return message; + }; + + /** + * Creates a plain object from a BizIdentityInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.BizIdentityInfo + * @static + * @param {proto.BizIdentityInfo} message BizIdentityInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + BizIdentityInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.vlevel = options.enums === String ? "UNKNOWN" : 0; + object.vnameCert = null; + object.signed = false; + object.revoked = false; + object.hostStorage = options.enums === String ? "ON_PREMISE" : 0; + object.actualActors = options.enums === String ? "SELF" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.privacyModeTs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.privacyModeTs = options.longs === String ? "0" : 0; + } + if (message.vlevel != null && message.hasOwnProperty("vlevel")) + object.vlevel = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue[message.vlevel] : message.vlevel; + if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) + object.vnameCert = $root.proto.VerifiedNameCertificate.toObject(message.vnameCert, options); + if (message.signed != null && message.hasOwnProperty("signed")) + object.signed = message.signed; + if (message.revoked != null && message.hasOwnProperty("revoked")) + object.revoked = message.revoked; + if (message.hostStorage != null && message.hasOwnProperty("hostStorage")) + object.hostStorage = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoHostStorageType[message.hostStorage] : message.hostStorage; + if (message.actualActors != null && message.hasOwnProperty("actualActors")) + object.actualActors = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoActualActorsType[message.actualActors] : message.actualActors; + if (message.privacyModeTs != null && message.hasOwnProperty("privacyModeTs")) + if (typeof message.privacyModeTs === "number") + object.privacyModeTs = options.longs === String ? String(message.privacyModeTs) : message.privacyModeTs; + else + object.privacyModeTs = options.longs === String ? $util.Long.prototype.toString.call(message.privacyModeTs) : options.longs === Number ? new $util.LongBits(message.privacyModeTs.low >>> 0, message.privacyModeTs.high >>> 0).toNumber(true) : message.privacyModeTs; + return object; + }; + + /** + * Converts this BizIdentityInfo to JSON. + * @function toJSON + * @memberof proto.BizIdentityInfo + * @instance + * @returns {Object.} JSON object + */ + BizIdentityInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * BizIdentityInfoVerifiedLevelValue enum. + * @name proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue + * @enum {number} + * @property {number} UNKNOWN=0 UNKNOWN value + * @property {number} LOW=1 LOW value + * @property {number} HIGH=2 HIGH value + */ + BizIdentityInfo.BizIdentityInfoVerifiedLevelValue = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN"] = 0; + values[valuesById[1] = "LOW"] = 1; + values[valuesById[2] = "HIGH"] = 2; + return values; + })(); + + /** + * BizIdentityInfoHostStorageType enum. + * @name proto.BizIdentityInfo.BizIdentityInfoHostStorageType + * @enum {number} + * @property {number} ON_PREMISE=0 ON_PREMISE value + * @property {number} FACEBOOK=1 FACEBOOK value + */ + BizIdentityInfo.BizIdentityInfoHostStorageType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "ON_PREMISE"] = 0; + values[valuesById[1] = "FACEBOOK"] = 1; + return values; + })(); + + /** + * BizIdentityInfoActualActorsType enum. + * @name proto.BizIdentityInfo.BizIdentityInfoActualActorsType + * @enum {number} + * @property {number} SELF=0 SELF value + * @property {number} BSP=1 BSP value + */ + BizIdentityInfo.BizIdentityInfoActualActorsType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "SELF"] = 0; + values[valuesById[1] = "BSP"] = 1; + return values; + })(); + + return BizIdentityInfo; + })(); + + proto.BizAccountLinkInfo = (function() { + + /** + * Properties of a BizAccountLinkInfo. + * @memberof proto + * @interface IBizAccountLinkInfo + * @property {number|Long|null} [whatsappBizAcctFbid] BizAccountLinkInfo whatsappBizAcctFbid + * @property {string|null} [whatsappAcctNumber] BizAccountLinkInfo whatsappAcctNumber + * @property {number|Long|null} [issueTime] BizAccountLinkInfo issueTime + * @property {proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType|null} [hostStorage] BizAccountLinkInfo hostStorage + * @property {proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType|null} [accountType] BizAccountLinkInfo accountType + */ + + /** + * Constructs a new BizAccountLinkInfo. + * @memberof proto + * @classdesc Represents a BizAccountLinkInfo. + * @implements IBizAccountLinkInfo + * @constructor + * @param {proto.IBizAccountLinkInfo=} [properties] Properties to set + */ + function BizAccountLinkInfo(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * BizAccountLinkInfo whatsappBizAcctFbid. + * @member {number|Long} whatsappBizAcctFbid + * @memberof proto.BizAccountLinkInfo + * @instance + */ + BizAccountLinkInfo.prototype.whatsappBizAcctFbid = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * BizAccountLinkInfo whatsappAcctNumber. + * @member {string} whatsappAcctNumber + * @memberof proto.BizAccountLinkInfo + * @instance + */ + BizAccountLinkInfo.prototype.whatsappAcctNumber = ""; + + /** + * BizAccountLinkInfo issueTime. + * @member {number|Long} issueTime + * @memberof proto.BizAccountLinkInfo + * @instance + */ + BizAccountLinkInfo.prototype.issueTime = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * BizAccountLinkInfo hostStorage. + * @member {proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType} hostStorage + * @memberof proto.BizAccountLinkInfo + * @instance + */ + BizAccountLinkInfo.prototype.hostStorage = 0; + + /** + * BizAccountLinkInfo accountType. + * @member {proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType} accountType + * @memberof proto.BizAccountLinkInfo + * @instance + */ + BizAccountLinkInfo.prototype.accountType = 0; + + /** + * Creates a new BizAccountLinkInfo instance using the specified properties. + * @function create + * @memberof proto.BizAccountLinkInfo + * @static + * @param {proto.IBizAccountLinkInfo=} [properties] Properties to set + * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo instance + */ + BizAccountLinkInfo.create = function create(properties) { + return new BizAccountLinkInfo(properties); + }; + + /** + * Encodes the specified BizAccountLinkInfo message. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages. + * @function encode + * @memberof proto.BizAccountLinkInfo + * @static + * @param {proto.IBizAccountLinkInfo} message BizAccountLinkInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + BizAccountLinkInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.whatsappBizAcctFbid != null && Object.hasOwnProperty.call(message, "whatsappBizAcctFbid")) + writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.whatsappBizAcctFbid); + if (message.whatsappAcctNumber != null && Object.hasOwnProperty.call(message, "whatsappAcctNumber")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.whatsappAcctNumber); + if (message.issueTime != null && Object.hasOwnProperty.call(message, "issueTime")) + writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.issueTime); + if (message.hostStorage != null && Object.hasOwnProperty.call(message, "hostStorage")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.hostStorage); + if (message.accountType != null && Object.hasOwnProperty.call(message, "accountType")) + writer.uint32(/* id 5, wireType 0 =*/40).int32(message.accountType); + return writer; + }; + + /** + * Encodes the specified BizAccountLinkInfo message, length delimited. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.BizAccountLinkInfo + * @static + * @param {proto.IBizAccountLinkInfo} message BizAccountLinkInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + BizAccountLinkInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a BizAccountLinkInfo message from the specified reader or buffer. + * @function decode + * @memberof proto.BizAccountLinkInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + BizAccountLinkInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.BizAccountLinkInfo(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.whatsappBizAcctFbid = reader.uint64(); + break; + case 2: + message.whatsappAcctNumber = reader.string(); + break; + case 3: + message.issueTime = reader.uint64(); + break; + case 4: + message.hostStorage = reader.int32(); + break; + case 5: + message.accountType = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a BizAccountLinkInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.BizAccountLinkInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + BizAccountLinkInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a BizAccountLinkInfo message. + * @function verify + * @memberof proto.BizAccountLinkInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + BizAccountLinkInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.whatsappBizAcctFbid != null && message.hasOwnProperty("whatsappBizAcctFbid")) + if (!$util.isInteger(message.whatsappBizAcctFbid) && !(message.whatsappBizAcctFbid && $util.isInteger(message.whatsappBizAcctFbid.low) && $util.isInteger(message.whatsappBizAcctFbid.high))) + return "whatsappBizAcctFbid: integer|Long expected"; + if (message.whatsappAcctNumber != null && message.hasOwnProperty("whatsappAcctNumber")) + if (!$util.isString(message.whatsappAcctNumber)) + return "whatsappAcctNumber: string expected"; + if (message.issueTime != null && message.hasOwnProperty("issueTime")) + if (!$util.isInteger(message.issueTime) && !(message.issueTime && $util.isInteger(message.issueTime.low) && $util.isInteger(message.issueTime.high))) + return "issueTime: integer|Long expected"; + if (message.hostStorage != null && message.hasOwnProperty("hostStorage")) + switch (message.hostStorage) { + default: + return "hostStorage: enum value expected"; + case 0: + case 1: + break; + } + if (message.accountType != null && message.hasOwnProperty("accountType")) + switch (message.accountType) { + default: + return "accountType: enum value expected"; + case 0: + case 1: + break; + } + return null; + }; + + /** + * Creates a BizAccountLinkInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.BizAccountLinkInfo + * @static + * @param {Object.} object Plain object + * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo + */ + BizAccountLinkInfo.fromObject = function fromObject(object) { + if (object instanceof $root.proto.BizAccountLinkInfo) + return object; + var message = new $root.proto.BizAccountLinkInfo(); + if (object.whatsappBizAcctFbid != null) + if ($util.Long) + (message.whatsappBizAcctFbid = $util.Long.fromValue(object.whatsappBizAcctFbid)).unsigned = true; + else if (typeof object.whatsappBizAcctFbid === "string") + message.whatsappBizAcctFbid = parseInt(object.whatsappBizAcctFbid, 10); + else if (typeof object.whatsappBizAcctFbid === "number") + message.whatsappBizAcctFbid = object.whatsappBizAcctFbid; + else if (typeof object.whatsappBizAcctFbid === "object") + message.whatsappBizAcctFbid = new $util.LongBits(object.whatsappBizAcctFbid.low >>> 0, object.whatsappBizAcctFbid.high >>> 0).toNumber(true); + if (object.whatsappAcctNumber != null) + message.whatsappAcctNumber = String(object.whatsappAcctNumber); + if (object.issueTime != null) + if ($util.Long) + (message.issueTime = $util.Long.fromValue(object.issueTime)).unsigned = true; + else if (typeof object.issueTime === "string") + message.issueTime = parseInt(object.issueTime, 10); + else if (typeof object.issueTime === "number") + message.issueTime = object.issueTime; + else if (typeof object.issueTime === "object") + message.issueTime = new $util.LongBits(object.issueTime.low >>> 0, object.issueTime.high >>> 0).toNumber(true); + switch (object.hostStorage) { + case "ON_PREMISE": + case 0: + message.hostStorage = 0; + break; + case "FACEBOOK": + case 1: + message.hostStorage = 1; + break; + } + switch (object.accountType) { + case "ENTERPRISE": + case 0: + message.accountType = 0; + break; + case "PAGE": + case 1: + message.accountType = 1; + break; + } + return message; + }; + + /** + * Creates a plain object from a BizAccountLinkInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.BizAccountLinkInfo + * @static + * @param {proto.BizAccountLinkInfo} message BizAccountLinkInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + BizAccountLinkInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.whatsappBizAcctFbid = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.whatsappBizAcctFbid = options.longs === String ? "0" : 0; + object.whatsappAcctNumber = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.issueTime = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.issueTime = options.longs === String ? "0" : 0; + object.hostStorage = options.enums === String ? "ON_PREMISE" : 0; + object.accountType = options.enums === String ? "ENTERPRISE" : 0; + } + if (message.whatsappBizAcctFbid != null && message.hasOwnProperty("whatsappBizAcctFbid")) + if (typeof message.whatsappBizAcctFbid === "number") + object.whatsappBizAcctFbid = options.longs === String ? String(message.whatsappBizAcctFbid) : message.whatsappBizAcctFbid; + else + object.whatsappBizAcctFbid = options.longs === String ? $util.Long.prototype.toString.call(message.whatsappBizAcctFbid) : options.longs === Number ? new $util.LongBits(message.whatsappBizAcctFbid.low >>> 0, message.whatsappBizAcctFbid.high >>> 0).toNumber(true) : message.whatsappBizAcctFbid; + if (message.whatsappAcctNumber != null && message.hasOwnProperty("whatsappAcctNumber")) + object.whatsappAcctNumber = message.whatsappAcctNumber; + if (message.issueTime != null && message.hasOwnProperty("issueTime")) + if (typeof message.issueTime === "number") + object.issueTime = options.longs === String ? String(message.issueTime) : message.issueTime; + else + object.issueTime = options.longs === String ? $util.Long.prototype.toString.call(message.issueTime) : options.longs === Number ? new $util.LongBits(message.issueTime.low >>> 0, message.issueTime.high >>> 0).toNumber(true) : message.issueTime; + if (message.hostStorage != null && message.hasOwnProperty("hostStorage")) + object.hostStorage = options.enums === String ? $root.proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType[message.hostStorage] : message.hostStorage; + if (message.accountType != null && message.hasOwnProperty("accountType")) + object.accountType = options.enums === String ? $root.proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType[message.accountType] : message.accountType; + return object; + }; + + /** + * Converts this BizAccountLinkInfo to JSON. + * @function toJSON + * @memberof proto.BizAccountLinkInfo + * @instance + * @returns {Object.} JSON object + */ + BizAccountLinkInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * BizAccountLinkInfoHostStorageType enum. + * @name proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType + * @enum {number} + * @property {number} ON_PREMISE=0 ON_PREMISE value + * @property {number} FACEBOOK=1 FACEBOOK value + */ + BizAccountLinkInfo.BizAccountLinkInfoHostStorageType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "ON_PREMISE"] = 0; + values[valuesById[1] = "FACEBOOK"] = 1; + return values; + })(); + + /** + * BizAccountLinkInfoAccountType enum. + * @name proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType + * @enum {number} + * @property {number} ENTERPRISE=0 ENTERPRISE value + * @property {number} PAGE=1 PAGE value + */ + BizAccountLinkInfo.BizAccountLinkInfoAccountType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "ENTERPRISE"] = 0; + values[valuesById[1] = "PAGE"] = 1; + return values; + })(); + + return BizAccountLinkInfo; + })(); + + proto.BizAccountPayload = (function() { + + /** + * Properties of a BizAccountPayload. + * @memberof proto + * @interface IBizAccountPayload + * @property {proto.IVerifiedNameCertificate|null} [vnameCert] BizAccountPayload vnameCert + * @property {Uint8Array|null} [bizAcctLinkInfo] BizAccountPayload bizAcctLinkInfo + */ + + /** + * Constructs a new BizAccountPayload. + * @memberof proto + * @classdesc Represents a BizAccountPayload. + * @implements IBizAccountPayload + * @constructor + * @param {proto.IBizAccountPayload=} [properties] Properties to set + */ + function BizAccountPayload(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * BizAccountPayload vnameCert. + * @member {proto.IVerifiedNameCertificate|null|undefined} vnameCert + * @memberof proto.BizAccountPayload + * @instance + */ + BizAccountPayload.prototype.vnameCert = null; + + /** + * BizAccountPayload bizAcctLinkInfo. + * @member {Uint8Array} bizAcctLinkInfo + * @memberof proto.BizAccountPayload + * @instance + */ + BizAccountPayload.prototype.bizAcctLinkInfo = $util.newBuffer([]); + + /** + * Creates a new BizAccountPayload instance using the specified properties. + * @function create + * @memberof proto.BizAccountPayload + * @static + * @param {proto.IBizAccountPayload=} [properties] Properties to set + * @returns {proto.BizAccountPayload} BizAccountPayload instance + */ + BizAccountPayload.create = function create(properties) { + return new BizAccountPayload(properties); + }; + + /** + * Encodes the specified BizAccountPayload message. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages. + * @function encode + * @memberof proto.BizAccountPayload + * @static + * @param {proto.IBizAccountPayload} message BizAccountPayload message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + BizAccountPayload.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.vnameCert != null && Object.hasOwnProperty.call(message, "vnameCert")) + $root.proto.VerifiedNameCertificate.encode(message.vnameCert, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.bizAcctLinkInfo != null && Object.hasOwnProperty.call(message, "bizAcctLinkInfo")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.bizAcctLinkInfo); + return writer; + }; + + /** + * Encodes the specified BizAccountPayload message, length delimited. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.BizAccountPayload + * @static + * @param {proto.IBizAccountPayload} message BizAccountPayload message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + BizAccountPayload.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a BizAccountPayload message from the specified reader or buffer. + * @function decode + * @memberof proto.BizAccountPayload + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.BizAccountPayload} BizAccountPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + BizAccountPayload.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.BizAccountPayload(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.vnameCert = $root.proto.VerifiedNameCertificate.decode(reader, reader.uint32()); + break; + case 2: + message.bizAcctLinkInfo = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a BizAccountPayload message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.BizAccountPayload + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.BizAccountPayload} BizAccountPayload + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + BizAccountPayload.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a BizAccountPayload message. + * @function verify + * @memberof proto.BizAccountPayload + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + BizAccountPayload.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) { + var error = $root.proto.VerifiedNameCertificate.verify(message.vnameCert); + if (error) + return "vnameCert." + error; + } + if (message.bizAcctLinkInfo != null && message.hasOwnProperty("bizAcctLinkInfo")) + if (!(message.bizAcctLinkInfo && typeof message.bizAcctLinkInfo.length === "number" || $util.isString(message.bizAcctLinkInfo))) + return "bizAcctLinkInfo: buffer expected"; + return null; + }; + + /** + * Creates a BizAccountPayload message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.BizAccountPayload + * @static + * @param {Object.} object Plain object + * @returns {proto.BizAccountPayload} BizAccountPayload + */ + BizAccountPayload.fromObject = function fromObject(object) { + if (object instanceof $root.proto.BizAccountPayload) + return object; + var message = new $root.proto.BizAccountPayload(); + if (object.vnameCert != null) { + if (typeof object.vnameCert !== "object") + throw TypeError(".proto.BizAccountPayload.vnameCert: object expected"); + message.vnameCert = $root.proto.VerifiedNameCertificate.fromObject(object.vnameCert); + } + if (object.bizAcctLinkInfo != null) + if (typeof object.bizAcctLinkInfo === "string") + $util.base64.decode(object.bizAcctLinkInfo, message.bizAcctLinkInfo = $util.newBuffer($util.base64.length(object.bizAcctLinkInfo)), 0); + else if (object.bizAcctLinkInfo.length) + message.bizAcctLinkInfo = object.bizAcctLinkInfo; + return message; + }; + + /** + * Creates a plain object from a BizAccountPayload message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.BizAccountPayload + * @static + * @param {proto.BizAccountPayload} message BizAccountPayload + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + BizAccountPayload.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.vnameCert = null; + if (options.bytes === String) + object.bizAcctLinkInfo = ""; + else { + object.bizAcctLinkInfo = []; + if (options.bytes !== Array) + object.bizAcctLinkInfo = $util.newBuffer(object.bizAcctLinkInfo); + } + } + if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) + object.vnameCert = $root.proto.VerifiedNameCertificate.toObject(message.vnameCert, options); + if (message.bizAcctLinkInfo != null && message.hasOwnProperty("bizAcctLinkInfo")) + object.bizAcctLinkInfo = options.bytes === String ? $util.base64.encode(message.bizAcctLinkInfo, 0, message.bizAcctLinkInfo.length) : options.bytes === Array ? Array.prototype.slice.call(message.bizAcctLinkInfo) : message.bizAcctLinkInfo; + return object; + }; + + /** + * Converts this BizAccountPayload to JSON. + * @function toJSON + * @memberof proto.BizAccountPayload + * @instance + * @returns {Object.} JSON object + */ + BizAccountPayload.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return BizAccountPayload; + })(); + + proto.VerifiedNameCertificate = (function() { + + /** + * Properties of a VerifiedNameCertificate. + * @memberof proto + * @interface IVerifiedNameCertificate + * @property {Uint8Array|null} [details] VerifiedNameCertificate details + * @property {Uint8Array|null} [signature] VerifiedNameCertificate signature + * @property {Uint8Array|null} [serverSignature] VerifiedNameCertificate serverSignature + */ + + /** + * Constructs a new VerifiedNameCertificate. + * @memberof proto + * @classdesc Represents a VerifiedNameCertificate. + * @implements IVerifiedNameCertificate + * @constructor + * @param {proto.IVerifiedNameCertificate=} [properties] Properties to set + */ + function VerifiedNameCertificate(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * VerifiedNameCertificate details. + * @member {Uint8Array} details + * @memberof proto.VerifiedNameCertificate + * @instance + */ + VerifiedNameCertificate.prototype.details = $util.newBuffer([]); + + /** + * VerifiedNameCertificate signature. + * @member {Uint8Array} signature + * @memberof proto.VerifiedNameCertificate + * @instance + */ + VerifiedNameCertificate.prototype.signature = $util.newBuffer([]); + + /** + * VerifiedNameCertificate serverSignature. + * @member {Uint8Array} serverSignature + * @memberof proto.VerifiedNameCertificate + * @instance + */ + VerifiedNameCertificate.prototype.serverSignature = $util.newBuffer([]); + + /** + * Creates a new VerifiedNameCertificate instance using the specified properties. + * @function create + * @memberof proto.VerifiedNameCertificate + * @static + * @param {proto.IVerifiedNameCertificate=} [properties] Properties to set + * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate instance + */ + VerifiedNameCertificate.create = function create(properties) { + return new VerifiedNameCertificate(properties); + }; + + /** + * Encodes the specified VerifiedNameCertificate message. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages. + * @function encode + * @memberof proto.VerifiedNameCertificate + * @static + * @param {proto.IVerifiedNameCertificate} message VerifiedNameCertificate message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + VerifiedNameCertificate.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.details != null && Object.hasOwnProperty.call(message, "details")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); + if (message.signature != null && Object.hasOwnProperty.call(message, "signature")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.signature); + if (message.serverSignature != null && Object.hasOwnProperty.call(message, "serverSignature")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.serverSignature); + return writer; + }; + + /** + * Encodes the specified VerifiedNameCertificate message, length delimited. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.VerifiedNameCertificate + * @static + * @param {proto.IVerifiedNameCertificate} message VerifiedNameCertificate message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + VerifiedNameCertificate.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a VerifiedNameCertificate message from the specified reader or buffer. + * @function decode + * @memberof proto.VerifiedNameCertificate + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + VerifiedNameCertificate.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.VerifiedNameCertificate(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.details = reader.bytes(); + break; + case 2: + message.signature = reader.bytes(); + break; + case 3: + message.serverSignature = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a VerifiedNameCertificate message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.VerifiedNameCertificate + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + VerifiedNameCertificate.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a VerifiedNameCertificate message. + * @function verify + * @memberof proto.VerifiedNameCertificate + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + VerifiedNameCertificate.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.details != null && message.hasOwnProperty("details")) + if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) + return "details: buffer expected"; + if (message.signature != null && message.hasOwnProperty("signature")) + if (!(message.signature && typeof message.signature.length === "number" || $util.isString(message.signature))) + return "signature: buffer expected"; + if (message.serverSignature != null && message.hasOwnProperty("serverSignature")) + if (!(message.serverSignature && typeof message.serverSignature.length === "number" || $util.isString(message.serverSignature))) + return "serverSignature: buffer expected"; + return null; + }; + + /** + * Creates a VerifiedNameCertificate message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.VerifiedNameCertificate + * @static + * @param {Object.} object Plain object + * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate + */ + VerifiedNameCertificate.fromObject = function fromObject(object) { + if (object instanceof $root.proto.VerifiedNameCertificate) + return object; + var message = new $root.proto.VerifiedNameCertificate(); + if (object.details != null) + if (typeof object.details === "string") + $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); + else if (object.details.length) + message.details = object.details; + if (object.signature != null) + if (typeof object.signature === "string") + $util.base64.decode(object.signature, message.signature = $util.newBuffer($util.base64.length(object.signature)), 0); + else if (object.signature.length) + message.signature = object.signature; + if (object.serverSignature != null) + if (typeof object.serverSignature === "string") + $util.base64.decode(object.serverSignature, message.serverSignature = $util.newBuffer($util.base64.length(object.serverSignature)), 0); + else if (object.serverSignature.length) + message.serverSignature = object.serverSignature; + return message; + }; + + /** + * Creates a plain object from a VerifiedNameCertificate message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.VerifiedNameCertificate + * @static + * @param {proto.VerifiedNameCertificate} message VerifiedNameCertificate + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + VerifiedNameCertificate.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.details = ""; + else { + object.details = []; + if (options.bytes !== Array) + object.details = $util.newBuffer(object.details); + } + if (options.bytes === String) + object.signature = ""; + else { + object.signature = []; + if (options.bytes !== Array) + object.signature = $util.newBuffer(object.signature); + } + if (options.bytes === String) + object.serverSignature = ""; + else { + object.serverSignature = []; + if (options.bytes !== Array) + object.serverSignature = $util.newBuffer(object.serverSignature); + } + } + if (message.details != null && message.hasOwnProperty("details")) + object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; + if (message.signature != null && message.hasOwnProperty("signature")) + object.signature = options.bytes === String ? $util.base64.encode(message.signature, 0, message.signature.length) : options.bytes === Array ? Array.prototype.slice.call(message.signature) : message.signature; + if (message.serverSignature != null && message.hasOwnProperty("serverSignature")) + object.serverSignature = options.bytes === String ? $util.base64.encode(message.serverSignature, 0, message.serverSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.serverSignature) : message.serverSignature; + return object; + }; + + /** + * Converts this VerifiedNameCertificate to JSON. + * @function toJSON + * @memberof proto.VerifiedNameCertificate + * @instance + * @returns {Object.} JSON object + */ + VerifiedNameCertificate.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return VerifiedNameCertificate; + })(); + + proto.LocalizedName = (function() { + + /** + * Properties of a LocalizedName. + * @memberof proto + * @interface ILocalizedName + * @property {string|null} [lg] LocalizedName lg + * @property {string|null} [lc] LocalizedName lc + * @property {string|null} [verifiedName] LocalizedName verifiedName + */ + + /** + * Constructs a new LocalizedName. + * @memberof proto + * @classdesc Represents a LocalizedName. + * @implements ILocalizedName + * @constructor + * @param {proto.ILocalizedName=} [properties] Properties to set + */ + function LocalizedName(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * LocalizedName lg. + * @member {string} lg + * @memberof proto.LocalizedName + * @instance + */ + LocalizedName.prototype.lg = ""; + + /** + * LocalizedName lc. + * @member {string} lc + * @memberof proto.LocalizedName + * @instance + */ + LocalizedName.prototype.lc = ""; + + /** + * LocalizedName verifiedName. + * @member {string} verifiedName + * @memberof proto.LocalizedName + * @instance + */ + LocalizedName.prototype.verifiedName = ""; + + /** + * Creates a new LocalizedName instance using the specified properties. + * @function create + * @memberof proto.LocalizedName + * @static + * @param {proto.ILocalizedName=} [properties] Properties to set + * @returns {proto.LocalizedName} LocalizedName instance + */ + LocalizedName.create = function create(properties) { + return new LocalizedName(properties); + }; + + /** + * Encodes the specified LocalizedName message. Does not implicitly {@link proto.LocalizedName.verify|verify} messages. + * @function encode + * @memberof proto.LocalizedName + * @static + * @param {proto.ILocalizedName} message LocalizedName message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LocalizedName.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.lg != null && Object.hasOwnProperty.call(message, "lg")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.lg); + if (message.lc != null && Object.hasOwnProperty.call(message, "lc")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.lc); + if (message.verifiedName != null && Object.hasOwnProperty.call(message, "verifiedName")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.verifiedName); + return writer; + }; + + /** + * Encodes the specified LocalizedName message, length delimited. Does not implicitly {@link proto.LocalizedName.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.LocalizedName + * @static + * @param {proto.ILocalizedName} message LocalizedName message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LocalizedName.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a LocalizedName message from the specified reader or buffer. + * @function decode + * @memberof proto.LocalizedName + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.LocalizedName} LocalizedName + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LocalizedName.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LocalizedName(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.lg = reader.string(); + break; + case 2: + message.lc = reader.string(); + break; + case 3: + message.verifiedName = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a LocalizedName message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.LocalizedName + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.LocalizedName} LocalizedName + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LocalizedName.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a LocalizedName message. + * @function verify + * @memberof proto.LocalizedName + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + LocalizedName.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.lg != null && message.hasOwnProperty("lg")) + if (!$util.isString(message.lg)) + return "lg: string expected"; + if (message.lc != null && message.hasOwnProperty("lc")) + if (!$util.isString(message.lc)) + return "lc: string expected"; + if (message.verifiedName != null && message.hasOwnProperty("verifiedName")) + if (!$util.isString(message.verifiedName)) + return "verifiedName: string expected"; + return null; + }; + + /** + * Creates a LocalizedName message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.LocalizedName + * @static + * @param {Object.} object Plain object + * @returns {proto.LocalizedName} LocalizedName + */ + LocalizedName.fromObject = function fromObject(object) { + if (object instanceof $root.proto.LocalizedName) + return object; + var message = new $root.proto.LocalizedName(); + if (object.lg != null) + message.lg = String(object.lg); + if (object.lc != null) + message.lc = String(object.lc); + if (object.verifiedName != null) + message.verifiedName = String(object.verifiedName); + return message; + }; + + /** + * Creates a plain object from a LocalizedName message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.LocalizedName + * @static + * @param {proto.LocalizedName} message LocalizedName + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + LocalizedName.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.lg = ""; + object.lc = ""; + object.verifiedName = ""; + } + if (message.lg != null && message.hasOwnProperty("lg")) + object.lg = message.lg; + if (message.lc != null && message.hasOwnProperty("lc")) + object.lc = message.lc; + if (message.verifiedName != null && message.hasOwnProperty("verifiedName")) + object.verifiedName = message.verifiedName; + return object; + }; + + /** + * Converts this LocalizedName to JSON. + * @function toJSON + * @memberof proto.LocalizedName + * @instance + * @returns {Object.} JSON object + */ + LocalizedName.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return LocalizedName; + })(); + + proto.SyncActionData = (function() { + + /** + * Properties of a SyncActionData. + * @memberof proto + * @interface ISyncActionData + * @property {Uint8Array|null} [index] SyncActionData index + * @property {proto.ISyncActionValue|null} [value] SyncActionData value + * @property {Uint8Array|null} [padding] SyncActionData padding + * @property {number|null} [version] SyncActionData version + */ + + /** + * Constructs a new SyncActionData. + * @memberof proto + * @classdesc Represents a SyncActionData. + * @implements ISyncActionData + * @constructor + * @param {proto.ISyncActionData=} [properties] Properties to set + */ + function SyncActionData(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncActionData index. + * @member {Uint8Array} index + * @memberof proto.SyncActionData + * @instance + */ + SyncActionData.prototype.index = $util.newBuffer([]); + + /** + * SyncActionData value. + * @member {proto.ISyncActionValue|null|undefined} value + * @memberof proto.SyncActionData + * @instance + */ + SyncActionData.prototype.value = null; + + /** + * SyncActionData padding. + * @member {Uint8Array} padding + * @memberof proto.SyncActionData + * @instance + */ + SyncActionData.prototype.padding = $util.newBuffer([]); + + /** + * SyncActionData version. + * @member {number} version + * @memberof proto.SyncActionData + * @instance + */ + SyncActionData.prototype.version = 0; + + /** + * Creates a new SyncActionData instance using the specified properties. + * @function create + * @memberof proto.SyncActionData + * @static + * @param {proto.ISyncActionData=} [properties] Properties to set + * @returns {proto.SyncActionData} SyncActionData instance + */ + SyncActionData.create = function create(properties) { + return new SyncActionData(properties); + }; + + /** + * Encodes the specified SyncActionData message. Does not implicitly {@link proto.SyncActionData.verify|verify} messages. + * @function encode + * @memberof proto.SyncActionData + * @static + * @param {proto.ISyncActionData} message SyncActionData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionData.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.index != null && Object.hasOwnProperty.call(message, "index")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.index); + if (message.value != null && Object.hasOwnProperty.call(message, "value")) + $root.proto.SyncActionValue.encode(message.value, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.padding != null && Object.hasOwnProperty.call(message, "padding")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.padding); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.version); + return writer; + }; + + /** + * Encodes the specified SyncActionData message, length delimited. Does not implicitly {@link proto.SyncActionData.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncActionData + * @static + * @param {proto.ISyncActionData} message SyncActionData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionData.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncActionData message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncActionData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncActionData} SyncActionData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionData.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionData(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.index = reader.bytes(); + break; + case 2: + message.value = $root.proto.SyncActionValue.decode(reader, reader.uint32()); + break; + case 3: + message.padding = reader.bytes(); + break; + case 4: + message.version = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncActionData message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncActionData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncActionData} SyncActionData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionData.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncActionData message. + * @function verify + * @memberof proto.SyncActionData + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncActionData.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.index != null && message.hasOwnProperty("index")) + if (!(message.index && typeof message.index.length === "number" || $util.isString(message.index))) + return "index: buffer expected"; + if (message.value != null && message.hasOwnProperty("value")) { + var error = $root.proto.SyncActionValue.verify(message.value); + if (error) + return "value." + error; + } + if (message.padding != null && message.hasOwnProperty("padding")) + if (!(message.padding && typeof message.padding.length === "number" || $util.isString(message.padding))) + return "padding: buffer expected"; + if (message.version != null && message.hasOwnProperty("version")) + if (!$util.isInteger(message.version)) + return "version: integer expected"; + return null; + }; + + /** + * Creates a SyncActionData message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncActionData + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncActionData} SyncActionData + */ + SyncActionData.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncActionData) + return object; + var message = new $root.proto.SyncActionData(); + if (object.index != null) + if (typeof object.index === "string") + $util.base64.decode(object.index, message.index = $util.newBuffer($util.base64.length(object.index)), 0); + else if (object.index.length) + message.index = object.index; + if (object.value != null) { + if (typeof object.value !== "object") + throw TypeError(".proto.SyncActionData.value: object expected"); + message.value = $root.proto.SyncActionValue.fromObject(object.value); + } + if (object.padding != null) + if (typeof object.padding === "string") + $util.base64.decode(object.padding, message.padding = $util.newBuffer($util.base64.length(object.padding)), 0); + else if (object.padding.length) + message.padding = object.padding; + if (object.version != null) + message.version = object.version | 0; + return message; + }; + + /** + * Creates a plain object from a SyncActionData message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncActionData + * @static + * @param {proto.SyncActionData} message SyncActionData + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncActionData.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.index = ""; + else { + object.index = []; + if (options.bytes !== Array) + object.index = $util.newBuffer(object.index); + } + object.value = null; + if (options.bytes === String) + object.padding = ""; + else { + object.padding = []; + if (options.bytes !== Array) + object.padding = $util.newBuffer(object.padding); + } + object.version = 0; + } + if (message.index != null && message.hasOwnProperty("index")) + object.index = options.bytes === String ? $util.base64.encode(message.index, 0, message.index.length) : options.bytes === Array ? Array.prototype.slice.call(message.index) : message.index; + if (message.value != null && message.hasOwnProperty("value")) + object.value = $root.proto.SyncActionValue.toObject(message.value, options); + if (message.padding != null && message.hasOwnProperty("padding")) + object.padding = options.bytes === String ? $util.base64.encode(message.padding, 0, message.padding.length) : options.bytes === Array ? Array.prototype.slice.call(message.padding) : message.padding; + if (message.version != null && message.hasOwnProperty("version")) + object.version = message.version; + return object; + }; + + /** + * Converts this SyncActionData to JSON. + * @function toJSON + * @memberof proto.SyncActionData + * @instance + * @returns {Object.} JSON object + */ + SyncActionData.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncActionData; + })(); + + proto.StarAction = (function() { + + /** + * Properties of a StarAction. + * @memberof proto + * @interface IStarAction + * @property {boolean|null} [starred] StarAction starred + */ + + /** + * Constructs a new StarAction. + * @memberof proto + * @classdesc Represents a StarAction. + * @implements IStarAction + * @constructor + * @param {proto.IStarAction=} [properties] Properties to set + */ + function StarAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * StarAction starred. + * @member {boolean} starred + * @memberof proto.StarAction + * @instance + */ + StarAction.prototype.starred = false; + + /** + * Creates a new StarAction instance using the specified properties. + * @function create + * @memberof proto.StarAction + * @static + * @param {proto.IStarAction=} [properties] Properties to set + * @returns {proto.StarAction} StarAction instance + */ + StarAction.create = function create(properties) { + return new StarAction(properties); + }; + + /** + * Encodes the specified StarAction message. Does not implicitly {@link proto.StarAction.verify|verify} messages. + * @function encode + * @memberof proto.StarAction + * @static + * @param {proto.IStarAction} message StarAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + StarAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.starred != null && Object.hasOwnProperty.call(message, "starred")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.starred); + return writer; + }; + + /** + * Encodes the specified StarAction message, length delimited. Does not implicitly {@link proto.StarAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.StarAction + * @static + * @param {proto.IStarAction} message StarAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + StarAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a StarAction message from the specified reader or buffer. + * @function decode + * @memberof proto.StarAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.StarAction} StarAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + StarAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.StarAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.starred = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a StarAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.StarAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.StarAction} StarAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + StarAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a StarAction message. + * @function verify + * @memberof proto.StarAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + StarAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.starred != null && message.hasOwnProperty("starred")) + if (typeof message.starred !== "boolean") + return "starred: boolean expected"; + return null; + }; + + /** + * Creates a StarAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.StarAction + * @static + * @param {Object.} object Plain object + * @returns {proto.StarAction} StarAction + */ + StarAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.StarAction) + return object; + var message = new $root.proto.StarAction(); + if (object.starred != null) + message.starred = Boolean(object.starred); + return message; + }; + + /** + * Creates a plain object from a StarAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.StarAction + * @static + * @param {proto.StarAction} message StarAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + StarAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.starred = false; + if (message.starred != null && message.hasOwnProperty("starred")) + object.starred = message.starred; + return object; + }; + + /** + * Converts this StarAction to JSON. + * @function toJSON + * @memberof proto.StarAction + * @instance + * @returns {Object.} JSON object + */ + StarAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return StarAction; + })(); + + proto.ContactAction = (function() { + + /** + * Properties of a ContactAction. + * @memberof proto + * @interface IContactAction + * @property {string|null} [fullName] ContactAction fullName + * @property {string|null} [firstName] ContactAction firstName + */ + + /** + * Constructs a new ContactAction. + * @memberof proto + * @classdesc Represents a ContactAction. + * @implements IContactAction + * @constructor + * @param {proto.IContactAction=} [properties] Properties to set + */ + function ContactAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ContactAction fullName. + * @member {string} fullName + * @memberof proto.ContactAction + * @instance + */ + ContactAction.prototype.fullName = ""; + + /** + * ContactAction firstName. + * @member {string} firstName + * @memberof proto.ContactAction + * @instance + */ + ContactAction.prototype.firstName = ""; + + /** + * Creates a new ContactAction instance using the specified properties. + * @function create + * @memberof proto.ContactAction + * @static + * @param {proto.IContactAction=} [properties] Properties to set + * @returns {proto.ContactAction} ContactAction instance + */ + ContactAction.create = function create(properties) { + return new ContactAction(properties); + }; + + /** + * Encodes the specified ContactAction message. Does not implicitly {@link proto.ContactAction.verify|verify} messages. + * @function encode + * @memberof proto.ContactAction + * @static + * @param {proto.IContactAction} message ContactAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ContactAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.fullName != null && Object.hasOwnProperty.call(message, "fullName")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.fullName); + if (message.firstName != null && Object.hasOwnProperty.call(message, "firstName")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.firstName); + return writer; + }; + + /** + * Encodes the specified ContactAction message, length delimited. Does not implicitly {@link proto.ContactAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ContactAction + * @static + * @param {proto.IContactAction} message ContactAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ContactAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ContactAction message from the specified reader or buffer. + * @function decode + * @memberof proto.ContactAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ContactAction} ContactAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ContactAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ContactAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.fullName = reader.string(); + break; + case 2: + message.firstName = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ContactAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ContactAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ContactAction} ContactAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ContactAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ContactAction message. + * @function verify + * @memberof proto.ContactAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ContactAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.fullName != null && message.hasOwnProperty("fullName")) + if (!$util.isString(message.fullName)) + return "fullName: string expected"; + if (message.firstName != null && message.hasOwnProperty("firstName")) + if (!$util.isString(message.firstName)) + return "firstName: string expected"; + return null; + }; + + /** + * Creates a ContactAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ContactAction + * @static + * @param {Object.} object Plain object + * @returns {proto.ContactAction} ContactAction + */ + ContactAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ContactAction) + return object; + var message = new $root.proto.ContactAction(); + if (object.fullName != null) + message.fullName = String(object.fullName); + if (object.firstName != null) + message.firstName = String(object.firstName); + return message; + }; + + /** + * Creates a plain object from a ContactAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ContactAction + * @static + * @param {proto.ContactAction} message ContactAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ContactAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.fullName = ""; + object.firstName = ""; + } + if (message.fullName != null && message.hasOwnProperty("fullName")) + object.fullName = message.fullName; + if (message.firstName != null && message.hasOwnProperty("firstName")) + object.firstName = message.firstName; + return object; + }; + + /** + * Converts this ContactAction to JSON. + * @function toJSON + * @memberof proto.ContactAction + * @instance + * @returns {Object.} JSON object + */ + ContactAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ContactAction; + })(); + + proto.MuteAction = (function() { + + /** + * Properties of a MuteAction. + * @memberof proto + * @interface IMuteAction + * @property {boolean|null} [muted] MuteAction muted + * @property {number|Long|null} [muteEndTimestamp] MuteAction muteEndTimestamp + */ + + /** + * Constructs a new MuteAction. + * @memberof proto + * @classdesc Represents a MuteAction. + * @implements IMuteAction + * @constructor + * @param {proto.IMuteAction=} [properties] Properties to set + */ + function MuteAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MuteAction muted. + * @member {boolean} muted + * @memberof proto.MuteAction + * @instance + */ + MuteAction.prototype.muted = false; + + /** + * MuteAction muteEndTimestamp. + * @member {number|Long} muteEndTimestamp + * @memberof proto.MuteAction + * @instance + */ + MuteAction.prototype.muteEndTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new MuteAction instance using the specified properties. + * @function create + * @memberof proto.MuteAction + * @static + * @param {proto.IMuteAction=} [properties] Properties to set + * @returns {proto.MuteAction} MuteAction instance + */ + MuteAction.create = function create(properties) { + return new MuteAction(properties); + }; + + /** + * Encodes the specified MuteAction message. Does not implicitly {@link proto.MuteAction.verify|verify} messages. + * @function encode + * @memberof proto.MuteAction + * @static + * @param {proto.IMuteAction} message MuteAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MuteAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.muted != null && Object.hasOwnProperty.call(message, "muted")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.muted); + if (message.muteEndTimestamp != null && Object.hasOwnProperty.call(message, "muteEndTimestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.muteEndTimestamp); + return writer; + }; + + /** + * Encodes the specified MuteAction message, length delimited. Does not implicitly {@link proto.MuteAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MuteAction + * @static + * @param {proto.IMuteAction} message MuteAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MuteAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MuteAction message from the specified reader or buffer. + * @function decode + * @memberof proto.MuteAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MuteAction} MuteAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MuteAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MuteAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.muted = reader.bool(); + break; + case 2: + message.muteEndTimestamp = reader.int64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MuteAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MuteAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MuteAction} MuteAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MuteAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MuteAction message. + * @function verify + * @memberof proto.MuteAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MuteAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.muted != null && message.hasOwnProperty("muted")) + if (typeof message.muted !== "boolean") + return "muted: boolean expected"; + if (message.muteEndTimestamp != null && message.hasOwnProperty("muteEndTimestamp")) + if (!$util.isInteger(message.muteEndTimestamp) && !(message.muteEndTimestamp && $util.isInteger(message.muteEndTimestamp.low) && $util.isInteger(message.muteEndTimestamp.high))) + return "muteEndTimestamp: integer|Long expected"; + return null; + }; + + /** + * Creates a MuteAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MuteAction + * @static + * @param {Object.} object Plain object + * @returns {proto.MuteAction} MuteAction + */ + MuteAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MuteAction) + return object; + var message = new $root.proto.MuteAction(); + if (object.muted != null) + message.muted = Boolean(object.muted); + if (object.muteEndTimestamp != null) + if ($util.Long) + (message.muteEndTimestamp = $util.Long.fromValue(object.muteEndTimestamp)).unsigned = false; + else if (typeof object.muteEndTimestamp === "string") + message.muteEndTimestamp = parseInt(object.muteEndTimestamp, 10); + else if (typeof object.muteEndTimestamp === "number") + message.muteEndTimestamp = object.muteEndTimestamp; + else if (typeof object.muteEndTimestamp === "object") + message.muteEndTimestamp = new $util.LongBits(object.muteEndTimestamp.low >>> 0, object.muteEndTimestamp.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from a MuteAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MuteAction + * @static + * @param {proto.MuteAction} message MuteAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MuteAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.muted = false; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.muteEndTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.muteEndTimestamp = options.longs === String ? "0" : 0; + } + if (message.muted != null && message.hasOwnProperty("muted")) + object.muted = message.muted; + if (message.muteEndTimestamp != null && message.hasOwnProperty("muteEndTimestamp")) + if (typeof message.muteEndTimestamp === "number") + object.muteEndTimestamp = options.longs === String ? String(message.muteEndTimestamp) : message.muteEndTimestamp; + else + object.muteEndTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.muteEndTimestamp) : options.longs === Number ? new $util.LongBits(message.muteEndTimestamp.low >>> 0, message.muteEndTimestamp.high >>> 0).toNumber() : message.muteEndTimestamp; + return object; + }; + + /** + * Converts this MuteAction to JSON. + * @function toJSON + * @memberof proto.MuteAction + * @instance + * @returns {Object.} JSON object + */ + MuteAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MuteAction; + })(); + + proto.PinAction = (function() { + + /** + * Properties of a PinAction. + * @memberof proto + * @interface IPinAction + * @property {boolean|null} [pinned] PinAction pinned + */ + + /** + * Constructs a new PinAction. + * @memberof proto + * @classdesc Represents a PinAction. + * @implements IPinAction + * @constructor + * @param {proto.IPinAction=} [properties] Properties to set + */ + function PinAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * PinAction pinned. + * @member {boolean} pinned + * @memberof proto.PinAction + * @instance + */ + PinAction.prototype.pinned = false; + + /** + * Creates a new PinAction instance using the specified properties. + * @function create + * @memberof proto.PinAction + * @static + * @param {proto.IPinAction=} [properties] Properties to set + * @returns {proto.PinAction} PinAction instance + */ + PinAction.create = function create(properties) { + return new PinAction(properties); + }; + + /** + * Encodes the specified PinAction message. Does not implicitly {@link proto.PinAction.verify|verify} messages. + * @function encode + * @memberof proto.PinAction + * @static + * @param {proto.IPinAction} message PinAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PinAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.pinned != null && Object.hasOwnProperty.call(message, "pinned")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.pinned); + return writer; + }; + + /** + * Encodes the specified PinAction message, length delimited. Does not implicitly {@link proto.PinAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.PinAction + * @static + * @param {proto.IPinAction} message PinAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PinAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a PinAction message from the specified reader or buffer. + * @function decode + * @memberof proto.PinAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.PinAction} PinAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PinAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PinAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.pinned = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a PinAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.PinAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.PinAction} PinAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PinAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a PinAction message. + * @function verify + * @memberof proto.PinAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + PinAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.pinned != null && message.hasOwnProperty("pinned")) + if (typeof message.pinned !== "boolean") + return "pinned: boolean expected"; + return null; + }; + + /** + * Creates a PinAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.PinAction + * @static + * @param {Object.} object Plain object + * @returns {proto.PinAction} PinAction + */ + PinAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.PinAction) + return object; + var message = new $root.proto.PinAction(); + if (object.pinned != null) + message.pinned = Boolean(object.pinned); + return message; + }; + + /** + * Creates a plain object from a PinAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.PinAction + * @static + * @param {proto.PinAction} message PinAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + PinAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.pinned = false; + if (message.pinned != null && message.hasOwnProperty("pinned")) + object.pinned = message.pinned; + return object; + }; + + /** + * Converts this PinAction to JSON. + * @function toJSON + * @memberof proto.PinAction + * @instance + * @returns {Object.} JSON object + */ + PinAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return PinAction; + })(); + + proto.SecurityNotificationSetting = (function() { + + /** + * Properties of a SecurityNotificationSetting. + * @memberof proto + * @interface ISecurityNotificationSetting + * @property {boolean|null} [showNotification] SecurityNotificationSetting showNotification + */ + + /** + * Constructs a new SecurityNotificationSetting. + * @memberof proto + * @classdesc Represents a SecurityNotificationSetting. + * @implements ISecurityNotificationSetting + * @constructor + * @param {proto.ISecurityNotificationSetting=} [properties] Properties to set + */ + function SecurityNotificationSetting(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SecurityNotificationSetting showNotification. + * @member {boolean} showNotification + * @memberof proto.SecurityNotificationSetting + * @instance + */ + SecurityNotificationSetting.prototype.showNotification = false; + + /** + * Creates a new SecurityNotificationSetting instance using the specified properties. + * @function create + * @memberof proto.SecurityNotificationSetting + * @static + * @param {proto.ISecurityNotificationSetting=} [properties] Properties to set + * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting instance + */ + SecurityNotificationSetting.create = function create(properties) { + return new SecurityNotificationSetting(properties); + }; + + /** + * Encodes the specified SecurityNotificationSetting message. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages. + * @function encode + * @memberof proto.SecurityNotificationSetting + * @static + * @param {proto.ISecurityNotificationSetting} message SecurityNotificationSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SecurityNotificationSetting.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.showNotification != null && Object.hasOwnProperty.call(message, "showNotification")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.showNotification); + return writer; + }; + + /** + * Encodes the specified SecurityNotificationSetting message, length delimited. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SecurityNotificationSetting + * @static + * @param {proto.ISecurityNotificationSetting} message SecurityNotificationSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SecurityNotificationSetting.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SecurityNotificationSetting message from the specified reader or buffer. + * @function decode + * @memberof proto.SecurityNotificationSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SecurityNotificationSetting.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SecurityNotificationSetting(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.showNotification = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SecurityNotificationSetting message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SecurityNotificationSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SecurityNotificationSetting.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SecurityNotificationSetting message. + * @function verify + * @memberof proto.SecurityNotificationSetting + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SecurityNotificationSetting.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.showNotification != null && message.hasOwnProperty("showNotification")) + if (typeof message.showNotification !== "boolean") + return "showNotification: boolean expected"; + return null; + }; + + /** + * Creates a SecurityNotificationSetting message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SecurityNotificationSetting + * @static + * @param {Object.} object Plain object + * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting + */ + SecurityNotificationSetting.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SecurityNotificationSetting) + return object; + var message = new $root.proto.SecurityNotificationSetting(); + if (object.showNotification != null) + message.showNotification = Boolean(object.showNotification); + return message; + }; + + /** + * Creates a plain object from a SecurityNotificationSetting message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SecurityNotificationSetting + * @static + * @param {proto.SecurityNotificationSetting} message SecurityNotificationSetting + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SecurityNotificationSetting.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.showNotification = false; + if (message.showNotification != null && message.hasOwnProperty("showNotification")) + object.showNotification = message.showNotification; + return object; + }; + + /** + * Converts this SecurityNotificationSetting to JSON. + * @function toJSON + * @memberof proto.SecurityNotificationSetting + * @instance + * @returns {Object.} JSON object + */ + SecurityNotificationSetting.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SecurityNotificationSetting; + })(); + + proto.PushNameSetting = (function() { + + /** + * Properties of a PushNameSetting. + * @memberof proto + * @interface IPushNameSetting + * @property {string|null} [name] PushNameSetting name + */ + + /** + * Constructs a new PushNameSetting. + * @memberof proto + * @classdesc Represents a PushNameSetting. + * @implements IPushNameSetting + * @constructor + * @param {proto.IPushNameSetting=} [properties] Properties to set + */ + function PushNameSetting(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * PushNameSetting name. + * @member {string} name + * @memberof proto.PushNameSetting + * @instance + */ + PushNameSetting.prototype.name = ""; + + /** + * Creates a new PushNameSetting instance using the specified properties. + * @function create + * @memberof proto.PushNameSetting + * @static + * @param {proto.IPushNameSetting=} [properties] Properties to set + * @returns {proto.PushNameSetting} PushNameSetting instance + */ + PushNameSetting.create = function create(properties) { + return new PushNameSetting(properties); + }; + + /** + * Encodes the specified PushNameSetting message. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages. + * @function encode + * @memberof proto.PushNameSetting + * @static + * @param {proto.IPushNameSetting} message PushNameSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PushNameSetting.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.name); + return writer; + }; + + /** + * Encodes the specified PushNameSetting message, length delimited. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.PushNameSetting + * @static + * @param {proto.IPushNameSetting} message PushNameSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PushNameSetting.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a PushNameSetting message from the specified reader or buffer. + * @function decode + * @memberof proto.PushNameSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.PushNameSetting} PushNameSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PushNameSetting.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PushNameSetting(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.name = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a PushNameSetting message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.PushNameSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.PushNameSetting} PushNameSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PushNameSetting.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a PushNameSetting message. + * @function verify + * @memberof proto.PushNameSetting + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + PushNameSetting.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + return null; + }; + + /** + * Creates a PushNameSetting message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.PushNameSetting + * @static + * @param {Object.} object Plain object + * @returns {proto.PushNameSetting} PushNameSetting + */ + PushNameSetting.fromObject = function fromObject(object) { + if (object instanceof $root.proto.PushNameSetting) + return object; + var message = new $root.proto.PushNameSetting(); + if (object.name != null) + message.name = String(object.name); + return message; + }; + + /** + * Creates a plain object from a PushNameSetting message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.PushNameSetting + * @static + * @param {proto.PushNameSetting} message PushNameSetting + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + PushNameSetting.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.name = ""; + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + return object; + }; + + /** + * Converts this PushNameSetting to JSON. + * @function toJSON + * @memberof proto.PushNameSetting + * @instance + * @returns {Object.} JSON object + */ + PushNameSetting.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return PushNameSetting; + })(); + + proto.LocaleSetting = (function() { + + /** + * Properties of a LocaleSetting. + * @memberof proto + * @interface ILocaleSetting + * @property {string|null} [locale] LocaleSetting locale + */ + + /** + * Constructs a new LocaleSetting. + * @memberof proto + * @classdesc Represents a LocaleSetting. + * @implements ILocaleSetting + * @constructor + * @param {proto.ILocaleSetting=} [properties] Properties to set + */ + function LocaleSetting(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * LocaleSetting locale. + * @member {string} locale + * @memberof proto.LocaleSetting + * @instance + */ + LocaleSetting.prototype.locale = ""; + + /** + * Creates a new LocaleSetting instance using the specified properties. + * @function create + * @memberof proto.LocaleSetting + * @static + * @param {proto.ILocaleSetting=} [properties] Properties to set + * @returns {proto.LocaleSetting} LocaleSetting instance + */ + LocaleSetting.create = function create(properties) { + return new LocaleSetting(properties); + }; + + /** + * Encodes the specified LocaleSetting message. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages. + * @function encode + * @memberof proto.LocaleSetting + * @static + * @param {proto.ILocaleSetting} message LocaleSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LocaleSetting.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.locale != null && Object.hasOwnProperty.call(message, "locale")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.locale); + return writer; + }; + + /** + * Encodes the specified LocaleSetting message, length delimited. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.LocaleSetting + * @static + * @param {proto.ILocaleSetting} message LocaleSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LocaleSetting.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a LocaleSetting message from the specified reader or buffer. + * @function decode + * @memberof proto.LocaleSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.LocaleSetting} LocaleSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LocaleSetting.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LocaleSetting(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.locale = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a LocaleSetting message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.LocaleSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.LocaleSetting} LocaleSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LocaleSetting.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a LocaleSetting message. + * @function verify + * @memberof proto.LocaleSetting + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + LocaleSetting.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.locale != null && message.hasOwnProperty("locale")) + if (!$util.isString(message.locale)) + return "locale: string expected"; + return null; + }; + + /** + * Creates a LocaleSetting message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.LocaleSetting + * @static + * @param {Object.} object Plain object + * @returns {proto.LocaleSetting} LocaleSetting + */ + LocaleSetting.fromObject = function fromObject(object) { + if (object instanceof $root.proto.LocaleSetting) + return object; + var message = new $root.proto.LocaleSetting(); + if (object.locale != null) + message.locale = String(object.locale); + return message; + }; + + /** + * Creates a plain object from a LocaleSetting message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.LocaleSetting + * @static + * @param {proto.LocaleSetting} message LocaleSetting + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + LocaleSetting.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.locale = ""; + if (message.locale != null && message.hasOwnProperty("locale")) + object.locale = message.locale; + return object; + }; + + /** + * Converts this LocaleSetting to JSON. + * @function toJSON + * @memberof proto.LocaleSetting + * @instance + * @returns {Object.} JSON object + */ + LocaleSetting.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return LocaleSetting; + })(); + + proto.QuickReplyAction = (function() { + + /** + * Properties of a QuickReplyAction. + * @memberof proto + * @interface IQuickReplyAction + * @property {string|null} [shortcut] QuickReplyAction shortcut + * @property {string|null} [message] QuickReplyAction message + * @property {Array.|null} [keywords] QuickReplyAction keywords + * @property {number|null} [count] QuickReplyAction count + * @property {boolean|null} [deleted] QuickReplyAction deleted + */ + + /** + * Constructs a new QuickReplyAction. + * @memberof proto + * @classdesc Represents a QuickReplyAction. + * @implements IQuickReplyAction + * @constructor + * @param {proto.IQuickReplyAction=} [properties] Properties to set + */ + function QuickReplyAction(properties) { + this.keywords = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * QuickReplyAction shortcut. + * @member {string} shortcut + * @memberof proto.QuickReplyAction + * @instance + */ + QuickReplyAction.prototype.shortcut = ""; + + /** + * QuickReplyAction message. + * @member {string} message + * @memberof proto.QuickReplyAction + * @instance + */ + QuickReplyAction.prototype.message = ""; + + /** + * QuickReplyAction keywords. + * @member {Array.} keywords + * @memberof proto.QuickReplyAction + * @instance + */ + QuickReplyAction.prototype.keywords = $util.emptyArray; + + /** + * QuickReplyAction count. + * @member {number} count + * @memberof proto.QuickReplyAction + * @instance + */ + QuickReplyAction.prototype.count = 0; + + /** + * QuickReplyAction deleted. + * @member {boolean} deleted + * @memberof proto.QuickReplyAction + * @instance + */ + QuickReplyAction.prototype.deleted = false; + + /** + * Creates a new QuickReplyAction instance using the specified properties. + * @function create + * @memberof proto.QuickReplyAction + * @static + * @param {proto.IQuickReplyAction=} [properties] Properties to set + * @returns {proto.QuickReplyAction} QuickReplyAction instance + */ + QuickReplyAction.create = function create(properties) { + return new QuickReplyAction(properties); + }; + + /** + * Encodes the specified QuickReplyAction message. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages. + * @function encode + * @memberof proto.QuickReplyAction + * @static + * @param {proto.IQuickReplyAction} message QuickReplyAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + QuickReplyAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.shortcut != null && Object.hasOwnProperty.call(message, "shortcut")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.shortcut); + if (message.message != null && Object.hasOwnProperty.call(message, "message")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.message); + if (message.keywords != null && message.keywords.length) + for (var i = 0; i < message.keywords.length; ++i) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.keywords[i]); + if (message.count != null && Object.hasOwnProperty.call(message, "count")) + writer.uint32(/* id 4, wireType 0 =*/32).int32(message.count); + if (message.deleted != null && Object.hasOwnProperty.call(message, "deleted")) + writer.uint32(/* id 5, wireType 0 =*/40).bool(message.deleted); + return writer; + }; + + /** + * Encodes the specified QuickReplyAction message, length delimited. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.QuickReplyAction + * @static + * @param {proto.IQuickReplyAction} message QuickReplyAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + QuickReplyAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a QuickReplyAction message from the specified reader or buffer. + * @function decode + * @memberof proto.QuickReplyAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.QuickReplyAction} QuickReplyAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + QuickReplyAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.QuickReplyAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.shortcut = reader.string(); + break; + case 2: + message.message = reader.string(); + break; + case 3: + if (!(message.keywords && message.keywords.length)) + message.keywords = []; + message.keywords.push(reader.string()); + break; + case 4: + message.count = reader.int32(); + break; + case 5: + message.deleted = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a QuickReplyAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.QuickReplyAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.QuickReplyAction} QuickReplyAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + QuickReplyAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a QuickReplyAction message. + * @function verify + * @memberof proto.QuickReplyAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + QuickReplyAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.shortcut != null && message.hasOwnProperty("shortcut")) + if (!$util.isString(message.shortcut)) + return "shortcut: string expected"; + if (message.message != null && message.hasOwnProperty("message")) + if (!$util.isString(message.message)) + return "message: string expected"; + if (message.keywords != null && message.hasOwnProperty("keywords")) { + if (!Array.isArray(message.keywords)) + return "keywords: array expected"; + for (var i = 0; i < message.keywords.length; ++i) + if (!$util.isString(message.keywords[i])) + return "keywords: string[] expected"; + } + if (message.count != null && message.hasOwnProperty("count")) + if (!$util.isInteger(message.count)) + return "count: integer expected"; + if (message.deleted != null && message.hasOwnProperty("deleted")) + if (typeof message.deleted !== "boolean") + return "deleted: boolean expected"; + return null; + }; + + /** + * Creates a QuickReplyAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.QuickReplyAction + * @static + * @param {Object.} object Plain object + * @returns {proto.QuickReplyAction} QuickReplyAction + */ + QuickReplyAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.QuickReplyAction) + return object; + var message = new $root.proto.QuickReplyAction(); + if (object.shortcut != null) + message.shortcut = String(object.shortcut); + if (object.message != null) + message.message = String(object.message); + if (object.keywords) { + if (!Array.isArray(object.keywords)) + throw TypeError(".proto.QuickReplyAction.keywords: array expected"); + message.keywords = []; + for (var i = 0; i < object.keywords.length; ++i) + message.keywords[i] = String(object.keywords[i]); + } + if (object.count != null) + message.count = object.count | 0; + if (object.deleted != null) + message.deleted = Boolean(object.deleted); + return message; + }; + + /** + * Creates a plain object from a QuickReplyAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.QuickReplyAction + * @static + * @param {proto.QuickReplyAction} message QuickReplyAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + QuickReplyAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.keywords = []; + if (options.defaults) { + object.shortcut = ""; + object.message = ""; + object.count = 0; + object.deleted = false; + } + if (message.shortcut != null && message.hasOwnProperty("shortcut")) + object.shortcut = message.shortcut; + if (message.message != null && message.hasOwnProperty("message")) + object.message = message.message; + if (message.keywords && message.keywords.length) { + object.keywords = []; + for (var j = 0; j < message.keywords.length; ++j) + object.keywords[j] = message.keywords[j]; + } + if (message.count != null && message.hasOwnProperty("count")) + object.count = message.count; + if (message.deleted != null && message.hasOwnProperty("deleted")) + object.deleted = message.deleted; + return object; + }; + + /** + * Converts this QuickReplyAction to JSON. + * @function toJSON + * @memberof proto.QuickReplyAction + * @instance + * @returns {Object.} JSON object + */ + QuickReplyAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return QuickReplyAction; + })(); + + proto.LabelAssociationAction = (function() { + + /** + * Properties of a LabelAssociationAction. + * @memberof proto + * @interface ILabelAssociationAction + * @property {boolean|null} [labeled] LabelAssociationAction labeled + */ + + /** + * Constructs a new LabelAssociationAction. + * @memberof proto + * @classdesc Represents a LabelAssociationAction. + * @implements ILabelAssociationAction + * @constructor + * @param {proto.ILabelAssociationAction=} [properties] Properties to set + */ + function LabelAssociationAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * LabelAssociationAction labeled. + * @member {boolean} labeled + * @memberof proto.LabelAssociationAction + * @instance + */ + LabelAssociationAction.prototype.labeled = false; + + /** + * Creates a new LabelAssociationAction instance using the specified properties. + * @function create + * @memberof proto.LabelAssociationAction + * @static + * @param {proto.ILabelAssociationAction=} [properties] Properties to set + * @returns {proto.LabelAssociationAction} LabelAssociationAction instance + */ + LabelAssociationAction.create = function create(properties) { + return new LabelAssociationAction(properties); + }; + + /** + * Encodes the specified LabelAssociationAction message. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages. + * @function encode + * @memberof proto.LabelAssociationAction + * @static + * @param {proto.ILabelAssociationAction} message LabelAssociationAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LabelAssociationAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.labeled != null && Object.hasOwnProperty.call(message, "labeled")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.labeled); + return writer; + }; + + /** + * Encodes the specified LabelAssociationAction message, length delimited. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.LabelAssociationAction + * @static + * @param {proto.ILabelAssociationAction} message LabelAssociationAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LabelAssociationAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a LabelAssociationAction message from the specified reader or buffer. + * @function decode + * @memberof proto.LabelAssociationAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.LabelAssociationAction} LabelAssociationAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LabelAssociationAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LabelAssociationAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.labeled = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a LabelAssociationAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.LabelAssociationAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.LabelAssociationAction} LabelAssociationAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LabelAssociationAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a LabelAssociationAction message. + * @function verify + * @memberof proto.LabelAssociationAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + LabelAssociationAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.labeled != null && message.hasOwnProperty("labeled")) + if (typeof message.labeled !== "boolean") + return "labeled: boolean expected"; + return null; + }; + + /** + * Creates a LabelAssociationAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.LabelAssociationAction + * @static + * @param {Object.} object Plain object + * @returns {proto.LabelAssociationAction} LabelAssociationAction + */ + LabelAssociationAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.LabelAssociationAction) + return object; + var message = new $root.proto.LabelAssociationAction(); + if (object.labeled != null) + message.labeled = Boolean(object.labeled); + return message; + }; + + /** + * Creates a plain object from a LabelAssociationAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.LabelAssociationAction + * @static + * @param {proto.LabelAssociationAction} message LabelAssociationAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + LabelAssociationAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.labeled = false; + if (message.labeled != null && message.hasOwnProperty("labeled")) + object.labeled = message.labeled; + return object; + }; + + /** + * Converts this LabelAssociationAction to JSON. + * @function toJSON + * @memberof proto.LabelAssociationAction + * @instance + * @returns {Object.} JSON object + */ + LabelAssociationAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return LabelAssociationAction; + })(); + + proto.LabelEditAction = (function() { + + /** + * Properties of a LabelEditAction. + * @memberof proto + * @interface ILabelEditAction + * @property {string|null} [name] LabelEditAction name + * @property {number|null} [color] LabelEditAction color + * @property {number|null} [predefinedId] LabelEditAction predefinedId + * @property {boolean|null} [deleted] LabelEditAction deleted + */ + + /** + * Constructs a new LabelEditAction. + * @memberof proto + * @classdesc Represents a LabelEditAction. + * @implements ILabelEditAction + * @constructor + * @param {proto.ILabelEditAction=} [properties] Properties to set + */ + function LabelEditAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * LabelEditAction name. + * @member {string} name + * @memberof proto.LabelEditAction + * @instance + */ + LabelEditAction.prototype.name = ""; + + /** + * LabelEditAction color. + * @member {number} color + * @memberof proto.LabelEditAction + * @instance + */ + LabelEditAction.prototype.color = 0; + + /** + * LabelEditAction predefinedId. + * @member {number} predefinedId + * @memberof proto.LabelEditAction + * @instance + */ + LabelEditAction.prototype.predefinedId = 0; + + /** + * LabelEditAction deleted. + * @member {boolean} deleted + * @memberof proto.LabelEditAction + * @instance + */ + LabelEditAction.prototype.deleted = false; + + /** + * Creates a new LabelEditAction instance using the specified properties. + * @function create + * @memberof proto.LabelEditAction + * @static + * @param {proto.ILabelEditAction=} [properties] Properties to set + * @returns {proto.LabelEditAction} LabelEditAction instance + */ + LabelEditAction.create = function create(properties) { + return new LabelEditAction(properties); + }; + + /** + * Encodes the specified LabelEditAction message. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages. + * @function encode + * @memberof proto.LabelEditAction + * @static + * @param {proto.ILabelEditAction} message LabelEditAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LabelEditAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.name); + if (message.color != null && Object.hasOwnProperty.call(message, "color")) + writer.uint32(/* id 2, wireType 0 =*/16).int32(message.color); + if (message.predefinedId != null && Object.hasOwnProperty.call(message, "predefinedId")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.predefinedId); + if (message.deleted != null && Object.hasOwnProperty.call(message, "deleted")) + writer.uint32(/* id 4, wireType 0 =*/32).bool(message.deleted); + return writer; + }; + + /** + * Encodes the specified LabelEditAction message, length delimited. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.LabelEditAction + * @static + * @param {proto.ILabelEditAction} message LabelEditAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + LabelEditAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a LabelEditAction message from the specified reader or buffer. + * @function decode + * @memberof proto.LabelEditAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.LabelEditAction} LabelEditAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LabelEditAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LabelEditAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.name = reader.string(); + break; + case 2: + message.color = reader.int32(); + break; + case 3: + message.predefinedId = reader.int32(); + break; + case 4: + message.deleted = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a LabelEditAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.LabelEditAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.LabelEditAction} LabelEditAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + LabelEditAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a LabelEditAction message. + * @function verify + * @memberof proto.LabelEditAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + LabelEditAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + if (message.color != null && message.hasOwnProperty("color")) + if (!$util.isInteger(message.color)) + return "color: integer expected"; + if (message.predefinedId != null && message.hasOwnProperty("predefinedId")) + if (!$util.isInteger(message.predefinedId)) + return "predefinedId: integer expected"; + if (message.deleted != null && message.hasOwnProperty("deleted")) + if (typeof message.deleted !== "boolean") + return "deleted: boolean expected"; + return null; + }; + + /** + * Creates a LabelEditAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.LabelEditAction + * @static + * @param {Object.} object Plain object + * @returns {proto.LabelEditAction} LabelEditAction + */ + LabelEditAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.LabelEditAction) + return object; + var message = new $root.proto.LabelEditAction(); + if (object.name != null) + message.name = String(object.name); + if (object.color != null) + message.color = object.color | 0; + if (object.predefinedId != null) + message.predefinedId = object.predefinedId | 0; + if (object.deleted != null) + message.deleted = Boolean(object.deleted); + return message; + }; + + /** + * Creates a plain object from a LabelEditAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.LabelEditAction + * @static + * @param {proto.LabelEditAction} message LabelEditAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + LabelEditAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.name = ""; + object.color = 0; + object.predefinedId = 0; + object.deleted = false; + } + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.color != null && message.hasOwnProperty("color")) + object.color = message.color; + if (message.predefinedId != null && message.hasOwnProperty("predefinedId")) + object.predefinedId = message.predefinedId; + if (message.deleted != null && message.hasOwnProperty("deleted")) + object.deleted = message.deleted; + return object; + }; + + /** + * Converts this LabelEditAction to JSON. + * @function toJSON + * @memberof proto.LabelEditAction + * @instance + * @returns {Object.} JSON object + */ + LabelEditAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return LabelEditAction; + })(); + + proto.RecentStickerWeightsAction = (function() { + + /** + * Properties of a RecentStickerWeightsAction. + * @memberof proto + * @interface IRecentStickerWeightsAction + * @property {Array.|null} [weights] RecentStickerWeightsAction weights + */ + + /** + * Constructs a new RecentStickerWeightsAction. + * @memberof proto + * @classdesc Represents a RecentStickerWeightsAction. + * @implements IRecentStickerWeightsAction + * @constructor + * @param {proto.IRecentStickerWeightsAction=} [properties] Properties to set + */ + function RecentStickerWeightsAction(properties) { + this.weights = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RecentStickerWeightsAction weights. + * @member {Array.} weights + * @memberof proto.RecentStickerWeightsAction + * @instance + */ + RecentStickerWeightsAction.prototype.weights = $util.emptyArray; + + /** + * Creates a new RecentStickerWeightsAction instance using the specified properties. + * @function create + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {proto.IRecentStickerWeightsAction=} [properties] Properties to set + * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction instance + */ + RecentStickerWeightsAction.create = function create(properties) { + return new RecentStickerWeightsAction(properties); + }; + + /** + * Encodes the specified RecentStickerWeightsAction message. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages. + * @function encode + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {proto.IRecentStickerWeightsAction} message RecentStickerWeightsAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentStickerWeightsAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.weights != null && message.weights.length) + for (var i = 0; i < message.weights.length; ++i) + $root.proto.RecentStickerWeight.encode(message.weights[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified RecentStickerWeightsAction message, length delimited. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {proto.IRecentStickerWeightsAction} message RecentStickerWeightsAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentStickerWeightsAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RecentStickerWeightsAction message from the specified reader or buffer. + * @function decode + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentStickerWeightsAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentStickerWeightsAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.weights && message.weights.length)) + message.weights = []; + message.weights.push($root.proto.RecentStickerWeight.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RecentStickerWeightsAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentStickerWeightsAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RecentStickerWeightsAction message. + * @function verify + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RecentStickerWeightsAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.weights != null && message.hasOwnProperty("weights")) { + if (!Array.isArray(message.weights)) + return "weights: array expected"; + for (var i = 0; i < message.weights.length; ++i) { + var error = $root.proto.RecentStickerWeight.verify(message.weights[i]); + if (error) + return "weights." + error; + } + } + return null; + }; + + /** + * Creates a RecentStickerWeightsAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {Object.} object Plain object + * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction + */ + RecentStickerWeightsAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.RecentStickerWeightsAction) + return object; + var message = new $root.proto.RecentStickerWeightsAction(); + if (object.weights) { + if (!Array.isArray(object.weights)) + throw TypeError(".proto.RecentStickerWeightsAction.weights: array expected"); + message.weights = []; + for (var i = 0; i < object.weights.length; ++i) { + if (typeof object.weights[i] !== "object") + throw TypeError(".proto.RecentStickerWeightsAction.weights: object expected"); + message.weights[i] = $root.proto.RecentStickerWeight.fromObject(object.weights[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a RecentStickerWeightsAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.RecentStickerWeightsAction + * @static + * @param {proto.RecentStickerWeightsAction} message RecentStickerWeightsAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RecentStickerWeightsAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.weights = []; + if (message.weights && message.weights.length) { + object.weights = []; + for (var j = 0; j < message.weights.length; ++j) + object.weights[j] = $root.proto.RecentStickerWeight.toObject(message.weights[j], options); + } + return object; + }; + + /** + * Converts this RecentStickerWeightsAction to JSON. + * @function toJSON + * @memberof proto.RecentStickerWeightsAction + * @instance + * @returns {Object.} JSON object + */ + RecentStickerWeightsAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RecentStickerWeightsAction; + })(); + + proto.RecentStickerMetadata = (function() { + + /** + * Properties of a RecentStickerMetadata. + * @memberof proto + * @interface IRecentStickerMetadata + * @property {string|null} [directPath] RecentStickerMetadata directPath + * @property {string|null} [encFilehash] RecentStickerMetadata encFilehash + * @property {string|null} [mediaKey] RecentStickerMetadata mediaKey + * @property {string|null} [stanzaId] RecentStickerMetadata stanzaId + * @property {string|null} [chatJid] RecentStickerMetadata chatJid + * @property {string|null} [participant] RecentStickerMetadata participant + * @property {boolean|null} [isSentByMe] RecentStickerMetadata isSentByMe + */ + + /** + * Constructs a new RecentStickerMetadata. + * @memberof proto + * @classdesc Represents a RecentStickerMetadata. + * @implements IRecentStickerMetadata + * @constructor + * @param {proto.IRecentStickerMetadata=} [properties] Properties to set + */ + function RecentStickerMetadata(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RecentStickerMetadata directPath. + * @member {string} directPath + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.directPath = ""; + + /** + * RecentStickerMetadata encFilehash. + * @member {string} encFilehash + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.encFilehash = ""; + + /** + * RecentStickerMetadata mediaKey. + * @member {string} mediaKey + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.mediaKey = ""; + + /** + * RecentStickerMetadata stanzaId. + * @member {string} stanzaId + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.stanzaId = ""; + + /** + * RecentStickerMetadata chatJid. + * @member {string} chatJid + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.chatJid = ""; + + /** + * RecentStickerMetadata participant. + * @member {string} participant + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.participant = ""; + + /** + * RecentStickerMetadata isSentByMe. + * @member {boolean} isSentByMe + * @memberof proto.RecentStickerMetadata + * @instance + */ + RecentStickerMetadata.prototype.isSentByMe = false; + + /** + * Creates a new RecentStickerMetadata instance using the specified properties. + * @function create + * @memberof proto.RecentStickerMetadata + * @static + * @param {proto.IRecentStickerMetadata=} [properties] Properties to set + * @returns {proto.RecentStickerMetadata} RecentStickerMetadata instance + */ + RecentStickerMetadata.create = function create(properties) { + return new RecentStickerMetadata(properties); + }; + + /** + * Encodes the specified RecentStickerMetadata message. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages. + * @function encode + * @memberof proto.RecentStickerMetadata + * @static + * @param {proto.IRecentStickerMetadata} message RecentStickerMetadata message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentStickerMetadata.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.directPath); + if (message.encFilehash != null && Object.hasOwnProperty.call(message, "encFilehash")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.encFilehash); + if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.mediaKey); + if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.stanzaId); + if (message.chatJid != null && Object.hasOwnProperty.call(message, "chatJid")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.chatJid); + if (message.participant != null && Object.hasOwnProperty.call(message, "participant")) + writer.uint32(/* id 6, wireType 2 =*/50).string(message.participant); + if (message.isSentByMe != null && Object.hasOwnProperty.call(message, "isSentByMe")) + writer.uint32(/* id 7, wireType 0 =*/56).bool(message.isSentByMe); + return writer; + }; + + /** + * Encodes the specified RecentStickerMetadata message, length delimited. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.RecentStickerMetadata + * @static + * @param {proto.IRecentStickerMetadata} message RecentStickerMetadata message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentStickerMetadata.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RecentStickerMetadata message from the specified reader or buffer. + * @function decode + * @memberof proto.RecentStickerMetadata + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.RecentStickerMetadata} RecentStickerMetadata + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentStickerMetadata.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentStickerMetadata(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.directPath = reader.string(); + break; + case 2: + message.encFilehash = reader.string(); + break; + case 3: + message.mediaKey = reader.string(); + break; + case 4: + message.stanzaId = reader.string(); + break; + case 5: + message.chatJid = reader.string(); + break; + case 6: + message.participant = reader.string(); + break; + case 7: + message.isSentByMe = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RecentStickerMetadata message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.RecentStickerMetadata + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.RecentStickerMetadata} RecentStickerMetadata + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentStickerMetadata.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RecentStickerMetadata message. + * @function verify + * @memberof proto.RecentStickerMetadata + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RecentStickerMetadata.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.directPath != null && message.hasOwnProperty("directPath")) + if (!$util.isString(message.directPath)) + return "directPath: string expected"; + if (message.encFilehash != null && message.hasOwnProperty("encFilehash")) + if (!$util.isString(message.encFilehash)) + return "encFilehash: string expected"; + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + if (!$util.isString(message.mediaKey)) + return "mediaKey: string expected"; + if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) + if (!$util.isString(message.stanzaId)) + return "stanzaId: string expected"; + if (message.chatJid != null && message.hasOwnProperty("chatJid")) + if (!$util.isString(message.chatJid)) + return "chatJid: string expected"; + if (message.participant != null && message.hasOwnProperty("participant")) + if (!$util.isString(message.participant)) + return "participant: string expected"; + if (message.isSentByMe != null && message.hasOwnProperty("isSentByMe")) + if (typeof message.isSentByMe !== "boolean") + return "isSentByMe: boolean expected"; + return null; + }; + + /** + * Creates a RecentStickerMetadata message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.RecentStickerMetadata + * @static + * @param {Object.} object Plain object + * @returns {proto.RecentStickerMetadata} RecentStickerMetadata + */ + RecentStickerMetadata.fromObject = function fromObject(object) { + if (object instanceof $root.proto.RecentStickerMetadata) + return object; + var message = new $root.proto.RecentStickerMetadata(); + if (object.directPath != null) + message.directPath = String(object.directPath); + if (object.encFilehash != null) + message.encFilehash = String(object.encFilehash); + if (object.mediaKey != null) + message.mediaKey = String(object.mediaKey); + if (object.stanzaId != null) + message.stanzaId = String(object.stanzaId); + if (object.chatJid != null) + message.chatJid = String(object.chatJid); + if (object.participant != null) + message.participant = String(object.participant); + if (object.isSentByMe != null) + message.isSentByMe = Boolean(object.isSentByMe); + return message; + }; + + /** + * Creates a plain object from a RecentStickerMetadata message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.RecentStickerMetadata + * @static + * @param {proto.RecentStickerMetadata} message RecentStickerMetadata + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RecentStickerMetadata.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.directPath = ""; + object.encFilehash = ""; + object.mediaKey = ""; + object.stanzaId = ""; + object.chatJid = ""; + object.participant = ""; + object.isSentByMe = false; + } + if (message.directPath != null && message.hasOwnProperty("directPath")) + object.directPath = message.directPath; + if (message.encFilehash != null && message.hasOwnProperty("encFilehash")) + object.encFilehash = message.encFilehash; + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + object.mediaKey = message.mediaKey; + if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) + object.stanzaId = message.stanzaId; + if (message.chatJid != null && message.hasOwnProperty("chatJid")) + object.chatJid = message.chatJid; + if (message.participant != null && message.hasOwnProperty("participant")) + object.participant = message.participant; + if (message.isSentByMe != null && message.hasOwnProperty("isSentByMe")) + object.isSentByMe = message.isSentByMe; + return object; + }; + + /** + * Converts this RecentStickerMetadata to JSON. + * @function toJSON + * @memberof proto.RecentStickerMetadata + * @instance + * @returns {Object.} JSON object + */ + RecentStickerMetadata.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RecentStickerMetadata; + })(); + + proto.RecentEmojiWeightsAction = (function() { + + /** + * Properties of a RecentEmojiWeightsAction. + * @memberof proto + * @interface IRecentEmojiWeightsAction + * @property {Array.|null} [weights] RecentEmojiWeightsAction weights + */ + + /** + * Constructs a new RecentEmojiWeightsAction. + * @memberof proto + * @classdesc Represents a RecentEmojiWeightsAction. + * @implements IRecentEmojiWeightsAction + * @constructor + * @param {proto.IRecentEmojiWeightsAction=} [properties] Properties to set + */ + function RecentEmojiWeightsAction(properties) { + this.weights = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RecentEmojiWeightsAction weights. + * @member {Array.} weights + * @memberof proto.RecentEmojiWeightsAction + * @instance + */ + RecentEmojiWeightsAction.prototype.weights = $util.emptyArray; + + /** + * Creates a new RecentEmojiWeightsAction instance using the specified properties. + * @function create + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {proto.IRecentEmojiWeightsAction=} [properties] Properties to set + * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction instance + */ + RecentEmojiWeightsAction.create = function create(properties) { + return new RecentEmojiWeightsAction(properties); + }; + + /** + * Encodes the specified RecentEmojiWeightsAction message. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages. + * @function encode + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {proto.IRecentEmojiWeightsAction} message RecentEmojiWeightsAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentEmojiWeightsAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.weights != null && message.weights.length) + for (var i = 0; i < message.weights.length; ++i) + $root.proto.RecentEmojiWeight.encode(message.weights[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified RecentEmojiWeightsAction message, length delimited. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {proto.IRecentEmojiWeightsAction} message RecentEmojiWeightsAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentEmojiWeightsAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer. + * @function decode + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentEmojiWeightsAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentEmojiWeightsAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.weights && message.weights.length)) + message.weights = []; + message.weights.push($root.proto.RecentEmojiWeight.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentEmojiWeightsAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RecentEmojiWeightsAction message. + * @function verify + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RecentEmojiWeightsAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.weights != null && message.hasOwnProperty("weights")) { + if (!Array.isArray(message.weights)) + return "weights: array expected"; + for (var i = 0; i < message.weights.length; ++i) { + var error = $root.proto.RecentEmojiWeight.verify(message.weights[i]); + if (error) + return "weights." + error; + } + } + return null; + }; + + /** + * Creates a RecentEmojiWeightsAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {Object.} object Plain object + * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction + */ + RecentEmojiWeightsAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.RecentEmojiWeightsAction) + return object; + var message = new $root.proto.RecentEmojiWeightsAction(); + if (object.weights) { + if (!Array.isArray(object.weights)) + throw TypeError(".proto.RecentEmojiWeightsAction.weights: array expected"); + message.weights = []; + for (var i = 0; i < object.weights.length; ++i) { + if (typeof object.weights[i] !== "object") + throw TypeError(".proto.RecentEmojiWeightsAction.weights: object expected"); + message.weights[i] = $root.proto.RecentEmojiWeight.fromObject(object.weights[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a RecentEmojiWeightsAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.RecentEmojiWeightsAction + * @static + * @param {proto.RecentEmojiWeightsAction} message RecentEmojiWeightsAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RecentEmojiWeightsAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.weights = []; + if (message.weights && message.weights.length) { + object.weights = []; + for (var j = 0; j < message.weights.length; ++j) + object.weights[j] = $root.proto.RecentEmojiWeight.toObject(message.weights[j], options); + } + return object; + }; + + /** + * Converts this RecentEmojiWeightsAction to JSON. + * @function toJSON + * @memberof proto.RecentEmojiWeightsAction + * @instance + * @returns {Object.} JSON object + */ + RecentEmojiWeightsAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RecentEmojiWeightsAction; + })(); + + proto.ArchiveChatAction = (function() { + + /** + * Properties of an ArchiveChatAction. + * @memberof proto + * @interface IArchiveChatAction + * @property {boolean|null} [archived] ArchiveChatAction archived + * @property {proto.ISyncActionMessageRange|null} [messageRange] ArchiveChatAction messageRange + */ + + /** + * Constructs a new ArchiveChatAction. + * @memberof proto + * @classdesc Represents an ArchiveChatAction. + * @implements IArchiveChatAction + * @constructor + * @param {proto.IArchiveChatAction=} [properties] Properties to set + */ + function ArchiveChatAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ArchiveChatAction archived. + * @member {boolean} archived + * @memberof proto.ArchiveChatAction + * @instance + */ + ArchiveChatAction.prototype.archived = false; + + /** + * ArchiveChatAction messageRange. + * @member {proto.ISyncActionMessageRange|null|undefined} messageRange + * @memberof proto.ArchiveChatAction + * @instance + */ + ArchiveChatAction.prototype.messageRange = null; + + /** + * Creates a new ArchiveChatAction instance using the specified properties. + * @function create + * @memberof proto.ArchiveChatAction + * @static + * @param {proto.IArchiveChatAction=} [properties] Properties to set + * @returns {proto.ArchiveChatAction} ArchiveChatAction instance + */ + ArchiveChatAction.create = function create(properties) { + return new ArchiveChatAction(properties); + }; + + /** + * Encodes the specified ArchiveChatAction message. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages. + * @function encode + * @memberof proto.ArchiveChatAction + * @static + * @param {proto.IArchiveChatAction} message ArchiveChatAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ArchiveChatAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.archived != null && Object.hasOwnProperty.call(message, "archived")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.archived); + if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange")) + $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified ArchiveChatAction message, length delimited. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ArchiveChatAction + * @static + * @param {proto.IArchiveChatAction} message ArchiveChatAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ArchiveChatAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an ArchiveChatAction message from the specified reader or buffer. + * @function decode + * @memberof proto.ArchiveChatAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ArchiveChatAction} ArchiveChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ArchiveChatAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ArchiveChatAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.archived = reader.bool(); + break; + case 2: + message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an ArchiveChatAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ArchiveChatAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ArchiveChatAction} ArchiveChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ArchiveChatAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an ArchiveChatAction message. + * @function verify + * @memberof proto.ArchiveChatAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ArchiveChatAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.archived != null && message.hasOwnProperty("archived")) + if (typeof message.archived !== "boolean") + return "archived: boolean expected"; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) { + var error = $root.proto.SyncActionMessageRange.verify(message.messageRange); + if (error) + return "messageRange." + error; + } + return null; + }; + + /** + * Creates an ArchiveChatAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ArchiveChatAction + * @static + * @param {Object.} object Plain object + * @returns {proto.ArchiveChatAction} ArchiveChatAction + */ + ArchiveChatAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ArchiveChatAction) + return object; + var message = new $root.proto.ArchiveChatAction(); + if (object.archived != null) + message.archived = Boolean(object.archived); + if (object.messageRange != null) { + if (typeof object.messageRange !== "object") + throw TypeError(".proto.ArchiveChatAction.messageRange: object expected"); + message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange); + } + return message; + }; + + /** + * Creates a plain object from an ArchiveChatAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ArchiveChatAction + * @static + * @param {proto.ArchiveChatAction} message ArchiveChatAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ArchiveChatAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.archived = false; + object.messageRange = null; + } + if (message.archived != null && message.hasOwnProperty("archived")) + object.archived = message.archived; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) + object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options); + return object; + }; + + /** + * Converts this ArchiveChatAction to JSON. + * @function toJSON + * @memberof proto.ArchiveChatAction + * @instance + * @returns {Object.} JSON object + */ + ArchiveChatAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ArchiveChatAction; + })(); + + proto.DeleteMessageForMeAction = (function() { + + /** + * Properties of a DeleteMessageForMeAction. + * @memberof proto + * @interface IDeleteMessageForMeAction + * @property {boolean|null} [deleteMedia] DeleteMessageForMeAction deleteMedia + * @property {number|Long|null} [messageTimestamp] DeleteMessageForMeAction messageTimestamp + */ + + /** + * Constructs a new DeleteMessageForMeAction. + * @memberof proto + * @classdesc Represents a DeleteMessageForMeAction. + * @implements IDeleteMessageForMeAction + * @constructor + * @param {proto.IDeleteMessageForMeAction=} [properties] Properties to set + */ + function DeleteMessageForMeAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * DeleteMessageForMeAction deleteMedia. + * @member {boolean} deleteMedia + * @memberof proto.DeleteMessageForMeAction + * @instance + */ + DeleteMessageForMeAction.prototype.deleteMedia = false; + + /** + * DeleteMessageForMeAction messageTimestamp. + * @member {number|Long} messageTimestamp + * @memberof proto.DeleteMessageForMeAction + * @instance + */ + DeleteMessageForMeAction.prototype.messageTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new DeleteMessageForMeAction instance using the specified properties. + * @function create + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {proto.IDeleteMessageForMeAction=} [properties] Properties to set + * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction instance + */ + DeleteMessageForMeAction.create = function create(properties) { + return new DeleteMessageForMeAction(properties); + }; + + /** + * Encodes the specified DeleteMessageForMeAction message. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages. + * @function encode + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {proto.IDeleteMessageForMeAction} message DeleteMessageForMeAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DeleteMessageForMeAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.deleteMedia != null && Object.hasOwnProperty.call(message, "deleteMedia")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.deleteMedia); + if (message.messageTimestamp != null && Object.hasOwnProperty.call(message, "messageTimestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.messageTimestamp); + return writer; + }; + + /** + * Encodes the specified DeleteMessageForMeAction message, length delimited. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {proto.IDeleteMessageForMeAction} message DeleteMessageForMeAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DeleteMessageForMeAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a DeleteMessageForMeAction message from the specified reader or buffer. + * @function decode + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DeleteMessageForMeAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DeleteMessageForMeAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.deleteMedia = reader.bool(); + break; + case 2: + message.messageTimestamp = reader.int64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a DeleteMessageForMeAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DeleteMessageForMeAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a DeleteMessageForMeAction message. + * @function verify + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + DeleteMessageForMeAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.deleteMedia != null && message.hasOwnProperty("deleteMedia")) + if (typeof message.deleteMedia !== "boolean") + return "deleteMedia: boolean expected"; + if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) + if (!$util.isInteger(message.messageTimestamp) && !(message.messageTimestamp && $util.isInteger(message.messageTimestamp.low) && $util.isInteger(message.messageTimestamp.high))) + return "messageTimestamp: integer|Long expected"; + return null; + }; + + /** + * Creates a DeleteMessageForMeAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {Object.} object Plain object + * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction + */ + DeleteMessageForMeAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.DeleteMessageForMeAction) + return object; + var message = new $root.proto.DeleteMessageForMeAction(); + if (object.deleteMedia != null) + message.deleteMedia = Boolean(object.deleteMedia); + if (object.messageTimestamp != null) + if ($util.Long) + (message.messageTimestamp = $util.Long.fromValue(object.messageTimestamp)).unsigned = false; + else if (typeof object.messageTimestamp === "string") + message.messageTimestamp = parseInt(object.messageTimestamp, 10); + else if (typeof object.messageTimestamp === "number") + message.messageTimestamp = object.messageTimestamp; + else if (typeof object.messageTimestamp === "object") + message.messageTimestamp = new $util.LongBits(object.messageTimestamp.low >>> 0, object.messageTimestamp.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from a DeleteMessageForMeAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.DeleteMessageForMeAction + * @static + * @param {proto.DeleteMessageForMeAction} message DeleteMessageForMeAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + DeleteMessageForMeAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.deleteMedia = false; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.messageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.messageTimestamp = options.longs === String ? "0" : 0; + } + if (message.deleteMedia != null && message.hasOwnProperty("deleteMedia")) + object.deleteMedia = message.deleteMedia; + if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp")) + if (typeof message.messageTimestamp === "number") + object.messageTimestamp = options.longs === String ? String(message.messageTimestamp) : message.messageTimestamp; + else + object.messageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.messageTimestamp) : options.longs === Number ? new $util.LongBits(message.messageTimestamp.low >>> 0, message.messageTimestamp.high >>> 0).toNumber() : message.messageTimestamp; + return object; + }; + + /** + * Converts this DeleteMessageForMeAction to JSON. + * @function toJSON + * @memberof proto.DeleteMessageForMeAction + * @instance + * @returns {Object.} JSON object + */ + DeleteMessageForMeAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return DeleteMessageForMeAction; + })(); + + proto.MarkChatAsReadAction = (function() { + + /** + * Properties of a MarkChatAsReadAction. + * @memberof proto + * @interface IMarkChatAsReadAction + * @property {boolean|null} [read] MarkChatAsReadAction read + * @property {proto.ISyncActionMessageRange|null} [messageRange] MarkChatAsReadAction messageRange + */ + + /** + * Constructs a new MarkChatAsReadAction. + * @memberof proto + * @classdesc Represents a MarkChatAsReadAction. + * @implements IMarkChatAsReadAction + * @constructor + * @param {proto.IMarkChatAsReadAction=} [properties] Properties to set + */ + function MarkChatAsReadAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MarkChatAsReadAction read. + * @member {boolean} read + * @memberof proto.MarkChatAsReadAction + * @instance + */ + MarkChatAsReadAction.prototype.read = false; + + /** + * MarkChatAsReadAction messageRange. + * @member {proto.ISyncActionMessageRange|null|undefined} messageRange + * @memberof proto.MarkChatAsReadAction + * @instance + */ + MarkChatAsReadAction.prototype.messageRange = null; + + /** + * Creates a new MarkChatAsReadAction instance using the specified properties. + * @function create + * @memberof proto.MarkChatAsReadAction + * @static + * @param {proto.IMarkChatAsReadAction=} [properties] Properties to set + * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction instance + */ + MarkChatAsReadAction.create = function create(properties) { + return new MarkChatAsReadAction(properties); + }; + + /** + * Encodes the specified MarkChatAsReadAction message. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages. + * @function encode + * @memberof proto.MarkChatAsReadAction + * @static + * @param {proto.IMarkChatAsReadAction} message MarkChatAsReadAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MarkChatAsReadAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.read != null && Object.hasOwnProperty.call(message, "read")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.read); + if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange")) + $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified MarkChatAsReadAction message, length delimited. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MarkChatAsReadAction + * @static + * @param {proto.IMarkChatAsReadAction} message MarkChatAsReadAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MarkChatAsReadAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MarkChatAsReadAction message from the specified reader or buffer. + * @function decode + * @memberof proto.MarkChatAsReadAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MarkChatAsReadAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MarkChatAsReadAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.read = reader.bool(); + break; + case 2: + message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MarkChatAsReadAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MarkChatAsReadAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MarkChatAsReadAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MarkChatAsReadAction message. + * @function verify + * @memberof proto.MarkChatAsReadAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MarkChatAsReadAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.read != null && message.hasOwnProperty("read")) + if (typeof message.read !== "boolean") + return "read: boolean expected"; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) { + var error = $root.proto.SyncActionMessageRange.verify(message.messageRange); + if (error) + return "messageRange." + error; + } + return null; + }; + + /** + * Creates a MarkChatAsReadAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MarkChatAsReadAction + * @static + * @param {Object.} object Plain object + * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction + */ + MarkChatAsReadAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MarkChatAsReadAction) + return object; + var message = new $root.proto.MarkChatAsReadAction(); + if (object.read != null) + message.read = Boolean(object.read); + if (object.messageRange != null) { + if (typeof object.messageRange !== "object") + throw TypeError(".proto.MarkChatAsReadAction.messageRange: object expected"); + message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange); + } + return message; + }; + + /** + * Creates a plain object from a MarkChatAsReadAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MarkChatAsReadAction + * @static + * @param {proto.MarkChatAsReadAction} message MarkChatAsReadAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MarkChatAsReadAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.read = false; + object.messageRange = null; + } + if (message.read != null && message.hasOwnProperty("read")) + object.read = message.read; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) + object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options); + return object; + }; + + /** + * Converts this MarkChatAsReadAction to JSON. + * @function toJSON + * @memberof proto.MarkChatAsReadAction + * @instance + * @returns {Object.} JSON object + */ + MarkChatAsReadAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MarkChatAsReadAction; + })(); + + proto.ClearChatAction = (function() { + + /** + * Properties of a ClearChatAction. + * @memberof proto + * @interface IClearChatAction + * @property {proto.ISyncActionMessageRange|null} [messageRange] ClearChatAction messageRange + */ + + /** + * Constructs a new ClearChatAction. + * @memberof proto + * @classdesc Represents a ClearChatAction. + * @implements IClearChatAction + * @constructor + * @param {proto.IClearChatAction=} [properties] Properties to set + */ + function ClearChatAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ClearChatAction messageRange. + * @member {proto.ISyncActionMessageRange|null|undefined} messageRange + * @memberof proto.ClearChatAction + * @instance + */ + ClearChatAction.prototype.messageRange = null; + + /** + * Creates a new ClearChatAction instance using the specified properties. + * @function create + * @memberof proto.ClearChatAction + * @static + * @param {proto.IClearChatAction=} [properties] Properties to set + * @returns {proto.ClearChatAction} ClearChatAction instance + */ + ClearChatAction.create = function create(properties) { + return new ClearChatAction(properties); + }; + + /** + * Encodes the specified ClearChatAction message. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages. + * @function encode + * @memberof proto.ClearChatAction + * @static + * @param {proto.IClearChatAction} message ClearChatAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClearChatAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange")) + $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified ClearChatAction message, length delimited. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ClearChatAction + * @static + * @param {proto.IClearChatAction} message ClearChatAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ClearChatAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ClearChatAction message from the specified reader or buffer. + * @function decode + * @memberof proto.ClearChatAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ClearChatAction} ClearChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClearChatAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClearChatAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ClearChatAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ClearChatAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ClearChatAction} ClearChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ClearChatAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ClearChatAction message. + * @function verify + * @memberof proto.ClearChatAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ClearChatAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) { + var error = $root.proto.SyncActionMessageRange.verify(message.messageRange); + if (error) + return "messageRange." + error; + } + return null; + }; + + /** + * Creates a ClearChatAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ClearChatAction + * @static + * @param {Object.} object Plain object + * @returns {proto.ClearChatAction} ClearChatAction + */ + ClearChatAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ClearChatAction) + return object; + var message = new $root.proto.ClearChatAction(); + if (object.messageRange != null) { + if (typeof object.messageRange !== "object") + throw TypeError(".proto.ClearChatAction.messageRange: object expected"); + message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange); + } + return message; + }; + + /** + * Creates a plain object from a ClearChatAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ClearChatAction + * @static + * @param {proto.ClearChatAction} message ClearChatAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ClearChatAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.messageRange = null; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) + object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options); + return object; + }; + + /** + * Converts this ClearChatAction to JSON. + * @function toJSON + * @memberof proto.ClearChatAction + * @instance + * @returns {Object.} JSON object + */ + ClearChatAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ClearChatAction; + })(); + + proto.DeleteChatAction = (function() { + + /** + * Properties of a DeleteChatAction. + * @memberof proto + * @interface IDeleteChatAction + * @property {proto.ISyncActionMessageRange|null} [messageRange] DeleteChatAction messageRange + */ + + /** + * Constructs a new DeleteChatAction. + * @memberof proto + * @classdesc Represents a DeleteChatAction. + * @implements IDeleteChatAction + * @constructor + * @param {proto.IDeleteChatAction=} [properties] Properties to set + */ + function DeleteChatAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * DeleteChatAction messageRange. + * @member {proto.ISyncActionMessageRange|null|undefined} messageRange + * @memberof proto.DeleteChatAction + * @instance + */ + DeleteChatAction.prototype.messageRange = null; + + /** + * Creates a new DeleteChatAction instance using the specified properties. + * @function create + * @memberof proto.DeleteChatAction + * @static + * @param {proto.IDeleteChatAction=} [properties] Properties to set + * @returns {proto.DeleteChatAction} DeleteChatAction instance + */ + DeleteChatAction.create = function create(properties) { + return new DeleteChatAction(properties); + }; + + /** + * Encodes the specified DeleteChatAction message. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages. + * @function encode + * @memberof proto.DeleteChatAction + * @static + * @param {proto.IDeleteChatAction} message DeleteChatAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DeleteChatAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange")) + $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified DeleteChatAction message, length delimited. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.DeleteChatAction + * @static + * @param {proto.IDeleteChatAction} message DeleteChatAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DeleteChatAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a DeleteChatAction message from the specified reader or buffer. + * @function decode + * @memberof proto.DeleteChatAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.DeleteChatAction} DeleteChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DeleteChatAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DeleteChatAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a DeleteChatAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.DeleteChatAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.DeleteChatAction} DeleteChatAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DeleteChatAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a DeleteChatAction message. + * @function verify + * @memberof proto.DeleteChatAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + DeleteChatAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) { + var error = $root.proto.SyncActionMessageRange.verify(message.messageRange); + if (error) + return "messageRange." + error; + } + return null; + }; + + /** + * Creates a DeleteChatAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.DeleteChatAction + * @static + * @param {Object.} object Plain object + * @returns {proto.DeleteChatAction} DeleteChatAction + */ + DeleteChatAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.DeleteChatAction) + return object; + var message = new $root.proto.DeleteChatAction(); + if (object.messageRange != null) { + if (typeof object.messageRange !== "object") + throw TypeError(".proto.DeleteChatAction.messageRange: object expected"); + message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange); + } + return message; + }; + + /** + * Creates a plain object from a DeleteChatAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.DeleteChatAction + * @static + * @param {proto.DeleteChatAction} message DeleteChatAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + DeleteChatAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.messageRange = null; + if (message.messageRange != null && message.hasOwnProperty("messageRange")) + object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options); + return object; + }; + + /** + * Converts this DeleteChatAction to JSON. + * @function toJSON + * @memberof proto.DeleteChatAction + * @instance + * @returns {Object.} JSON object + */ + DeleteChatAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return DeleteChatAction; + })(); + + proto.UnarchiveChatsSetting = (function() { + + /** + * Properties of an UnarchiveChatsSetting. + * @memberof proto + * @interface IUnarchiveChatsSetting + * @property {boolean|null} [unarchiveChats] UnarchiveChatsSetting unarchiveChats + */ + + /** + * Constructs a new UnarchiveChatsSetting. + * @memberof proto + * @classdesc Represents an UnarchiveChatsSetting. + * @implements IUnarchiveChatsSetting + * @constructor + * @param {proto.IUnarchiveChatsSetting=} [properties] Properties to set + */ + function UnarchiveChatsSetting(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * UnarchiveChatsSetting unarchiveChats. + * @member {boolean} unarchiveChats + * @memberof proto.UnarchiveChatsSetting + * @instance + */ + UnarchiveChatsSetting.prototype.unarchiveChats = false; + + /** + * Creates a new UnarchiveChatsSetting instance using the specified properties. + * @function create + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {proto.IUnarchiveChatsSetting=} [properties] Properties to set + * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting instance + */ + UnarchiveChatsSetting.create = function create(properties) { + return new UnarchiveChatsSetting(properties); + }; + + /** + * Encodes the specified UnarchiveChatsSetting message. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages. + * @function encode + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {proto.IUnarchiveChatsSetting} message UnarchiveChatsSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UnarchiveChatsSetting.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.unarchiveChats != null && Object.hasOwnProperty.call(message, "unarchiveChats")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.unarchiveChats); + return writer; + }; + + /** + * Encodes the specified UnarchiveChatsSetting message, length delimited. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {proto.IUnarchiveChatsSetting} message UnarchiveChatsSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UnarchiveChatsSetting.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an UnarchiveChatsSetting message from the specified reader or buffer. + * @function decode + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UnarchiveChatsSetting.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.UnarchiveChatsSetting(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.unarchiveChats = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an UnarchiveChatsSetting message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UnarchiveChatsSetting.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an UnarchiveChatsSetting message. + * @function verify + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + UnarchiveChatsSetting.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.unarchiveChats != null && message.hasOwnProperty("unarchiveChats")) + if (typeof message.unarchiveChats !== "boolean") + return "unarchiveChats: boolean expected"; + return null; + }; + + /** + * Creates an UnarchiveChatsSetting message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {Object.} object Plain object + * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting + */ + UnarchiveChatsSetting.fromObject = function fromObject(object) { + if (object instanceof $root.proto.UnarchiveChatsSetting) + return object; + var message = new $root.proto.UnarchiveChatsSetting(); + if (object.unarchiveChats != null) + message.unarchiveChats = Boolean(object.unarchiveChats); + return message; + }; + + /** + * Creates a plain object from an UnarchiveChatsSetting message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.UnarchiveChatsSetting + * @static + * @param {proto.UnarchiveChatsSetting} message UnarchiveChatsSetting + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + UnarchiveChatsSetting.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.unarchiveChats = false; + if (message.unarchiveChats != null && message.hasOwnProperty("unarchiveChats")) + object.unarchiveChats = message.unarchiveChats; + return object; + }; + + /** + * Converts this UnarchiveChatsSetting to JSON. + * @function toJSON + * @memberof proto.UnarchiveChatsSetting + * @instance + * @returns {Object.} JSON object + */ + UnarchiveChatsSetting.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return UnarchiveChatsSetting; + })(); + + proto.SyncActionMessageRange = (function() { + + /** + * Properties of a SyncActionMessageRange. + * @memberof proto + * @interface ISyncActionMessageRange + * @property {number|Long|null} [lastMessageTimestamp] SyncActionMessageRange lastMessageTimestamp + * @property {number|Long|null} [lastSystemMessageTimestamp] SyncActionMessageRange lastSystemMessageTimestamp + * @property {Array.|null} [messages] SyncActionMessageRange messages + */ + + /** + * Constructs a new SyncActionMessageRange. + * @memberof proto + * @classdesc Represents a SyncActionMessageRange. + * @implements ISyncActionMessageRange + * @constructor + * @param {proto.ISyncActionMessageRange=} [properties] Properties to set + */ + function SyncActionMessageRange(properties) { + this.messages = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncActionMessageRange lastMessageTimestamp. + * @member {number|Long} lastMessageTimestamp + * @memberof proto.SyncActionMessageRange + * @instance + */ + SyncActionMessageRange.prototype.lastMessageTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * SyncActionMessageRange lastSystemMessageTimestamp. + * @member {number|Long} lastSystemMessageTimestamp + * @memberof proto.SyncActionMessageRange + * @instance + */ + SyncActionMessageRange.prototype.lastSystemMessageTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * SyncActionMessageRange messages. + * @member {Array.} messages + * @memberof proto.SyncActionMessageRange + * @instance + */ + SyncActionMessageRange.prototype.messages = $util.emptyArray; + + /** + * Creates a new SyncActionMessageRange instance using the specified properties. + * @function create + * @memberof proto.SyncActionMessageRange + * @static + * @param {proto.ISyncActionMessageRange=} [properties] Properties to set + * @returns {proto.SyncActionMessageRange} SyncActionMessageRange instance + */ + SyncActionMessageRange.create = function create(properties) { + return new SyncActionMessageRange(properties); + }; + + /** + * Encodes the specified SyncActionMessageRange message. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages. + * @function encode + * @memberof proto.SyncActionMessageRange + * @static + * @param {proto.ISyncActionMessageRange} message SyncActionMessageRange message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionMessageRange.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.lastMessageTimestamp != null && Object.hasOwnProperty.call(message, "lastMessageTimestamp")) + writer.uint32(/* id 1, wireType 0 =*/8).int64(message.lastMessageTimestamp); + if (message.lastSystemMessageTimestamp != null && Object.hasOwnProperty.call(message, "lastSystemMessageTimestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.lastSystemMessageTimestamp); + if (message.messages != null && message.messages.length) + for (var i = 0; i < message.messages.length; ++i) + $root.proto.SyncActionMessage.encode(message.messages[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SyncActionMessageRange message, length delimited. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncActionMessageRange + * @static + * @param {proto.ISyncActionMessageRange} message SyncActionMessageRange message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionMessageRange.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncActionMessageRange message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncActionMessageRange + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncActionMessageRange} SyncActionMessageRange + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionMessageRange.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionMessageRange(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.lastMessageTimestamp = reader.int64(); + break; + case 2: + message.lastSystemMessageTimestamp = reader.int64(); + break; + case 3: + if (!(message.messages && message.messages.length)) + message.messages = []; + message.messages.push($root.proto.SyncActionMessage.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncActionMessageRange message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncActionMessageRange + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncActionMessageRange} SyncActionMessageRange + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionMessageRange.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncActionMessageRange message. + * @function verify + * @memberof proto.SyncActionMessageRange + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncActionMessageRange.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.lastMessageTimestamp != null && message.hasOwnProperty("lastMessageTimestamp")) + if (!$util.isInteger(message.lastMessageTimestamp) && !(message.lastMessageTimestamp && $util.isInteger(message.lastMessageTimestamp.low) && $util.isInteger(message.lastMessageTimestamp.high))) + return "lastMessageTimestamp: integer|Long expected"; + if (message.lastSystemMessageTimestamp != null && message.hasOwnProperty("lastSystemMessageTimestamp")) + if (!$util.isInteger(message.lastSystemMessageTimestamp) && !(message.lastSystemMessageTimestamp && $util.isInteger(message.lastSystemMessageTimestamp.low) && $util.isInteger(message.lastSystemMessageTimestamp.high))) + return "lastSystemMessageTimestamp: integer|Long expected"; + if (message.messages != null && message.hasOwnProperty("messages")) { + if (!Array.isArray(message.messages)) + return "messages: array expected"; + for (var i = 0; i < message.messages.length; ++i) { + var error = $root.proto.SyncActionMessage.verify(message.messages[i]); + if (error) + return "messages." + error; + } + } + return null; + }; + + /** + * Creates a SyncActionMessageRange message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncActionMessageRange + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncActionMessageRange} SyncActionMessageRange + */ + SyncActionMessageRange.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncActionMessageRange) + return object; + var message = new $root.proto.SyncActionMessageRange(); + if (object.lastMessageTimestamp != null) + if ($util.Long) + (message.lastMessageTimestamp = $util.Long.fromValue(object.lastMessageTimestamp)).unsigned = false; + else if (typeof object.lastMessageTimestamp === "string") + message.lastMessageTimestamp = parseInt(object.lastMessageTimestamp, 10); + else if (typeof object.lastMessageTimestamp === "number") + message.lastMessageTimestamp = object.lastMessageTimestamp; + else if (typeof object.lastMessageTimestamp === "object") + message.lastMessageTimestamp = new $util.LongBits(object.lastMessageTimestamp.low >>> 0, object.lastMessageTimestamp.high >>> 0).toNumber(); + if (object.lastSystemMessageTimestamp != null) + if ($util.Long) + (message.lastSystemMessageTimestamp = $util.Long.fromValue(object.lastSystemMessageTimestamp)).unsigned = false; + else if (typeof object.lastSystemMessageTimestamp === "string") + message.lastSystemMessageTimestamp = parseInt(object.lastSystemMessageTimestamp, 10); + else if (typeof object.lastSystemMessageTimestamp === "number") + message.lastSystemMessageTimestamp = object.lastSystemMessageTimestamp; + else if (typeof object.lastSystemMessageTimestamp === "object") + message.lastSystemMessageTimestamp = new $util.LongBits(object.lastSystemMessageTimestamp.low >>> 0, object.lastSystemMessageTimestamp.high >>> 0).toNumber(); + if (object.messages) { + if (!Array.isArray(object.messages)) + throw TypeError(".proto.SyncActionMessageRange.messages: array expected"); + message.messages = []; + for (var i = 0; i < object.messages.length; ++i) { + if (typeof object.messages[i] !== "object") + throw TypeError(".proto.SyncActionMessageRange.messages: object expected"); + message.messages[i] = $root.proto.SyncActionMessage.fromObject(object.messages[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a SyncActionMessageRange message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncActionMessageRange + * @static + * @param {proto.SyncActionMessageRange} message SyncActionMessageRange + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncActionMessageRange.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.messages = []; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.lastMessageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.lastMessageTimestamp = options.longs === String ? "0" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.lastSystemMessageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.lastSystemMessageTimestamp = options.longs === String ? "0" : 0; + } + if (message.lastMessageTimestamp != null && message.hasOwnProperty("lastMessageTimestamp")) + if (typeof message.lastMessageTimestamp === "number") + object.lastMessageTimestamp = options.longs === String ? String(message.lastMessageTimestamp) : message.lastMessageTimestamp; + else + object.lastMessageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.lastMessageTimestamp) : options.longs === Number ? new $util.LongBits(message.lastMessageTimestamp.low >>> 0, message.lastMessageTimestamp.high >>> 0).toNumber() : message.lastMessageTimestamp; + if (message.lastSystemMessageTimestamp != null && message.hasOwnProperty("lastSystemMessageTimestamp")) + if (typeof message.lastSystemMessageTimestamp === "number") + object.lastSystemMessageTimestamp = options.longs === String ? String(message.lastSystemMessageTimestamp) : message.lastSystemMessageTimestamp; + else + object.lastSystemMessageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.lastSystemMessageTimestamp) : options.longs === Number ? new $util.LongBits(message.lastSystemMessageTimestamp.low >>> 0, message.lastSystemMessageTimestamp.high >>> 0).toNumber() : message.lastSystemMessageTimestamp; + if (message.messages && message.messages.length) { + object.messages = []; + for (var j = 0; j < message.messages.length; ++j) + object.messages[j] = $root.proto.SyncActionMessage.toObject(message.messages[j], options); + } + return object; + }; + + /** + * Converts this SyncActionMessageRange to JSON. + * @function toJSON + * @memberof proto.SyncActionMessageRange + * @instance + * @returns {Object.} JSON object + */ + SyncActionMessageRange.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncActionMessageRange; + })(); + + proto.SyncActionMessage = (function() { + + /** + * Properties of a SyncActionMessage. + * @memberof proto + * @interface ISyncActionMessage + * @property {proto.IMessageKey|null} [key] SyncActionMessage key + * @property {number|Long|null} [timestamp] SyncActionMessage timestamp + */ + + /** + * Constructs a new SyncActionMessage. + * @memberof proto + * @classdesc Represents a SyncActionMessage. + * @implements ISyncActionMessage + * @constructor + * @param {proto.ISyncActionMessage=} [properties] Properties to set + */ + function SyncActionMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncActionMessage key. + * @member {proto.IMessageKey|null|undefined} key + * @memberof proto.SyncActionMessage + * @instance + */ + SyncActionMessage.prototype.key = null; + + /** + * SyncActionMessage timestamp. + * @member {number|Long} timestamp + * @memberof proto.SyncActionMessage + * @instance + */ + SyncActionMessage.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new SyncActionMessage instance using the specified properties. + * @function create + * @memberof proto.SyncActionMessage + * @static + * @param {proto.ISyncActionMessage=} [properties] Properties to set + * @returns {proto.SyncActionMessage} SyncActionMessage instance + */ + SyncActionMessage.create = function create(properties) { + return new SyncActionMessage(properties); + }; + + /** + * Encodes the specified SyncActionMessage message. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages. + * @function encode + * @memberof proto.SyncActionMessage + * @static + * @param {proto.ISyncActionMessage} message SyncActionMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.key != null && Object.hasOwnProperty.call(message, "key")) + $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.timestamp); + return writer; + }; + + /** + * Encodes the specified SyncActionMessage message, length delimited. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncActionMessage + * @static + * @param {proto.ISyncActionMessage} message SyncActionMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncActionMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncActionMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncActionMessage} SyncActionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.key = $root.proto.MessageKey.decode(reader, reader.uint32()); + break; + case 2: + message.timestamp = reader.int64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncActionMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncActionMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncActionMessage} SyncActionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncActionMessage message. + * @function verify + * @memberof proto.SyncActionMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncActionMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.key != null && message.hasOwnProperty("key")) { + var error = $root.proto.MessageKey.verify(message.key); + if (error) + return "key." + error; + } + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) + return "timestamp: integer|Long expected"; + return null; + }; + + /** + * Creates a SyncActionMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncActionMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncActionMessage} SyncActionMessage + */ + SyncActionMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncActionMessage) + return object; + var message = new $root.proto.SyncActionMessage(); + if (object.key != null) { + if (typeof object.key !== "object") + throw TypeError(".proto.SyncActionMessage.key: object expected"); + message.key = $root.proto.MessageKey.fromObject(object.key); + } + if (object.timestamp != null) + if ($util.Long) + (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false; + else if (typeof object.timestamp === "string") + message.timestamp = parseInt(object.timestamp, 10); + else if (typeof object.timestamp === "number") + message.timestamp = object.timestamp; + else if (typeof object.timestamp === "object") + message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from a SyncActionMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncActionMessage + * @static + * @param {proto.SyncActionMessage} message SyncActionMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncActionMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.key = null; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.timestamp = options.longs === String ? "0" : 0; + } + if (message.key != null && message.hasOwnProperty("key")) + object.key = $root.proto.MessageKey.toObject(message.key, options); + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (typeof message.timestamp === "number") + object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; + else + object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp; + return object; + }; + + /** + * Converts this SyncActionMessage to JSON. + * @function toJSON + * @memberof proto.SyncActionMessage + * @instance + * @returns {Object.} JSON object + */ + SyncActionMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncActionMessage; + })(); + + proto.KeyExpiration = (function() { + + /** + * Properties of a KeyExpiration. + * @memberof proto + * @interface IKeyExpiration + * @property {number|null} [expiredKeyEpoch] KeyExpiration expiredKeyEpoch + */ + + /** + * Constructs a new KeyExpiration. + * @memberof proto + * @classdesc Represents a KeyExpiration. + * @implements IKeyExpiration + * @constructor + * @param {proto.IKeyExpiration=} [properties] Properties to set + */ + function KeyExpiration(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * KeyExpiration expiredKeyEpoch. + * @member {number} expiredKeyEpoch + * @memberof proto.KeyExpiration + * @instance + */ + KeyExpiration.prototype.expiredKeyEpoch = 0; + + /** + * Creates a new KeyExpiration instance using the specified properties. + * @function create + * @memberof proto.KeyExpiration + * @static + * @param {proto.IKeyExpiration=} [properties] Properties to set + * @returns {proto.KeyExpiration} KeyExpiration instance + */ + KeyExpiration.create = function create(properties) { + return new KeyExpiration(properties); + }; + + /** + * Encodes the specified KeyExpiration message. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages. + * @function encode + * @memberof proto.KeyExpiration + * @static + * @param {proto.IKeyExpiration} message KeyExpiration message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + KeyExpiration.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.expiredKeyEpoch != null && Object.hasOwnProperty.call(message, "expiredKeyEpoch")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.expiredKeyEpoch); + return writer; + }; + + /** + * Encodes the specified KeyExpiration message, length delimited. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.KeyExpiration + * @static + * @param {proto.IKeyExpiration} message KeyExpiration message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + KeyExpiration.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a KeyExpiration message from the specified reader or buffer. + * @function decode + * @memberof proto.KeyExpiration + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.KeyExpiration} KeyExpiration + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + KeyExpiration.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.KeyExpiration(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.expiredKeyEpoch = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a KeyExpiration message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.KeyExpiration + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.KeyExpiration} KeyExpiration + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + KeyExpiration.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a KeyExpiration message. + * @function verify + * @memberof proto.KeyExpiration + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + KeyExpiration.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.expiredKeyEpoch != null && message.hasOwnProperty("expiredKeyEpoch")) + if (!$util.isInteger(message.expiredKeyEpoch)) + return "expiredKeyEpoch: integer expected"; + return null; + }; + + /** + * Creates a KeyExpiration message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.KeyExpiration + * @static + * @param {Object.} object Plain object + * @returns {proto.KeyExpiration} KeyExpiration + */ + KeyExpiration.fromObject = function fromObject(object) { + if (object instanceof $root.proto.KeyExpiration) + return object; + var message = new $root.proto.KeyExpiration(); + if (object.expiredKeyEpoch != null) + message.expiredKeyEpoch = object.expiredKeyEpoch | 0; + return message; + }; + + /** + * Creates a plain object from a KeyExpiration message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.KeyExpiration + * @static + * @param {proto.KeyExpiration} message KeyExpiration + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + KeyExpiration.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.expiredKeyEpoch = 0; + if (message.expiredKeyEpoch != null && message.hasOwnProperty("expiredKeyEpoch")) + object.expiredKeyEpoch = message.expiredKeyEpoch; + return object; + }; + + /** + * Converts this KeyExpiration to JSON. + * @function toJSON + * @memberof proto.KeyExpiration + * @instance + * @returns {Object.} JSON object + */ + KeyExpiration.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return KeyExpiration; + })(); + + proto.SyncActionValue = (function() { + + /** + * Properties of a SyncActionValue. + * @memberof proto + * @interface ISyncActionValue + * @property {number|Long|null} [timestamp] SyncActionValue timestamp + * @property {proto.IStarAction|null} [starAction] SyncActionValue starAction + * @property {proto.IContactAction|null} [contactAction] SyncActionValue contactAction + * @property {proto.IMuteAction|null} [muteAction] SyncActionValue muteAction + * @property {proto.IPinAction|null} [pinAction] SyncActionValue pinAction + * @property {proto.ISecurityNotificationSetting|null} [securityNotificationSetting] SyncActionValue securityNotificationSetting + * @property {proto.IPushNameSetting|null} [pushNameSetting] SyncActionValue pushNameSetting + * @property {proto.IQuickReplyAction|null} [quickReplyAction] SyncActionValue quickReplyAction + * @property {proto.IRecentStickerWeightsAction|null} [recentStickerWeightsAction] SyncActionValue recentStickerWeightsAction + * @property {proto.IRecentStickerMetadata|null} [recentStickerMetadata] SyncActionValue recentStickerMetadata + * @property {proto.IRecentEmojiWeightsAction|null} [recentEmojiWeightsAction] SyncActionValue recentEmojiWeightsAction + * @property {proto.ILabelEditAction|null} [labelEditAction] SyncActionValue labelEditAction + * @property {proto.ILabelAssociationAction|null} [labelAssociationAction] SyncActionValue labelAssociationAction + * @property {proto.ILocaleSetting|null} [localeSetting] SyncActionValue localeSetting + * @property {proto.IArchiveChatAction|null} [archiveChatAction] SyncActionValue archiveChatAction + * @property {proto.IDeleteMessageForMeAction|null} [deleteMessageForMeAction] SyncActionValue deleteMessageForMeAction + * @property {proto.IKeyExpiration|null} [keyExpiration] SyncActionValue keyExpiration + * @property {proto.IMarkChatAsReadAction|null} [markChatAsReadAction] SyncActionValue markChatAsReadAction + * @property {proto.IClearChatAction|null} [clearChatAction] SyncActionValue clearChatAction + * @property {proto.IDeleteChatAction|null} [deleteChatAction] SyncActionValue deleteChatAction + * @property {proto.IUnarchiveChatsSetting|null} [unarchiveChatsSetting] SyncActionValue unarchiveChatsSetting + */ + + /** + * Constructs a new SyncActionValue. + * @memberof proto + * @classdesc Represents a SyncActionValue. + * @implements ISyncActionValue + * @constructor + * @param {proto.ISyncActionValue=} [properties] Properties to set + */ + function SyncActionValue(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncActionValue timestamp. + * @member {number|Long} timestamp + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * SyncActionValue starAction. + * @member {proto.IStarAction|null|undefined} starAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.starAction = null; + + /** + * SyncActionValue contactAction. + * @member {proto.IContactAction|null|undefined} contactAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.contactAction = null; + + /** + * SyncActionValue muteAction. + * @member {proto.IMuteAction|null|undefined} muteAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.muteAction = null; + + /** + * SyncActionValue pinAction. + * @member {proto.IPinAction|null|undefined} pinAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.pinAction = null; + + /** + * SyncActionValue securityNotificationSetting. + * @member {proto.ISecurityNotificationSetting|null|undefined} securityNotificationSetting + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.securityNotificationSetting = null; + + /** + * SyncActionValue pushNameSetting. + * @member {proto.IPushNameSetting|null|undefined} pushNameSetting + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.pushNameSetting = null; + + /** + * SyncActionValue quickReplyAction. + * @member {proto.IQuickReplyAction|null|undefined} quickReplyAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.quickReplyAction = null; + + /** + * SyncActionValue recentStickerWeightsAction. + * @member {proto.IRecentStickerWeightsAction|null|undefined} recentStickerWeightsAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.recentStickerWeightsAction = null; + + /** + * SyncActionValue recentStickerMetadata. + * @member {proto.IRecentStickerMetadata|null|undefined} recentStickerMetadata + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.recentStickerMetadata = null; + + /** + * SyncActionValue recentEmojiWeightsAction. + * @member {proto.IRecentEmojiWeightsAction|null|undefined} recentEmojiWeightsAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.recentEmojiWeightsAction = null; + + /** + * SyncActionValue labelEditAction. + * @member {proto.ILabelEditAction|null|undefined} labelEditAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.labelEditAction = null; + + /** + * SyncActionValue labelAssociationAction. + * @member {proto.ILabelAssociationAction|null|undefined} labelAssociationAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.labelAssociationAction = null; + + /** + * SyncActionValue localeSetting. + * @member {proto.ILocaleSetting|null|undefined} localeSetting + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.localeSetting = null; + + /** + * SyncActionValue archiveChatAction. + * @member {proto.IArchiveChatAction|null|undefined} archiveChatAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.archiveChatAction = null; + + /** + * SyncActionValue deleteMessageForMeAction. + * @member {proto.IDeleteMessageForMeAction|null|undefined} deleteMessageForMeAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.deleteMessageForMeAction = null; + + /** + * SyncActionValue keyExpiration. + * @member {proto.IKeyExpiration|null|undefined} keyExpiration + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.keyExpiration = null; + + /** + * SyncActionValue markChatAsReadAction. + * @member {proto.IMarkChatAsReadAction|null|undefined} markChatAsReadAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.markChatAsReadAction = null; + + /** + * SyncActionValue clearChatAction. + * @member {proto.IClearChatAction|null|undefined} clearChatAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.clearChatAction = null; + + /** + * SyncActionValue deleteChatAction. + * @member {proto.IDeleteChatAction|null|undefined} deleteChatAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.deleteChatAction = null; + + /** + * SyncActionValue unarchiveChatsSetting. + * @member {proto.IUnarchiveChatsSetting|null|undefined} unarchiveChatsSetting + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.unarchiveChatsSetting = null; + + /** + * Creates a new SyncActionValue instance using the specified properties. + * @function create + * @memberof proto.SyncActionValue + * @static + * @param {proto.ISyncActionValue=} [properties] Properties to set + * @returns {proto.SyncActionValue} SyncActionValue instance + */ + SyncActionValue.create = function create(properties) { + return new SyncActionValue(properties); + }; + + /** + * Encodes the specified SyncActionValue message. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages. + * @function encode + * @memberof proto.SyncActionValue + * @static + * @param {proto.ISyncActionValue} message SyncActionValue message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionValue.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) + writer.uint32(/* id 1, wireType 0 =*/8).int64(message.timestamp); + if (message.starAction != null && Object.hasOwnProperty.call(message, "starAction")) + $root.proto.StarAction.encode(message.starAction, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.contactAction != null && Object.hasOwnProperty.call(message, "contactAction")) + $root.proto.ContactAction.encode(message.contactAction, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.muteAction != null && Object.hasOwnProperty.call(message, "muteAction")) + $root.proto.MuteAction.encode(message.muteAction, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + if (message.pinAction != null && Object.hasOwnProperty.call(message, "pinAction")) + $root.proto.PinAction.encode(message.pinAction, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + if (message.securityNotificationSetting != null && Object.hasOwnProperty.call(message, "securityNotificationSetting")) + $root.proto.SecurityNotificationSetting.encode(message.securityNotificationSetting, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.pushNameSetting != null && Object.hasOwnProperty.call(message, "pushNameSetting")) + $root.proto.PushNameSetting.encode(message.pushNameSetting, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); + if (message.quickReplyAction != null && Object.hasOwnProperty.call(message, "quickReplyAction")) + $root.proto.QuickReplyAction.encode(message.quickReplyAction, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim(); + if (message.recentStickerWeightsAction != null && Object.hasOwnProperty.call(message, "recentStickerWeightsAction")) + $root.proto.RecentStickerWeightsAction.encode(message.recentStickerWeightsAction, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim(); + if (message.recentStickerMetadata != null && Object.hasOwnProperty.call(message, "recentStickerMetadata")) + $root.proto.RecentStickerMetadata.encode(message.recentStickerMetadata, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim(); + if (message.recentEmojiWeightsAction != null && Object.hasOwnProperty.call(message, "recentEmojiWeightsAction")) + $root.proto.RecentEmojiWeightsAction.encode(message.recentEmojiWeightsAction, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim(); + if (message.labelEditAction != null && Object.hasOwnProperty.call(message, "labelEditAction")) + $root.proto.LabelEditAction.encode(message.labelEditAction, writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim(); + if (message.labelAssociationAction != null && Object.hasOwnProperty.call(message, "labelAssociationAction")) + $root.proto.LabelAssociationAction.encode(message.labelAssociationAction, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim(); + if (message.localeSetting != null && Object.hasOwnProperty.call(message, "localeSetting")) + $root.proto.LocaleSetting.encode(message.localeSetting, writer.uint32(/* id 16, wireType 2 =*/130).fork()).ldelim(); + if (message.archiveChatAction != null && Object.hasOwnProperty.call(message, "archiveChatAction")) + $root.proto.ArchiveChatAction.encode(message.archiveChatAction, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim(); + if (message.deleteMessageForMeAction != null && Object.hasOwnProperty.call(message, "deleteMessageForMeAction")) + $root.proto.DeleteMessageForMeAction.encode(message.deleteMessageForMeAction, writer.uint32(/* id 18, wireType 2 =*/146).fork()).ldelim(); + if (message.keyExpiration != null && Object.hasOwnProperty.call(message, "keyExpiration")) + $root.proto.KeyExpiration.encode(message.keyExpiration, writer.uint32(/* id 19, wireType 2 =*/154).fork()).ldelim(); + if (message.markChatAsReadAction != null && Object.hasOwnProperty.call(message, "markChatAsReadAction")) + $root.proto.MarkChatAsReadAction.encode(message.markChatAsReadAction, writer.uint32(/* id 20, wireType 2 =*/162).fork()).ldelim(); + if (message.clearChatAction != null && Object.hasOwnProperty.call(message, "clearChatAction")) + $root.proto.ClearChatAction.encode(message.clearChatAction, writer.uint32(/* id 21, wireType 2 =*/170).fork()).ldelim(); + if (message.deleteChatAction != null && Object.hasOwnProperty.call(message, "deleteChatAction")) + $root.proto.DeleteChatAction.encode(message.deleteChatAction, writer.uint32(/* id 22, wireType 2 =*/178).fork()).ldelim(); + if (message.unarchiveChatsSetting != null && Object.hasOwnProperty.call(message, "unarchiveChatsSetting")) + $root.proto.UnarchiveChatsSetting.encode(message.unarchiveChatsSetting, writer.uint32(/* id 23, wireType 2 =*/186).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SyncActionValue message, length delimited. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncActionValue + * @static + * @param {proto.ISyncActionValue} message SyncActionValue message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncActionValue.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncActionValue message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncActionValue + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncActionValue} SyncActionValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionValue.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionValue(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.timestamp = reader.int64(); + break; + case 2: + message.starAction = $root.proto.StarAction.decode(reader, reader.uint32()); + break; + case 3: + message.contactAction = $root.proto.ContactAction.decode(reader, reader.uint32()); + break; + case 4: + message.muteAction = $root.proto.MuteAction.decode(reader, reader.uint32()); + break; + case 5: + message.pinAction = $root.proto.PinAction.decode(reader, reader.uint32()); + break; + case 6: + message.securityNotificationSetting = $root.proto.SecurityNotificationSetting.decode(reader, reader.uint32()); + break; + case 7: + message.pushNameSetting = $root.proto.PushNameSetting.decode(reader, reader.uint32()); + break; + case 8: + message.quickReplyAction = $root.proto.QuickReplyAction.decode(reader, reader.uint32()); + break; + case 9: + message.recentStickerWeightsAction = $root.proto.RecentStickerWeightsAction.decode(reader, reader.uint32()); + break; + case 10: + message.recentStickerMetadata = $root.proto.RecentStickerMetadata.decode(reader, reader.uint32()); + break; + case 11: + message.recentEmojiWeightsAction = $root.proto.RecentEmojiWeightsAction.decode(reader, reader.uint32()); + break; + case 14: + message.labelEditAction = $root.proto.LabelEditAction.decode(reader, reader.uint32()); + break; + case 15: + message.labelAssociationAction = $root.proto.LabelAssociationAction.decode(reader, reader.uint32()); + break; + case 16: + message.localeSetting = $root.proto.LocaleSetting.decode(reader, reader.uint32()); + break; + case 17: + message.archiveChatAction = $root.proto.ArchiveChatAction.decode(reader, reader.uint32()); + break; + case 18: + message.deleteMessageForMeAction = $root.proto.DeleteMessageForMeAction.decode(reader, reader.uint32()); + break; + case 19: + message.keyExpiration = $root.proto.KeyExpiration.decode(reader, reader.uint32()); + break; + case 20: + message.markChatAsReadAction = $root.proto.MarkChatAsReadAction.decode(reader, reader.uint32()); + break; + case 21: + message.clearChatAction = $root.proto.ClearChatAction.decode(reader, reader.uint32()); + break; + case 22: + message.deleteChatAction = $root.proto.DeleteChatAction.decode(reader, reader.uint32()); + break; + case 23: + message.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncActionValue message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncActionValue + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncActionValue} SyncActionValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncActionValue.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncActionValue message. + * @function verify + * @memberof proto.SyncActionValue + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncActionValue.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) + return "timestamp: integer|Long expected"; + if (message.starAction != null && message.hasOwnProperty("starAction")) { + var error = $root.proto.StarAction.verify(message.starAction); + if (error) + return "starAction." + error; + } + if (message.contactAction != null && message.hasOwnProperty("contactAction")) { + var error = $root.proto.ContactAction.verify(message.contactAction); + if (error) + return "contactAction." + error; + } + if (message.muteAction != null && message.hasOwnProperty("muteAction")) { + var error = $root.proto.MuteAction.verify(message.muteAction); + if (error) + return "muteAction." + error; + } + if (message.pinAction != null && message.hasOwnProperty("pinAction")) { + var error = $root.proto.PinAction.verify(message.pinAction); + if (error) + return "pinAction." + error; + } + if (message.securityNotificationSetting != null && message.hasOwnProperty("securityNotificationSetting")) { + var error = $root.proto.SecurityNotificationSetting.verify(message.securityNotificationSetting); + if (error) + return "securityNotificationSetting." + error; + } + if (message.pushNameSetting != null && message.hasOwnProperty("pushNameSetting")) { + var error = $root.proto.PushNameSetting.verify(message.pushNameSetting); + if (error) + return "pushNameSetting." + error; + } + if (message.quickReplyAction != null && message.hasOwnProperty("quickReplyAction")) { + var error = $root.proto.QuickReplyAction.verify(message.quickReplyAction); + if (error) + return "quickReplyAction." + error; + } + if (message.recentStickerWeightsAction != null && message.hasOwnProperty("recentStickerWeightsAction")) { + var error = $root.proto.RecentStickerWeightsAction.verify(message.recentStickerWeightsAction); + if (error) + return "recentStickerWeightsAction." + error; + } + if (message.recentStickerMetadata != null && message.hasOwnProperty("recentStickerMetadata")) { + var error = $root.proto.RecentStickerMetadata.verify(message.recentStickerMetadata); + if (error) + return "recentStickerMetadata." + error; + } + if (message.recentEmojiWeightsAction != null && message.hasOwnProperty("recentEmojiWeightsAction")) { + var error = $root.proto.RecentEmojiWeightsAction.verify(message.recentEmojiWeightsAction); + if (error) + return "recentEmojiWeightsAction." + error; + } + if (message.labelEditAction != null && message.hasOwnProperty("labelEditAction")) { + var error = $root.proto.LabelEditAction.verify(message.labelEditAction); + if (error) + return "labelEditAction." + error; + } + if (message.labelAssociationAction != null && message.hasOwnProperty("labelAssociationAction")) { + var error = $root.proto.LabelAssociationAction.verify(message.labelAssociationAction); + if (error) + return "labelAssociationAction." + error; + } + if (message.localeSetting != null && message.hasOwnProperty("localeSetting")) { + var error = $root.proto.LocaleSetting.verify(message.localeSetting); + if (error) + return "localeSetting." + error; + } + if (message.archiveChatAction != null && message.hasOwnProperty("archiveChatAction")) { + var error = $root.proto.ArchiveChatAction.verify(message.archiveChatAction); + if (error) + return "archiveChatAction." + error; + } + if (message.deleteMessageForMeAction != null && message.hasOwnProperty("deleteMessageForMeAction")) { + var error = $root.proto.DeleteMessageForMeAction.verify(message.deleteMessageForMeAction); + if (error) + return "deleteMessageForMeAction." + error; + } + if (message.keyExpiration != null && message.hasOwnProperty("keyExpiration")) { + var error = $root.proto.KeyExpiration.verify(message.keyExpiration); + if (error) + return "keyExpiration." + error; + } + if (message.markChatAsReadAction != null && message.hasOwnProperty("markChatAsReadAction")) { + var error = $root.proto.MarkChatAsReadAction.verify(message.markChatAsReadAction); + if (error) + return "markChatAsReadAction." + error; + } + if (message.clearChatAction != null && message.hasOwnProperty("clearChatAction")) { + var error = $root.proto.ClearChatAction.verify(message.clearChatAction); + if (error) + return "clearChatAction." + error; + } + if (message.deleteChatAction != null && message.hasOwnProperty("deleteChatAction")) { + var error = $root.proto.DeleteChatAction.verify(message.deleteChatAction); + if (error) + return "deleteChatAction." + error; + } + if (message.unarchiveChatsSetting != null && message.hasOwnProperty("unarchiveChatsSetting")) { + var error = $root.proto.UnarchiveChatsSetting.verify(message.unarchiveChatsSetting); + if (error) + return "unarchiveChatsSetting." + error; + } + return null; + }; + + /** + * Creates a SyncActionValue message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncActionValue + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncActionValue} SyncActionValue + */ + SyncActionValue.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncActionValue) + return object; + var message = new $root.proto.SyncActionValue(); + if (object.timestamp != null) + if ($util.Long) + (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false; + else if (typeof object.timestamp === "string") + message.timestamp = parseInt(object.timestamp, 10); + else if (typeof object.timestamp === "number") + message.timestamp = object.timestamp; + else if (typeof object.timestamp === "object") + message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(); + if (object.starAction != null) { + if (typeof object.starAction !== "object") + throw TypeError(".proto.SyncActionValue.starAction: object expected"); + message.starAction = $root.proto.StarAction.fromObject(object.starAction); + } + if (object.contactAction != null) { + if (typeof object.contactAction !== "object") + throw TypeError(".proto.SyncActionValue.contactAction: object expected"); + message.contactAction = $root.proto.ContactAction.fromObject(object.contactAction); + } + if (object.muteAction != null) { + if (typeof object.muteAction !== "object") + throw TypeError(".proto.SyncActionValue.muteAction: object expected"); + message.muteAction = $root.proto.MuteAction.fromObject(object.muteAction); + } + if (object.pinAction != null) { + if (typeof object.pinAction !== "object") + throw TypeError(".proto.SyncActionValue.pinAction: object expected"); + message.pinAction = $root.proto.PinAction.fromObject(object.pinAction); + } + if (object.securityNotificationSetting != null) { + if (typeof object.securityNotificationSetting !== "object") + throw TypeError(".proto.SyncActionValue.securityNotificationSetting: object expected"); + message.securityNotificationSetting = $root.proto.SecurityNotificationSetting.fromObject(object.securityNotificationSetting); + } + if (object.pushNameSetting != null) { + if (typeof object.pushNameSetting !== "object") + throw TypeError(".proto.SyncActionValue.pushNameSetting: object expected"); + message.pushNameSetting = $root.proto.PushNameSetting.fromObject(object.pushNameSetting); + } + if (object.quickReplyAction != null) { + if (typeof object.quickReplyAction !== "object") + throw TypeError(".proto.SyncActionValue.quickReplyAction: object expected"); + message.quickReplyAction = $root.proto.QuickReplyAction.fromObject(object.quickReplyAction); + } + if (object.recentStickerWeightsAction != null) { + if (typeof object.recentStickerWeightsAction !== "object") + throw TypeError(".proto.SyncActionValue.recentStickerWeightsAction: object expected"); + message.recentStickerWeightsAction = $root.proto.RecentStickerWeightsAction.fromObject(object.recentStickerWeightsAction); + } + if (object.recentStickerMetadata != null) { + if (typeof object.recentStickerMetadata !== "object") + throw TypeError(".proto.SyncActionValue.recentStickerMetadata: object expected"); + message.recentStickerMetadata = $root.proto.RecentStickerMetadata.fromObject(object.recentStickerMetadata); + } + if (object.recentEmojiWeightsAction != null) { + if (typeof object.recentEmojiWeightsAction !== "object") + throw TypeError(".proto.SyncActionValue.recentEmojiWeightsAction: object expected"); + message.recentEmojiWeightsAction = $root.proto.RecentEmojiWeightsAction.fromObject(object.recentEmojiWeightsAction); + } + if (object.labelEditAction != null) { + if (typeof object.labelEditAction !== "object") + throw TypeError(".proto.SyncActionValue.labelEditAction: object expected"); + message.labelEditAction = $root.proto.LabelEditAction.fromObject(object.labelEditAction); + } + if (object.labelAssociationAction != null) { + if (typeof object.labelAssociationAction !== "object") + throw TypeError(".proto.SyncActionValue.labelAssociationAction: object expected"); + message.labelAssociationAction = $root.proto.LabelAssociationAction.fromObject(object.labelAssociationAction); + } + if (object.localeSetting != null) { + if (typeof object.localeSetting !== "object") + throw TypeError(".proto.SyncActionValue.localeSetting: object expected"); + message.localeSetting = $root.proto.LocaleSetting.fromObject(object.localeSetting); + } + if (object.archiveChatAction != null) { + if (typeof object.archiveChatAction !== "object") + throw TypeError(".proto.SyncActionValue.archiveChatAction: object expected"); + message.archiveChatAction = $root.proto.ArchiveChatAction.fromObject(object.archiveChatAction); + } + if (object.deleteMessageForMeAction != null) { + if (typeof object.deleteMessageForMeAction !== "object") + throw TypeError(".proto.SyncActionValue.deleteMessageForMeAction: object expected"); + message.deleteMessageForMeAction = $root.proto.DeleteMessageForMeAction.fromObject(object.deleteMessageForMeAction); + } + if (object.keyExpiration != null) { + if (typeof object.keyExpiration !== "object") + throw TypeError(".proto.SyncActionValue.keyExpiration: object expected"); + message.keyExpiration = $root.proto.KeyExpiration.fromObject(object.keyExpiration); + } + if (object.markChatAsReadAction != null) { + if (typeof object.markChatAsReadAction !== "object") + throw TypeError(".proto.SyncActionValue.markChatAsReadAction: object expected"); + message.markChatAsReadAction = $root.proto.MarkChatAsReadAction.fromObject(object.markChatAsReadAction); + } + if (object.clearChatAction != null) { + if (typeof object.clearChatAction !== "object") + throw TypeError(".proto.SyncActionValue.clearChatAction: object expected"); + message.clearChatAction = $root.proto.ClearChatAction.fromObject(object.clearChatAction); + } + if (object.deleteChatAction != null) { + if (typeof object.deleteChatAction !== "object") + throw TypeError(".proto.SyncActionValue.deleteChatAction: object expected"); + message.deleteChatAction = $root.proto.DeleteChatAction.fromObject(object.deleteChatAction); + } + if (object.unarchiveChatsSetting != null) { + if (typeof object.unarchiveChatsSetting !== "object") + throw TypeError(".proto.SyncActionValue.unarchiveChatsSetting: object expected"); + message.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.fromObject(object.unarchiveChatsSetting); + } + return message; + }; + + /** + * Creates a plain object from a SyncActionValue message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncActionValue + * @static + * @param {proto.SyncActionValue} message SyncActionValue + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncActionValue.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.timestamp = options.longs === String ? "0" : 0; + object.starAction = null; + object.contactAction = null; + object.muteAction = null; + object.pinAction = null; + object.securityNotificationSetting = null; + object.pushNameSetting = null; + object.quickReplyAction = null; + object.recentStickerWeightsAction = null; + object.recentStickerMetadata = null; + object.recentEmojiWeightsAction = null; + object.labelEditAction = null; + object.labelAssociationAction = null; + object.localeSetting = null; + object.archiveChatAction = null; + object.deleteMessageForMeAction = null; + object.keyExpiration = null; + object.markChatAsReadAction = null; + object.clearChatAction = null; + object.deleteChatAction = null; + object.unarchiveChatsSetting = null; + } + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (typeof message.timestamp === "number") + object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; + else + object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp; + if (message.starAction != null && message.hasOwnProperty("starAction")) + object.starAction = $root.proto.StarAction.toObject(message.starAction, options); + if (message.contactAction != null && message.hasOwnProperty("contactAction")) + object.contactAction = $root.proto.ContactAction.toObject(message.contactAction, options); + if (message.muteAction != null && message.hasOwnProperty("muteAction")) + object.muteAction = $root.proto.MuteAction.toObject(message.muteAction, options); + if (message.pinAction != null && message.hasOwnProperty("pinAction")) + object.pinAction = $root.proto.PinAction.toObject(message.pinAction, options); + if (message.securityNotificationSetting != null && message.hasOwnProperty("securityNotificationSetting")) + object.securityNotificationSetting = $root.proto.SecurityNotificationSetting.toObject(message.securityNotificationSetting, options); + if (message.pushNameSetting != null && message.hasOwnProperty("pushNameSetting")) + object.pushNameSetting = $root.proto.PushNameSetting.toObject(message.pushNameSetting, options); + if (message.quickReplyAction != null && message.hasOwnProperty("quickReplyAction")) + object.quickReplyAction = $root.proto.QuickReplyAction.toObject(message.quickReplyAction, options); + if (message.recentStickerWeightsAction != null && message.hasOwnProperty("recentStickerWeightsAction")) + object.recentStickerWeightsAction = $root.proto.RecentStickerWeightsAction.toObject(message.recentStickerWeightsAction, options); + if (message.recentStickerMetadata != null && message.hasOwnProperty("recentStickerMetadata")) + object.recentStickerMetadata = $root.proto.RecentStickerMetadata.toObject(message.recentStickerMetadata, options); + if (message.recentEmojiWeightsAction != null && message.hasOwnProperty("recentEmojiWeightsAction")) + object.recentEmojiWeightsAction = $root.proto.RecentEmojiWeightsAction.toObject(message.recentEmojiWeightsAction, options); + if (message.labelEditAction != null && message.hasOwnProperty("labelEditAction")) + object.labelEditAction = $root.proto.LabelEditAction.toObject(message.labelEditAction, options); + if (message.labelAssociationAction != null && message.hasOwnProperty("labelAssociationAction")) + object.labelAssociationAction = $root.proto.LabelAssociationAction.toObject(message.labelAssociationAction, options); + if (message.localeSetting != null && message.hasOwnProperty("localeSetting")) + object.localeSetting = $root.proto.LocaleSetting.toObject(message.localeSetting, options); + if (message.archiveChatAction != null && message.hasOwnProperty("archiveChatAction")) + object.archiveChatAction = $root.proto.ArchiveChatAction.toObject(message.archiveChatAction, options); + if (message.deleteMessageForMeAction != null && message.hasOwnProperty("deleteMessageForMeAction")) + object.deleteMessageForMeAction = $root.proto.DeleteMessageForMeAction.toObject(message.deleteMessageForMeAction, options); + if (message.keyExpiration != null && message.hasOwnProperty("keyExpiration")) + object.keyExpiration = $root.proto.KeyExpiration.toObject(message.keyExpiration, options); + if (message.markChatAsReadAction != null && message.hasOwnProperty("markChatAsReadAction")) + object.markChatAsReadAction = $root.proto.MarkChatAsReadAction.toObject(message.markChatAsReadAction, options); + if (message.clearChatAction != null && message.hasOwnProperty("clearChatAction")) + object.clearChatAction = $root.proto.ClearChatAction.toObject(message.clearChatAction, options); + if (message.deleteChatAction != null && message.hasOwnProperty("deleteChatAction")) + object.deleteChatAction = $root.proto.DeleteChatAction.toObject(message.deleteChatAction, options); + if (message.unarchiveChatsSetting != null && message.hasOwnProperty("unarchiveChatsSetting")) + object.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.toObject(message.unarchiveChatsSetting, options); + return object; + }; + + /** + * Converts this SyncActionValue to JSON. + * @function toJSON + * @memberof proto.SyncActionValue + * @instance + * @returns {Object.} JSON object + */ + SyncActionValue.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncActionValue; + })(); + + proto.RecentEmojiWeight = (function() { + + /** + * Properties of a RecentEmojiWeight. + * @memberof proto + * @interface IRecentEmojiWeight + * @property {string|null} [emoji] RecentEmojiWeight emoji + * @property {number|null} [weight] RecentEmojiWeight weight + */ + + /** + * Constructs a new RecentEmojiWeight. + * @memberof proto + * @classdesc Represents a RecentEmojiWeight. + * @implements IRecentEmojiWeight + * @constructor + * @param {proto.IRecentEmojiWeight=} [properties] Properties to set + */ + function RecentEmojiWeight(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RecentEmojiWeight emoji. + * @member {string} emoji + * @memberof proto.RecentEmojiWeight + * @instance + */ + RecentEmojiWeight.prototype.emoji = ""; + + /** + * RecentEmojiWeight weight. + * @member {number} weight + * @memberof proto.RecentEmojiWeight + * @instance + */ + RecentEmojiWeight.prototype.weight = 0; + + /** + * Creates a new RecentEmojiWeight instance using the specified properties. + * @function create + * @memberof proto.RecentEmojiWeight + * @static + * @param {proto.IRecentEmojiWeight=} [properties] Properties to set + * @returns {proto.RecentEmojiWeight} RecentEmojiWeight instance + */ + RecentEmojiWeight.create = function create(properties) { + return new RecentEmojiWeight(properties); + }; + + /** + * Encodes the specified RecentEmojiWeight message. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages. + * @function encode + * @memberof proto.RecentEmojiWeight + * @static + * @param {proto.IRecentEmojiWeight} message RecentEmojiWeight message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentEmojiWeight.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.emoji != null && Object.hasOwnProperty.call(message, "emoji")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.emoji); + if (message.weight != null && Object.hasOwnProperty.call(message, "weight")) + writer.uint32(/* id 2, wireType 5 =*/21).float(message.weight); + return writer; + }; + + /** + * Encodes the specified RecentEmojiWeight message, length delimited. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.RecentEmojiWeight + * @static + * @param {proto.IRecentEmojiWeight} message RecentEmojiWeight message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentEmojiWeight.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RecentEmojiWeight message from the specified reader or buffer. + * @function decode + * @memberof proto.RecentEmojiWeight + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.RecentEmojiWeight} RecentEmojiWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentEmojiWeight.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentEmojiWeight(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.emoji = reader.string(); + break; + case 2: + message.weight = reader.float(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RecentEmojiWeight message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.RecentEmojiWeight + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.RecentEmojiWeight} RecentEmojiWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentEmojiWeight.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RecentEmojiWeight message. + * @function verify + * @memberof proto.RecentEmojiWeight + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RecentEmojiWeight.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.emoji != null && message.hasOwnProperty("emoji")) + if (!$util.isString(message.emoji)) + return "emoji: string expected"; + if (message.weight != null && message.hasOwnProperty("weight")) + if (typeof message.weight !== "number") + return "weight: number expected"; + return null; + }; + + /** + * Creates a RecentEmojiWeight message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.RecentEmojiWeight + * @static + * @param {Object.} object Plain object + * @returns {proto.RecentEmojiWeight} RecentEmojiWeight + */ + RecentEmojiWeight.fromObject = function fromObject(object) { + if (object instanceof $root.proto.RecentEmojiWeight) + return object; + var message = new $root.proto.RecentEmojiWeight(); + if (object.emoji != null) + message.emoji = String(object.emoji); + if (object.weight != null) + message.weight = Number(object.weight); + return message; + }; + + /** + * Creates a plain object from a RecentEmojiWeight message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.RecentEmojiWeight + * @static + * @param {proto.RecentEmojiWeight} message RecentEmojiWeight + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RecentEmojiWeight.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.emoji = ""; + object.weight = 0; + } + if (message.emoji != null && message.hasOwnProperty("emoji")) + object.emoji = message.emoji; + if (message.weight != null && message.hasOwnProperty("weight")) + object.weight = options.json && !isFinite(message.weight) ? String(message.weight) : message.weight; + return object; + }; + + /** + * Converts this RecentEmojiWeight to JSON. + * @function toJSON + * @memberof proto.RecentEmojiWeight + * @instance + * @returns {Object.} JSON object + */ + RecentEmojiWeight.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RecentEmojiWeight; + })(); + + proto.RecentStickerWeight = (function() { + + /** + * Properties of a RecentStickerWeight. + * @memberof proto + * @interface IRecentStickerWeight + * @property {string|null} [filehash] RecentStickerWeight filehash + * @property {number|null} [weight] RecentStickerWeight weight + */ + + /** + * Constructs a new RecentStickerWeight. + * @memberof proto + * @classdesc Represents a RecentStickerWeight. + * @implements IRecentStickerWeight + * @constructor + * @param {proto.IRecentStickerWeight=} [properties] Properties to set + */ + function RecentStickerWeight(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RecentStickerWeight filehash. + * @member {string} filehash + * @memberof proto.RecentStickerWeight + * @instance + */ + RecentStickerWeight.prototype.filehash = ""; + + /** + * RecentStickerWeight weight. + * @member {number} weight + * @memberof proto.RecentStickerWeight + * @instance + */ + RecentStickerWeight.prototype.weight = 0; + + /** + * Creates a new RecentStickerWeight instance using the specified properties. + * @function create + * @memberof proto.RecentStickerWeight + * @static + * @param {proto.IRecentStickerWeight=} [properties] Properties to set + * @returns {proto.RecentStickerWeight} RecentStickerWeight instance + */ + RecentStickerWeight.create = function create(properties) { + return new RecentStickerWeight(properties); + }; + + /** + * Encodes the specified RecentStickerWeight message. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages. + * @function encode + * @memberof proto.RecentStickerWeight + * @static + * @param {proto.IRecentStickerWeight} message RecentStickerWeight message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentStickerWeight.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.filehash != null && Object.hasOwnProperty.call(message, "filehash")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.filehash); + if (message.weight != null && Object.hasOwnProperty.call(message, "weight")) + writer.uint32(/* id 2, wireType 5 =*/21).float(message.weight); + return writer; + }; + + /** + * Encodes the specified RecentStickerWeight message, length delimited. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.RecentStickerWeight + * @static + * @param {proto.IRecentStickerWeight} message RecentStickerWeight message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RecentStickerWeight.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RecentStickerWeight message from the specified reader or buffer. + * @function decode + * @memberof proto.RecentStickerWeight + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.RecentStickerWeight} RecentStickerWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentStickerWeight.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentStickerWeight(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.filehash = reader.string(); + break; + case 2: + message.weight = reader.float(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RecentStickerWeight message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.RecentStickerWeight + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.RecentStickerWeight} RecentStickerWeight + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RecentStickerWeight.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RecentStickerWeight message. + * @function verify + * @memberof proto.RecentStickerWeight + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RecentStickerWeight.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.filehash != null && message.hasOwnProperty("filehash")) + if (!$util.isString(message.filehash)) + return "filehash: string expected"; + if (message.weight != null && message.hasOwnProperty("weight")) + if (typeof message.weight !== "number") + return "weight: number expected"; + return null; + }; + + /** + * Creates a RecentStickerWeight message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.RecentStickerWeight + * @static + * @param {Object.} object Plain object + * @returns {proto.RecentStickerWeight} RecentStickerWeight + */ + RecentStickerWeight.fromObject = function fromObject(object) { + if (object instanceof $root.proto.RecentStickerWeight) + return object; + var message = new $root.proto.RecentStickerWeight(); + if (object.filehash != null) + message.filehash = String(object.filehash); + if (object.weight != null) + message.weight = Number(object.weight); + return message; + }; + + /** + * Creates a plain object from a RecentStickerWeight message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.RecentStickerWeight + * @static + * @param {proto.RecentStickerWeight} message RecentStickerWeight + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RecentStickerWeight.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.filehash = ""; + object.weight = 0; + } + if (message.filehash != null && message.hasOwnProperty("filehash")) + object.filehash = message.filehash; + if (message.weight != null && message.hasOwnProperty("weight")) + object.weight = options.json && !isFinite(message.weight) ? String(message.weight) : message.weight; + return object; + }; + + /** + * Converts this RecentStickerWeight to JSON. + * @function toJSON + * @memberof proto.RecentStickerWeight + * @instance + * @returns {Object.} JSON object + */ + RecentStickerWeight.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RecentStickerWeight; + })(); + + proto.SyncdPatch = (function() { + + /** + * Properties of a SyncdPatch. + * @memberof proto + * @interface ISyncdPatch + * @property {proto.ISyncdVersion|null} [version] SyncdPatch version + * @property {Array.|null} [mutations] SyncdPatch mutations + * @property {proto.IExternalBlobReference|null} [externalMutations] SyncdPatch externalMutations + * @property {Uint8Array|null} [snapshotMac] SyncdPatch snapshotMac + * @property {Uint8Array|null} [patchMac] SyncdPatch patchMac + * @property {proto.IKeyId|null} [keyId] SyncdPatch keyId + * @property {proto.IExitCode|null} [exitCode] SyncdPatch exitCode + * @property {number|null} [deviceIndex] SyncdPatch deviceIndex + */ + + /** + * Constructs a new SyncdPatch. + * @memberof proto + * @classdesc Represents a SyncdPatch. + * @implements ISyncdPatch + * @constructor + * @param {proto.ISyncdPatch=} [properties] Properties to set + */ + function SyncdPatch(properties) { + this.mutations = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdPatch version. + * @member {proto.ISyncdVersion|null|undefined} version + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.version = null; + + /** + * SyncdPatch mutations. + * @member {Array.} mutations + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.mutations = $util.emptyArray; + + /** + * SyncdPatch externalMutations. + * @member {proto.IExternalBlobReference|null|undefined} externalMutations + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.externalMutations = null; + + /** + * SyncdPatch snapshotMac. + * @member {Uint8Array} snapshotMac + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.snapshotMac = $util.newBuffer([]); + + /** + * SyncdPatch patchMac. + * @member {Uint8Array} patchMac + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.patchMac = $util.newBuffer([]); + + /** + * SyncdPatch keyId. + * @member {proto.IKeyId|null|undefined} keyId + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.keyId = null; + + /** + * SyncdPatch exitCode. + * @member {proto.IExitCode|null|undefined} exitCode + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.exitCode = null; + + /** + * SyncdPatch deviceIndex. + * @member {number} deviceIndex + * @memberof proto.SyncdPatch + * @instance + */ + SyncdPatch.prototype.deviceIndex = 0; + + /** + * Creates a new SyncdPatch instance using the specified properties. + * @function create + * @memberof proto.SyncdPatch + * @static + * @param {proto.ISyncdPatch=} [properties] Properties to set + * @returns {proto.SyncdPatch} SyncdPatch instance + */ + SyncdPatch.create = function create(properties) { + return new SyncdPatch(properties); + }; + + /** + * Encodes the specified SyncdPatch message. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages. + * @function encode + * @memberof proto.SyncdPatch + * @static + * @param {proto.ISyncdPatch} message SyncdPatch message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdPatch.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + $root.proto.SyncdVersion.encode(message.version, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.mutations != null && message.mutations.length) + for (var i = 0; i < message.mutations.length; ++i) + $root.proto.SyncdMutation.encode(message.mutations[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.externalMutations != null && Object.hasOwnProperty.call(message, "externalMutations")) + $root.proto.ExternalBlobReference.encode(message.externalMutations, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.snapshotMac != null && Object.hasOwnProperty.call(message, "snapshotMac")) + writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.snapshotMac); + if (message.patchMac != null && Object.hasOwnProperty.call(message, "patchMac")) + writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.patchMac); + if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId")) + $root.proto.KeyId.encode(message.keyId, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.exitCode != null && Object.hasOwnProperty.call(message, "exitCode")) + $root.proto.ExitCode.encode(message.exitCode, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); + if (message.deviceIndex != null && Object.hasOwnProperty.call(message, "deviceIndex")) + writer.uint32(/* id 8, wireType 0 =*/64).uint32(message.deviceIndex); + return writer; + }; + + /** + * Encodes the specified SyncdPatch message, length delimited. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdPatch + * @static + * @param {proto.ISyncdPatch} message SyncdPatch message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdPatch.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdPatch message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdPatch + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdPatch} SyncdPatch + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdPatch.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdPatch(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.version = $root.proto.SyncdVersion.decode(reader, reader.uint32()); + break; + case 2: + if (!(message.mutations && message.mutations.length)) + message.mutations = []; + message.mutations.push($root.proto.SyncdMutation.decode(reader, reader.uint32())); + break; + case 3: + message.externalMutations = $root.proto.ExternalBlobReference.decode(reader, reader.uint32()); + break; + case 4: + message.snapshotMac = reader.bytes(); + break; + case 5: + message.patchMac = reader.bytes(); + break; + case 6: + message.keyId = $root.proto.KeyId.decode(reader, reader.uint32()); + break; + case 7: + message.exitCode = $root.proto.ExitCode.decode(reader, reader.uint32()); + break; + case 8: + message.deviceIndex = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdPatch message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdPatch + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdPatch} SyncdPatch + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdPatch.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdPatch message. + * @function verify + * @memberof proto.SyncdPatch + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdPatch.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.version != null && message.hasOwnProperty("version")) { + var error = $root.proto.SyncdVersion.verify(message.version); + if (error) + return "version." + error; + } + if (message.mutations != null && message.hasOwnProperty("mutations")) { + if (!Array.isArray(message.mutations)) + return "mutations: array expected"; + for (var i = 0; i < message.mutations.length; ++i) { + var error = $root.proto.SyncdMutation.verify(message.mutations[i]); + if (error) + return "mutations." + error; + } + } + if (message.externalMutations != null && message.hasOwnProperty("externalMutations")) { + var error = $root.proto.ExternalBlobReference.verify(message.externalMutations); + if (error) + return "externalMutations." + error; + } + if (message.snapshotMac != null && message.hasOwnProperty("snapshotMac")) + if (!(message.snapshotMac && typeof message.snapshotMac.length === "number" || $util.isString(message.snapshotMac))) + return "snapshotMac: buffer expected"; + if (message.patchMac != null && message.hasOwnProperty("patchMac")) + if (!(message.patchMac && typeof message.patchMac.length === "number" || $util.isString(message.patchMac))) + return "patchMac: buffer expected"; + if (message.keyId != null && message.hasOwnProperty("keyId")) { + var error = $root.proto.KeyId.verify(message.keyId); + if (error) + return "keyId." + error; + } + if (message.exitCode != null && message.hasOwnProperty("exitCode")) { + var error = $root.proto.ExitCode.verify(message.exitCode); + if (error) + return "exitCode." + error; + } + if (message.deviceIndex != null && message.hasOwnProperty("deviceIndex")) + if (!$util.isInteger(message.deviceIndex)) + return "deviceIndex: integer expected"; + return null; + }; + + /** + * Creates a SyncdPatch message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdPatch + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdPatch} SyncdPatch + */ + SyncdPatch.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdPatch) + return object; + var message = new $root.proto.SyncdPatch(); + if (object.version != null) { + if (typeof object.version !== "object") + throw TypeError(".proto.SyncdPatch.version: object expected"); + message.version = $root.proto.SyncdVersion.fromObject(object.version); + } + if (object.mutations) { + if (!Array.isArray(object.mutations)) + throw TypeError(".proto.SyncdPatch.mutations: array expected"); + message.mutations = []; + for (var i = 0; i < object.mutations.length; ++i) { + if (typeof object.mutations[i] !== "object") + throw TypeError(".proto.SyncdPatch.mutations: object expected"); + message.mutations[i] = $root.proto.SyncdMutation.fromObject(object.mutations[i]); + } + } + if (object.externalMutations != null) { + if (typeof object.externalMutations !== "object") + throw TypeError(".proto.SyncdPatch.externalMutations: object expected"); + message.externalMutations = $root.proto.ExternalBlobReference.fromObject(object.externalMutations); + } + if (object.snapshotMac != null) + if (typeof object.snapshotMac === "string") + $util.base64.decode(object.snapshotMac, message.snapshotMac = $util.newBuffer($util.base64.length(object.snapshotMac)), 0); + else if (object.snapshotMac.length) + message.snapshotMac = object.snapshotMac; + if (object.patchMac != null) + if (typeof object.patchMac === "string") + $util.base64.decode(object.patchMac, message.patchMac = $util.newBuffer($util.base64.length(object.patchMac)), 0); + else if (object.patchMac.length) + message.patchMac = object.patchMac; + if (object.keyId != null) { + if (typeof object.keyId !== "object") + throw TypeError(".proto.SyncdPatch.keyId: object expected"); + message.keyId = $root.proto.KeyId.fromObject(object.keyId); + } + if (object.exitCode != null) { + if (typeof object.exitCode !== "object") + throw TypeError(".proto.SyncdPatch.exitCode: object expected"); + message.exitCode = $root.proto.ExitCode.fromObject(object.exitCode); + } + if (object.deviceIndex != null) + message.deviceIndex = object.deviceIndex >>> 0; + return message; + }; + + /** + * Creates a plain object from a SyncdPatch message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdPatch + * @static + * @param {proto.SyncdPatch} message SyncdPatch + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdPatch.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.mutations = []; + if (options.defaults) { + object.version = null; + object.externalMutations = null; + if (options.bytes === String) + object.snapshotMac = ""; + else { + object.snapshotMac = []; + if (options.bytes !== Array) + object.snapshotMac = $util.newBuffer(object.snapshotMac); + } + if (options.bytes === String) + object.patchMac = ""; + else { + object.patchMac = []; + if (options.bytes !== Array) + object.patchMac = $util.newBuffer(object.patchMac); + } + object.keyId = null; + object.exitCode = null; + object.deviceIndex = 0; + } + if (message.version != null && message.hasOwnProperty("version")) + object.version = $root.proto.SyncdVersion.toObject(message.version, options); + if (message.mutations && message.mutations.length) { + object.mutations = []; + for (var j = 0; j < message.mutations.length; ++j) + object.mutations[j] = $root.proto.SyncdMutation.toObject(message.mutations[j], options); + } + if (message.externalMutations != null && message.hasOwnProperty("externalMutations")) + object.externalMutations = $root.proto.ExternalBlobReference.toObject(message.externalMutations, options); + if (message.snapshotMac != null && message.hasOwnProperty("snapshotMac")) + object.snapshotMac = options.bytes === String ? $util.base64.encode(message.snapshotMac, 0, message.snapshotMac.length) : options.bytes === Array ? Array.prototype.slice.call(message.snapshotMac) : message.snapshotMac; + if (message.patchMac != null && message.hasOwnProperty("patchMac")) + object.patchMac = options.bytes === String ? $util.base64.encode(message.patchMac, 0, message.patchMac.length) : options.bytes === Array ? Array.prototype.slice.call(message.patchMac) : message.patchMac; + if (message.keyId != null && message.hasOwnProperty("keyId")) + object.keyId = $root.proto.KeyId.toObject(message.keyId, options); + if (message.exitCode != null && message.hasOwnProperty("exitCode")) + object.exitCode = $root.proto.ExitCode.toObject(message.exitCode, options); + if (message.deviceIndex != null && message.hasOwnProperty("deviceIndex")) + object.deviceIndex = message.deviceIndex; + return object; + }; + + /** + * Converts this SyncdPatch to JSON. + * @function toJSON + * @memberof proto.SyncdPatch + * @instance + * @returns {Object.} JSON object + */ + SyncdPatch.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdPatch; + })(); + + proto.SyncdMutation = (function() { + + /** + * Properties of a SyncdMutation. + * @memberof proto + * @interface ISyncdMutation + * @property {proto.SyncdMutation.SyncdMutationSyncdOperation|null} [operation] SyncdMutation operation + * @property {proto.ISyncdRecord|null} [record] SyncdMutation record + */ + + /** + * Constructs a new SyncdMutation. + * @memberof proto + * @classdesc Represents a SyncdMutation. + * @implements ISyncdMutation + * @constructor + * @param {proto.ISyncdMutation=} [properties] Properties to set + */ + function SyncdMutation(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdMutation operation. + * @member {proto.SyncdMutation.SyncdMutationSyncdOperation} operation + * @memberof proto.SyncdMutation + * @instance + */ + SyncdMutation.prototype.operation = 0; + + /** + * SyncdMutation record. + * @member {proto.ISyncdRecord|null|undefined} record + * @memberof proto.SyncdMutation + * @instance + */ + SyncdMutation.prototype.record = null; + + /** + * Creates a new SyncdMutation instance using the specified properties. + * @function create + * @memberof proto.SyncdMutation + * @static + * @param {proto.ISyncdMutation=} [properties] Properties to set + * @returns {proto.SyncdMutation} SyncdMutation instance + */ + SyncdMutation.create = function create(properties) { + return new SyncdMutation(properties); + }; + + /** + * Encodes the specified SyncdMutation message. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages. + * @function encode + * @memberof proto.SyncdMutation + * @static + * @param {proto.ISyncdMutation} message SyncdMutation message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdMutation.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.operation != null && Object.hasOwnProperty.call(message, "operation")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.operation); + if (message.record != null && Object.hasOwnProperty.call(message, "record")) + $root.proto.SyncdRecord.encode(message.record, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SyncdMutation message, length delimited. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdMutation + * @static + * @param {proto.ISyncdMutation} message SyncdMutation message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdMutation.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdMutation message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdMutation + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdMutation} SyncdMutation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdMutation.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdMutation(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.operation = reader.int32(); + break; + case 2: + message.record = $root.proto.SyncdRecord.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdMutation message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdMutation + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdMutation} SyncdMutation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdMutation.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdMutation message. + * @function verify + * @memberof proto.SyncdMutation + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdMutation.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.operation != null && message.hasOwnProperty("operation")) + switch (message.operation) { + default: + return "operation: enum value expected"; + case 0: + case 1: + break; + } + if (message.record != null && message.hasOwnProperty("record")) { + var error = $root.proto.SyncdRecord.verify(message.record); + if (error) + return "record." + error; + } + return null; + }; + + /** + * Creates a SyncdMutation message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdMutation + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdMutation} SyncdMutation + */ + SyncdMutation.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdMutation) + return object; + var message = new $root.proto.SyncdMutation(); + switch (object.operation) { + case "SET": + case 0: + message.operation = 0; + break; + case "REMOVE": + case 1: + message.operation = 1; + break; + } + if (object.record != null) { + if (typeof object.record !== "object") + throw TypeError(".proto.SyncdMutation.record: object expected"); + message.record = $root.proto.SyncdRecord.fromObject(object.record); + } + return message; + }; + + /** + * Creates a plain object from a SyncdMutation message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdMutation + * @static + * @param {proto.SyncdMutation} message SyncdMutation + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdMutation.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.operation = options.enums === String ? "SET" : 0; + object.record = null; + } + if (message.operation != null && message.hasOwnProperty("operation")) + object.operation = options.enums === String ? $root.proto.SyncdMutation.SyncdMutationSyncdOperation[message.operation] : message.operation; + if (message.record != null && message.hasOwnProperty("record")) + object.record = $root.proto.SyncdRecord.toObject(message.record, options); + return object; + }; + + /** + * Converts this SyncdMutation to JSON. + * @function toJSON + * @memberof proto.SyncdMutation + * @instance + * @returns {Object.} JSON object + */ + SyncdMutation.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * SyncdMutationSyncdOperation enum. + * @name proto.SyncdMutation.SyncdMutationSyncdOperation + * @enum {number} + * @property {number} SET=0 SET value + * @property {number} REMOVE=1 REMOVE value + */ + SyncdMutation.SyncdMutationSyncdOperation = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "SET"] = 0; + values[valuesById[1] = "REMOVE"] = 1; + return values; + })(); + + return SyncdMutation; + })(); + + proto.SyncdMutations = (function() { + + /** + * Properties of a SyncdMutations. + * @memberof proto + * @interface ISyncdMutations + * @property {Array.|null} [mutations] SyncdMutations mutations + */ + + /** + * Constructs a new SyncdMutations. + * @memberof proto + * @classdesc Represents a SyncdMutations. + * @implements ISyncdMutations + * @constructor + * @param {proto.ISyncdMutations=} [properties] Properties to set + */ + function SyncdMutations(properties) { + this.mutations = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdMutations mutations. + * @member {Array.} mutations + * @memberof proto.SyncdMutations + * @instance + */ + SyncdMutations.prototype.mutations = $util.emptyArray; + + /** + * Creates a new SyncdMutations instance using the specified properties. + * @function create + * @memberof proto.SyncdMutations + * @static + * @param {proto.ISyncdMutations=} [properties] Properties to set + * @returns {proto.SyncdMutations} SyncdMutations instance + */ + SyncdMutations.create = function create(properties) { + return new SyncdMutations(properties); + }; + + /** + * Encodes the specified SyncdMutations message. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages. + * @function encode + * @memberof proto.SyncdMutations + * @static + * @param {proto.ISyncdMutations} message SyncdMutations message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdMutations.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.mutations != null && message.mutations.length) + for (var i = 0; i < message.mutations.length; ++i) + $root.proto.SyncdMutation.encode(message.mutations[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SyncdMutations message, length delimited. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdMutations + * @static + * @param {proto.ISyncdMutations} message SyncdMutations message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdMutations.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdMutations message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdMutations + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdMutations} SyncdMutations + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdMutations.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdMutations(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.mutations && message.mutations.length)) + message.mutations = []; + message.mutations.push($root.proto.SyncdMutation.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdMutations message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdMutations + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdMutations} SyncdMutations + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdMutations.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdMutations message. + * @function verify + * @memberof proto.SyncdMutations + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdMutations.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.mutations != null && message.hasOwnProperty("mutations")) { + if (!Array.isArray(message.mutations)) + return "mutations: array expected"; + for (var i = 0; i < message.mutations.length; ++i) { + var error = $root.proto.SyncdMutation.verify(message.mutations[i]); + if (error) + return "mutations." + error; + } + } + return null; + }; + + /** + * Creates a SyncdMutations message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdMutations + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdMutations} SyncdMutations + */ + SyncdMutations.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdMutations) + return object; + var message = new $root.proto.SyncdMutations(); + if (object.mutations) { + if (!Array.isArray(object.mutations)) + throw TypeError(".proto.SyncdMutations.mutations: array expected"); + message.mutations = []; + for (var i = 0; i < object.mutations.length; ++i) { + if (typeof object.mutations[i] !== "object") + throw TypeError(".proto.SyncdMutations.mutations: object expected"); + message.mutations[i] = $root.proto.SyncdMutation.fromObject(object.mutations[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a SyncdMutations message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdMutations + * @static + * @param {proto.SyncdMutations} message SyncdMutations + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdMutations.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.mutations = []; + if (message.mutations && message.mutations.length) { + object.mutations = []; + for (var j = 0; j < message.mutations.length; ++j) + object.mutations[j] = $root.proto.SyncdMutation.toObject(message.mutations[j], options); + } + return object; + }; + + /** + * Converts this SyncdMutations to JSON. + * @function toJSON + * @memberof proto.SyncdMutations + * @instance + * @returns {Object.} JSON object + */ + SyncdMutations.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdMutations; + })(); + + proto.SyncdSnapshot = (function() { + + /** + * Properties of a SyncdSnapshot. + * @memberof proto + * @interface ISyncdSnapshot + * @property {proto.ISyncdVersion|null} [version] SyncdSnapshot version + * @property {Array.|null} [records] SyncdSnapshot records + * @property {Uint8Array|null} [mac] SyncdSnapshot mac + * @property {proto.IKeyId|null} [keyId] SyncdSnapshot keyId + */ + + /** + * Constructs a new SyncdSnapshot. + * @memberof proto + * @classdesc Represents a SyncdSnapshot. + * @implements ISyncdSnapshot + * @constructor + * @param {proto.ISyncdSnapshot=} [properties] Properties to set + */ + function SyncdSnapshot(properties) { + this.records = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdSnapshot version. + * @member {proto.ISyncdVersion|null|undefined} version + * @memberof proto.SyncdSnapshot + * @instance + */ + SyncdSnapshot.prototype.version = null; + + /** + * SyncdSnapshot records. + * @member {Array.} records + * @memberof proto.SyncdSnapshot + * @instance + */ + SyncdSnapshot.prototype.records = $util.emptyArray; + + /** + * SyncdSnapshot mac. + * @member {Uint8Array} mac + * @memberof proto.SyncdSnapshot + * @instance + */ + SyncdSnapshot.prototype.mac = $util.newBuffer([]); + + /** + * SyncdSnapshot keyId. + * @member {proto.IKeyId|null|undefined} keyId + * @memberof proto.SyncdSnapshot + * @instance + */ + SyncdSnapshot.prototype.keyId = null; + + /** + * Creates a new SyncdSnapshot instance using the specified properties. + * @function create + * @memberof proto.SyncdSnapshot + * @static + * @param {proto.ISyncdSnapshot=} [properties] Properties to set + * @returns {proto.SyncdSnapshot} SyncdSnapshot instance + */ + SyncdSnapshot.create = function create(properties) { + return new SyncdSnapshot(properties); + }; + + /** + * Encodes the specified SyncdSnapshot message. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages. + * @function encode + * @memberof proto.SyncdSnapshot + * @static + * @param {proto.ISyncdSnapshot} message SyncdSnapshot message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdSnapshot.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + $root.proto.SyncdVersion.encode(message.version, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.records != null && message.records.length) + for (var i = 0; i < message.records.length; ++i) + $root.proto.SyncdRecord.encode(message.records[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.mac != null && Object.hasOwnProperty.call(message, "mac")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.mac); + if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId")) + $root.proto.KeyId.encode(message.keyId, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SyncdSnapshot message, length delimited. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdSnapshot + * @static + * @param {proto.ISyncdSnapshot} message SyncdSnapshot message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdSnapshot.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdSnapshot message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdSnapshot + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdSnapshot} SyncdSnapshot + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdSnapshot.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdSnapshot(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.version = $root.proto.SyncdVersion.decode(reader, reader.uint32()); + break; + case 2: + if (!(message.records && message.records.length)) + message.records = []; + message.records.push($root.proto.SyncdRecord.decode(reader, reader.uint32())); + break; + case 3: + message.mac = reader.bytes(); + break; + case 4: + message.keyId = $root.proto.KeyId.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdSnapshot message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdSnapshot + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdSnapshot} SyncdSnapshot + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdSnapshot.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdSnapshot message. + * @function verify + * @memberof proto.SyncdSnapshot + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdSnapshot.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.version != null && message.hasOwnProperty("version")) { + var error = $root.proto.SyncdVersion.verify(message.version); + if (error) + return "version." + error; + } + if (message.records != null && message.hasOwnProperty("records")) { + if (!Array.isArray(message.records)) + return "records: array expected"; + for (var i = 0; i < message.records.length; ++i) { + var error = $root.proto.SyncdRecord.verify(message.records[i]); + if (error) + return "records." + error; + } + } + if (message.mac != null && message.hasOwnProperty("mac")) + if (!(message.mac && typeof message.mac.length === "number" || $util.isString(message.mac))) + return "mac: buffer expected"; + if (message.keyId != null && message.hasOwnProperty("keyId")) { + var error = $root.proto.KeyId.verify(message.keyId); + if (error) + return "keyId." + error; + } + return null; + }; + + /** + * Creates a SyncdSnapshot message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdSnapshot + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdSnapshot} SyncdSnapshot + */ + SyncdSnapshot.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdSnapshot) + return object; + var message = new $root.proto.SyncdSnapshot(); + if (object.version != null) { + if (typeof object.version !== "object") + throw TypeError(".proto.SyncdSnapshot.version: object expected"); + message.version = $root.proto.SyncdVersion.fromObject(object.version); + } + if (object.records) { + if (!Array.isArray(object.records)) + throw TypeError(".proto.SyncdSnapshot.records: array expected"); + message.records = []; + for (var i = 0; i < object.records.length; ++i) { + if (typeof object.records[i] !== "object") + throw TypeError(".proto.SyncdSnapshot.records: object expected"); + message.records[i] = $root.proto.SyncdRecord.fromObject(object.records[i]); + } + } + if (object.mac != null) + if (typeof object.mac === "string") + $util.base64.decode(object.mac, message.mac = $util.newBuffer($util.base64.length(object.mac)), 0); + else if (object.mac.length) + message.mac = object.mac; + if (object.keyId != null) { + if (typeof object.keyId !== "object") + throw TypeError(".proto.SyncdSnapshot.keyId: object expected"); + message.keyId = $root.proto.KeyId.fromObject(object.keyId); + } + return message; + }; + + /** + * Creates a plain object from a SyncdSnapshot message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdSnapshot + * @static + * @param {proto.SyncdSnapshot} message SyncdSnapshot + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdSnapshot.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.records = []; + if (options.defaults) { + object.version = null; + if (options.bytes === String) + object.mac = ""; + else { + object.mac = []; + if (options.bytes !== Array) + object.mac = $util.newBuffer(object.mac); + } + object.keyId = null; + } + if (message.version != null && message.hasOwnProperty("version")) + object.version = $root.proto.SyncdVersion.toObject(message.version, options); + if (message.records && message.records.length) { + object.records = []; + for (var j = 0; j < message.records.length; ++j) + object.records[j] = $root.proto.SyncdRecord.toObject(message.records[j], options); + } + if (message.mac != null && message.hasOwnProperty("mac")) + object.mac = options.bytes === String ? $util.base64.encode(message.mac, 0, message.mac.length) : options.bytes === Array ? Array.prototype.slice.call(message.mac) : message.mac; + if (message.keyId != null && message.hasOwnProperty("keyId")) + object.keyId = $root.proto.KeyId.toObject(message.keyId, options); + return object; + }; + + /** + * Converts this SyncdSnapshot to JSON. + * @function toJSON + * @memberof proto.SyncdSnapshot + * @instance + * @returns {Object.} JSON object + */ + SyncdSnapshot.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdSnapshot; + })(); + + proto.ExternalBlobReference = (function() { + + /** + * Properties of an ExternalBlobReference. + * @memberof proto + * @interface IExternalBlobReference + * @property {Uint8Array|null} [mediaKey] ExternalBlobReference mediaKey + * @property {string|null} [directPath] ExternalBlobReference directPath + * @property {string|null} [handle] ExternalBlobReference handle + * @property {number|Long|null} [fileSizeBytes] ExternalBlobReference fileSizeBytes + * @property {Uint8Array|null} [fileSha256] ExternalBlobReference fileSha256 + * @property {Uint8Array|null} [fileEncSha256] ExternalBlobReference fileEncSha256 + */ + + /** + * Constructs a new ExternalBlobReference. + * @memberof proto + * @classdesc Represents an ExternalBlobReference. + * @implements IExternalBlobReference + * @constructor + * @param {proto.IExternalBlobReference=} [properties] Properties to set + */ + function ExternalBlobReference(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ExternalBlobReference mediaKey. + * @member {Uint8Array} mediaKey + * @memberof proto.ExternalBlobReference + * @instance + */ + ExternalBlobReference.prototype.mediaKey = $util.newBuffer([]); + + /** + * ExternalBlobReference directPath. + * @member {string} directPath + * @memberof proto.ExternalBlobReference + * @instance + */ + ExternalBlobReference.prototype.directPath = ""; + + /** + * ExternalBlobReference handle. + * @member {string} handle + * @memberof proto.ExternalBlobReference + * @instance + */ + ExternalBlobReference.prototype.handle = ""; + + /** + * ExternalBlobReference fileSizeBytes. + * @member {number|Long} fileSizeBytes + * @memberof proto.ExternalBlobReference + * @instance + */ + ExternalBlobReference.prototype.fileSizeBytes = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * ExternalBlobReference fileSha256. + * @member {Uint8Array} fileSha256 + * @memberof proto.ExternalBlobReference + * @instance + */ + ExternalBlobReference.prototype.fileSha256 = $util.newBuffer([]); + + /** + * ExternalBlobReference fileEncSha256. + * @member {Uint8Array} fileEncSha256 + * @memberof proto.ExternalBlobReference + * @instance + */ + ExternalBlobReference.prototype.fileEncSha256 = $util.newBuffer([]); + + /** + * Creates a new ExternalBlobReference instance using the specified properties. + * @function create + * @memberof proto.ExternalBlobReference + * @static + * @param {proto.IExternalBlobReference=} [properties] Properties to set + * @returns {proto.ExternalBlobReference} ExternalBlobReference instance + */ + ExternalBlobReference.create = function create(properties) { + return new ExternalBlobReference(properties); + }; + + /** + * Encodes the specified ExternalBlobReference message. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages. + * @function encode + * @memberof proto.ExternalBlobReference + * @static + * @param {proto.IExternalBlobReference} message ExternalBlobReference message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ExternalBlobReference.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.mediaKey); + if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.directPath); + if (message.handle != null && Object.hasOwnProperty.call(message, "handle")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.handle); + if (message.fileSizeBytes != null && Object.hasOwnProperty.call(message, "fileSizeBytes")) + writer.uint32(/* id 4, wireType 0 =*/32).uint64(message.fileSizeBytes); + if (message.fileSha256 != null && Object.hasOwnProperty.call(message, "fileSha256")) + writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.fileSha256); + if (message.fileEncSha256 != null && Object.hasOwnProperty.call(message, "fileEncSha256")) + writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.fileEncSha256); + return writer; + }; + + /** + * Encodes the specified ExternalBlobReference message, length delimited. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ExternalBlobReference + * @static + * @param {proto.IExternalBlobReference} message ExternalBlobReference message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ExternalBlobReference.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an ExternalBlobReference message from the specified reader or buffer. + * @function decode + * @memberof proto.ExternalBlobReference + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ExternalBlobReference} ExternalBlobReference + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ExternalBlobReference.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ExternalBlobReference(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.mediaKey = reader.bytes(); + break; + case 2: + message.directPath = reader.string(); + break; + case 3: + message.handle = reader.string(); + break; + case 4: + message.fileSizeBytes = reader.uint64(); + break; + case 5: + message.fileSha256 = reader.bytes(); + break; + case 6: + message.fileEncSha256 = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an ExternalBlobReference message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ExternalBlobReference + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ExternalBlobReference} ExternalBlobReference + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ExternalBlobReference.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an ExternalBlobReference message. + * @function verify + * @memberof proto.ExternalBlobReference + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ExternalBlobReference.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey))) + return "mediaKey: buffer expected"; + if (message.directPath != null && message.hasOwnProperty("directPath")) + if (!$util.isString(message.directPath)) + return "directPath: string expected"; + if (message.handle != null && message.hasOwnProperty("handle")) + if (!$util.isString(message.handle)) + return "handle: string expected"; + if (message.fileSizeBytes != null && message.hasOwnProperty("fileSizeBytes")) + if (!$util.isInteger(message.fileSizeBytes) && !(message.fileSizeBytes && $util.isInteger(message.fileSizeBytes.low) && $util.isInteger(message.fileSizeBytes.high))) + return "fileSizeBytes: integer|Long expected"; + if (message.fileSha256 != null && message.hasOwnProperty("fileSha256")) + if (!(message.fileSha256 && typeof message.fileSha256.length === "number" || $util.isString(message.fileSha256))) + return "fileSha256: buffer expected"; + if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256")) + if (!(message.fileEncSha256 && typeof message.fileEncSha256.length === "number" || $util.isString(message.fileEncSha256))) + return "fileEncSha256: buffer expected"; + return null; + }; + + /** + * Creates an ExternalBlobReference message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ExternalBlobReference + * @static + * @param {Object.} object Plain object + * @returns {proto.ExternalBlobReference} ExternalBlobReference + */ + ExternalBlobReference.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ExternalBlobReference) + return object; + var message = new $root.proto.ExternalBlobReference(); + if (object.mediaKey != null) + if (typeof object.mediaKey === "string") + $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0); + else if (object.mediaKey.length) + message.mediaKey = object.mediaKey; + if (object.directPath != null) + message.directPath = String(object.directPath); + if (object.handle != null) + message.handle = String(object.handle); + if (object.fileSizeBytes != null) + if ($util.Long) + (message.fileSizeBytes = $util.Long.fromValue(object.fileSizeBytes)).unsigned = true; + else if (typeof object.fileSizeBytes === "string") + message.fileSizeBytes = parseInt(object.fileSizeBytes, 10); + else if (typeof object.fileSizeBytes === "number") + message.fileSizeBytes = object.fileSizeBytes; + else if (typeof object.fileSizeBytes === "object") + message.fileSizeBytes = new $util.LongBits(object.fileSizeBytes.low >>> 0, object.fileSizeBytes.high >>> 0).toNumber(true); + if (object.fileSha256 != null) + if (typeof object.fileSha256 === "string") + $util.base64.decode(object.fileSha256, message.fileSha256 = $util.newBuffer($util.base64.length(object.fileSha256)), 0); + else if (object.fileSha256.length) + message.fileSha256 = object.fileSha256; + if (object.fileEncSha256 != null) + if (typeof object.fileEncSha256 === "string") + $util.base64.decode(object.fileEncSha256, message.fileEncSha256 = $util.newBuffer($util.base64.length(object.fileEncSha256)), 0); + else if (object.fileEncSha256.length) + message.fileEncSha256 = object.fileEncSha256; + return message; + }; + + /** + * Creates a plain object from an ExternalBlobReference message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ExternalBlobReference + * @static + * @param {proto.ExternalBlobReference} message ExternalBlobReference + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ExternalBlobReference.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.mediaKey = ""; + else { + object.mediaKey = []; + if (options.bytes !== Array) + object.mediaKey = $util.newBuffer(object.mediaKey); + } + object.directPath = ""; + object.handle = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.fileSizeBytes = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.fileSizeBytes = options.longs === String ? "0" : 0; + if (options.bytes === String) + object.fileSha256 = ""; + else { + object.fileSha256 = []; + if (options.bytes !== Array) + object.fileSha256 = $util.newBuffer(object.fileSha256); + } + if (options.bytes === String) + object.fileEncSha256 = ""; + else { + object.fileEncSha256 = []; + if (options.bytes !== Array) + object.fileEncSha256 = $util.newBuffer(object.fileEncSha256); + } + } + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey; + if (message.directPath != null && message.hasOwnProperty("directPath")) + object.directPath = message.directPath; + if (message.handle != null && message.hasOwnProperty("handle")) + object.handle = message.handle; + if (message.fileSizeBytes != null && message.hasOwnProperty("fileSizeBytes")) + if (typeof message.fileSizeBytes === "number") + object.fileSizeBytes = options.longs === String ? String(message.fileSizeBytes) : message.fileSizeBytes; + else + object.fileSizeBytes = options.longs === String ? $util.Long.prototype.toString.call(message.fileSizeBytes) : options.longs === Number ? new $util.LongBits(message.fileSizeBytes.low >>> 0, message.fileSizeBytes.high >>> 0).toNumber(true) : message.fileSizeBytes; + if (message.fileSha256 != null && message.hasOwnProperty("fileSha256")) + object.fileSha256 = options.bytes === String ? $util.base64.encode(message.fileSha256, 0, message.fileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileSha256) : message.fileSha256; + if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256")) + object.fileEncSha256 = options.bytes === String ? $util.base64.encode(message.fileEncSha256, 0, message.fileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileEncSha256) : message.fileEncSha256; + return object; + }; + + /** + * Converts this ExternalBlobReference to JSON. + * @function toJSON + * @memberof proto.ExternalBlobReference + * @instance + * @returns {Object.} JSON object + */ + ExternalBlobReference.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ExternalBlobReference; + })(); + + proto.SyncdRecord = (function() { + + /** + * Properties of a SyncdRecord. + * @memberof proto + * @interface ISyncdRecord + * @property {proto.ISyncdIndex|null} [index] SyncdRecord index + * @property {proto.ISyncdValue|null} [value] SyncdRecord value + * @property {proto.IKeyId|null} [keyId] SyncdRecord keyId + */ + + /** + * Constructs a new SyncdRecord. + * @memberof proto + * @classdesc Represents a SyncdRecord. + * @implements ISyncdRecord + * @constructor + * @param {proto.ISyncdRecord=} [properties] Properties to set + */ + function SyncdRecord(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdRecord index. + * @member {proto.ISyncdIndex|null|undefined} index + * @memberof proto.SyncdRecord + * @instance + */ + SyncdRecord.prototype.index = null; + + /** + * SyncdRecord value. + * @member {proto.ISyncdValue|null|undefined} value + * @memberof proto.SyncdRecord + * @instance + */ + SyncdRecord.prototype.value = null; + + /** + * SyncdRecord keyId. + * @member {proto.IKeyId|null|undefined} keyId + * @memberof proto.SyncdRecord + * @instance + */ + SyncdRecord.prototype.keyId = null; + + /** + * Creates a new SyncdRecord instance using the specified properties. + * @function create + * @memberof proto.SyncdRecord + * @static + * @param {proto.ISyncdRecord=} [properties] Properties to set + * @returns {proto.SyncdRecord} SyncdRecord instance + */ + SyncdRecord.create = function create(properties) { + return new SyncdRecord(properties); + }; + + /** + * Encodes the specified SyncdRecord message. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages. + * @function encode + * @memberof proto.SyncdRecord + * @static + * @param {proto.ISyncdRecord} message SyncdRecord message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdRecord.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.index != null && Object.hasOwnProperty.call(message, "index")) + $root.proto.SyncdIndex.encode(message.index, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.value != null && Object.hasOwnProperty.call(message, "value")) + $root.proto.SyncdValue.encode(message.value, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId")) + $root.proto.KeyId.encode(message.keyId, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SyncdRecord message, length delimited. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdRecord + * @static + * @param {proto.ISyncdRecord} message SyncdRecord message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdRecord.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdRecord message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdRecord + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdRecord} SyncdRecord + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdRecord.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdRecord(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.index = $root.proto.SyncdIndex.decode(reader, reader.uint32()); + break; + case 2: + message.value = $root.proto.SyncdValue.decode(reader, reader.uint32()); + break; + case 3: + message.keyId = $root.proto.KeyId.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdRecord message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdRecord + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdRecord} SyncdRecord + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdRecord.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdRecord message. + * @function verify + * @memberof proto.SyncdRecord + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdRecord.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.index != null && message.hasOwnProperty("index")) { + var error = $root.proto.SyncdIndex.verify(message.index); + if (error) + return "index." + error; + } + if (message.value != null && message.hasOwnProperty("value")) { + var error = $root.proto.SyncdValue.verify(message.value); + if (error) + return "value." + error; + } + if (message.keyId != null && message.hasOwnProperty("keyId")) { + var error = $root.proto.KeyId.verify(message.keyId); + if (error) + return "keyId." + error; + } + return null; + }; + + /** + * Creates a SyncdRecord message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdRecord + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdRecord} SyncdRecord + */ + SyncdRecord.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdRecord) + return object; + var message = new $root.proto.SyncdRecord(); + if (object.index != null) { + if (typeof object.index !== "object") + throw TypeError(".proto.SyncdRecord.index: object expected"); + message.index = $root.proto.SyncdIndex.fromObject(object.index); + } + if (object.value != null) { + if (typeof object.value !== "object") + throw TypeError(".proto.SyncdRecord.value: object expected"); + message.value = $root.proto.SyncdValue.fromObject(object.value); + } + if (object.keyId != null) { + if (typeof object.keyId !== "object") + throw TypeError(".proto.SyncdRecord.keyId: object expected"); + message.keyId = $root.proto.KeyId.fromObject(object.keyId); + } + return message; + }; + + /** + * Creates a plain object from a SyncdRecord message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdRecord + * @static + * @param {proto.SyncdRecord} message SyncdRecord + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdRecord.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.index = null; + object.value = null; + object.keyId = null; + } + if (message.index != null && message.hasOwnProperty("index")) + object.index = $root.proto.SyncdIndex.toObject(message.index, options); + if (message.value != null && message.hasOwnProperty("value")) + object.value = $root.proto.SyncdValue.toObject(message.value, options); + if (message.keyId != null && message.hasOwnProperty("keyId")) + object.keyId = $root.proto.KeyId.toObject(message.keyId, options); + return object; + }; + + /** + * Converts this SyncdRecord to JSON. + * @function toJSON + * @memberof proto.SyncdRecord + * @instance + * @returns {Object.} JSON object + */ + SyncdRecord.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdRecord; + })(); + + proto.KeyId = (function() { + + /** + * Properties of a KeyId. + * @memberof proto + * @interface IKeyId + * @property {Uint8Array|null} [id] KeyId id + */ + + /** + * Constructs a new KeyId. + * @memberof proto + * @classdesc Represents a KeyId. + * @implements IKeyId + * @constructor + * @param {proto.IKeyId=} [properties] Properties to set + */ + function KeyId(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * KeyId id. + * @member {Uint8Array} id + * @memberof proto.KeyId + * @instance + */ + KeyId.prototype.id = $util.newBuffer([]); + + /** + * Creates a new KeyId instance using the specified properties. + * @function create + * @memberof proto.KeyId + * @static + * @param {proto.IKeyId=} [properties] Properties to set + * @returns {proto.KeyId} KeyId instance + */ + KeyId.create = function create(properties) { + return new KeyId(properties); + }; + + /** + * Encodes the specified KeyId message. Does not implicitly {@link proto.KeyId.verify|verify} messages. + * @function encode + * @memberof proto.KeyId + * @static + * @param {proto.IKeyId} message KeyId message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + KeyId.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.id); + return writer; + }; + + /** + * Encodes the specified KeyId message, length delimited. Does not implicitly {@link proto.KeyId.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.KeyId + * @static + * @param {proto.IKeyId} message KeyId message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + KeyId.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a KeyId message from the specified reader or buffer. + * @function decode + * @memberof proto.KeyId + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.KeyId} KeyId + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + KeyId.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.KeyId(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a KeyId message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.KeyId + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.KeyId} KeyId + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + KeyId.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a KeyId message. + * @function verify + * @memberof proto.KeyId + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + KeyId.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!(message.id && typeof message.id.length === "number" || $util.isString(message.id))) + return "id: buffer expected"; + return null; + }; + + /** + * Creates a KeyId message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.KeyId + * @static + * @param {Object.} object Plain object + * @returns {proto.KeyId} KeyId + */ + KeyId.fromObject = function fromObject(object) { + if (object instanceof $root.proto.KeyId) + return object; + var message = new $root.proto.KeyId(); + if (object.id != null) + if (typeof object.id === "string") + $util.base64.decode(object.id, message.id = $util.newBuffer($util.base64.length(object.id)), 0); + else if (object.id.length) + message.id = object.id; + return message; + }; + + /** + * Creates a plain object from a KeyId message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.KeyId + * @static + * @param {proto.KeyId} message KeyId + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + KeyId.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + if (options.bytes === String) + object.id = ""; + else { + object.id = []; + if (options.bytes !== Array) + object.id = $util.newBuffer(object.id); + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = options.bytes === String ? $util.base64.encode(message.id, 0, message.id.length) : options.bytes === Array ? Array.prototype.slice.call(message.id) : message.id; + return object; + }; + + /** + * Converts this KeyId to JSON. + * @function toJSON + * @memberof proto.KeyId + * @instance + * @returns {Object.} JSON object + */ + KeyId.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return KeyId; + })(); + + proto.SyncdValue = (function() { + + /** + * Properties of a SyncdValue. + * @memberof proto + * @interface ISyncdValue + * @property {Uint8Array|null} [blob] SyncdValue blob + */ + + /** + * Constructs a new SyncdValue. + * @memberof proto + * @classdesc Represents a SyncdValue. + * @implements ISyncdValue + * @constructor + * @param {proto.ISyncdValue=} [properties] Properties to set + */ + function SyncdValue(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdValue blob. + * @member {Uint8Array} blob + * @memberof proto.SyncdValue + * @instance + */ + SyncdValue.prototype.blob = $util.newBuffer([]); + + /** + * Creates a new SyncdValue instance using the specified properties. + * @function create + * @memberof proto.SyncdValue + * @static + * @param {proto.ISyncdValue=} [properties] Properties to set + * @returns {proto.SyncdValue} SyncdValue instance + */ + SyncdValue.create = function create(properties) { + return new SyncdValue(properties); + }; + + /** + * Encodes the specified SyncdValue message. Does not implicitly {@link proto.SyncdValue.verify|verify} messages. + * @function encode + * @memberof proto.SyncdValue + * @static + * @param {proto.ISyncdValue} message SyncdValue message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdValue.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.blob != null && Object.hasOwnProperty.call(message, "blob")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.blob); + return writer; + }; + + /** + * Encodes the specified SyncdValue message, length delimited. Does not implicitly {@link proto.SyncdValue.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdValue + * @static + * @param {proto.ISyncdValue} message SyncdValue message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdValue.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdValue message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdValue + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdValue} SyncdValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdValue.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdValue(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.blob = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdValue message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdValue + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdValue} SyncdValue + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdValue.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdValue message. + * @function verify + * @memberof proto.SyncdValue + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdValue.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.blob != null && message.hasOwnProperty("blob")) + if (!(message.blob && typeof message.blob.length === "number" || $util.isString(message.blob))) + return "blob: buffer expected"; + return null; + }; + + /** + * Creates a SyncdValue message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdValue + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdValue} SyncdValue + */ + SyncdValue.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdValue) + return object; + var message = new $root.proto.SyncdValue(); + if (object.blob != null) + if (typeof object.blob === "string") + $util.base64.decode(object.blob, message.blob = $util.newBuffer($util.base64.length(object.blob)), 0); + else if (object.blob.length) + message.blob = object.blob; + return message; + }; + + /** + * Creates a plain object from a SyncdValue message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdValue + * @static + * @param {proto.SyncdValue} message SyncdValue + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdValue.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + if (options.bytes === String) + object.blob = ""; + else { + object.blob = []; + if (options.bytes !== Array) + object.blob = $util.newBuffer(object.blob); + } + if (message.blob != null && message.hasOwnProperty("blob")) + object.blob = options.bytes === String ? $util.base64.encode(message.blob, 0, message.blob.length) : options.bytes === Array ? Array.prototype.slice.call(message.blob) : message.blob; + return object; + }; + + /** + * Converts this SyncdValue to JSON. + * @function toJSON + * @memberof proto.SyncdValue + * @instance + * @returns {Object.} JSON object + */ + SyncdValue.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdValue; + })(); + + proto.SyncdIndex = (function() { + + /** + * Properties of a SyncdIndex. + * @memberof proto + * @interface ISyncdIndex + * @property {Uint8Array|null} [blob] SyncdIndex blob + */ + + /** + * Constructs a new SyncdIndex. + * @memberof proto + * @classdesc Represents a SyncdIndex. + * @implements ISyncdIndex + * @constructor + * @param {proto.ISyncdIndex=} [properties] Properties to set + */ + function SyncdIndex(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdIndex blob. + * @member {Uint8Array} blob + * @memberof proto.SyncdIndex + * @instance + */ + SyncdIndex.prototype.blob = $util.newBuffer([]); + + /** + * Creates a new SyncdIndex instance using the specified properties. + * @function create + * @memberof proto.SyncdIndex + * @static + * @param {proto.ISyncdIndex=} [properties] Properties to set + * @returns {proto.SyncdIndex} SyncdIndex instance + */ + SyncdIndex.create = function create(properties) { + return new SyncdIndex(properties); + }; + + /** + * Encodes the specified SyncdIndex message. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages. + * @function encode + * @memberof proto.SyncdIndex + * @static + * @param {proto.ISyncdIndex} message SyncdIndex message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdIndex.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.blob != null && Object.hasOwnProperty.call(message, "blob")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.blob); + return writer; + }; + + /** + * Encodes the specified SyncdIndex message, length delimited. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdIndex + * @static + * @param {proto.ISyncdIndex} message SyncdIndex message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdIndex.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdIndex message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdIndex + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdIndex} SyncdIndex + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdIndex.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdIndex(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.blob = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdIndex message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdIndex + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdIndex} SyncdIndex + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdIndex.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdIndex message. + * @function verify + * @memberof proto.SyncdIndex + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdIndex.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.blob != null && message.hasOwnProperty("blob")) + if (!(message.blob && typeof message.blob.length === "number" || $util.isString(message.blob))) + return "blob: buffer expected"; + return null; + }; + + /** + * Creates a SyncdIndex message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdIndex + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdIndex} SyncdIndex + */ + SyncdIndex.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdIndex) + return object; + var message = new $root.proto.SyncdIndex(); + if (object.blob != null) + if (typeof object.blob === "string") + $util.base64.decode(object.blob, message.blob = $util.newBuffer($util.base64.length(object.blob)), 0); + else if (object.blob.length) + message.blob = object.blob; + return message; + }; + + /** + * Creates a plain object from a SyncdIndex message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdIndex + * @static + * @param {proto.SyncdIndex} message SyncdIndex + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdIndex.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + if (options.bytes === String) + object.blob = ""; + else { + object.blob = []; + if (options.bytes !== Array) + object.blob = $util.newBuffer(object.blob); + } + if (message.blob != null && message.hasOwnProperty("blob")) + object.blob = options.bytes === String ? $util.base64.encode(message.blob, 0, message.blob.length) : options.bytes === Array ? Array.prototype.slice.call(message.blob) : message.blob; + return object; + }; + + /** + * Converts this SyncdIndex to JSON. + * @function toJSON + * @memberof proto.SyncdIndex + * @instance + * @returns {Object.} JSON object + */ + SyncdIndex.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdIndex; + })(); + + proto.ExitCode = (function() { + + /** + * Properties of an ExitCode. + * @memberof proto + * @interface IExitCode + * @property {number|Long|null} [code] ExitCode code + * @property {string|null} [text] ExitCode text + */ + + /** + * Constructs a new ExitCode. + * @memberof proto + * @classdesc Represents an ExitCode. + * @implements IExitCode + * @constructor + * @param {proto.IExitCode=} [properties] Properties to set + */ + function ExitCode(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ExitCode code. + * @member {number|Long} code + * @memberof proto.ExitCode + * @instance + */ + ExitCode.prototype.code = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * ExitCode text. + * @member {string} text + * @memberof proto.ExitCode + * @instance + */ + ExitCode.prototype.text = ""; + + /** + * Creates a new ExitCode instance using the specified properties. + * @function create + * @memberof proto.ExitCode + * @static + * @param {proto.IExitCode=} [properties] Properties to set + * @returns {proto.ExitCode} ExitCode instance + */ + ExitCode.create = function create(properties) { + return new ExitCode(properties); + }; + + /** + * Encodes the specified ExitCode message. Does not implicitly {@link proto.ExitCode.verify|verify} messages. + * @function encode + * @memberof proto.ExitCode + * @static + * @param {proto.IExitCode} message ExitCode message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ExitCode.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.code != null && Object.hasOwnProperty.call(message, "code")) + writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.code); + if (message.text != null && Object.hasOwnProperty.call(message, "text")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.text); + return writer; + }; + + /** + * Encodes the specified ExitCode message, length delimited. Does not implicitly {@link proto.ExitCode.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ExitCode + * @static + * @param {proto.IExitCode} message ExitCode message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ExitCode.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an ExitCode message from the specified reader or buffer. + * @function decode + * @memberof proto.ExitCode + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ExitCode} ExitCode + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ExitCode.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ExitCode(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.code = reader.uint64(); + break; + case 2: + message.text = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an ExitCode message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ExitCode + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ExitCode} ExitCode + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ExitCode.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an ExitCode message. + * @function verify + * @memberof proto.ExitCode + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ExitCode.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.code != null && message.hasOwnProperty("code")) + if (!$util.isInteger(message.code) && !(message.code && $util.isInteger(message.code.low) && $util.isInteger(message.code.high))) + return "code: integer|Long expected"; + if (message.text != null && message.hasOwnProperty("text")) + if (!$util.isString(message.text)) + return "text: string expected"; + return null; + }; + + /** + * Creates an ExitCode message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ExitCode + * @static + * @param {Object.} object Plain object + * @returns {proto.ExitCode} ExitCode + */ + ExitCode.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ExitCode) + return object; + var message = new $root.proto.ExitCode(); + if (object.code != null) + if ($util.Long) + (message.code = $util.Long.fromValue(object.code)).unsigned = true; + else if (typeof object.code === "string") + message.code = parseInt(object.code, 10); + else if (typeof object.code === "number") + message.code = object.code; + else if (typeof object.code === "object") + message.code = new $util.LongBits(object.code.low >>> 0, object.code.high >>> 0).toNumber(true); + if (object.text != null) + message.text = String(object.text); + return message; + }; + + /** + * Creates a plain object from an ExitCode message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ExitCode + * @static + * @param {proto.ExitCode} message ExitCode + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ExitCode.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.code = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.code = options.longs === String ? "0" : 0; + object.text = ""; + } + if (message.code != null && message.hasOwnProperty("code")) + if (typeof message.code === "number") + object.code = options.longs === String ? String(message.code) : message.code; + else + object.code = options.longs === String ? $util.Long.prototype.toString.call(message.code) : options.longs === Number ? new $util.LongBits(message.code.low >>> 0, message.code.high >>> 0).toNumber(true) : message.code; + if (message.text != null && message.hasOwnProperty("text")) + object.text = message.text; + return object; + }; + + /** + * Converts this ExitCode to JSON. + * @function toJSON + * @memberof proto.ExitCode + * @instance + * @returns {Object.} JSON object + */ + ExitCode.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ExitCode; + })(); + + proto.SyncdVersion = (function() { + + /** + * Properties of a SyncdVersion. + * @memberof proto + * @interface ISyncdVersion + * @property {number|Long|null} [version] SyncdVersion version + */ + + /** + * Constructs a new SyncdVersion. + * @memberof proto + * @classdesc Represents a SyncdVersion. + * @implements ISyncdVersion + * @constructor + * @param {proto.ISyncdVersion=} [properties] Properties to set + */ + function SyncdVersion(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SyncdVersion version. + * @member {number|Long} version + * @memberof proto.SyncdVersion + * @instance + */ + SyncdVersion.prototype.version = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Creates a new SyncdVersion instance using the specified properties. + * @function create + * @memberof proto.SyncdVersion + * @static + * @param {proto.ISyncdVersion=} [properties] Properties to set + * @returns {proto.SyncdVersion} SyncdVersion instance + */ + SyncdVersion.create = function create(properties) { + return new SyncdVersion(properties); + }; + + /** + * Encodes the specified SyncdVersion message. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages. + * @function encode + * @memberof proto.SyncdVersion + * @static + * @param {proto.ISyncdVersion} message SyncdVersion message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdVersion.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.version); + return writer; + }; + + /** + * Encodes the specified SyncdVersion message, length delimited. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.SyncdVersion + * @static + * @param {proto.ISyncdVersion} message SyncdVersion message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SyncdVersion.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SyncdVersion message from the specified reader or buffer. + * @function decode + * @memberof proto.SyncdVersion + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.SyncdVersion} SyncdVersion + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdVersion.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdVersion(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.version = reader.uint64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SyncdVersion message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.SyncdVersion + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.SyncdVersion} SyncdVersion + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SyncdVersion.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SyncdVersion message. + * @function verify + * @memberof proto.SyncdVersion + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SyncdVersion.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.version != null && message.hasOwnProperty("version")) + if (!$util.isInteger(message.version) && !(message.version && $util.isInteger(message.version.low) && $util.isInteger(message.version.high))) + return "version: integer|Long expected"; + return null; + }; + + /** + * Creates a SyncdVersion message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.SyncdVersion + * @static + * @param {Object.} object Plain object + * @returns {proto.SyncdVersion} SyncdVersion + */ + SyncdVersion.fromObject = function fromObject(object) { + if (object instanceof $root.proto.SyncdVersion) + return object; + var message = new $root.proto.SyncdVersion(); + if (object.version != null) + if ($util.Long) + (message.version = $util.Long.fromValue(object.version)).unsigned = true; + else if (typeof object.version === "string") + message.version = parseInt(object.version, 10); + else if (typeof object.version === "number") + message.version = object.version; + else if (typeof object.version === "object") + message.version = new $util.LongBits(object.version.low >>> 0, object.version.high >>> 0).toNumber(true); + return message; + }; + + /** + * Creates a plain object from a SyncdVersion message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.SyncdVersion + * @static + * @param {proto.SyncdVersion} message SyncdVersion + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SyncdVersion.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.version = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.version = options.longs === String ? "0" : 0; + if (message.version != null && message.hasOwnProperty("version")) + if (typeof message.version === "number") + object.version = options.longs === String ? String(message.version) : message.version; + else + object.version = options.longs === String ? $util.Long.prototype.toString.call(message.version) : options.longs === Number ? new $util.LongBits(message.version.low >>> 0, message.version.high >>> 0).toNumber(true) : message.version; + return object; + }; + + /** + * Converts this SyncdVersion to JSON. + * @function toJSON + * @memberof proto.SyncdVersion + * @instance + * @returns {Object.} JSON object + */ + SyncdVersion.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SyncdVersion; + })(); + + proto.ServerErrorReceipt = (function() { + + /** + * Properties of a ServerErrorReceipt. + * @memberof proto + * @interface IServerErrorReceipt + * @property {string|null} [stanzaId] ServerErrorReceipt stanzaId + */ + + /** + * Constructs a new ServerErrorReceipt. + * @memberof proto + * @classdesc Represents a ServerErrorReceipt. + * @implements IServerErrorReceipt + * @constructor + * @param {proto.IServerErrorReceipt=} [properties] Properties to set + */ + function ServerErrorReceipt(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ServerErrorReceipt stanzaId. + * @member {string} stanzaId + * @memberof proto.ServerErrorReceipt + * @instance + */ + ServerErrorReceipt.prototype.stanzaId = ""; + + /** + * Creates a new ServerErrorReceipt instance using the specified properties. + * @function create + * @memberof proto.ServerErrorReceipt + * @static + * @param {proto.IServerErrorReceipt=} [properties] Properties to set + * @returns {proto.ServerErrorReceipt} ServerErrorReceipt instance + */ + ServerErrorReceipt.create = function create(properties) { + return new ServerErrorReceipt(properties); + }; + + /** + * Encodes the specified ServerErrorReceipt message. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages. + * @function encode + * @memberof proto.ServerErrorReceipt + * @static + * @param {proto.IServerErrorReceipt} message ServerErrorReceipt message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ServerErrorReceipt.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.stanzaId); + return writer; + }; + + /** + * Encodes the specified ServerErrorReceipt message, length delimited. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ServerErrorReceipt + * @static + * @param {proto.IServerErrorReceipt} message ServerErrorReceipt message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ServerErrorReceipt.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ServerErrorReceipt message from the specified reader or buffer. + * @function decode + * @memberof proto.ServerErrorReceipt + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ServerErrorReceipt} ServerErrorReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ServerErrorReceipt.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ServerErrorReceipt(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.stanzaId = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ServerErrorReceipt message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ServerErrorReceipt + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ServerErrorReceipt} ServerErrorReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ServerErrorReceipt.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ServerErrorReceipt message. + * @function verify + * @memberof proto.ServerErrorReceipt + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ServerErrorReceipt.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) + if (!$util.isString(message.stanzaId)) + return "stanzaId: string expected"; + return null; + }; + + /** + * Creates a ServerErrorReceipt message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ServerErrorReceipt + * @static + * @param {Object.} object Plain object + * @returns {proto.ServerErrorReceipt} ServerErrorReceipt + */ + ServerErrorReceipt.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ServerErrorReceipt) + return object; + var message = new $root.proto.ServerErrorReceipt(); + if (object.stanzaId != null) + message.stanzaId = String(object.stanzaId); + return message; + }; + + /** + * Creates a plain object from a ServerErrorReceipt message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ServerErrorReceipt + * @static + * @param {proto.ServerErrorReceipt} message ServerErrorReceipt + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ServerErrorReceipt.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.stanzaId = ""; + if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) + object.stanzaId = message.stanzaId; + return object; + }; + + /** + * Converts this ServerErrorReceipt to JSON. + * @function toJSON + * @memberof proto.ServerErrorReceipt + * @instance + * @returns {Object.} JSON object + */ + ServerErrorReceipt.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ServerErrorReceipt; + })(); + + proto.MediaRetryNotification = (function() { + + /** + * Properties of a MediaRetryNotification. + * @memberof proto + * @interface IMediaRetryNotification + * @property {string|null} [stanzaId] MediaRetryNotification stanzaId + * @property {string|null} [directPath] MediaRetryNotification directPath + * @property {proto.MediaRetryNotification.MediaRetryNotificationResultType|null} [result] MediaRetryNotification result + */ + + /** + * Constructs a new MediaRetryNotification. + * @memberof proto + * @classdesc Represents a MediaRetryNotification. + * @implements IMediaRetryNotification + * @constructor + * @param {proto.IMediaRetryNotification=} [properties] Properties to set + */ + function MediaRetryNotification(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MediaRetryNotification stanzaId. + * @member {string} stanzaId + * @memberof proto.MediaRetryNotification + * @instance + */ + MediaRetryNotification.prototype.stanzaId = ""; + + /** + * MediaRetryNotification directPath. + * @member {string} directPath + * @memberof proto.MediaRetryNotification + * @instance + */ + MediaRetryNotification.prototype.directPath = ""; + + /** + * MediaRetryNotification result. + * @member {proto.MediaRetryNotification.MediaRetryNotificationResultType} result + * @memberof proto.MediaRetryNotification + * @instance + */ + MediaRetryNotification.prototype.result = 0; + + /** + * Creates a new MediaRetryNotification instance using the specified properties. + * @function create + * @memberof proto.MediaRetryNotification + * @static + * @param {proto.IMediaRetryNotification=} [properties] Properties to set + * @returns {proto.MediaRetryNotification} MediaRetryNotification instance + */ + MediaRetryNotification.create = function create(properties) { + return new MediaRetryNotification(properties); + }; + + /** + * Encodes the specified MediaRetryNotification message. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages. + * @function encode + * @memberof proto.MediaRetryNotification + * @static + * @param {proto.IMediaRetryNotification} message MediaRetryNotification message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MediaRetryNotification.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.stanzaId); + if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.directPath); + if (message.result != null && Object.hasOwnProperty.call(message, "result")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.result); + return writer; + }; + + /** + * Encodes the specified MediaRetryNotification message, length delimited. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MediaRetryNotification + * @static + * @param {proto.IMediaRetryNotification} message MediaRetryNotification message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MediaRetryNotification.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MediaRetryNotification message from the specified reader or buffer. + * @function decode + * @memberof proto.MediaRetryNotification + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MediaRetryNotification} MediaRetryNotification + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MediaRetryNotification.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MediaRetryNotification(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.stanzaId = reader.string(); + break; + case 2: + message.directPath = reader.string(); + break; + case 3: + message.result = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MediaRetryNotification message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MediaRetryNotification + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MediaRetryNotification} MediaRetryNotification + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MediaRetryNotification.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MediaRetryNotification message. + * @function verify + * @memberof proto.MediaRetryNotification + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MediaRetryNotification.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) + if (!$util.isString(message.stanzaId)) + return "stanzaId: string expected"; + if (message.directPath != null && message.hasOwnProperty("directPath")) + if (!$util.isString(message.directPath)) + return "directPath: string expected"; + if (message.result != null && message.hasOwnProperty("result")) + switch (message.result) { + default: + return "result: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + return null; + }; + + /** + * Creates a MediaRetryNotification message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MediaRetryNotification + * @static + * @param {Object.} object Plain object + * @returns {proto.MediaRetryNotification} MediaRetryNotification + */ + MediaRetryNotification.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MediaRetryNotification) + return object; + var message = new $root.proto.MediaRetryNotification(); + if (object.stanzaId != null) + message.stanzaId = String(object.stanzaId); + if (object.directPath != null) + message.directPath = String(object.directPath); + switch (object.result) { + case "GENERAL_ERROR": + case 0: + message.result = 0; + break; + case "SUCCESS": + case 1: + message.result = 1; + break; + case "NOT_FOUND": + case 2: + message.result = 2; + break; + case "DECRYPTION_ERROR": + case 3: + message.result = 3; + break; + } + return message; + }; + + /** + * Creates a plain object from a MediaRetryNotification message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MediaRetryNotification + * @static + * @param {proto.MediaRetryNotification} message MediaRetryNotification + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MediaRetryNotification.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.stanzaId = ""; + object.directPath = ""; + object.result = options.enums === String ? "GENERAL_ERROR" : 0; + } + if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) + object.stanzaId = message.stanzaId; + if (message.directPath != null && message.hasOwnProperty("directPath")) + object.directPath = message.directPath; + if (message.result != null && message.hasOwnProperty("result")) + object.result = options.enums === String ? $root.proto.MediaRetryNotification.MediaRetryNotificationResultType[message.result] : message.result; + return object; + }; + + /** + * Converts this MediaRetryNotification to JSON. + * @function toJSON + * @memberof proto.MediaRetryNotification + * @instance + * @returns {Object.} JSON object + */ + MediaRetryNotification.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * MediaRetryNotificationResultType enum. + * @name proto.MediaRetryNotification.MediaRetryNotificationResultType + * @enum {number} + * @property {number} GENERAL_ERROR=0 GENERAL_ERROR value + * @property {number} SUCCESS=1 SUCCESS value + * @property {number} NOT_FOUND=2 NOT_FOUND value + * @property {number} DECRYPTION_ERROR=3 DECRYPTION_ERROR value + */ + MediaRetryNotification.MediaRetryNotificationResultType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "GENERAL_ERROR"] = 0; + values[valuesById[1] = "SUCCESS"] = 1; + values[valuesById[2] = "NOT_FOUND"] = 2; + values[valuesById[3] = "DECRYPTION_ERROR"] = 3; + return values; + })(); + + return MediaRetryNotification; + })(); + + proto.MsgOpaqueData = (function() { + + /** + * Properties of a MsgOpaqueData. + * @memberof proto + * @interface IMsgOpaqueData + * @property {string|null} [body] MsgOpaqueData body + * @property {string|null} [caption] MsgOpaqueData caption + * @property {string|null} [clientUrl] MsgOpaqueData clientUrl + * @property {number|null} [lng] MsgOpaqueData lng + * @property {number|null} [lat] MsgOpaqueData lat + * @property {number|null} [paymentAmount1000] MsgOpaqueData paymentAmount1000 + * @property {string|null} [paymentNoteMsgBody] MsgOpaqueData paymentNoteMsgBody + * @property {string|null} [canonicalUrl] MsgOpaqueData canonicalUrl + * @property {string|null} [matchedText] MsgOpaqueData matchedText + * @property {string|null} [title] MsgOpaqueData title + * @property {string|null} [description] MsgOpaqueData description + */ + + /** + * Constructs a new MsgOpaqueData. + * @memberof proto + * @classdesc Represents a MsgOpaqueData. + * @implements IMsgOpaqueData + * @constructor + * @param {proto.IMsgOpaqueData=} [properties] Properties to set + */ + function MsgOpaqueData(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MsgOpaqueData body. + * @member {string} body + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.body = ""; + + /** + * MsgOpaqueData caption. + * @member {string} caption + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.caption = ""; + + /** + * MsgOpaqueData clientUrl. + * @member {string} clientUrl + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.clientUrl = ""; + + /** + * MsgOpaqueData lng. + * @member {number} lng + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.lng = 0; + + /** + * MsgOpaqueData lat. + * @member {number} lat + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.lat = 0; + + /** + * MsgOpaqueData paymentAmount1000. + * @member {number} paymentAmount1000 + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.paymentAmount1000 = 0; + + /** + * MsgOpaqueData paymentNoteMsgBody. + * @member {string} paymentNoteMsgBody + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.paymentNoteMsgBody = ""; + + /** + * MsgOpaqueData canonicalUrl. + * @member {string} canonicalUrl + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.canonicalUrl = ""; + + /** + * MsgOpaqueData matchedText. + * @member {string} matchedText + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.matchedText = ""; + + /** + * MsgOpaqueData title. + * @member {string} title + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.title = ""; + + /** + * MsgOpaqueData description. + * @member {string} description + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.description = ""; + + /** + * Creates a new MsgOpaqueData instance using the specified properties. + * @function create + * @memberof proto.MsgOpaqueData + * @static + * @param {proto.IMsgOpaqueData=} [properties] Properties to set + * @returns {proto.MsgOpaqueData} MsgOpaqueData instance + */ + MsgOpaqueData.create = function create(properties) { + return new MsgOpaqueData(properties); + }; + + /** + * Encodes the specified MsgOpaqueData message. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages. + * @function encode + * @memberof proto.MsgOpaqueData + * @static + * @param {proto.IMsgOpaqueData} message MsgOpaqueData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MsgOpaqueData.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.body != null && Object.hasOwnProperty.call(message, "body")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.body); + if (message.caption != null && Object.hasOwnProperty.call(message, "caption")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.caption); + if (message.clientUrl != null && Object.hasOwnProperty.call(message, "clientUrl")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.clientUrl); + if (message.lng != null && Object.hasOwnProperty.call(message, "lng")) + writer.uint32(/* id 5, wireType 1 =*/41).double(message.lng); + if (message.lat != null && Object.hasOwnProperty.call(message, "lat")) + writer.uint32(/* id 7, wireType 1 =*/57).double(message.lat); + if (message.paymentAmount1000 != null && Object.hasOwnProperty.call(message, "paymentAmount1000")) + writer.uint32(/* id 8, wireType 0 =*/64).int32(message.paymentAmount1000); + if (message.paymentNoteMsgBody != null && Object.hasOwnProperty.call(message, "paymentNoteMsgBody")) + writer.uint32(/* id 9, wireType 2 =*/74).string(message.paymentNoteMsgBody); + if (message.canonicalUrl != null && Object.hasOwnProperty.call(message, "canonicalUrl")) + writer.uint32(/* id 10, wireType 2 =*/82).string(message.canonicalUrl); + if (message.matchedText != null && Object.hasOwnProperty.call(message, "matchedText")) + writer.uint32(/* id 11, wireType 2 =*/90).string(message.matchedText); + if (message.title != null && Object.hasOwnProperty.call(message, "title")) + writer.uint32(/* id 12, wireType 2 =*/98).string(message.title); + if (message.description != null && Object.hasOwnProperty.call(message, "description")) + writer.uint32(/* id 13, wireType 2 =*/106).string(message.description); + return writer; + }; + + /** + * Encodes the specified MsgOpaqueData message, length delimited. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MsgOpaqueData + * @static + * @param {proto.IMsgOpaqueData} message MsgOpaqueData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MsgOpaqueData.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MsgOpaqueData message from the specified reader or buffer. + * @function decode + * @memberof proto.MsgOpaqueData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MsgOpaqueData} MsgOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MsgOpaqueData.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MsgOpaqueData(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.body = reader.string(); + break; + case 3: + message.caption = reader.string(); + break; + case 4: + message.clientUrl = reader.string(); + break; + case 5: + message.lng = reader.double(); + break; + case 7: + message.lat = reader.double(); + break; + case 8: + message.paymentAmount1000 = reader.int32(); + break; + case 9: + message.paymentNoteMsgBody = reader.string(); + break; + case 10: + message.canonicalUrl = reader.string(); + break; + case 11: + message.matchedText = reader.string(); + break; + case 12: + message.title = reader.string(); + break; + case 13: + message.description = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MsgOpaqueData message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MsgOpaqueData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MsgOpaqueData} MsgOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MsgOpaqueData.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MsgOpaqueData message. + * @function verify + * @memberof proto.MsgOpaqueData + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MsgOpaqueData.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.body != null && message.hasOwnProperty("body")) + if (!$util.isString(message.body)) + return "body: string expected"; + if (message.caption != null && message.hasOwnProperty("caption")) + if (!$util.isString(message.caption)) + return "caption: string expected"; + if (message.clientUrl != null && message.hasOwnProperty("clientUrl")) + if (!$util.isString(message.clientUrl)) + return "clientUrl: string expected"; + if (message.lng != null && message.hasOwnProperty("lng")) + if (typeof message.lng !== "number") + return "lng: number expected"; + if (message.lat != null && message.hasOwnProperty("lat")) + if (typeof message.lat !== "number") + return "lat: number expected"; + if (message.paymentAmount1000 != null && message.hasOwnProperty("paymentAmount1000")) + if (!$util.isInteger(message.paymentAmount1000)) + return "paymentAmount1000: integer expected"; + if (message.paymentNoteMsgBody != null && message.hasOwnProperty("paymentNoteMsgBody")) + if (!$util.isString(message.paymentNoteMsgBody)) + return "paymentNoteMsgBody: string expected"; + if (message.canonicalUrl != null && message.hasOwnProperty("canonicalUrl")) + if (!$util.isString(message.canonicalUrl)) + return "canonicalUrl: string expected"; + if (message.matchedText != null && message.hasOwnProperty("matchedText")) + if (!$util.isString(message.matchedText)) + return "matchedText: string expected"; + if (message.title != null && message.hasOwnProperty("title")) + if (!$util.isString(message.title)) + return "title: string expected"; + if (message.description != null && message.hasOwnProperty("description")) + if (!$util.isString(message.description)) + return "description: string expected"; + return null; + }; + + /** + * Creates a MsgOpaqueData message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MsgOpaqueData + * @static + * @param {Object.} object Plain object + * @returns {proto.MsgOpaqueData} MsgOpaqueData + */ + MsgOpaqueData.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MsgOpaqueData) + return object; + var message = new $root.proto.MsgOpaqueData(); + if (object.body != null) + message.body = String(object.body); + if (object.caption != null) + message.caption = String(object.caption); + if (object.clientUrl != null) + message.clientUrl = String(object.clientUrl); + if (object.lng != null) + message.lng = Number(object.lng); + if (object.lat != null) + message.lat = Number(object.lat); + if (object.paymentAmount1000 != null) + message.paymentAmount1000 = object.paymentAmount1000 | 0; + if (object.paymentNoteMsgBody != null) + message.paymentNoteMsgBody = String(object.paymentNoteMsgBody); + if (object.canonicalUrl != null) + message.canonicalUrl = String(object.canonicalUrl); + if (object.matchedText != null) + message.matchedText = String(object.matchedText); + if (object.title != null) + message.title = String(object.title); + if (object.description != null) + message.description = String(object.description); + return message; + }; + + /** + * Creates a plain object from a MsgOpaqueData message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MsgOpaqueData + * @static + * @param {proto.MsgOpaqueData} message MsgOpaqueData + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MsgOpaqueData.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.body = ""; + object.caption = ""; + object.clientUrl = ""; + object.lng = 0; + object.lat = 0; + object.paymentAmount1000 = 0; + object.paymentNoteMsgBody = ""; + object.canonicalUrl = ""; + object.matchedText = ""; + object.title = ""; + object.description = ""; + } + if (message.body != null && message.hasOwnProperty("body")) + object.body = message.body; + if (message.caption != null && message.hasOwnProperty("caption")) + object.caption = message.caption; + if (message.clientUrl != null && message.hasOwnProperty("clientUrl")) + object.clientUrl = message.clientUrl; + if (message.lng != null && message.hasOwnProperty("lng")) + object.lng = options.json && !isFinite(message.lng) ? String(message.lng) : message.lng; + if (message.lat != null && message.hasOwnProperty("lat")) + object.lat = options.json && !isFinite(message.lat) ? String(message.lat) : message.lat; + if (message.paymentAmount1000 != null && message.hasOwnProperty("paymentAmount1000")) + object.paymentAmount1000 = message.paymentAmount1000; + if (message.paymentNoteMsgBody != null && message.hasOwnProperty("paymentNoteMsgBody")) + object.paymentNoteMsgBody = message.paymentNoteMsgBody; + if (message.canonicalUrl != null && message.hasOwnProperty("canonicalUrl")) + object.canonicalUrl = message.canonicalUrl; + if (message.matchedText != null && message.hasOwnProperty("matchedText")) + object.matchedText = message.matchedText; + if (message.title != null && message.hasOwnProperty("title")) + object.title = message.title; + if (message.description != null && message.hasOwnProperty("description")) + object.description = message.description; + return object; + }; + + /** + * Converts this MsgOpaqueData to JSON. + * @function toJSON + * @memberof proto.MsgOpaqueData + * @instance + * @returns {Object.} JSON object + */ + MsgOpaqueData.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MsgOpaqueData; + })(); + + proto.MsgRowOpaqueData = (function() { + + /** + * Properties of a MsgRowOpaqueData. + * @memberof proto + * @interface IMsgRowOpaqueData + * @property {proto.IMsgOpaqueData|null} [currentMsg] MsgRowOpaqueData currentMsg + * @property {proto.IMsgOpaqueData|null} [quotedMsg] MsgRowOpaqueData quotedMsg + */ + + /** + * Constructs a new MsgRowOpaqueData. + * @memberof proto + * @classdesc Represents a MsgRowOpaqueData. + * @implements IMsgRowOpaqueData + * @constructor + * @param {proto.IMsgRowOpaqueData=} [properties] Properties to set + */ + function MsgRowOpaqueData(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MsgRowOpaqueData currentMsg. + * @member {proto.IMsgOpaqueData|null|undefined} currentMsg + * @memberof proto.MsgRowOpaqueData + * @instance + */ + MsgRowOpaqueData.prototype.currentMsg = null; + + /** + * MsgRowOpaqueData quotedMsg. + * @member {proto.IMsgOpaqueData|null|undefined} quotedMsg + * @memberof proto.MsgRowOpaqueData + * @instance + */ + MsgRowOpaqueData.prototype.quotedMsg = null; + + /** + * Creates a new MsgRowOpaqueData instance using the specified properties. + * @function create + * @memberof proto.MsgRowOpaqueData + * @static + * @param {proto.IMsgRowOpaqueData=} [properties] Properties to set + * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData instance + */ + MsgRowOpaqueData.create = function create(properties) { + return new MsgRowOpaqueData(properties); + }; + + /** + * Encodes the specified MsgRowOpaqueData message. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages. + * @function encode + * @memberof proto.MsgRowOpaqueData + * @static + * @param {proto.IMsgRowOpaqueData} message MsgRowOpaqueData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MsgRowOpaqueData.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.currentMsg != null && Object.hasOwnProperty.call(message, "currentMsg")) + $root.proto.MsgOpaqueData.encode(message.currentMsg, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.quotedMsg != null && Object.hasOwnProperty.call(message, "quotedMsg")) + $root.proto.MsgOpaqueData.encode(message.quotedMsg, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified MsgRowOpaqueData message, length delimited. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MsgRowOpaqueData + * @static + * @param {proto.IMsgRowOpaqueData} message MsgRowOpaqueData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MsgRowOpaqueData.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MsgRowOpaqueData message from the specified reader or buffer. + * @function decode + * @memberof proto.MsgRowOpaqueData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MsgRowOpaqueData.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MsgRowOpaqueData(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.currentMsg = $root.proto.MsgOpaqueData.decode(reader, reader.uint32()); + break; + case 2: + message.quotedMsg = $root.proto.MsgOpaqueData.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MsgRowOpaqueData message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MsgRowOpaqueData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MsgRowOpaqueData.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MsgRowOpaqueData message. + * @function verify + * @memberof proto.MsgRowOpaqueData + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MsgRowOpaqueData.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.currentMsg != null && message.hasOwnProperty("currentMsg")) { + var error = $root.proto.MsgOpaqueData.verify(message.currentMsg); + if (error) + return "currentMsg." + error; + } + if (message.quotedMsg != null && message.hasOwnProperty("quotedMsg")) { + var error = $root.proto.MsgOpaqueData.verify(message.quotedMsg); + if (error) + return "quotedMsg." + error; + } + return null; + }; + + /** + * Creates a MsgRowOpaqueData message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MsgRowOpaqueData + * @static + * @param {Object.} object Plain object + * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData + */ + MsgRowOpaqueData.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MsgRowOpaqueData) + return object; + var message = new $root.proto.MsgRowOpaqueData(); + if (object.currentMsg != null) { + if (typeof object.currentMsg !== "object") + throw TypeError(".proto.MsgRowOpaqueData.currentMsg: object expected"); + message.currentMsg = $root.proto.MsgOpaqueData.fromObject(object.currentMsg); + } + if (object.quotedMsg != null) { + if (typeof object.quotedMsg !== "object") + throw TypeError(".proto.MsgRowOpaqueData.quotedMsg: object expected"); + message.quotedMsg = $root.proto.MsgOpaqueData.fromObject(object.quotedMsg); + } + return message; + }; + + /** + * Creates a plain object from a MsgRowOpaqueData message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MsgRowOpaqueData + * @static + * @param {proto.MsgRowOpaqueData} message MsgRowOpaqueData + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MsgRowOpaqueData.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.currentMsg = null; + object.quotedMsg = null; + } + if (message.currentMsg != null && message.hasOwnProperty("currentMsg")) + object.currentMsg = $root.proto.MsgOpaqueData.toObject(message.currentMsg, options); + if (message.quotedMsg != null && message.hasOwnProperty("quotedMsg")) + object.quotedMsg = $root.proto.MsgOpaqueData.toObject(message.quotedMsg, options); + return object; + }; + + /** + * Converts this MsgRowOpaqueData to JSON. + * @function toJSON + * @memberof proto.MsgRowOpaqueData + * @instance + * @returns {Object.} JSON object + */ + MsgRowOpaqueData.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MsgRowOpaqueData; + })(); + + proto.Pushname = (function() { + + /** + * Properties of a Pushname. + * @memberof proto + * @interface IPushname + * @property {string|null} [id] Pushname id + * @property {string|null} [pushname] Pushname pushname + */ + + /** + * Constructs a new Pushname. + * @memberof proto + * @classdesc Represents a Pushname. + * @implements IPushname + * @constructor + * @param {proto.IPushname=} [properties] Properties to set + */ + function Pushname(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Pushname id. + * @member {string} id + * @memberof proto.Pushname + * @instance + */ + Pushname.prototype.id = ""; + + /** + * Pushname pushname. + * @member {string} pushname + * @memberof proto.Pushname + * @instance + */ + Pushname.prototype.pushname = ""; + + /** + * Creates a new Pushname instance using the specified properties. + * @function create + * @memberof proto.Pushname + * @static + * @param {proto.IPushname=} [properties] Properties to set + * @returns {proto.Pushname} Pushname instance + */ + Pushname.create = function create(properties) { + return new Pushname(properties); + }; + + /** + * Encodes the specified Pushname message. Does not implicitly {@link proto.Pushname.verify|verify} messages. + * @function encode + * @memberof proto.Pushname + * @static + * @param {proto.IPushname} message Pushname message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Pushname.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); + if (message.pushname != null && Object.hasOwnProperty.call(message, "pushname")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.pushname); + return writer; + }; + + /** + * Encodes the specified Pushname message, length delimited. Does not implicitly {@link proto.Pushname.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Pushname + * @static + * @param {proto.IPushname} message Pushname message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Pushname.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Pushname message from the specified reader or buffer. + * @function decode + * @memberof proto.Pushname + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Pushname} Pushname + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Pushname.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Pushname(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.pushname = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Pushname message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Pushname + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Pushname} Pushname + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Pushname.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Pushname message. + * @function verify + * @memberof proto.Pushname + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Pushname.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.pushname != null && message.hasOwnProperty("pushname")) + if (!$util.isString(message.pushname)) + return "pushname: string expected"; + return null; + }; + + /** + * Creates a Pushname message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Pushname + * @static + * @param {Object.} object Plain object + * @returns {proto.Pushname} Pushname + */ + Pushname.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Pushname) + return object; + var message = new $root.proto.Pushname(); + if (object.id != null) + message.id = String(object.id); + if (object.pushname != null) + message.pushname = String(object.pushname); + return message; + }; + + /** + * Creates a plain object from a Pushname message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Pushname + * @static + * @param {proto.Pushname} message Pushname + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Pushname.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.id = ""; + object.pushname = ""; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.pushname != null && message.hasOwnProperty("pushname")) + object.pushname = message.pushname; + return object; + }; + + /** + * Converts this Pushname to JSON. + * @function toJSON + * @memberof proto.Pushname + * @instance + * @returns {Object.} JSON object + */ + Pushname.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Pushname; + })(); + + proto.HistorySyncMsg = (function() { + + /** + * Properties of a HistorySyncMsg. + * @memberof proto + * @interface IHistorySyncMsg + * @property {proto.IWebMessageInfo|null} [message] HistorySyncMsg message + * @property {number|Long|null} [msgOrderId] HistorySyncMsg msgOrderId + */ + + /** + * Constructs a new HistorySyncMsg. + * @memberof proto + * @classdesc Represents a HistorySyncMsg. + * @implements IHistorySyncMsg + * @constructor + * @param {proto.IHistorySyncMsg=} [properties] Properties to set + */ + function HistorySyncMsg(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HistorySyncMsg message. + * @member {proto.IWebMessageInfo|null|undefined} message + * @memberof proto.HistorySyncMsg + * @instance + */ + HistorySyncMsg.prototype.message = null; + + /** + * HistorySyncMsg msgOrderId. + * @member {number|Long} msgOrderId + * @memberof proto.HistorySyncMsg + * @instance + */ + HistorySyncMsg.prototype.msgOrderId = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Creates a new HistorySyncMsg instance using the specified properties. + * @function create + * @memberof proto.HistorySyncMsg + * @static + * @param {proto.IHistorySyncMsg=} [properties] Properties to set + * @returns {proto.HistorySyncMsg} HistorySyncMsg instance + */ + HistorySyncMsg.create = function create(properties) { + return new HistorySyncMsg(properties); + }; + + /** + * Encodes the specified HistorySyncMsg message. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages. + * @function encode + * @memberof proto.HistorySyncMsg + * @static + * @param {proto.IHistorySyncMsg} message HistorySyncMsg message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HistorySyncMsg.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.message != null && Object.hasOwnProperty.call(message, "message")) + $root.proto.WebMessageInfo.encode(message.message, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.msgOrderId != null && Object.hasOwnProperty.call(message, "msgOrderId")) + writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.msgOrderId); + return writer; + }; + + /** + * Encodes the specified HistorySyncMsg message, length delimited. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HistorySyncMsg + * @static + * @param {proto.IHistorySyncMsg} message HistorySyncMsg message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HistorySyncMsg.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HistorySyncMsg message from the specified reader or buffer. + * @function decode + * @memberof proto.HistorySyncMsg + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HistorySyncMsg} HistorySyncMsg + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HistorySyncMsg.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HistorySyncMsg(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.message = $root.proto.WebMessageInfo.decode(reader, reader.uint32()); + break; + case 2: + message.msgOrderId = reader.uint64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HistorySyncMsg message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HistorySyncMsg + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HistorySyncMsg} HistorySyncMsg + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HistorySyncMsg.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HistorySyncMsg message. + * @function verify + * @memberof proto.HistorySyncMsg + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HistorySyncMsg.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.message != null && message.hasOwnProperty("message")) { + var error = $root.proto.WebMessageInfo.verify(message.message); + if (error) + return "message." + error; + } + if (message.msgOrderId != null && message.hasOwnProperty("msgOrderId")) + if (!$util.isInteger(message.msgOrderId) && !(message.msgOrderId && $util.isInteger(message.msgOrderId.low) && $util.isInteger(message.msgOrderId.high))) + return "msgOrderId: integer|Long expected"; + return null; + }; + + /** + * Creates a HistorySyncMsg message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HistorySyncMsg + * @static + * @param {Object.} object Plain object + * @returns {proto.HistorySyncMsg} HistorySyncMsg + */ + HistorySyncMsg.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HistorySyncMsg) + return object; + var message = new $root.proto.HistorySyncMsg(); + if (object.message != null) { + if (typeof object.message !== "object") + throw TypeError(".proto.HistorySyncMsg.message: object expected"); + message.message = $root.proto.WebMessageInfo.fromObject(object.message); + } + if (object.msgOrderId != null) + if ($util.Long) + (message.msgOrderId = $util.Long.fromValue(object.msgOrderId)).unsigned = true; + else if (typeof object.msgOrderId === "string") + message.msgOrderId = parseInt(object.msgOrderId, 10); + else if (typeof object.msgOrderId === "number") + message.msgOrderId = object.msgOrderId; + else if (typeof object.msgOrderId === "object") + message.msgOrderId = new $util.LongBits(object.msgOrderId.low >>> 0, object.msgOrderId.high >>> 0).toNumber(true); + return message; + }; + + /** + * Creates a plain object from a HistorySyncMsg message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HistorySyncMsg + * @static + * @param {proto.HistorySyncMsg} message HistorySyncMsg + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HistorySyncMsg.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.message = null; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.msgOrderId = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.msgOrderId = options.longs === String ? "0" : 0; + } + if (message.message != null && message.hasOwnProperty("message")) + object.message = $root.proto.WebMessageInfo.toObject(message.message, options); + if (message.msgOrderId != null && message.hasOwnProperty("msgOrderId")) + if (typeof message.msgOrderId === "number") + object.msgOrderId = options.longs === String ? String(message.msgOrderId) : message.msgOrderId; + else + object.msgOrderId = options.longs === String ? $util.Long.prototype.toString.call(message.msgOrderId) : options.longs === Number ? new $util.LongBits(message.msgOrderId.low >>> 0, message.msgOrderId.high >>> 0).toNumber(true) : message.msgOrderId; + return object; + }; + + /** + * Converts this HistorySyncMsg to JSON. + * @function toJSON + * @memberof proto.HistorySyncMsg + * @instance + * @returns {Object.} JSON object + */ + HistorySyncMsg.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HistorySyncMsg; + })(); + + proto.Conversation = (function() { + + /** + * Properties of a Conversation. + * @memberof proto + * @interface IConversation + * @property {string} id Conversation id + * @property {Array.|null} [messages] Conversation messages + * @property {string|null} [newJid] Conversation newJid + * @property {string|null} [oldJid] Conversation oldJid + * @property {number|Long|null} [lastMsgTimestamp] Conversation lastMsgTimestamp + * @property {number|null} [unreadCount] Conversation unreadCount + * @property {boolean|null} [readOnly] Conversation readOnly + * @property {boolean|null} [endOfHistoryTransfer] Conversation endOfHistoryTransfer + * @property {number|null} [ephemeralExpiration] Conversation ephemeralExpiration + * @property {number|Long|null} [ephemeralSettingTimestamp] Conversation ephemeralSettingTimestamp + * @property {proto.Conversation.ConversationEndOfHistoryTransferType|null} [endOfHistoryTransferType] Conversation endOfHistoryTransferType + * @property {number|Long|null} [conversationTimestamp] Conversation conversationTimestamp + * @property {string|null} [name] Conversation name + * @property {string|null} [pHash] Conversation pHash + * @property {boolean|null} [notSpam] Conversation notSpam + */ + + /** + * Constructs a new Conversation. + * @memberof proto + * @classdesc Represents a Conversation. + * @implements IConversation + * @constructor + * @param {proto.IConversation=} [properties] Properties to set + */ + function Conversation(properties) { + this.messages = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Conversation id. + * @member {string} id + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.id = ""; + + /** + * Conversation messages. + * @member {Array.} messages + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.messages = $util.emptyArray; + + /** + * Conversation newJid. + * @member {string} newJid + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.newJid = ""; + + /** + * Conversation oldJid. + * @member {string} oldJid + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.oldJid = ""; + + /** + * Conversation lastMsgTimestamp. + * @member {number|Long} lastMsgTimestamp + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.lastMsgTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Conversation unreadCount. + * @member {number} unreadCount + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.unreadCount = 0; + + /** + * Conversation readOnly. + * @member {boolean} readOnly + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.readOnly = false; + + /** + * Conversation endOfHistoryTransfer. + * @member {boolean} endOfHistoryTransfer + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.endOfHistoryTransfer = false; + + /** + * Conversation ephemeralExpiration. + * @member {number} ephemeralExpiration + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.ephemeralExpiration = 0; + + /** + * Conversation ephemeralSettingTimestamp. + * @member {number|Long} ephemeralSettingTimestamp + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.ephemeralSettingTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Conversation endOfHistoryTransferType. + * @member {proto.Conversation.ConversationEndOfHistoryTransferType} endOfHistoryTransferType + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.endOfHistoryTransferType = 0; + + /** + * Conversation conversationTimestamp. + * @member {number|Long} conversationTimestamp + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.conversationTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Conversation name. + * @member {string} name + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.name = ""; + + /** + * Conversation pHash. + * @member {string} pHash + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.pHash = ""; + + /** + * Conversation notSpam. + * @member {boolean} notSpam + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.notSpam = false; + + /** + * Creates a new Conversation instance using the specified properties. + * @function create + * @memberof proto.Conversation + * @static + * @param {proto.IConversation=} [properties] Properties to set + * @returns {proto.Conversation} Conversation instance + */ + Conversation.create = function create(properties) { + return new Conversation(properties); + }; + + /** + * Encodes the specified Conversation message. Does not implicitly {@link proto.Conversation.verify|verify} messages. + * @function encode + * @memberof proto.Conversation + * @static + * @param {proto.IConversation} message Conversation message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Conversation.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); + if (message.messages != null && message.messages.length) + for (var i = 0; i < message.messages.length; ++i) + $root.proto.HistorySyncMsg.encode(message.messages[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.newJid != null && Object.hasOwnProperty.call(message, "newJid")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.newJid); + if (message.oldJid != null && Object.hasOwnProperty.call(message, "oldJid")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.oldJid); + if (message.lastMsgTimestamp != null && Object.hasOwnProperty.call(message, "lastMsgTimestamp")) + writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.lastMsgTimestamp); + if (message.unreadCount != null && Object.hasOwnProperty.call(message, "unreadCount")) + writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.unreadCount); + if (message.readOnly != null && Object.hasOwnProperty.call(message, "readOnly")) + writer.uint32(/* id 7, wireType 0 =*/56).bool(message.readOnly); + if (message.endOfHistoryTransfer != null && Object.hasOwnProperty.call(message, "endOfHistoryTransfer")) + writer.uint32(/* id 8, wireType 0 =*/64).bool(message.endOfHistoryTransfer); + if (message.ephemeralExpiration != null && Object.hasOwnProperty.call(message, "ephemeralExpiration")) + writer.uint32(/* id 9, wireType 0 =*/72).uint32(message.ephemeralExpiration); + if (message.ephemeralSettingTimestamp != null && Object.hasOwnProperty.call(message, "ephemeralSettingTimestamp")) + writer.uint32(/* id 10, wireType 0 =*/80).int64(message.ephemeralSettingTimestamp); + if (message.endOfHistoryTransferType != null && Object.hasOwnProperty.call(message, "endOfHistoryTransferType")) + writer.uint32(/* id 11, wireType 0 =*/88).int32(message.endOfHistoryTransferType); + if (message.conversationTimestamp != null && Object.hasOwnProperty.call(message, "conversationTimestamp")) + writer.uint32(/* id 12, wireType 0 =*/96).uint64(message.conversationTimestamp); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 13, wireType 2 =*/106).string(message.name); + if (message.pHash != null && Object.hasOwnProperty.call(message, "pHash")) + writer.uint32(/* id 14, wireType 2 =*/114).string(message.pHash); + if (message.notSpam != null && Object.hasOwnProperty.call(message, "notSpam")) + writer.uint32(/* id 15, wireType 0 =*/120).bool(message.notSpam); + return writer; + }; + + /** + * Encodes the specified Conversation message, length delimited. Does not implicitly {@link proto.Conversation.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Conversation + * @static + * @param {proto.IConversation} message Conversation message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Conversation.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Conversation message from the specified reader or buffer. + * @function decode + * @memberof proto.Conversation + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Conversation} Conversation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Conversation.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Conversation(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + if (!(message.messages && message.messages.length)) + message.messages = []; + message.messages.push($root.proto.HistorySyncMsg.decode(reader, reader.uint32())); + break; + case 3: + message.newJid = reader.string(); + break; + case 4: + message.oldJid = reader.string(); + break; + case 5: + message.lastMsgTimestamp = reader.uint64(); + break; + case 6: + message.unreadCount = reader.uint32(); + break; + case 7: + message.readOnly = reader.bool(); + break; + case 8: + message.endOfHistoryTransfer = reader.bool(); + break; + case 9: + message.ephemeralExpiration = reader.uint32(); + break; + case 10: + message.ephemeralSettingTimestamp = reader.int64(); + break; + case 11: + message.endOfHistoryTransferType = reader.int32(); + break; + case 12: + message.conversationTimestamp = reader.uint64(); + break; + case 13: + message.name = reader.string(); + break; + case 14: + message.pHash = reader.string(); + break; + case 15: + message.notSpam = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + if (!message.hasOwnProperty("id")) + throw $util.ProtocolError("missing required 'id'", { instance: message }); + return message; + }; + + /** + * Decodes a Conversation message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Conversation + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Conversation} Conversation + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Conversation.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Conversation message. + * @function verify + * @memberof proto.Conversation + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Conversation.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.messages != null && message.hasOwnProperty("messages")) { + if (!Array.isArray(message.messages)) + return "messages: array expected"; + for (var i = 0; i < message.messages.length; ++i) { + var error = $root.proto.HistorySyncMsg.verify(message.messages[i]); + if (error) + return "messages." + error; + } + } + if (message.newJid != null && message.hasOwnProperty("newJid")) + if (!$util.isString(message.newJid)) + return "newJid: string expected"; + if (message.oldJid != null && message.hasOwnProperty("oldJid")) + if (!$util.isString(message.oldJid)) + return "oldJid: string expected"; + if (message.lastMsgTimestamp != null && message.hasOwnProperty("lastMsgTimestamp")) + if (!$util.isInteger(message.lastMsgTimestamp) && !(message.lastMsgTimestamp && $util.isInteger(message.lastMsgTimestamp.low) && $util.isInteger(message.lastMsgTimestamp.high))) + return "lastMsgTimestamp: integer|Long expected"; + if (message.unreadCount != null && message.hasOwnProperty("unreadCount")) + if (!$util.isInteger(message.unreadCount)) + return "unreadCount: integer expected"; + if (message.readOnly != null && message.hasOwnProperty("readOnly")) + if (typeof message.readOnly !== "boolean") + return "readOnly: boolean expected"; + if (message.endOfHistoryTransfer != null && message.hasOwnProperty("endOfHistoryTransfer")) + if (typeof message.endOfHistoryTransfer !== "boolean") + return "endOfHistoryTransfer: boolean expected"; + if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration")) + if (!$util.isInteger(message.ephemeralExpiration)) + return "ephemeralExpiration: integer expected"; + if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp")) + if (!$util.isInteger(message.ephemeralSettingTimestamp) && !(message.ephemeralSettingTimestamp && $util.isInteger(message.ephemeralSettingTimestamp.low) && $util.isInteger(message.ephemeralSettingTimestamp.high))) + return "ephemeralSettingTimestamp: integer|Long expected"; + if (message.endOfHistoryTransferType != null && message.hasOwnProperty("endOfHistoryTransferType")) + switch (message.endOfHistoryTransferType) { + default: + return "endOfHistoryTransferType: enum value expected"; + case 0: + case 1: + break; + } + if (message.conversationTimestamp != null && message.hasOwnProperty("conversationTimestamp")) + if (!$util.isInteger(message.conversationTimestamp) && !(message.conversationTimestamp && $util.isInteger(message.conversationTimestamp.low) && $util.isInteger(message.conversationTimestamp.high))) + return "conversationTimestamp: integer|Long expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + if (message.pHash != null && message.hasOwnProperty("pHash")) + if (!$util.isString(message.pHash)) + return "pHash: string expected"; + if (message.notSpam != null && message.hasOwnProperty("notSpam")) + if (typeof message.notSpam !== "boolean") + return "notSpam: boolean expected"; + return null; + }; + + /** + * Creates a Conversation message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Conversation + * @static + * @param {Object.} object Plain object + * @returns {proto.Conversation} Conversation + */ + Conversation.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Conversation) + return object; + var message = new $root.proto.Conversation(); + if (object.id != null) + message.id = String(object.id); + if (object.messages) { + if (!Array.isArray(object.messages)) + throw TypeError(".proto.Conversation.messages: array expected"); + message.messages = []; + for (var i = 0; i < object.messages.length; ++i) { + if (typeof object.messages[i] !== "object") + throw TypeError(".proto.Conversation.messages: object expected"); + message.messages[i] = $root.proto.HistorySyncMsg.fromObject(object.messages[i]); + } + } + if (object.newJid != null) + message.newJid = String(object.newJid); + if (object.oldJid != null) + message.oldJid = String(object.oldJid); + if (object.lastMsgTimestamp != null) + if ($util.Long) + (message.lastMsgTimestamp = $util.Long.fromValue(object.lastMsgTimestamp)).unsigned = true; + else if (typeof object.lastMsgTimestamp === "string") + message.lastMsgTimestamp = parseInt(object.lastMsgTimestamp, 10); + else if (typeof object.lastMsgTimestamp === "number") + message.lastMsgTimestamp = object.lastMsgTimestamp; + else if (typeof object.lastMsgTimestamp === "object") + message.lastMsgTimestamp = new $util.LongBits(object.lastMsgTimestamp.low >>> 0, object.lastMsgTimestamp.high >>> 0).toNumber(true); + if (object.unreadCount != null) + message.unreadCount = object.unreadCount >>> 0; + if (object.readOnly != null) + message.readOnly = Boolean(object.readOnly); + if (object.endOfHistoryTransfer != null) + message.endOfHistoryTransfer = Boolean(object.endOfHistoryTransfer); + if (object.ephemeralExpiration != null) + message.ephemeralExpiration = object.ephemeralExpiration >>> 0; + if (object.ephemeralSettingTimestamp != null) + if ($util.Long) + (message.ephemeralSettingTimestamp = $util.Long.fromValue(object.ephemeralSettingTimestamp)).unsigned = false; + else if (typeof object.ephemeralSettingTimestamp === "string") + message.ephemeralSettingTimestamp = parseInt(object.ephemeralSettingTimestamp, 10); + else if (typeof object.ephemeralSettingTimestamp === "number") + message.ephemeralSettingTimestamp = object.ephemeralSettingTimestamp; + else if (typeof object.ephemeralSettingTimestamp === "object") + message.ephemeralSettingTimestamp = new $util.LongBits(object.ephemeralSettingTimestamp.low >>> 0, object.ephemeralSettingTimestamp.high >>> 0).toNumber(); + switch (object.endOfHistoryTransferType) { + case "COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY": + case 0: + message.endOfHistoryTransferType = 0; + break; + case "COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY": + case 1: + message.endOfHistoryTransferType = 1; + break; + } + if (object.conversationTimestamp != null) + if ($util.Long) + (message.conversationTimestamp = $util.Long.fromValue(object.conversationTimestamp)).unsigned = true; + else if (typeof object.conversationTimestamp === "string") + message.conversationTimestamp = parseInt(object.conversationTimestamp, 10); + else if (typeof object.conversationTimestamp === "number") + message.conversationTimestamp = object.conversationTimestamp; + else if (typeof object.conversationTimestamp === "object") + message.conversationTimestamp = new $util.LongBits(object.conversationTimestamp.low >>> 0, object.conversationTimestamp.high >>> 0).toNumber(true); + if (object.name != null) + message.name = String(object.name); + if (object.pHash != null) + message.pHash = String(object.pHash); + if (object.notSpam != null) + message.notSpam = Boolean(object.notSpam); + return message; + }; + + /** + * Creates a plain object from a Conversation message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Conversation + * @static + * @param {proto.Conversation} message Conversation + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Conversation.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.messages = []; + if (options.defaults) { + object.id = ""; + object.newJid = ""; + object.oldJid = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.lastMsgTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.lastMsgTimestamp = options.longs === String ? "0" : 0; + object.unreadCount = 0; + object.readOnly = false; + object.endOfHistoryTransfer = false; + object.ephemeralExpiration = 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.ephemeralSettingTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.ephemeralSettingTimestamp = options.longs === String ? "0" : 0; + object.endOfHistoryTransferType = options.enums === String ? "COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.conversationTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.conversationTimestamp = options.longs === String ? "0" : 0; + object.name = ""; + object.pHash = ""; + object.notSpam = false; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.messages && message.messages.length) { + object.messages = []; + for (var j = 0; j < message.messages.length; ++j) + object.messages[j] = $root.proto.HistorySyncMsg.toObject(message.messages[j], options); + } + if (message.newJid != null && message.hasOwnProperty("newJid")) + object.newJid = message.newJid; + if (message.oldJid != null && message.hasOwnProperty("oldJid")) + object.oldJid = message.oldJid; + if (message.lastMsgTimestamp != null && message.hasOwnProperty("lastMsgTimestamp")) + if (typeof message.lastMsgTimestamp === "number") + object.lastMsgTimestamp = options.longs === String ? String(message.lastMsgTimestamp) : message.lastMsgTimestamp; + else + object.lastMsgTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.lastMsgTimestamp) : options.longs === Number ? new $util.LongBits(message.lastMsgTimestamp.low >>> 0, message.lastMsgTimestamp.high >>> 0).toNumber(true) : message.lastMsgTimestamp; + if (message.unreadCount != null && message.hasOwnProperty("unreadCount")) + object.unreadCount = message.unreadCount; + if (message.readOnly != null && message.hasOwnProperty("readOnly")) + object.readOnly = message.readOnly; + if (message.endOfHistoryTransfer != null && message.hasOwnProperty("endOfHistoryTransfer")) + object.endOfHistoryTransfer = message.endOfHistoryTransfer; + if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration")) + object.ephemeralExpiration = message.ephemeralExpiration; + if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp")) + if (typeof message.ephemeralSettingTimestamp === "number") + object.ephemeralSettingTimestamp = options.longs === String ? String(message.ephemeralSettingTimestamp) : message.ephemeralSettingTimestamp; + else + object.ephemeralSettingTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.ephemeralSettingTimestamp) : options.longs === Number ? new $util.LongBits(message.ephemeralSettingTimestamp.low >>> 0, message.ephemeralSettingTimestamp.high >>> 0).toNumber() : message.ephemeralSettingTimestamp; + if (message.endOfHistoryTransferType != null && message.hasOwnProperty("endOfHistoryTransferType")) + object.endOfHistoryTransferType = options.enums === String ? $root.proto.Conversation.ConversationEndOfHistoryTransferType[message.endOfHistoryTransferType] : message.endOfHistoryTransferType; + if (message.conversationTimestamp != null && message.hasOwnProperty("conversationTimestamp")) + if (typeof message.conversationTimestamp === "number") + object.conversationTimestamp = options.longs === String ? String(message.conversationTimestamp) : message.conversationTimestamp; + else + object.conversationTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.conversationTimestamp) : options.longs === Number ? new $util.LongBits(message.conversationTimestamp.low >>> 0, message.conversationTimestamp.high >>> 0).toNumber(true) : message.conversationTimestamp; + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.pHash != null && message.hasOwnProperty("pHash")) + object.pHash = message.pHash; + if (message.notSpam != null && message.hasOwnProperty("notSpam")) + object.notSpam = message.notSpam; + return object; + }; + + /** + * Converts this Conversation to JSON. + * @function toJSON + * @memberof proto.Conversation + * @instance + * @returns {Object.} JSON object + */ + Conversation.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * ConversationEndOfHistoryTransferType enum. + * @name proto.Conversation.ConversationEndOfHistoryTransferType + * @enum {number} + * @property {number} COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY=0 COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY value + * @property {number} COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY=1 COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY value + */ + Conversation.ConversationEndOfHistoryTransferType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY"] = 0; + values[valuesById[1] = "COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY"] = 1; + return values; + })(); + + return Conversation; + })(); + + proto.HistorySync = (function() { + + /** + * Properties of a HistorySync. + * @memberof proto + * @interface IHistorySync + * @property {proto.HistorySync.HistorySyncHistorySyncType} syncType HistorySync syncType + * @property {Array.|null} [conversations] HistorySync conversations + * @property {Array.|null} [statusV3Messages] HistorySync statusV3Messages + * @property {number|null} [chunkOrder] HistorySync chunkOrder + * @property {number|null} [progress] HistorySync progress + * @property {Array.|null} [pushnames] HistorySync pushnames + */ + + /** + * Constructs a new HistorySync. + * @memberof proto + * @classdesc Represents a HistorySync. + * @implements IHistorySync + * @constructor + * @param {proto.IHistorySync=} [properties] Properties to set + */ + function HistorySync(properties) { + this.conversations = []; + this.statusV3Messages = []; + this.pushnames = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HistorySync syncType. + * @member {proto.HistorySync.HistorySyncHistorySyncType} syncType + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.syncType = 0; + + /** + * HistorySync conversations. + * @member {Array.} conversations + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.conversations = $util.emptyArray; + + /** + * HistorySync statusV3Messages. + * @member {Array.} statusV3Messages + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.statusV3Messages = $util.emptyArray; + + /** + * HistorySync chunkOrder. + * @member {number} chunkOrder + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.chunkOrder = 0; + + /** + * HistorySync progress. + * @member {number} progress + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.progress = 0; + + /** + * HistorySync pushnames. + * @member {Array.} pushnames + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.pushnames = $util.emptyArray; + + /** + * Creates a new HistorySync instance using the specified properties. + * @function create + * @memberof proto.HistorySync + * @static + * @param {proto.IHistorySync=} [properties] Properties to set + * @returns {proto.HistorySync} HistorySync instance + */ + HistorySync.create = function create(properties) { + return new HistorySync(properties); + }; + + /** + * Encodes the specified HistorySync message. Does not implicitly {@link proto.HistorySync.verify|verify} messages. + * @function encode + * @memberof proto.HistorySync + * @static + * @param {proto.IHistorySync} message HistorySync message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HistorySync.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.syncType); + if (message.conversations != null && message.conversations.length) + for (var i = 0; i < message.conversations.length; ++i) + $root.proto.Conversation.encode(message.conversations[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.statusV3Messages != null && message.statusV3Messages.length) + for (var i = 0; i < message.statusV3Messages.length; ++i) + $root.proto.WebMessageInfo.encode(message.statusV3Messages[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.chunkOrder != null && Object.hasOwnProperty.call(message, "chunkOrder")) + writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.chunkOrder); + if (message.progress != null && Object.hasOwnProperty.call(message, "progress")) + writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.progress); + if (message.pushnames != null && message.pushnames.length) + for (var i = 0; i < message.pushnames.length; ++i) + $root.proto.Pushname.encode(message.pushnames[i], writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified HistorySync message, length delimited. Does not implicitly {@link proto.HistorySync.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HistorySync + * @static + * @param {proto.IHistorySync} message HistorySync message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HistorySync.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HistorySync message from the specified reader or buffer. + * @function decode + * @memberof proto.HistorySync + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HistorySync} HistorySync + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HistorySync.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HistorySync(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.syncType = reader.int32(); + break; + case 2: + if (!(message.conversations && message.conversations.length)) + message.conversations = []; + message.conversations.push($root.proto.Conversation.decode(reader, reader.uint32())); + break; + case 3: + if (!(message.statusV3Messages && message.statusV3Messages.length)) + message.statusV3Messages = []; + message.statusV3Messages.push($root.proto.WebMessageInfo.decode(reader, reader.uint32())); + break; + case 5: + message.chunkOrder = reader.uint32(); + break; + case 6: + message.progress = reader.uint32(); + break; + case 7: + if (!(message.pushnames && message.pushnames.length)) + message.pushnames = []; + message.pushnames.push($root.proto.Pushname.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + if (!message.hasOwnProperty("syncType")) + throw $util.ProtocolError("missing required 'syncType'", { instance: message }); + return message; + }; + + /** + * Decodes a HistorySync message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HistorySync + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HistorySync} HistorySync + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HistorySync.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HistorySync message. + * @function verify + * @memberof proto.HistorySync + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HistorySync.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + switch (message.syncType) { + default: + return "syncType: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + break; + } + if (message.conversations != null && message.hasOwnProperty("conversations")) { + if (!Array.isArray(message.conversations)) + return "conversations: array expected"; + for (var i = 0; i < message.conversations.length; ++i) { + var error = $root.proto.Conversation.verify(message.conversations[i]); + if (error) + return "conversations." + error; + } + } + if (message.statusV3Messages != null && message.hasOwnProperty("statusV3Messages")) { + if (!Array.isArray(message.statusV3Messages)) + return "statusV3Messages: array expected"; + for (var i = 0; i < message.statusV3Messages.length; ++i) { + var error = $root.proto.WebMessageInfo.verify(message.statusV3Messages[i]); + if (error) + return "statusV3Messages." + error; + } + } + if (message.chunkOrder != null && message.hasOwnProperty("chunkOrder")) + if (!$util.isInteger(message.chunkOrder)) + return "chunkOrder: integer expected"; + if (message.progress != null && message.hasOwnProperty("progress")) + if (!$util.isInteger(message.progress)) + return "progress: integer expected"; + if (message.pushnames != null && message.hasOwnProperty("pushnames")) { + if (!Array.isArray(message.pushnames)) + return "pushnames: array expected"; + for (var i = 0; i < message.pushnames.length; ++i) { + var error = $root.proto.Pushname.verify(message.pushnames[i]); + if (error) + return "pushnames." + error; + } + } + return null; + }; + + /** + * Creates a HistorySync message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HistorySync + * @static + * @param {Object.} object Plain object + * @returns {proto.HistorySync} HistorySync + */ + HistorySync.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HistorySync) + return object; + var message = new $root.proto.HistorySync(); + switch (object.syncType) { + case "INITIAL_BOOTSTRAP": + case 0: + message.syncType = 0; + break; + case "INITIAL_STATUS_V3": + case 1: + message.syncType = 1; + break; + case "FULL": + case 2: + message.syncType = 2; + break; + case "RECENT": + case 3: + message.syncType = 3; + break; + case "PUSH_NAME": + case 4: + message.syncType = 4; + break; + } + if (object.conversations) { + if (!Array.isArray(object.conversations)) + throw TypeError(".proto.HistorySync.conversations: array expected"); + message.conversations = []; + for (var i = 0; i < object.conversations.length; ++i) { + if (typeof object.conversations[i] !== "object") + throw TypeError(".proto.HistorySync.conversations: object expected"); + message.conversations[i] = $root.proto.Conversation.fromObject(object.conversations[i]); + } + } + if (object.statusV3Messages) { + if (!Array.isArray(object.statusV3Messages)) + throw TypeError(".proto.HistorySync.statusV3Messages: array expected"); + message.statusV3Messages = []; + for (var i = 0; i < object.statusV3Messages.length; ++i) { + if (typeof object.statusV3Messages[i] !== "object") + throw TypeError(".proto.HistorySync.statusV3Messages: object expected"); + message.statusV3Messages[i] = $root.proto.WebMessageInfo.fromObject(object.statusV3Messages[i]); + } + } + if (object.chunkOrder != null) + message.chunkOrder = object.chunkOrder >>> 0; + if (object.progress != null) + message.progress = object.progress >>> 0; + if (object.pushnames) { + if (!Array.isArray(object.pushnames)) + throw TypeError(".proto.HistorySync.pushnames: array expected"); + message.pushnames = []; + for (var i = 0; i < object.pushnames.length; ++i) { + if (typeof object.pushnames[i] !== "object") + throw TypeError(".proto.HistorySync.pushnames: object expected"); + message.pushnames[i] = $root.proto.Pushname.fromObject(object.pushnames[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a HistorySync message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HistorySync + * @static + * @param {proto.HistorySync} message HistorySync + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HistorySync.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.conversations = []; + object.statusV3Messages = []; + object.pushnames = []; + } + if (options.defaults) { + object.syncType = options.enums === String ? "INITIAL_BOOTSTRAP" : 0; + object.chunkOrder = 0; + object.progress = 0; + } + if (message.syncType != null && message.hasOwnProperty("syncType")) + object.syncType = options.enums === String ? $root.proto.HistorySync.HistorySyncHistorySyncType[message.syncType] : message.syncType; + if (message.conversations && message.conversations.length) { + object.conversations = []; + for (var j = 0; j < message.conversations.length; ++j) + object.conversations[j] = $root.proto.Conversation.toObject(message.conversations[j], options); + } + if (message.statusV3Messages && message.statusV3Messages.length) { + object.statusV3Messages = []; + for (var j = 0; j < message.statusV3Messages.length; ++j) + object.statusV3Messages[j] = $root.proto.WebMessageInfo.toObject(message.statusV3Messages[j], options); + } + if (message.chunkOrder != null && message.hasOwnProperty("chunkOrder")) + object.chunkOrder = message.chunkOrder; + if (message.progress != null && message.hasOwnProperty("progress")) + object.progress = message.progress; + if (message.pushnames && message.pushnames.length) { + object.pushnames = []; + for (var j = 0; j < message.pushnames.length; ++j) + object.pushnames[j] = $root.proto.Pushname.toObject(message.pushnames[j], options); + } + return object; + }; + + /** + * Converts this HistorySync to JSON. + * @function toJSON + * @memberof proto.HistorySync + * @instance + * @returns {Object.} JSON object + */ + HistorySync.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * HistorySyncHistorySyncType enum. + * @name proto.HistorySync.HistorySyncHistorySyncType + * @enum {number} + * @property {number} INITIAL_BOOTSTRAP=0 INITIAL_BOOTSTRAP value + * @property {number} INITIAL_STATUS_V3=1 INITIAL_STATUS_V3 value + * @property {number} FULL=2 FULL value + * @property {number} RECENT=3 RECENT value + * @property {number} PUSH_NAME=4 PUSH_NAME value + */ + HistorySync.HistorySyncHistorySyncType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "INITIAL_BOOTSTRAP"] = 0; + values[valuesById[1] = "INITIAL_STATUS_V3"] = 1; + values[valuesById[2] = "FULL"] = 2; + values[valuesById[3] = "RECENT"] = 3; + values[valuesById[4] = "PUSH_NAME"] = 4; + return values; + })(); + + return HistorySync; + })(); + + proto.EphemeralSetting = (function() { + + /** + * Properties of an EphemeralSetting. + * @memberof proto + * @interface IEphemeralSetting + * @property {number|null} [duration] EphemeralSetting duration + * @property {number|Long|null} [timestamp] EphemeralSetting timestamp + */ + + /** + * Constructs a new EphemeralSetting. + * @memberof proto + * @classdesc Represents an EphemeralSetting. + * @implements IEphemeralSetting + * @constructor + * @param {proto.IEphemeralSetting=} [properties] Properties to set + */ + function EphemeralSetting(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * EphemeralSetting duration. + * @member {number} duration + * @memberof proto.EphemeralSetting + * @instance + */ + EphemeralSetting.prototype.duration = 0; + + /** + * EphemeralSetting timestamp. + * @member {number|Long} timestamp + * @memberof proto.EphemeralSetting + * @instance + */ + EphemeralSetting.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new EphemeralSetting instance using the specified properties. + * @function create + * @memberof proto.EphemeralSetting + * @static + * @param {proto.IEphemeralSetting=} [properties] Properties to set + * @returns {proto.EphemeralSetting} EphemeralSetting instance + */ + EphemeralSetting.create = function create(properties) { + return new EphemeralSetting(properties); + }; + + /** + * Encodes the specified EphemeralSetting message. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. + * @function encode + * @memberof proto.EphemeralSetting + * @static + * @param {proto.IEphemeralSetting} message EphemeralSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + EphemeralSetting.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.duration != null && Object.hasOwnProperty.call(message, "duration")) + writer.uint32(/* id 1, wireType 5 =*/13).sfixed32(message.duration); + if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) + writer.uint32(/* id 2, wireType 1 =*/17).sfixed64(message.timestamp); + return writer; + }; + + /** + * Encodes the specified EphemeralSetting message, length delimited. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.EphemeralSetting + * @static + * @param {proto.IEphemeralSetting} message EphemeralSetting message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + EphemeralSetting.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an EphemeralSetting message from the specified reader or buffer. + * @function decode + * @memberof proto.EphemeralSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.EphemeralSetting} EphemeralSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + EphemeralSetting.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.EphemeralSetting(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.duration = reader.sfixed32(); + break; + case 2: + message.timestamp = reader.sfixed64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an EphemeralSetting message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.EphemeralSetting + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.EphemeralSetting} EphemeralSetting + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + EphemeralSetting.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an EphemeralSetting message. + * @function verify + * @memberof proto.EphemeralSetting + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + EphemeralSetting.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.duration != null && message.hasOwnProperty("duration")) + if (!$util.isInteger(message.duration)) + return "duration: integer expected"; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) + return "timestamp: integer|Long expected"; + return null; + }; + + /** + * Creates an EphemeralSetting message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.EphemeralSetting + * @static + * @param {Object.} object Plain object + * @returns {proto.EphemeralSetting} EphemeralSetting + */ + EphemeralSetting.fromObject = function fromObject(object) { + if (object instanceof $root.proto.EphemeralSetting) + return object; + var message = new $root.proto.EphemeralSetting(); + if (object.duration != null) + message.duration = object.duration | 0; + if (object.timestamp != null) + if ($util.Long) + (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false; + else if (typeof object.timestamp === "string") + message.timestamp = parseInt(object.timestamp, 10); + else if (typeof object.timestamp === "number") + message.timestamp = object.timestamp; + else if (typeof object.timestamp === "object") + message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from an EphemeralSetting message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.EphemeralSetting + * @static + * @param {proto.EphemeralSetting} message EphemeralSetting + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + EphemeralSetting.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.duration = 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.timestamp = options.longs === String ? "0" : 0; + } + if (message.duration != null && message.hasOwnProperty("duration")) + object.duration = message.duration; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (typeof message.timestamp === "number") + object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; + else + object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp; + return object; + }; + + /** + * Converts this EphemeralSetting to JSON. + * @function toJSON + * @memberof proto.EphemeralSetting + * @instance + * @returns {Object.} JSON object + */ + EphemeralSetting.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return EphemeralSetting; + })(); + + proto.PaymentBackground = (function() { + + /** + * Properties of a PaymentBackground. + * @memberof proto + * @interface IPaymentBackground + * @property {string|null} [id] PaymentBackground id + * @property {string|null} [fileLength] PaymentBackground fileLength + * @property {number|null} [width] PaymentBackground width + * @property {number|null} [height] PaymentBackground height + * @property {string|null} [mimetype] PaymentBackground mimetype + * @property {number|null} [placeholderArgb] PaymentBackground placeholderArgb + * @property {number|null} [textArgb] PaymentBackground textArgb + * @property {number|null} [subtextArgb] PaymentBackground subtextArgb + */ + + /** + * Constructs a new PaymentBackground. + * @memberof proto + * @classdesc Represents a PaymentBackground. + * @implements IPaymentBackground + * @constructor + * @param {proto.IPaymentBackground=} [properties] Properties to set + */ + function PaymentBackground(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * PaymentBackground id. + * @member {string} id + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.id = ""; + + /** + * PaymentBackground fileLength. + * @member {string} fileLength + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.fileLength = ""; + + /** + * PaymentBackground width. + * @member {number} width + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.width = 0; + + /** + * PaymentBackground height. + * @member {number} height + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.height = 0; + + /** + * PaymentBackground mimetype. + * @member {string} mimetype + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.mimetype = ""; + + /** + * PaymentBackground placeholderArgb. + * @member {number} placeholderArgb + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.placeholderArgb = 0; + + /** + * PaymentBackground textArgb. + * @member {number} textArgb + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.textArgb = 0; + + /** + * PaymentBackground subtextArgb. + * @member {number} subtextArgb + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.subtextArgb = 0; + + /** + * Creates a new PaymentBackground instance using the specified properties. + * @function create + * @memberof proto.PaymentBackground + * @static + * @param {proto.IPaymentBackground=} [properties] Properties to set + * @returns {proto.PaymentBackground} PaymentBackground instance + */ + PaymentBackground.create = function create(properties) { + return new PaymentBackground(properties); + }; + + /** + * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @function encode + * @memberof proto.PaymentBackground + * @static + * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PaymentBackground.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); + if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.fileLength); + if (message.width != null && Object.hasOwnProperty.call(message, "width")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.width); + if (message.height != null && Object.hasOwnProperty.call(message, "height")) + writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.height); + if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.mimetype); + if (message.placeholderArgb != null && Object.hasOwnProperty.call(message, "placeholderArgb")) + writer.uint32(/* id 6, wireType 5 =*/53).fixed32(message.placeholderArgb); + if (message.textArgb != null && Object.hasOwnProperty.call(message, "textArgb")) + writer.uint32(/* id 7, wireType 5 =*/61).fixed32(message.textArgb); + if (message.subtextArgb != null && Object.hasOwnProperty.call(message, "subtextArgb")) + writer.uint32(/* id 8, wireType 5 =*/69).fixed32(message.subtextArgb); + return writer; + }; + + /** + * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.PaymentBackground + * @static + * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PaymentBackground.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a PaymentBackground message from the specified reader or buffer. + * @function decode + * @memberof proto.PaymentBackground + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.PaymentBackground} PaymentBackground + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PaymentBackground.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentBackground(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.fileLength = reader.string(); + break; + case 3: + message.width = reader.uint32(); + break; + case 4: + message.height = reader.uint32(); + break; + case 5: + message.mimetype = reader.string(); + break; + case 6: + message.placeholderArgb = reader.fixed32(); + break; + case 7: + message.textArgb = reader.fixed32(); + break; + case 8: + message.subtextArgb = reader.fixed32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.PaymentBackground + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.PaymentBackground} PaymentBackground + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PaymentBackground.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a PaymentBackground message. + * @function verify + * @memberof proto.PaymentBackground + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + PaymentBackground.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.fileLength != null && message.hasOwnProperty("fileLength")) + if (!$util.isString(message.fileLength)) + return "fileLength: string expected"; + if (message.width != null && message.hasOwnProperty("width")) + if (!$util.isInteger(message.width)) + return "width: integer expected"; + if (message.height != null && message.hasOwnProperty("height")) + if (!$util.isInteger(message.height)) + return "height: integer expected"; + if (message.mimetype != null && message.hasOwnProperty("mimetype")) + if (!$util.isString(message.mimetype)) + return "mimetype: string expected"; + if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) + if (!$util.isInteger(message.placeholderArgb)) + return "placeholderArgb: integer expected"; + if (message.textArgb != null && message.hasOwnProperty("textArgb")) + if (!$util.isInteger(message.textArgb)) + return "textArgb: integer expected"; + if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) + if (!$util.isInteger(message.subtextArgb)) + return "subtextArgb: integer expected"; + return null; + }; + + /** + * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.PaymentBackground + * @static + * @param {Object.} object Plain object + * @returns {proto.PaymentBackground} PaymentBackground + */ + PaymentBackground.fromObject = function fromObject(object) { + if (object instanceof $root.proto.PaymentBackground) + return object; + var message = new $root.proto.PaymentBackground(); + if (object.id != null) + message.id = String(object.id); + if (object.fileLength != null) + message.fileLength = String(object.fileLength); + if (object.width != null) + message.width = object.width >>> 0; + if (object.height != null) + message.height = object.height >>> 0; + if (object.mimetype != null) + message.mimetype = String(object.mimetype); + if (object.placeholderArgb != null) + message.placeholderArgb = object.placeholderArgb >>> 0; + if (object.textArgb != null) + message.textArgb = object.textArgb >>> 0; + if (object.subtextArgb != null) + message.subtextArgb = object.subtextArgb >>> 0; + return message; + }; + + /** + * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.PaymentBackground + * @static + * @param {proto.PaymentBackground} message PaymentBackground + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + PaymentBackground.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.id = ""; + object.fileLength = ""; + object.width = 0; + object.height = 0; + object.mimetype = ""; + object.placeholderArgb = 0; + object.textArgb = 0; + object.subtextArgb = 0; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.fileLength != null && message.hasOwnProperty("fileLength")) + object.fileLength = message.fileLength; + if (message.width != null && message.hasOwnProperty("width")) + object.width = message.width; + if (message.height != null && message.hasOwnProperty("height")) + object.height = message.height; + if (message.mimetype != null && message.hasOwnProperty("mimetype")) + object.mimetype = message.mimetype; + if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) + object.placeholderArgb = message.placeholderArgb; + if (message.textArgb != null && message.hasOwnProperty("textArgb")) + object.textArgb = message.textArgb; + if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) + object.subtextArgb = message.subtextArgb; + return object; + }; + + /** + * Converts this PaymentBackground to JSON. + * @function toJSON + * @memberof proto.PaymentBackground + * @instance + * @returns {Object.} JSON object + */ + PaymentBackground.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return PaymentBackground; + })(); + + proto.Money = (function() { + + /** + * Properties of a Money. + * @memberof proto + * @interface IMoney + * @property {number|Long|null} [value] Money value + * @property {number|null} [offset] Money offset + * @property {string|null} [currencyCode] Money currencyCode + */ + + /** + * Constructs a new Money. + * @memberof proto + * @classdesc Represents a Money. + * @implements IMoney + * @constructor + * @param {proto.IMoney=} [properties] Properties to set + */ + function Money(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Money value. + * @member {number|Long} value + * @memberof proto.Money + * @instance + */ + Money.prototype.value = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Money offset. + * @member {number} offset + * @memberof proto.Money + * @instance + */ + Money.prototype.offset = 0; + + /** + * Money currencyCode. + * @member {string} currencyCode + * @memberof proto.Money + * @instance + */ + Money.prototype.currencyCode = ""; + + /** + * Creates a new Money instance using the specified properties. + * @function create + * @memberof proto.Money + * @static + * @param {proto.IMoney=} [properties] Properties to set + * @returns {proto.Money} Money instance + */ + Money.create = function create(properties) { + return new Money(properties); + }; + + /** + * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. + * @function encode + * @memberof proto.Money + * @static + * @param {proto.IMoney} message Money message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Money.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.value != null && Object.hasOwnProperty.call(message, "value")) + writer.uint32(/* id 1, wireType 0 =*/8).int64(message.value); + if (message.offset != null && Object.hasOwnProperty.call(message, "offset")) + writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.offset); + if (message.currencyCode != null && Object.hasOwnProperty.call(message, "currencyCode")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.currencyCode); + return writer; + }; + + /** + * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Money + * @static + * @param {proto.IMoney} message Money message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Money.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Money message from the specified reader or buffer. + * @function decode + * @memberof proto.Money + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Money} Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Money.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Money(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.value = reader.int64(); + break; + case 2: + message.offset = reader.uint32(); + break; + case 3: + message.currencyCode = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Money message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Money + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Money} Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Money.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Money message. + * @function verify + * @memberof proto.Money + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Money.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.value != null && message.hasOwnProperty("value")) + if (!$util.isInteger(message.value) && !(message.value && $util.isInteger(message.value.low) && $util.isInteger(message.value.high))) + return "value: integer|Long expected"; + if (message.offset != null && message.hasOwnProperty("offset")) + if (!$util.isInteger(message.offset)) + return "offset: integer expected"; + if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) + if (!$util.isString(message.currencyCode)) + return "currencyCode: string expected"; + return null; + }; + + /** + * Creates a Money message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Money + * @static + * @param {Object.} object Plain object + * @returns {proto.Money} Money + */ + Money.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Money) + return object; + var message = new $root.proto.Money(); + if (object.value != null) + if ($util.Long) + (message.value = $util.Long.fromValue(object.value)).unsigned = false; + else if (typeof object.value === "string") + message.value = parseInt(object.value, 10); + else if (typeof object.value === "number") + message.value = object.value; + else if (typeof object.value === "object") + message.value = new $util.LongBits(object.value.low >>> 0, object.value.high >>> 0).toNumber(); + if (object.offset != null) + message.offset = object.offset >>> 0; + if (object.currencyCode != null) + message.currencyCode = String(object.currencyCode); + return message; + }; + + /** + * Creates a plain object from a Money message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Money + * @static + * @param {proto.Money} message Money + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Money.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.value = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.value = options.longs === String ? "0" : 0; + object.offset = 0; + object.currencyCode = ""; + } + if (message.value != null && message.hasOwnProperty("value")) + if (typeof message.value === "number") + object.value = options.longs === String ? String(message.value) : message.value; + else + object.value = options.longs === String ? $util.Long.prototype.toString.call(message.value) : options.longs === Number ? new $util.LongBits(message.value.low >>> 0, message.value.high >>> 0).toNumber() : message.value; + if (message.offset != null && message.hasOwnProperty("offset")) + object.offset = message.offset; + if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) + object.currencyCode = message.currencyCode; + return object; + }; + + /** + * Converts this Money to JSON. + * @function toJSON + * @memberof proto.Money + * @instance + * @returns {Object.} JSON object + */ + Money.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Money; + })(); + + proto.HydratedQuickReplyButton = (function() { + + /** + * Properties of a HydratedQuickReplyButton. + * @memberof proto + * @interface IHydratedQuickReplyButton + * @property {string|null} [displayText] HydratedQuickReplyButton displayText + * @property {string|null} [id] HydratedQuickReplyButton id + */ + + /** + * Constructs a new HydratedQuickReplyButton. + * @memberof proto + * @classdesc Represents a HydratedQuickReplyButton. + * @implements IHydratedQuickReplyButton + * @constructor + * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set + */ + function HydratedQuickReplyButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HydratedQuickReplyButton displayText. + * @member {string} displayText + * @memberof proto.HydratedQuickReplyButton + * @instance + */ + HydratedQuickReplyButton.prototype.displayText = ""; + + /** + * HydratedQuickReplyButton id. + * @member {string} id + * @memberof proto.HydratedQuickReplyButton + * @instance + */ + HydratedQuickReplyButton.prototype.id = ""; + + /** + * Creates a new HydratedQuickReplyButton instance using the specified properties. + * @function create + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set + * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton instance + */ + HydratedQuickReplyButton.create = function create(properties) { + return new HydratedQuickReplyButton(properties); + }; + + /** + * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * @function encode + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedQuickReplyButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.id); + return writer; + }; + + /** + * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedQuickReplyButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HydratedQuickReplyButton message from the specified reader or buffer. + * @function decode + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedQuickReplyButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedQuickReplyButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = reader.string(); + break; + case 2: + message.id = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedQuickReplyButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HydratedQuickReplyButton message. + * @function verify + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HydratedQuickReplyButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) + if (!$util.isString(message.displayText)) + return "displayText: string expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + return null; + }; + + /** + * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {Object.} object Plain object + * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton + */ + HydratedQuickReplyButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HydratedQuickReplyButton) + return object; + var message = new $root.proto.HydratedQuickReplyButton(); + if (object.displayText != null) + message.displayText = String(object.displayText); + if (object.id != null) + message.id = String(object.id); + return message; + }; + + /** + * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {proto.HydratedQuickReplyButton} message HydratedQuickReplyButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HydratedQuickReplyButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.displayText = ""; + object.id = ""; + } + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = message.displayText; + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + return object; + }; + + /** + * Converts this HydratedQuickReplyButton to JSON. + * @function toJSON + * @memberof proto.HydratedQuickReplyButton + * @instance + * @returns {Object.} JSON object + */ + HydratedQuickReplyButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HydratedQuickReplyButton; + })(); + + proto.HydratedURLButton = (function() { + + /** + * Properties of a HydratedURLButton. + * @memberof proto + * @interface IHydratedURLButton + * @property {string|null} [displayText] HydratedURLButton displayText + * @property {string|null} [url] HydratedURLButton url + */ + + /** + * Constructs a new HydratedURLButton. + * @memberof proto + * @classdesc Represents a HydratedURLButton. + * @implements IHydratedURLButton + * @constructor + * @param {proto.IHydratedURLButton=} [properties] Properties to set + */ + function HydratedURLButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HydratedURLButton displayText. + * @member {string} displayText + * @memberof proto.HydratedURLButton + * @instance + */ + HydratedURLButton.prototype.displayText = ""; + + /** + * HydratedURLButton url. + * @member {string} url + * @memberof proto.HydratedURLButton + * @instance + */ + HydratedURLButton.prototype.url = ""; + + /** + * Creates a new HydratedURLButton instance using the specified properties. + * @function create + * @memberof proto.HydratedURLButton + * @static + * @param {proto.IHydratedURLButton=} [properties] Properties to set + * @returns {proto.HydratedURLButton} HydratedURLButton instance + */ + HydratedURLButton.create = function create(properties) { + return new HydratedURLButton(properties); + }; + + /** + * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. + * @function encode + * @memberof proto.HydratedURLButton + * @static + * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedURLButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); + if (message.url != null && Object.hasOwnProperty.call(message, "url")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.url); + return writer; + }; + + /** + * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HydratedURLButton + * @static + * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedURLButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HydratedURLButton message from the specified reader or buffer. + * @function decode + * @memberof proto.HydratedURLButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HydratedURLButton} HydratedURLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedURLButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedURLButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = reader.string(); + break; + case 2: + message.url = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HydratedURLButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HydratedURLButton} HydratedURLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedURLButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HydratedURLButton message. + * @function verify + * @memberof proto.HydratedURLButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HydratedURLButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) + if (!$util.isString(message.displayText)) + return "displayText: string expected"; + if (message.url != null && message.hasOwnProperty("url")) + if (!$util.isString(message.url)) + return "url: string expected"; + return null; + }; + + /** + * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HydratedURLButton + * @static + * @param {Object.} object Plain object + * @returns {proto.HydratedURLButton} HydratedURLButton + */ + HydratedURLButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HydratedURLButton) + return object; + var message = new $root.proto.HydratedURLButton(); + if (object.displayText != null) + message.displayText = String(object.displayText); + if (object.url != null) + message.url = String(object.url); + return message; + }; + + /** + * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HydratedURLButton + * @static + * @param {proto.HydratedURLButton} message HydratedURLButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HydratedURLButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.displayText = ""; + object.url = ""; + } + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = message.displayText; + if (message.url != null && message.hasOwnProperty("url")) + object.url = message.url; + return object; + }; + + /** + * Converts this HydratedURLButton to JSON. + * @function toJSON + * @memberof proto.HydratedURLButton + * @instance + * @returns {Object.} JSON object + */ + HydratedURLButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HydratedURLButton; + })(); + + proto.HydratedCallButton = (function() { + + /** + * Properties of a HydratedCallButton. + * @memberof proto + * @interface IHydratedCallButton + * @property {string|null} [displayText] HydratedCallButton displayText + * @property {string|null} [phoneNumber] HydratedCallButton phoneNumber + */ + + /** + * Constructs a new HydratedCallButton. + * @memberof proto + * @classdesc Represents a HydratedCallButton. + * @implements IHydratedCallButton + * @constructor + * @param {proto.IHydratedCallButton=} [properties] Properties to set + */ + function HydratedCallButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HydratedCallButton displayText. + * @member {string} displayText + * @memberof proto.HydratedCallButton + * @instance + */ + HydratedCallButton.prototype.displayText = ""; + + /** + * HydratedCallButton phoneNumber. + * @member {string} phoneNumber + * @memberof proto.HydratedCallButton + * @instance + */ + HydratedCallButton.prototype.phoneNumber = ""; + + /** + * Creates a new HydratedCallButton instance using the specified properties. + * @function create + * @memberof proto.HydratedCallButton + * @static + * @param {proto.IHydratedCallButton=} [properties] Properties to set + * @returns {proto.HydratedCallButton} HydratedCallButton instance + */ + HydratedCallButton.create = function create(properties) { + return new HydratedCallButton(properties); + }; + + /** + * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. + * @function encode + * @memberof proto.HydratedCallButton + * @static + * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedCallButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); + if (message.phoneNumber != null && Object.hasOwnProperty.call(message, "phoneNumber")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.phoneNumber); + return writer; + }; + + /** + * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HydratedCallButton + * @static + * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedCallButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HydratedCallButton message from the specified reader or buffer. + * @function decode + * @memberof proto.HydratedCallButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HydratedCallButton} HydratedCallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedCallButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedCallButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = reader.string(); + break; + case 2: + message.phoneNumber = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HydratedCallButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HydratedCallButton} HydratedCallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedCallButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HydratedCallButton message. + * @function verify + * @memberof proto.HydratedCallButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HydratedCallButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) + if (!$util.isString(message.displayText)) + return "displayText: string expected"; + if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) + if (!$util.isString(message.phoneNumber)) + return "phoneNumber: string expected"; + return null; + }; + + /** + * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HydratedCallButton + * @static + * @param {Object.} object Plain object + * @returns {proto.HydratedCallButton} HydratedCallButton + */ + HydratedCallButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HydratedCallButton) + return object; + var message = new $root.proto.HydratedCallButton(); + if (object.displayText != null) + message.displayText = String(object.displayText); + if (object.phoneNumber != null) + message.phoneNumber = String(object.phoneNumber); + return message; + }; + + /** + * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HydratedCallButton + * @static + * @param {proto.HydratedCallButton} message HydratedCallButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HydratedCallButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.displayText = ""; + object.phoneNumber = ""; + } + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = message.displayText; + if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) + object.phoneNumber = message.phoneNumber; + return object; + }; + + /** + * Converts this HydratedCallButton to JSON. + * @function toJSON + * @memberof proto.HydratedCallButton + * @instance + * @returns {Object.} JSON object + */ + HydratedCallButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HydratedCallButton; + })(); + + proto.HydratedTemplateButton = (function() { + + /** + * Properties of a HydratedTemplateButton. + * @memberof proto + * @interface IHydratedTemplateButton + * @property {number|null} [index] HydratedTemplateButton index + * @property {proto.IHydratedQuickReplyButton|null} [quickReplyButton] HydratedTemplateButton quickReplyButton + * @property {proto.IHydratedURLButton|null} [urlButton] HydratedTemplateButton urlButton + * @property {proto.IHydratedCallButton|null} [callButton] HydratedTemplateButton callButton + */ + + /** + * Constructs a new HydratedTemplateButton. + * @memberof proto + * @classdesc Represents a HydratedTemplateButton. + * @implements IHydratedTemplateButton + * @constructor + * @param {proto.IHydratedTemplateButton=} [properties] Properties to set + */ + function HydratedTemplateButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HydratedTemplateButton index. + * @member {number} index + * @memberof proto.HydratedTemplateButton + * @instance + */ + HydratedTemplateButton.prototype.index = 0; + + /** + * HydratedTemplateButton quickReplyButton. + * @member {proto.IHydratedQuickReplyButton|null|undefined} quickReplyButton + * @memberof proto.HydratedTemplateButton + * @instance + */ + HydratedTemplateButton.prototype.quickReplyButton = null; + + /** + * HydratedTemplateButton urlButton. + * @member {proto.IHydratedURLButton|null|undefined} urlButton + * @memberof proto.HydratedTemplateButton + * @instance + */ + HydratedTemplateButton.prototype.urlButton = null; + + /** + * HydratedTemplateButton callButton. + * @member {proto.IHydratedCallButton|null|undefined} callButton + * @memberof proto.HydratedTemplateButton + * @instance + */ + HydratedTemplateButton.prototype.callButton = null; + + // OneOf field names bound to virtual getters and setters + var $oneOfFields; + + /** + * HydratedTemplateButton hydratedButton. + * @member {"quickReplyButton"|"urlButton"|"callButton"|undefined} hydratedButton + * @memberof proto.HydratedTemplateButton + * @instance + */ + Object.defineProperty(HydratedTemplateButton.prototype, "hydratedButton", { + get: $util.oneOfGetter($oneOfFields = ["quickReplyButton", "urlButton", "callButton"]), + set: $util.oneOfSetter($oneOfFields) + }); + + /** + * Creates a new HydratedTemplateButton instance using the specified properties. + * @function create + * @memberof proto.HydratedTemplateButton + * @static + * @param {proto.IHydratedTemplateButton=} [properties] Properties to set + * @returns {proto.HydratedTemplateButton} HydratedTemplateButton instance + */ + HydratedTemplateButton.create = function create(properties) { + return new HydratedTemplateButton(properties); + }; + + /** + * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. + * @function encode + * @memberof proto.HydratedTemplateButton + * @static + * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedTemplateButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.quickReplyButton != null && Object.hasOwnProperty.call(message, "quickReplyButton")) + $root.proto.HydratedQuickReplyButton.encode(message.quickReplyButton, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.urlButton != null && Object.hasOwnProperty.call(message, "urlButton")) + $root.proto.HydratedURLButton.encode(message.urlButton, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.callButton != null && Object.hasOwnProperty.call(message, "callButton")) + $root.proto.HydratedCallButton.encode(message.callButton, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.index != null && Object.hasOwnProperty.call(message, "index")) + writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.index); + return writer; + }; + + /** + * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HydratedTemplateButton + * @static + * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedTemplateButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HydratedTemplateButton message from the specified reader or buffer. + * @function decode + * @memberof proto.HydratedTemplateButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HydratedTemplateButton} HydratedTemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedTemplateButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedTemplateButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 4: + message.index = reader.uint32(); + break; + case 1: + message.quickReplyButton = $root.proto.HydratedQuickReplyButton.decode(reader, reader.uint32()); + break; + case 2: + message.urlButton = $root.proto.HydratedURLButton.decode(reader, reader.uint32()); + break; + case 3: + message.callButton = $root.proto.HydratedCallButton.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HydratedTemplateButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HydratedTemplateButton} HydratedTemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedTemplateButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HydratedTemplateButton message. + * @function verify + * @memberof proto.HydratedTemplateButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HydratedTemplateButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var properties = {}; + if (message.index != null && message.hasOwnProperty("index")) + if (!$util.isInteger(message.index)) + return "index: integer expected"; + if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { + properties.hydratedButton = 1; + { + var error = $root.proto.HydratedQuickReplyButton.verify(message.quickReplyButton); + if (error) + return "quickReplyButton." + error; + } + } + if (message.urlButton != null && message.hasOwnProperty("urlButton")) { + if (properties.hydratedButton === 1) + return "hydratedButton: multiple values"; + properties.hydratedButton = 1; + { + var error = $root.proto.HydratedURLButton.verify(message.urlButton); + if (error) + return "urlButton." + error; + } + } + if (message.callButton != null && message.hasOwnProperty("callButton")) { + if (properties.hydratedButton === 1) + return "hydratedButton: multiple values"; + properties.hydratedButton = 1; + { + var error = $root.proto.HydratedCallButton.verify(message.callButton); + if (error) + return "callButton." + error; + } + } + return null; + }; + + /** + * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HydratedTemplateButton + * @static + * @param {Object.} object Plain object + * @returns {proto.HydratedTemplateButton} HydratedTemplateButton + */ + HydratedTemplateButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HydratedTemplateButton) + return object; + var message = new $root.proto.HydratedTemplateButton(); + if (object.index != null) + message.index = object.index >>> 0; + if (object.quickReplyButton != null) { + if (typeof object.quickReplyButton !== "object") + throw TypeError(".proto.HydratedTemplateButton.quickReplyButton: object expected"); + message.quickReplyButton = $root.proto.HydratedQuickReplyButton.fromObject(object.quickReplyButton); + } + if (object.urlButton != null) { + if (typeof object.urlButton !== "object") + throw TypeError(".proto.HydratedTemplateButton.urlButton: object expected"); + message.urlButton = $root.proto.HydratedURLButton.fromObject(object.urlButton); + } + if (object.callButton != null) { + if (typeof object.callButton !== "object") + throw TypeError(".proto.HydratedTemplateButton.callButton: object expected"); + message.callButton = $root.proto.HydratedCallButton.fromObject(object.callButton); + } + return message; + }; + + /** + * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HydratedTemplateButton + * @static + * @param {proto.HydratedTemplateButton} message HydratedTemplateButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HydratedTemplateButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.index = 0; + if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { + object.quickReplyButton = $root.proto.HydratedQuickReplyButton.toObject(message.quickReplyButton, options); + if (options.oneofs) + object.hydratedButton = "quickReplyButton"; + } + if (message.urlButton != null && message.hasOwnProperty("urlButton")) { + object.urlButton = $root.proto.HydratedURLButton.toObject(message.urlButton, options); + if (options.oneofs) + object.hydratedButton = "urlButton"; + } + if (message.callButton != null && message.hasOwnProperty("callButton")) { + object.callButton = $root.proto.HydratedCallButton.toObject(message.callButton, options); + if (options.oneofs) + object.hydratedButton = "callButton"; + } + if (message.index != null && message.hasOwnProperty("index")) + object.index = message.index; + return object; + }; + + /** + * Converts this HydratedTemplateButton to JSON. + * @function toJSON + * @memberof proto.HydratedTemplateButton + * @instance + * @returns {Object.} JSON object + */ + HydratedTemplateButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HydratedTemplateButton; })(); proto.QuickReplyButton = (function() { @@ -3308,7 +22635,6 @@ $root.proto = (function() { * @property {string|null} [entryPointConversionSource] ContextInfo entryPointConversionSource * @property {string|null} [entryPointConversionApp] ContextInfo entryPointConversionApp * @property {number|null} [entryPointConversionDelaySeconds] ContextInfo entryPointConversionDelaySeconds - * @property {proto.IDisappearingMode|null} [disappearingMode] ContextInfo disappearingMode */ /** @@ -3479,14 +22805,6 @@ $root.proto = (function() { */ ContextInfo.prototype.entryPointConversionDelaySeconds = 0; - /** - * ContextInfo disappearingMode. - * @member {proto.IDisappearingMode|null|undefined} disappearingMode - * @memberof proto.ContextInfo - * @instance - */ - ContextInfo.prototype.disappearingMode = null; - /** * Creates a new ContextInfo instance using the specified properties. * @function create @@ -3550,8 +22868,6 @@ $root.proto = (function() { writer.uint32(/* id 30, wireType 2 =*/242).string(message.entryPointConversionApp); if (message.entryPointConversionDelaySeconds != null && Object.hasOwnProperty.call(message, "entryPointConversionDelaySeconds")) writer.uint32(/* id 31, wireType 0 =*/248).uint32(message.entryPointConversionDelaySeconds); - if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode")) - $root.proto.DisappearingMode.encode(message.disappearingMode, writer.uint32(/* id 32, wireType 2 =*/258).fork()).ldelim(); return writer; }; @@ -3645,9 +22961,6 @@ $root.proto = (function() { case 31: message.entryPointConversionDelaySeconds = reader.uint32(); break; - case 32: - message.disappearingMode = $root.proto.DisappearingMode.decode(reader, reader.uint32()); - break; default: reader.skipType(tag & 7); break; @@ -3752,11 +23065,6 @@ $root.proto = (function() { if (message.entryPointConversionDelaySeconds != null && message.hasOwnProperty("entryPointConversionDelaySeconds")) if (!$util.isInteger(message.entryPointConversionDelaySeconds)) return "entryPointConversionDelaySeconds: integer expected"; - if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) { - var error = $root.proto.DisappearingMode.verify(message.disappearingMode); - if (error) - return "disappearingMode." + error; - } return null; }; @@ -3840,11 +23148,6 @@ $root.proto = (function() { message.entryPointConversionApp = String(object.entryPointConversionApp); if (object.entryPointConversionDelaySeconds != null) message.entryPointConversionDelaySeconds = object.entryPointConversionDelaySeconds >>> 0; - if (object.disappearingMode != null) { - if (typeof object.disappearingMode !== "object") - throw TypeError(".proto.ContextInfo.disappearingMode: object expected"); - message.disappearingMode = $root.proto.DisappearingMode.fromObject(object.disappearingMode); - } return message; }; @@ -3898,7 +23201,6 @@ $root.proto = (function() { object.entryPointConversionSource = ""; object.entryPointConversionApp = ""; object.entryPointConversionDelaySeconds = 0; - object.disappearingMode = null; } if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) object.stanzaId = message.stanzaId; @@ -3944,8 +23246,6 @@ $root.proto = (function() { object.entryPointConversionApp = message.entryPointConversionApp; if (message.entryPointConversionDelaySeconds != null && message.hasOwnProperty("entryPointConversionDelaySeconds")) object.entryPointConversionDelaySeconds = message.entryPointConversionDelaySeconds; - if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) - object.disappearingMode = $root.proto.DisappearingMode.toObject(message.disappearingMode, options); return object; }; @@ -4213,7 +23513,6 @@ $root.proto = (function() { * @property {string|null} [thumbnailDirectPath] ImageMessage thumbnailDirectPath * @property {Uint8Array|null} [thumbnailSha256] ImageMessage thumbnailSha256 * @property {Uint8Array|null} [thumbnailEncSha256] ImageMessage thumbnailEncSha256 - * @property {string|null} [staticUrl] ImageMessage staticUrl */ /** @@ -4433,14 +23732,6 @@ $root.proto = (function() { */ ImageMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]); - /** - * ImageMessage staticUrl. - * @member {string} staticUrl - * @memberof proto.ImageMessage - * @instance - */ - ImageMessage.prototype.staticUrl = ""; - /** * Creates a new ImageMessage instance using the specified properties. * @function create @@ -4517,8 +23808,6 @@ $root.proto = (function() { writer.uint32(/* id 27, wireType 2 =*/218).bytes(message.thumbnailSha256); if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256")) writer.uint32(/* id 28, wireType 2 =*/226).bytes(message.thumbnailEncSha256); - if (message.staticUrl != null && Object.hasOwnProperty.call(message, "staticUrl")) - writer.uint32(/* id 29, wireType 2 =*/234).string(message.staticUrl); return writer; }; @@ -4637,9 +23926,6 @@ $root.proto = (function() { case 28: message.thumbnailEncSha256 = reader.bytes(); break; - case 29: - message.staticUrl = reader.string(); - break; default: reader.skipType(tag & 7); break; @@ -4762,9 +24048,6 @@ $root.proto = (function() { if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256))) return "thumbnailEncSha256: buffer expected"; - if (message.staticUrl != null && message.hasOwnProperty("staticUrl")) - if (!$util.isString(message.staticUrl)) - return "staticUrl: string expected"; return null; }; @@ -4890,8 +24173,6 @@ $root.proto = (function() { $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0); else if (object.thumbnailEncSha256.length) message.thumbnailEncSha256 = object.thumbnailEncSha256; - if (object.staticUrl != null) - message.staticUrl = String(object.staticUrl); return message; }; @@ -5004,7 +24285,6 @@ $root.proto = (function() { if (options.bytes !== Array) object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256); } - object.staticUrl = ""; } if (message.url != null && message.hasOwnProperty("url")) object.url = message.url; @@ -5068,8 +24348,6 @@ $root.proto = (function() { object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256; if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256; - if (message.staticUrl != null && message.hasOwnProperty("staticUrl")) - object.staticUrl = message.staticUrl; return object; }; @@ -8150,7 +27428,6 @@ $root.proto = (function() { * @property {string|null} [thumbnailDirectPath] VideoMessage thumbnailDirectPath * @property {Uint8Array|null} [thumbnailSha256] VideoMessage thumbnailSha256 * @property {Uint8Array|null} [thumbnailEncSha256] VideoMessage thumbnailEncSha256 - * @property {string|null} [staticUrl] VideoMessage staticUrl */ /** @@ -8345,14 +27622,6 @@ $root.proto = (function() { */ VideoMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]); - /** - * VideoMessage staticUrl. - * @member {string} staticUrl - * @memberof proto.VideoMessage - * @instance - */ - VideoMessage.prototype.staticUrl = ""; - /** * Creates a new VideoMessage instance using the specified properties. * @function create @@ -8422,8 +27691,6 @@ $root.proto = (function() { writer.uint32(/* id 22, wireType 2 =*/178).bytes(message.thumbnailSha256); if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256")) writer.uint32(/* id 23, wireType 2 =*/186).bytes(message.thumbnailEncSha256); - if (message.staticUrl != null && Object.hasOwnProperty.call(message, "staticUrl")) - writer.uint32(/* id 24, wireType 2 =*/194).string(message.staticUrl); return writer; }; @@ -8526,9 +27793,6 @@ $root.proto = (function() { case 23: message.thumbnailEncSha256 = reader.bytes(); break; - case 24: - message.staticUrl = reader.string(); - break; default: reader.skipType(tag & 7); break; @@ -8644,9 +27908,6 @@ $root.proto = (function() { if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256))) return "thumbnailEncSha256: buffer expected"; - if (message.staticUrl != null && message.hasOwnProperty("staticUrl")) - if (!$util.isString(message.staticUrl)) - return "staticUrl: string expected"; return null; }; @@ -8764,8 +28025,6 @@ $root.proto = (function() { $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0); else if (object.thumbnailEncSha256.length) message.thumbnailEncSha256 = object.thumbnailEncSha256; - if (object.staticUrl != null) - message.staticUrl = String(object.staticUrl); return message; }; @@ -8856,7 +28115,6 @@ $root.proto = (function() { if (options.bytes !== Array) object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256); } - object.staticUrl = ""; } if (message.url != null && message.hasOwnProperty("url")) object.url = message.url; @@ -8911,8 +28169,6 @@ $root.proto = (function() { object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256; if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256; - if (message.staticUrl != null && message.hasOwnProperty("staticUrl")) - object.staticUrl = message.staticUrl; return object; }; @@ -9443,7 +28699,6 @@ $root.proto = (function() { * @property {proto.IAppStateSyncKeyRequest|null} [appStateSyncKeyRequest] ProtocolMessage appStateSyncKeyRequest * @property {proto.IInitialSecurityNotificationSettingSync|null} [initialSecurityNotificationSettingSync] ProtocolMessage initialSecurityNotificationSettingSync * @property {proto.IAppStateFatalExceptionNotification|null} [appStateFatalExceptionNotification] ProtocolMessage appStateFatalExceptionNotification - * @property {proto.IDisappearingMode|null} [disappearingMode] ProtocolMessage disappearingMode */ /** @@ -9533,14 +28788,6 @@ $root.proto = (function() { */ ProtocolMessage.prototype.appStateFatalExceptionNotification = null; - /** - * ProtocolMessage disappearingMode. - * @member {proto.IDisappearingMode|null|undefined} disappearingMode - * @memberof proto.ProtocolMessage - * @instance - */ - ProtocolMessage.prototype.disappearingMode = null; - /** * Creates a new ProtocolMessage instance using the specified properties. * @function create @@ -9583,8 +28830,6 @@ $root.proto = (function() { $root.proto.InitialSecurityNotificationSettingSync.encode(message.initialSecurityNotificationSettingSync, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim(); if (message.appStateFatalExceptionNotification != null && Object.hasOwnProperty.call(message, "appStateFatalExceptionNotification")) $root.proto.AppStateFatalExceptionNotification.encode(message.appStateFatalExceptionNotification, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim(); - if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode")) - $root.proto.DisappearingMode.encode(message.disappearingMode, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim(); return writer; }; @@ -9646,9 +28891,6 @@ $root.proto = (function() { case 10: message.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.decode(reader, reader.uint32()); break; - case 11: - message.disappearingMode = $root.proto.DisappearingMode.decode(reader, reader.uint32()); - break; default: reader.skipType(tag & 7); break; @@ -9735,11 +28977,6 @@ $root.proto = (function() { if (error) return "appStateFatalExceptionNotification." + error; } - if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) { - var error = $root.proto.DisappearingMode.verify(message.disappearingMode); - if (error) - return "disappearingMode." + error; - } return null; }; @@ -9834,11 +29071,6 @@ $root.proto = (function() { throw TypeError(".proto.ProtocolMessage.appStateFatalExceptionNotification: object expected"); message.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.fromObject(object.appStateFatalExceptionNotification); } - if (object.disappearingMode != null) { - if (typeof object.disappearingMode !== "object") - throw TypeError(".proto.ProtocolMessage.disappearingMode: object expected"); - message.disappearingMode = $root.proto.DisappearingMode.fromObject(object.disappearingMode); - } return message; }; @@ -9869,7 +29101,6 @@ $root.proto = (function() { object.appStateSyncKeyRequest = null; object.initialSecurityNotificationSettingSync = null; object.appStateFatalExceptionNotification = null; - object.disappearingMode = null; } if (message.key != null && message.hasOwnProperty("key")) object.key = $root.proto.MessageKey.toObject(message.key, options); @@ -9892,8 +29123,6 @@ $root.proto = (function() { object.initialSecurityNotificationSettingSync = $root.proto.InitialSecurityNotificationSettingSync.toObject(message.initialSecurityNotificationSettingSync, options); if (message.appStateFatalExceptionNotification != null && message.hasOwnProperty("appStateFatalExceptionNotification")) object.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.toObject(message.appStateFatalExceptionNotification, options); - if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) - object.disappearingMode = $root.proto.DisappearingMode.toObject(message.disappearingMode, options); return object; }; @@ -21579,1594 +40808,6 @@ $root.proto = (function() { return ListResponseMessage; })(); - proto.Header = (function() { - - /** - * Properties of a Header. - * @memberof proto - * @interface IHeader - * @property {string|null} [title] Header title - * @property {string|null} [subtitle] Header subtitle - * @property {proto.IDocumentMessage|null} [documentMessage] Header documentMessage - * @property {proto.IImageMessage|null} [imageMessage] Header imageMessage - */ - - /** - * Constructs a new Header. - * @memberof proto - * @classdesc Represents a Header. - * @implements IHeader - * @constructor - * @param {proto.IHeader=} [properties] Properties to set - */ - function Header(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * Header title. - * @member {string} title - * @memberof proto.Header - * @instance - */ - Header.prototype.title = ""; - - /** - * Header subtitle. - * @member {string} subtitle - * @memberof proto.Header - * @instance - */ - Header.prototype.subtitle = ""; - - /** - * Header documentMessage. - * @member {proto.IDocumentMessage|null|undefined} documentMessage - * @memberof proto.Header - * @instance - */ - Header.prototype.documentMessage = null; - - /** - * Header imageMessage. - * @member {proto.IImageMessage|null|undefined} imageMessage - * @memberof proto.Header - * @instance - */ - Header.prototype.imageMessage = null; - - // OneOf field names bound to virtual getters and setters - var $oneOfFields; - - /** - * Header media. - * @member {"documentMessage"|"imageMessage"|undefined} media - * @memberof proto.Header - * @instance - */ - Object.defineProperty(Header.prototype, "media", { - get: $util.oneOfGetter($oneOfFields = ["documentMessage", "imageMessage"]), - set: $util.oneOfSetter($oneOfFields) - }); - - /** - * Creates a new Header instance using the specified properties. - * @function create - * @memberof proto.Header - * @static - * @param {proto.IHeader=} [properties] Properties to set - * @returns {proto.Header} Header instance - */ - Header.create = function create(properties) { - return new Header(properties); - }; - - /** - * Encodes the specified Header message. Does not implicitly {@link proto.Header.verify|verify} messages. - * @function encode - * @memberof proto.Header - * @static - * @param {proto.IHeader} message Header message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Header.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.title != null && Object.hasOwnProperty.call(message, "title")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.title); - if (message.subtitle != null && Object.hasOwnProperty.call(message, "subtitle")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.subtitle); - if (message.documentMessage != null && Object.hasOwnProperty.call(message, "documentMessage")) - $root.proto.DocumentMessage.encode(message.documentMessage, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - if (message.imageMessage != null && Object.hasOwnProperty.call(message, "imageMessage")) - $root.proto.ImageMessage.encode(message.imageMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified Header message, length delimited. Does not implicitly {@link proto.Header.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.Header - * @static - * @param {proto.IHeader} message Header message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Header.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a Header message from the specified reader or buffer. - * @function decode - * @memberof proto.Header - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.Header} Header - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Header.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Header(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.title = reader.string(); - break; - case 2: - message.subtitle = reader.string(); - break; - case 3: - message.documentMessage = $root.proto.DocumentMessage.decode(reader, reader.uint32()); - break; - case 4: - message.imageMessage = $root.proto.ImageMessage.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a Header message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.Header - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.Header} Header - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Header.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a Header message. - * @function verify - * @memberof proto.Header - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - Header.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - var properties = {}; - if (message.title != null && message.hasOwnProperty("title")) - if (!$util.isString(message.title)) - return "title: string expected"; - if (message.subtitle != null && message.hasOwnProperty("subtitle")) - if (!$util.isString(message.subtitle)) - return "subtitle: string expected"; - if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) { - properties.media = 1; - { - var error = $root.proto.DocumentMessage.verify(message.documentMessage); - if (error) - return "documentMessage." + error; - } - } - if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) { - if (properties.media === 1) - return "media: multiple values"; - properties.media = 1; - { - var error = $root.proto.ImageMessage.verify(message.imageMessage); - if (error) - return "imageMessage." + error; - } - } - return null; - }; - - /** - * Creates a Header message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.Header - * @static - * @param {Object.} object Plain object - * @returns {proto.Header} Header - */ - Header.fromObject = function fromObject(object) { - if (object instanceof $root.proto.Header) - return object; - var message = new $root.proto.Header(); - if (object.title != null) - message.title = String(object.title); - if (object.subtitle != null) - message.subtitle = String(object.subtitle); - if (object.documentMessage != null) { - if (typeof object.documentMessage !== "object") - throw TypeError(".proto.Header.documentMessage: object expected"); - message.documentMessage = $root.proto.DocumentMessage.fromObject(object.documentMessage); - } - if (object.imageMessage != null) { - if (typeof object.imageMessage !== "object") - throw TypeError(".proto.Header.imageMessage: object expected"); - message.imageMessage = $root.proto.ImageMessage.fromObject(object.imageMessage); - } - return message; - }; - - /** - * Creates a plain object from a Header message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.Header - * @static - * @param {proto.Header} message Header - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - Header.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.title = ""; - object.subtitle = ""; - } - if (message.title != null && message.hasOwnProperty("title")) - object.title = message.title; - if (message.subtitle != null && message.hasOwnProperty("subtitle")) - object.subtitle = message.subtitle; - if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) { - object.documentMessage = $root.proto.DocumentMessage.toObject(message.documentMessage, options); - if (options.oneofs) - object.media = "documentMessage"; - } - if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) { - object.imageMessage = $root.proto.ImageMessage.toObject(message.imageMessage, options); - if (options.oneofs) - object.media = "imageMessage"; - } - return object; - }; - - /** - * Converts this Header to JSON. - * @function toJSON - * @memberof proto.Header - * @instance - * @returns {Object.} JSON object - */ - Header.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return Header; - })(); - - proto.Body = (function() { - - /** - * Properties of a Body. - * @memberof proto - * @interface IBody - * @property {string|null} [text] Body text - */ - - /** - * Constructs a new Body. - * @memberof proto - * @classdesc Represents a Body. - * @implements IBody - * @constructor - * @param {proto.IBody=} [properties] Properties to set - */ - function Body(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * Body text. - * @member {string} text - * @memberof proto.Body - * @instance - */ - Body.prototype.text = ""; - - /** - * Creates a new Body instance using the specified properties. - * @function create - * @memberof proto.Body - * @static - * @param {proto.IBody=} [properties] Properties to set - * @returns {proto.Body} Body instance - */ - Body.create = function create(properties) { - return new Body(properties); - }; - - /** - * Encodes the specified Body message. Does not implicitly {@link proto.Body.verify|verify} messages. - * @function encode - * @memberof proto.Body - * @static - * @param {proto.IBody} message Body message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Body.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.text != null && Object.hasOwnProperty.call(message, "text")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.text); - return writer; - }; - - /** - * Encodes the specified Body message, length delimited. Does not implicitly {@link proto.Body.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.Body - * @static - * @param {proto.IBody} message Body message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Body.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a Body message from the specified reader or buffer. - * @function decode - * @memberof proto.Body - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.Body} Body - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Body.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Body(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.text = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a Body message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.Body - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.Body} Body - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Body.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a Body message. - * @function verify - * @memberof proto.Body - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - Body.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.text != null && message.hasOwnProperty("text")) - if (!$util.isString(message.text)) - return "text: string expected"; - return null; - }; - - /** - * Creates a Body message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.Body - * @static - * @param {Object.} object Plain object - * @returns {proto.Body} Body - */ - Body.fromObject = function fromObject(object) { - if (object instanceof $root.proto.Body) - return object; - var message = new $root.proto.Body(); - if (object.text != null) - message.text = String(object.text); - return message; - }; - - /** - * Creates a plain object from a Body message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.Body - * @static - * @param {proto.Body} message Body - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - Body.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.text = ""; - if (message.text != null && message.hasOwnProperty("text")) - object.text = message.text; - return object; - }; - - /** - * Converts this Body to JSON. - * @function toJSON - * @memberof proto.Body - * @instance - * @returns {Object.} JSON object - */ - Body.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return Body; - })(); - - proto.Footer = (function() { - - /** - * Properties of a Footer. - * @memberof proto - * @interface IFooter - * @property {string|null} [text] Footer text - */ - - /** - * Constructs a new Footer. - * @memberof proto - * @classdesc Represents a Footer. - * @implements IFooter - * @constructor - * @param {proto.IFooter=} [properties] Properties to set - */ - function Footer(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * Footer text. - * @member {string} text - * @memberof proto.Footer - * @instance - */ - Footer.prototype.text = ""; - - /** - * Creates a new Footer instance using the specified properties. - * @function create - * @memberof proto.Footer - * @static - * @param {proto.IFooter=} [properties] Properties to set - * @returns {proto.Footer} Footer instance - */ - Footer.create = function create(properties) { - return new Footer(properties); - }; - - /** - * Encodes the specified Footer message. Does not implicitly {@link proto.Footer.verify|verify} messages. - * @function encode - * @memberof proto.Footer - * @static - * @param {proto.IFooter} message Footer message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Footer.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.text != null && Object.hasOwnProperty.call(message, "text")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.text); - return writer; - }; - - /** - * Encodes the specified Footer message, length delimited. Does not implicitly {@link proto.Footer.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.Footer - * @static - * @param {proto.IFooter} message Footer message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Footer.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a Footer message from the specified reader or buffer. - * @function decode - * @memberof proto.Footer - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.Footer} Footer - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Footer.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Footer(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.text = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a Footer message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.Footer - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.Footer} Footer - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Footer.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a Footer message. - * @function verify - * @memberof proto.Footer - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - Footer.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.text != null && message.hasOwnProperty("text")) - if (!$util.isString(message.text)) - return "text: string expected"; - return null; - }; - - /** - * Creates a Footer message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.Footer - * @static - * @param {Object.} object Plain object - * @returns {proto.Footer} Footer - */ - Footer.fromObject = function fromObject(object) { - if (object instanceof $root.proto.Footer) - return object; - var message = new $root.proto.Footer(); - if (object.text != null) - message.text = String(object.text); - return message; - }; - - /** - * Creates a plain object from a Footer message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.Footer - * @static - * @param {proto.Footer} message Footer - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - Footer.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.text = ""; - if (message.text != null && message.hasOwnProperty("text")) - object.text = message.text; - return object; - }; - - /** - * Converts this Footer to JSON. - * @function toJSON - * @memberof proto.Footer - * @instance - * @returns {Object.} JSON object - */ - Footer.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return Footer; - })(); - - proto.ShopsMessage = (function() { - - /** - * Properties of a ShopsMessage. - * @memberof proto - * @interface IShopsMessage - * @property {string|null} [id] ShopsMessage id - * @property {proto.ShopsMessage.ShopsMessageSurface|null} [surface] ShopsMessage surface - * @property {proto.ShopsMessage.ShopsMessageType|null} [type] ShopsMessage type - * @property {number|null} [messageVersion] ShopsMessage messageVersion - */ - - /** - * Constructs a new ShopsMessage. - * @memberof proto - * @classdesc Represents a ShopsMessage. - * @implements IShopsMessage - * @constructor - * @param {proto.IShopsMessage=} [properties] Properties to set - */ - function ShopsMessage(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ShopsMessage id. - * @member {string} id - * @memberof proto.ShopsMessage - * @instance - */ - ShopsMessage.prototype.id = ""; - - /** - * ShopsMessage surface. - * @member {proto.ShopsMessage.ShopsMessageSurface} surface - * @memberof proto.ShopsMessage - * @instance - */ - ShopsMessage.prototype.surface = 0; - - /** - * ShopsMessage type. - * @member {proto.ShopsMessage.ShopsMessageType} type - * @memberof proto.ShopsMessage - * @instance - */ - ShopsMessage.prototype.type = 0; - - /** - * ShopsMessage messageVersion. - * @member {number} messageVersion - * @memberof proto.ShopsMessage - * @instance - */ - ShopsMessage.prototype.messageVersion = 0; - - /** - * Creates a new ShopsMessage instance using the specified properties. - * @function create - * @memberof proto.ShopsMessage - * @static - * @param {proto.IShopsMessage=} [properties] Properties to set - * @returns {proto.ShopsMessage} ShopsMessage instance - */ - ShopsMessage.create = function create(properties) { - return new ShopsMessage(properties); - }; - - /** - * Encodes the specified ShopsMessage message. Does not implicitly {@link proto.ShopsMessage.verify|verify} messages. - * @function encode - * @memberof proto.ShopsMessage - * @static - * @param {proto.IShopsMessage} message ShopsMessage message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ShopsMessage.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); - if (message.surface != null && Object.hasOwnProperty.call(message, "surface")) - writer.uint32(/* id 2, wireType 0 =*/16).int32(message.surface); - if (message.type != null && Object.hasOwnProperty.call(message, "type")) - writer.uint32(/* id 3, wireType 0 =*/24).int32(message.type); - if (message.messageVersion != null && Object.hasOwnProperty.call(message, "messageVersion")) - writer.uint32(/* id 4, wireType 0 =*/32).int32(message.messageVersion); - return writer; - }; - - /** - * Encodes the specified ShopsMessage message, length delimited. Does not implicitly {@link proto.ShopsMessage.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.ShopsMessage - * @static - * @param {proto.IShopsMessage} message ShopsMessage message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ShopsMessage.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a ShopsMessage message from the specified reader or buffer. - * @function decode - * @memberof proto.ShopsMessage - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.ShopsMessage} ShopsMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ShopsMessage.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ShopsMessage(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.id = reader.string(); - break; - case 2: - message.surface = reader.int32(); - break; - case 3: - message.type = reader.int32(); - break; - case 4: - message.messageVersion = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a ShopsMessage message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.ShopsMessage - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.ShopsMessage} ShopsMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ShopsMessage.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a ShopsMessage message. - * @function verify - * @memberof proto.ShopsMessage - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ShopsMessage.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.id != null && message.hasOwnProperty("id")) - if (!$util.isString(message.id)) - return "id: string expected"; - if (message.surface != null && message.hasOwnProperty("surface")) - switch (message.surface) { - default: - return "surface: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.type != null && message.hasOwnProperty("type")) - switch (message.type) { - default: - return "type: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } - if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) - if (!$util.isInteger(message.messageVersion)) - return "messageVersion: integer expected"; - return null; - }; - - /** - * Creates a ShopsMessage message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.ShopsMessage - * @static - * @param {Object.} object Plain object - * @returns {proto.ShopsMessage} ShopsMessage - */ - ShopsMessage.fromObject = function fromObject(object) { - if (object instanceof $root.proto.ShopsMessage) - return object; - var message = new $root.proto.ShopsMessage(); - if (object.id != null) - message.id = String(object.id); - switch (object.surface) { - case "UNKNOWN_SURFACE": - case 0: - message.surface = 0; - break; - case "FB": - case 1: - message.surface = 1; - break; - case "IG": - case 2: - message.surface = 2; - break; - case "WA": - case 3: - message.surface = 3; - break; - } - switch (object.type) { - case "UNKNOWN_TYPE": - case 0: - message.type = 0; - break; - case "PRODUCT": - case 1: - message.type = 1; - break; - case "STOREFRONT": - case 2: - message.type = 2; - break; - case "COLLECTION": - case 3: - message.type = 3; - break; - } - if (object.messageVersion != null) - message.messageVersion = object.messageVersion | 0; - return message; - }; - - /** - * Creates a plain object from a ShopsMessage message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.ShopsMessage - * @static - * @param {proto.ShopsMessage} message ShopsMessage - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ShopsMessage.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.id = ""; - object.surface = options.enums === String ? "UNKNOWN_SURFACE" : 0; - object.type = options.enums === String ? "UNKNOWN_TYPE" : 0; - object.messageVersion = 0; - } - if (message.id != null && message.hasOwnProperty("id")) - object.id = message.id; - if (message.surface != null && message.hasOwnProperty("surface")) - object.surface = options.enums === String ? $root.proto.ShopsMessage.ShopsMessageSurface[message.surface] : message.surface; - if (message.type != null && message.hasOwnProperty("type")) - object.type = options.enums === String ? $root.proto.ShopsMessage.ShopsMessageType[message.type] : message.type; - if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) - object.messageVersion = message.messageVersion; - return object; - }; - - /** - * Converts this ShopsMessage to JSON. - * @function toJSON - * @memberof proto.ShopsMessage - * @instance - * @returns {Object.} JSON object - */ - ShopsMessage.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * ShopsMessageSurface enum. - * @name proto.ShopsMessage.ShopsMessageSurface - * @enum {number} - * @property {number} UNKNOWN_SURFACE=0 UNKNOWN_SURFACE value - * @property {number} FB=1 FB value - * @property {number} IG=2 IG value - * @property {number} WA=3 WA value - */ - ShopsMessage.ShopsMessageSurface = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "UNKNOWN_SURFACE"] = 0; - values[valuesById[1] = "FB"] = 1; - values[valuesById[2] = "IG"] = 2; - values[valuesById[3] = "WA"] = 3; - return values; - })(); - - /** - * ShopsMessageType enum. - * @name proto.ShopsMessage.ShopsMessageType - * @enum {number} - * @property {number} UNKNOWN_TYPE=0 UNKNOWN_TYPE value - * @property {number} PRODUCT=1 PRODUCT value - * @property {number} STOREFRONT=2 STOREFRONT value - * @property {number} COLLECTION=3 COLLECTION value - */ - ShopsMessage.ShopsMessageType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "UNKNOWN_TYPE"] = 0; - values[valuesById[1] = "PRODUCT"] = 1; - values[valuesById[2] = "STOREFRONT"] = 2; - values[valuesById[3] = "COLLECTION"] = 3; - return values; - })(); - - return ShopsMessage; - })(); - - proto.CollectionMessage = (function() { - - /** - * Properties of a CollectionMessage. - * @memberof proto - * @interface ICollectionMessage - * @property {string|null} [bizJid] CollectionMessage bizJid - * @property {string|null} [id] CollectionMessage id - * @property {number|null} [messageVersion] CollectionMessage messageVersion - */ - - /** - * Constructs a new CollectionMessage. - * @memberof proto - * @classdesc Represents a CollectionMessage. - * @implements ICollectionMessage - * @constructor - * @param {proto.ICollectionMessage=} [properties] Properties to set - */ - function CollectionMessage(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * CollectionMessage bizJid. - * @member {string} bizJid - * @memberof proto.CollectionMessage - * @instance - */ - CollectionMessage.prototype.bizJid = ""; - - /** - * CollectionMessage id. - * @member {string} id - * @memberof proto.CollectionMessage - * @instance - */ - CollectionMessage.prototype.id = ""; - - /** - * CollectionMessage messageVersion. - * @member {number} messageVersion - * @memberof proto.CollectionMessage - * @instance - */ - CollectionMessage.prototype.messageVersion = 0; - - /** - * Creates a new CollectionMessage instance using the specified properties. - * @function create - * @memberof proto.CollectionMessage - * @static - * @param {proto.ICollectionMessage=} [properties] Properties to set - * @returns {proto.CollectionMessage} CollectionMessage instance - */ - CollectionMessage.create = function create(properties) { - return new CollectionMessage(properties); - }; - - /** - * Encodes the specified CollectionMessage message. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages. - * @function encode - * @memberof proto.CollectionMessage - * @static - * @param {proto.ICollectionMessage} message CollectionMessage message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - CollectionMessage.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.bizJid != null && Object.hasOwnProperty.call(message, "bizJid")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.bizJid); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.id); - if (message.messageVersion != null && Object.hasOwnProperty.call(message, "messageVersion")) - writer.uint32(/* id 3, wireType 0 =*/24).int32(message.messageVersion); - return writer; - }; - - /** - * Encodes the specified CollectionMessage message, length delimited. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.CollectionMessage - * @static - * @param {proto.ICollectionMessage} message CollectionMessage message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - CollectionMessage.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a CollectionMessage message from the specified reader or buffer. - * @function decode - * @memberof proto.CollectionMessage - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.CollectionMessage} CollectionMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - CollectionMessage.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CollectionMessage(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.bizJid = reader.string(); - break; - case 2: - message.id = reader.string(); - break; - case 3: - message.messageVersion = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a CollectionMessage message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.CollectionMessage - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.CollectionMessage} CollectionMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - CollectionMessage.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a CollectionMessage message. - * @function verify - * @memberof proto.CollectionMessage - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - CollectionMessage.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.bizJid != null && message.hasOwnProperty("bizJid")) - if (!$util.isString(message.bizJid)) - return "bizJid: string expected"; - if (message.id != null && message.hasOwnProperty("id")) - if (!$util.isString(message.id)) - return "id: string expected"; - if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) - if (!$util.isInteger(message.messageVersion)) - return "messageVersion: integer expected"; - return null; - }; - - /** - * Creates a CollectionMessage message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.CollectionMessage - * @static - * @param {Object.} object Plain object - * @returns {proto.CollectionMessage} CollectionMessage - */ - CollectionMessage.fromObject = function fromObject(object) { - if (object instanceof $root.proto.CollectionMessage) - return object; - var message = new $root.proto.CollectionMessage(); - if (object.bizJid != null) - message.bizJid = String(object.bizJid); - if (object.id != null) - message.id = String(object.id); - if (object.messageVersion != null) - message.messageVersion = object.messageVersion | 0; - return message; - }; - - /** - * Creates a plain object from a CollectionMessage message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.CollectionMessage - * @static - * @param {proto.CollectionMessage} message CollectionMessage - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - CollectionMessage.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.bizJid = ""; - object.id = ""; - object.messageVersion = 0; - } - if (message.bizJid != null && message.hasOwnProperty("bizJid")) - object.bizJid = message.bizJid; - if (message.id != null && message.hasOwnProperty("id")) - object.id = message.id; - if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) - object.messageVersion = message.messageVersion; - return object; - }; - - /** - * Converts this CollectionMessage to JSON. - * @function toJSON - * @memberof proto.CollectionMessage - * @instance - * @returns {Object.} JSON object - */ - CollectionMessage.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return CollectionMessage; - })(); - - proto.InteractiveMessage = (function() { - - /** - * Properties of an InteractiveMessage. - * @memberof proto - * @interface IInteractiveMessage - * @property {proto.IHeader|null} [header] InteractiveMessage header - * @property {proto.IBody|null} [body] InteractiveMessage body - * @property {proto.IFooter|null} [footer] InteractiveMessage footer - * @property {proto.IContextInfo|null} [contextInfo] InteractiveMessage contextInfo - * @property {proto.IShopsMessage|null} [shopsMessage] InteractiveMessage shopsMessage - * @property {proto.ICollectionMessage|null} [collectionMessage] InteractiveMessage collectionMessage - */ - - /** - * Constructs a new InteractiveMessage. - * @memberof proto - * @classdesc Represents an InteractiveMessage. - * @implements IInteractiveMessage - * @constructor - * @param {proto.IInteractiveMessage=} [properties] Properties to set - */ - function InteractiveMessage(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * InteractiveMessage header. - * @member {proto.IHeader|null|undefined} header - * @memberof proto.InteractiveMessage - * @instance - */ - InteractiveMessage.prototype.header = null; - - /** - * InteractiveMessage body. - * @member {proto.IBody|null|undefined} body - * @memberof proto.InteractiveMessage - * @instance - */ - InteractiveMessage.prototype.body = null; - - /** - * InteractiveMessage footer. - * @member {proto.IFooter|null|undefined} footer - * @memberof proto.InteractiveMessage - * @instance - */ - InteractiveMessage.prototype.footer = null; - - /** - * InteractiveMessage contextInfo. - * @member {proto.IContextInfo|null|undefined} contextInfo - * @memberof proto.InteractiveMessage - * @instance - */ - InteractiveMessage.prototype.contextInfo = null; - - /** - * InteractiveMessage shopsMessage. - * @member {proto.IShopsMessage|null|undefined} shopsMessage - * @memberof proto.InteractiveMessage - * @instance - */ - InteractiveMessage.prototype.shopsMessage = null; - - /** - * InteractiveMessage collectionMessage. - * @member {proto.ICollectionMessage|null|undefined} collectionMessage - * @memberof proto.InteractiveMessage - * @instance - */ - InteractiveMessage.prototype.collectionMessage = null; - - // OneOf field names bound to virtual getters and setters - var $oneOfFields; - - /** - * InteractiveMessage interactiveMessage. - * @member {"shopsMessage"|"collectionMessage"|undefined} interactiveMessage - * @memberof proto.InteractiveMessage - * @instance - */ - Object.defineProperty(InteractiveMessage.prototype, "interactiveMessage", { - get: $util.oneOfGetter($oneOfFields = ["shopsMessage", "collectionMessage"]), - set: $util.oneOfSetter($oneOfFields) - }); - - /** - * Creates a new InteractiveMessage instance using the specified properties. - * @function create - * @memberof proto.InteractiveMessage - * @static - * @param {proto.IInteractiveMessage=} [properties] Properties to set - * @returns {proto.InteractiveMessage} InteractiveMessage instance - */ - InteractiveMessage.create = function create(properties) { - return new InteractiveMessage(properties); - }; - - /** - * Encodes the specified InteractiveMessage message. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages. - * @function encode - * @memberof proto.InteractiveMessage - * @static - * @param {proto.IInteractiveMessage} message InteractiveMessage message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - InteractiveMessage.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.header != null && Object.hasOwnProperty.call(message, "header")) - $root.proto.Header.encode(message.header, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.body != null && Object.hasOwnProperty.call(message, "body")) - $root.proto.Body.encode(message.body, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.footer != null && Object.hasOwnProperty.call(message, "footer")) - $root.proto.Footer.encode(message.footer, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - if (message.shopsMessage != null && Object.hasOwnProperty.call(message, "shopsMessage")) - $root.proto.ShopsMessage.encode(message.shopsMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); - if (message.collectionMessage != null && Object.hasOwnProperty.call(message, "collectionMessage")) - $root.proto.CollectionMessage.encode(message.collectionMessage, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); - if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo")) - $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified InteractiveMessage message, length delimited. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.InteractiveMessage - * @static - * @param {proto.IInteractiveMessage} message InteractiveMessage message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - InteractiveMessage.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes an InteractiveMessage message from the specified reader or buffer. - * @function decode - * @memberof proto.InteractiveMessage - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.InteractiveMessage} InteractiveMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - InteractiveMessage.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.InteractiveMessage(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.header = $root.proto.Header.decode(reader, reader.uint32()); - break; - case 2: - message.body = $root.proto.Body.decode(reader, reader.uint32()); - break; - case 3: - message.footer = $root.proto.Footer.decode(reader, reader.uint32()); - break; - case 15: - message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32()); - break; - case 4: - message.shopsMessage = $root.proto.ShopsMessage.decode(reader, reader.uint32()); - break; - case 5: - message.collectionMessage = $root.proto.CollectionMessage.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes an InteractiveMessage message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.InteractiveMessage - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.InteractiveMessage} InteractiveMessage - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - InteractiveMessage.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies an InteractiveMessage message. - * @function verify - * @memberof proto.InteractiveMessage - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - InteractiveMessage.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - var properties = {}; - if (message.header != null && message.hasOwnProperty("header")) { - var error = $root.proto.Header.verify(message.header); - if (error) - return "header." + error; - } - if (message.body != null && message.hasOwnProperty("body")) { - var error = $root.proto.Body.verify(message.body); - if (error) - return "body." + error; - } - if (message.footer != null && message.hasOwnProperty("footer")) { - var error = $root.proto.Footer.verify(message.footer); - if (error) - return "footer." + error; - } - if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) { - var error = $root.proto.ContextInfo.verify(message.contextInfo); - if (error) - return "contextInfo." + error; - } - if (message.shopsMessage != null && message.hasOwnProperty("shopsMessage")) { - properties.interactiveMessage = 1; - { - var error = $root.proto.ShopsMessage.verify(message.shopsMessage); - if (error) - return "shopsMessage." + error; - } - } - if (message.collectionMessage != null && message.hasOwnProperty("collectionMessage")) { - if (properties.interactiveMessage === 1) - return "interactiveMessage: multiple values"; - properties.interactiveMessage = 1; - { - var error = $root.proto.CollectionMessage.verify(message.collectionMessage); - if (error) - return "collectionMessage." + error; - } - } - return null; - }; - - /** - * Creates an InteractiveMessage message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.InteractiveMessage - * @static - * @param {Object.} object Plain object - * @returns {proto.InteractiveMessage} InteractiveMessage - */ - InteractiveMessage.fromObject = function fromObject(object) { - if (object instanceof $root.proto.InteractiveMessage) - return object; - var message = new $root.proto.InteractiveMessage(); - if (object.header != null) { - if (typeof object.header !== "object") - throw TypeError(".proto.InteractiveMessage.header: object expected"); - message.header = $root.proto.Header.fromObject(object.header); - } - if (object.body != null) { - if (typeof object.body !== "object") - throw TypeError(".proto.InteractiveMessage.body: object expected"); - message.body = $root.proto.Body.fromObject(object.body); - } - if (object.footer != null) { - if (typeof object.footer !== "object") - throw TypeError(".proto.InteractiveMessage.footer: object expected"); - message.footer = $root.proto.Footer.fromObject(object.footer); - } - if (object.contextInfo != null) { - if (typeof object.contextInfo !== "object") - throw TypeError(".proto.InteractiveMessage.contextInfo: object expected"); - message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo); - } - if (object.shopsMessage != null) { - if (typeof object.shopsMessage !== "object") - throw TypeError(".proto.InteractiveMessage.shopsMessage: object expected"); - message.shopsMessage = $root.proto.ShopsMessage.fromObject(object.shopsMessage); - } - if (object.collectionMessage != null) { - if (typeof object.collectionMessage !== "object") - throw TypeError(".proto.InteractiveMessage.collectionMessage: object expected"); - message.collectionMessage = $root.proto.CollectionMessage.fromObject(object.collectionMessage); - } - return message; - }; - - /** - * Creates a plain object from an InteractiveMessage message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.InteractiveMessage - * @static - * @param {proto.InteractiveMessage} message InteractiveMessage - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - InteractiveMessage.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.header = null; - object.body = null; - object.footer = null; - object.contextInfo = null; - } - if (message.header != null && message.hasOwnProperty("header")) - object.header = $root.proto.Header.toObject(message.header, options); - if (message.body != null && message.hasOwnProperty("body")) - object.body = $root.proto.Body.toObject(message.body, options); - if (message.footer != null && message.hasOwnProperty("footer")) - object.footer = $root.proto.Footer.toObject(message.footer, options); - if (message.shopsMessage != null && message.hasOwnProperty("shopsMessage")) { - object.shopsMessage = $root.proto.ShopsMessage.toObject(message.shopsMessage, options); - if (options.oneofs) - object.interactiveMessage = "shopsMessage"; - } - if (message.collectionMessage != null && message.hasOwnProperty("collectionMessage")) { - object.collectionMessage = $root.proto.CollectionMessage.toObject(message.collectionMessage, options); - if (options.oneofs) - object.interactiveMessage = "collectionMessage"; - } - if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) - object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options); - return object; - }; - - /** - * Converts this InteractiveMessage to JSON. - * @function toJSON - * @memberof proto.InteractiveMessage - * @instance - * @returns {Object.} JSON object - */ - InteractiveMessage.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return InteractiveMessage; - })(); - proto.GroupInviteMessage = (function() { /** @@ -25528,7 +43169,6 @@ $root.proto = (function() { * @property {proto.IButtonsMessage|null} [buttonsMessage] Message buttonsMessage * @property {proto.IButtonsResponseMessage|null} [buttonsResponseMessage] Message buttonsResponseMessage * @property {proto.IPaymentInviteMessage|null} [paymentInviteMessage] Message paymentInviteMessage - * @property {proto.IInteractiveMessage|null} [interactiveMessage] Message interactiveMessage */ /** @@ -25834,14 +43474,6 @@ $root.proto = (function() { */ Message.prototype.paymentInviteMessage = null; - /** - * Message interactiveMessage. - * @member {proto.IInteractiveMessage|null|undefined} interactiveMessage - * @memberof proto.Message - * @instance - */ - Message.prototype.interactiveMessage = null; - /** * Creates a new Message instance using the specified properties. * @function create @@ -25938,8 +43570,6 @@ $root.proto = (function() { $root.proto.ButtonsResponseMessage.encode(message.buttonsResponseMessage, writer.uint32(/* id 43, wireType 2 =*/346).fork()).ldelim(); if (message.paymentInviteMessage != null && Object.hasOwnProperty.call(message, "paymentInviteMessage")) $root.proto.PaymentInviteMessage.encode(message.paymentInviteMessage, writer.uint32(/* id 44, wireType 2 =*/354).fork()).ldelim(); - if (message.interactiveMessage != null && Object.hasOwnProperty.call(message, "interactiveMessage")) - $root.proto.InteractiveMessage.encode(message.interactiveMessage, writer.uint32(/* id 45, wireType 2 =*/362).fork()).ldelim(); return writer; }; @@ -26082,9 +43712,6 @@ $root.proto = (function() { case 44: message.paymentInviteMessage = $root.proto.PaymentInviteMessage.decode(reader, reader.uint32()); break; - case 45: - message.interactiveMessage = $root.proto.InteractiveMessage.decode(reader, reader.uint32()); - break; default: reader.skipType(tag & 7); break; @@ -26298,11 +43925,6 @@ $root.proto = (function() { if (error) return "paymentInviteMessage." + error; } - if (message.interactiveMessage != null && message.hasOwnProperty("interactiveMessage")) { - var error = $root.proto.InteractiveMessage.verify(message.interactiveMessage); - if (error) - return "interactiveMessage." + error; - } return null; }; @@ -26495,11 +44117,6 @@ $root.proto = (function() { throw TypeError(".proto.Message.paymentInviteMessage: object expected"); message.paymentInviteMessage = $root.proto.PaymentInviteMessage.fromObject(object.paymentInviteMessage); } - if (object.interactiveMessage != null) { - if (typeof object.interactiveMessage !== "object") - throw TypeError(".proto.Message.interactiveMessage: object expected"); - message.interactiveMessage = $root.proto.InteractiveMessage.fromObject(object.interactiveMessage); - } return message; }; @@ -26553,7 +44170,6 @@ $root.proto = (function() { object.buttonsMessage = null; object.buttonsResponseMessage = null; object.paymentInviteMessage = null; - object.interactiveMessage = null; } if (message.conversation != null && message.hasOwnProperty("conversation")) object.conversation = message.conversation; @@ -26627,8 +44243,6 @@ $root.proto = (function() { object.buttonsResponseMessage = $root.proto.ButtonsResponseMessage.toObject(message.buttonsResponseMessage, options); if (message.paymentInviteMessage != null && message.hasOwnProperty("paymentInviteMessage")) object.paymentInviteMessage = $root.proto.PaymentInviteMessage.toObject(message.paymentInviteMessage, options); - if (message.interactiveMessage != null && message.hasOwnProperty("interactiveMessage")) - object.interactiveMessage = $root.proto.InteractiveMessage.toObject(message.interactiveMessage, options); return object; }; @@ -26646,24 +44260,27 @@ $root.proto = (function() { return Message; })(); - proto.DisappearingMode = (function() { + proto.CompanionProps = (function() { /** - * Properties of a DisappearingMode. + * Properties of a CompanionProps. * @memberof proto - * @interface IDisappearingMode - * @property {proto.DisappearingMode.DisappearingModeInitiator|null} [initiator] DisappearingMode initiator + * @interface ICompanionProps + * @property {string|null} [os] CompanionProps os + * @property {proto.IAppVersion|null} [version] CompanionProps version + * @property {proto.CompanionProps.CompanionPropsPlatformType|null} [platformType] CompanionProps platformType + * @property {boolean|null} [requireFullSync] CompanionProps requireFullSync */ /** - * Constructs a new DisappearingMode. + * Constructs a new CompanionProps. * @memberof proto - * @classdesc Represents a DisappearingMode. - * @implements IDisappearingMode + * @classdesc Represents a CompanionProps. + * @implements ICompanionProps * @constructor - * @param {proto.IDisappearingMode=} [properties] Properties to set + * @param {proto.ICompanionProps=} [properties] Properties to set */ - function DisappearingMode(properties) { + function CompanionProps(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -26671,75 +44288,114 @@ $root.proto = (function() { } /** - * DisappearingMode initiator. - * @member {proto.DisappearingMode.DisappearingModeInitiator} initiator - * @memberof proto.DisappearingMode + * CompanionProps os. + * @member {string} os + * @memberof proto.CompanionProps * @instance */ - DisappearingMode.prototype.initiator = 0; + CompanionProps.prototype.os = ""; /** - * Creates a new DisappearingMode instance using the specified properties. - * @function create - * @memberof proto.DisappearingMode - * @static - * @param {proto.IDisappearingMode=} [properties] Properties to set - * @returns {proto.DisappearingMode} DisappearingMode instance + * CompanionProps version. + * @member {proto.IAppVersion|null|undefined} version + * @memberof proto.CompanionProps + * @instance */ - DisappearingMode.create = function create(properties) { - return new DisappearingMode(properties); + CompanionProps.prototype.version = null; + + /** + * CompanionProps platformType. + * @member {proto.CompanionProps.CompanionPropsPlatformType} platformType + * @memberof proto.CompanionProps + * @instance + */ + CompanionProps.prototype.platformType = 0; + + /** + * CompanionProps requireFullSync. + * @member {boolean} requireFullSync + * @memberof proto.CompanionProps + * @instance + */ + CompanionProps.prototype.requireFullSync = false; + + /** + * Creates a new CompanionProps instance using the specified properties. + * @function create + * @memberof proto.CompanionProps + * @static + * @param {proto.ICompanionProps=} [properties] Properties to set + * @returns {proto.CompanionProps} CompanionProps instance + */ + CompanionProps.create = function create(properties) { + return new CompanionProps(properties); }; /** - * Encodes the specified DisappearingMode message. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages. + * Encodes the specified CompanionProps message. Does not implicitly {@link proto.CompanionProps.verify|verify} messages. * @function encode - * @memberof proto.DisappearingMode + * @memberof proto.CompanionProps * @static - * @param {proto.IDisappearingMode} message DisappearingMode message or plain object to encode + * @param {proto.ICompanionProps} message CompanionProps message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - DisappearingMode.encode = function encode(message, writer) { + CompanionProps.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.initiator != null && Object.hasOwnProperty.call(message, "initiator")) - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.initiator); + if (message.os != null && Object.hasOwnProperty.call(message, "os")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.os); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + $root.proto.AppVersion.encode(message.version, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.platformType != null && Object.hasOwnProperty.call(message, "platformType")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.platformType); + if (message.requireFullSync != null && Object.hasOwnProperty.call(message, "requireFullSync")) + writer.uint32(/* id 4, wireType 0 =*/32).bool(message.requireFullSync); return writer; }; /** - * Encodes the specified DisappearingMode message, length delimited. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages. + * Encodes the specified CompanionProps message, length delimited. Does not implicitly {@link proto.CompanionProps.verify|verify} messages. * @function encodeDelimited - * @memberof proto.DisappearingMode + * @memberof proto.CompanionProps * @static - * @param {proto.IDisappearingMode} message DisappearingMode message or plain object to encode + * @param {proto.ICompanionProps} message CompanionProps message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - DisappearingMode.encodeDelimited = function encodeDelimited(message, writer) { + CompanionProps.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; /** - * Decodes a DisappearingMode message from the specified reader or buffer. + * Decodes a CompanionProps message from the specified reader or buffer. * @function decode - * @memberof proto.DisappearingMode + * @memberof proto.CompanionProps * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from * @param {number} [length] Message length if known beforehand - * @returns {proto.DisappearingMode} DisappearingMode + * @returns {proto.CompanionProps} CompanionProps * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - DisappearingMode.decode = function decode(reader, length) { + CompanionProps.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DisappearingMode(); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CompanionProps(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.initiator = reader.int32(); + message.os = reader.string(); + break; + case 2: + message.version = $root.proto.AppVersion.decode(reader, reader.uint32()); + break; + case 3: + message.platformType = reader.int32(); + break; + case 4: + message.requireFullSync = reader.bool(); break; default: reader.skipType(tag & 7); @@ -26750,148 +44406,242 @@ $root.proto = (function() { }; /** - * Decodes a DisappearingMode message from the specified reader or buffer, length delimited. + * Decodes a CompanionProps message from the specified reader or buffer, length delimited. * @function decodeDelimited - * @memberof proto.DisappearingMode + * @memberof proto.CompanionProps * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.DisappearingMode} DisappearingMode + * @returns {proto.CompanionProps} CompanionProps * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - DisappearingMode.decodeDelimited = function decodeDelimited(reader) { + CompanionProps.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; /** - * Verifies a DisappearingMode message. + * Verifies a CompanionProps message. * @function verify - * @memberof proto.DisappearingMode + * @memberof proto.CompanionProps * @static * @param {Object.} message Plain object to verify * @returns {string|null} `null` if valid, otherwise the reason why it is not */ - DisappearingMode.verify = function verify(message) { + CompanionProps.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.initiator != null && message.hasOwnProperty("initiator")) - switch (message.initiator) { + if (message.os != null && message.hasOwnProperty("os")) + if (!$util.isString(message.os)) + return "os: string expected"; + if (message.version != null && message.hasOwnProperty("version")) { + var error = $root.proto.AppVersion.verify(message.version); + if (error) + return "version." + error; + } + if (message.platformType != null && message.hasOwnProperty("platformType")) + switch (message.platformType) { default: - return "initiator: enum value expected"; + return "platformType: enum value expected"; case 0: case 1: case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: break; } + if (message.requireFullSync != null && message.hasOwnProperty("requireFullSync")) + if (typeof message.requireFullSync !== "boolean") + return "requireFullSync: boolean expected"; return null; }; /** - * Creates a DisappearingMode message from a plain object. Also converts values to their respective internal types. + * Creates a CompanionProps message from a plain object. Also converts values to their respective internal types. * @function fromObject - * @memberof proto.DisappearingMode + * @memberof proto.CompanionProps * @static * @param {Object.} object Plain object - * @returns {proto.DisappearingMode} DisappearingMode + * @returns {proto.CompanionProps} CompanionProps */ - DisappearingMode.fromObject = function fromObject(object) { - if (object instanceof $root.proto.DisappearingMode) + CompanionProps.fromObject = function fromObject(object) { + if (object instanceof $root.proto.CompanionProps) return object; - var message = new $root.proto.DisappearingMode(); - switch (object.initiator) { - case "CHANGED_IN_CHAT": + var message = new $root.proto.CompanionProps(); + if (object.os != null) + message.os = String(object.os); + if (object.version != null) { + if (typeof object.version !== "object") + throw TypeError(".proto.CompanionProps.version: object expected"); + message.version = $root.proto.AppVersion.fromObject(object.version); + } + switch (object.platformType) { + case "UNKNOWN": case 0: - message.initiator = 0; + message.platformType = 0; break; - case "INITIATED_BY_ME": + case "CHROME": case 1: - message.initiator = 1; + message.platformType = 1; break; - case "INITIATED_BY_OTHER": + case "FIREFOX": case 2: - message.initiator = 2; + message.platformType = 2; + break; + case "IE": + case 3: + message.platformType = 3; + break; + case "OPERA": + case 4: + message.platformType = 4; + break; + case "SAFARI": + case 5: + message.platformType = 5; + break; + case "EDGE": + case 6: + message.platformType = 6; + break; + case "DESKTOP": + case 7: + message.platformType = 7; + break; + case "IPAD": + case 8: + message.platformType = 8; + break; + case "ANDROID_TABLET": + case 9: + message.platformType = 9; + break; + case "OHANA": + case 10: + message.platformType = 10; + break; + case "ALOHA": + case 11: + message.platformType = 11; + break; + case "CATALINA": + case 12: + message.platformType = 12; break; } + if (object.requireFullSync != null) + message.requireFullSync = Boolean(object.requireFullSync); return message; }; /** - * Creates a plain object from a DisappearingMode message. Also converts values to other types if specified. + * Creates a plain object from a CompanionProps message. Also converts values to other types if specified. * @function toObject - * @memberof proto.DisappearingMode + * @memberof proto.CompanionProps * @static - * @param {proto.DisappearingMode} message DisappearingMode + * @param {proto.CompanionProps} message CompanionProps * @param {$protobuf.IConversionOptions} [options] Conversion options * @returns {Object.} Plain object */ - DisappearingMode.toObject = function toObject(message, options) { + CompanionProps.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; - if (options.defaults) - object.initiator = options.enums === String ? "CHANGED_IN_CHAT" : 0; - if (message.initiator != null && message.hasOwnProperty("initiator")) - object.initiator = options.enums === String ? $root.proto.DisappearingMode.DisappearingModeInitiator[message.initiator] : message.initiator; + if (options.defaults) { + object.os = ""; + object.version = null; + object.platformType = options.enums === String ? "UNKNOWN" : 0; + object.requireFullSync = false; + } + if (message.os != null && message.hasOwnProperty("os")) + object.os = message.os; + if (message.version != null && message.hasOwnProperty("version")) + object.version = $root.proto.AppVersion.toObject(message.version, options); + if (message.platformType != null && message.hasOwnProperty("platformType")) + object.platformType = options.enums === String ? $root.proto.CompanionProps.CompanionPropsPlatformType[message.platformType] : message.platformType; + if (message.requireFullSync != null && message.hasOwnProperty("requireFullSync")) + object.requireFullSync = message.requireFullSync; return object; }; /** - * Converts this DisappearingMode to JSON. + * Converts this CompanionProps to JSON. * @function toJSON - * @memberof proto.DisappearingMode + * @memberof proto.CompanionProps * @instance * @returns {Object.} JSON object */ - DisappearingMode.prototype.toJSON = function toJSON() { + CompanionProps.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; /** - * DisappearingModeInitiator enum. - * @name proto.DisappearingMode.DisappearingModeInitiator + * CompanionPropsPlatformType enum. + * @name proto.CompanionProps.CompanionPropsPlatformType * @enum {number} - * @property {number} CHANGED_IN_CHAT=0 CHANGED_IN_CHAT value - * @property {number} INITIATED_BY_ME=1 INITIATED_BY_ME value - * @property {number} INITIATED_BY_OTHER=2 INITIATED_BY_OTHER value + * @property {number} UNKNOWN=0 UNKNOWN value + * @property {number} CHROME=1 CHROME value + * @property {number} FIREFOX=2 FIREFOX value + * @property {number} IE=3 IE value + * @property {number} OPERA=4 OPERA value + * @property {number} SAFARI=5 SAFARI value + * @property {number} EDGE=6 EDGE value + * @property {number} DESKTOP=7 DESKTOP value + * @property {number} IPAD=8 IPAD value + * @property {number} ANDROID_TABLET=9 ANDROID_TABLET value + * @property {number} OHANA=10 OHANA value + * @property {number} ALOHA=11 ALOHA value + * @property {number} CATALINA=12 CATALINA value */ - DisappearingMode.DisappearingModeInitiator = (function() { + CompanionProps.CompanionPropsPlatformType = (function() { var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "CHANGED_IN_CHAT"] = 0; - values[valuesById[1] = "INITIATED_BY_ME"] = 1; - values[valuesById[2] = "INITIATED_BY_OTHER"] = 2; + values[valuesById[0] = "UNKNOWN"] = 0; + values[valuesById[1] = "CHROME"] = 1; + values[valuesById[2] = "FIREFOX"] = 2; + values[valuesById[3] = "IE"] = 3; + values[valuesById[4] = "OPERA"] = 4; + values[valuesById[5] = "SAFARI"] = 5; + values[valuesById[6] = "EDGE"] = 6; + values[valuesById[7] = "DESKTOP"] = 7; + values[valuesById[8] = "IPAD"] = 8; + values[valuesById[9] = "ANDROID_TABLET"] = 9; + values[valuesById[10] = "OHANA"] = 10; + values[valuesById[11] = "ALOHA"] = 11; + values[valuesById[12] = "CATALINA"] = 12; return values; })(); - return DisappearingMode; + return CompanionProps; })(); - proto.PaymentBackground = (function() { + proto.ADVSignedDeviceIdentityHMAC = (function() { /** - * Properties of a PaymentBackground. + * Properties of a ADVSignedDeviceIdentityHMAC. * @memberof proto - * @interface IPaymentBackground - * @property {string|null} [id] PaymentBackground id - * @property {number|Long|null} [fileLength] PaymentBackground fileLength - * @property {number|null} [width] PaymentBackground width - * @property {number|null} [height] PaymentBackground height - * @property {string|null} [mimetype] PaymentBackground mimetype - * @property {number|null} [placeholderArgb] PaymentBackground placeholderArgb - * @property {number|null} [textArgb] PaymentBackground textArgb - * @property {number|null} [subtextArgb] PaymentBackground subtextArgb + * @interface IADVSignedDeviceIdentityHMAC + * @property {Uint8Array|null} [details] ADVSignedDeviceIdentityHMAC details + * @property {Uint8Array|null} [hmac] ADVSignedDeviceIdentityHMAC hmac */ /** - * Constructs a new PaymentBackground. + * Constructs a new ADVSignedDeviceIdentityHMAC. * @memberof proto - * @classdesc Represents a PaymentBackground. - * @implements IPaymentBackground + * @classdesc Represents a ADVSignedDeviceIdentityHMAC. + * @implements IADVSignedDeviceIdentityHMAC * @constructor - * @param {proto.IPaymentBackground=} [properties] Properties to set + * @param {proto.IADVSignedDeviceIdentityHMAC=} [properties] Properties to set */ - function PaymentBackground(properties) { + function ADVSignedDeviceIdentityHMAC(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -26899,166 +44649,88 @@ $root.proto = (function() { } /** - * PaymentBackground id. - * @member {string} id - * @memberof proto.PaymentBackground + * ADVSignedDeviceIdentityHMAC details. + * @member {Uint8Array} details + * @memberof proto.ADVSignedDeviceIdentityHMAC * @instance */ - PaymentBackground.prototype.id = ""; + ADVSignedDeviceIdentityHMAC.prototype.details = $util.newBuffer([]); /** - * PaymentBackground fileLength. - * @member {number|Long} fileLength - * @memberof proto.PaymentBackground + * ADVSignedDeviceIdentityHMAC hmac. + * @member {Uint8Array} hmac + * @memberof proto.ADVSignedDeviceIdentityHMAC * @instance */ - PaymentBackground.prototype.fileLength = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + ADVSignedDeviceIdentityHMAC.prototype.hmac = $util.newBuffer([]); /** - * PaymentBackground width. - * @member {number} width - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.width = 0; - - /** - * PaymentBackground height. - * @member {number} height - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.height = 0; - - /** - * PaymentBackground mimetype. - * @member {string} mimetype - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.mimetype = ""; - - /** - * PaymentBackground placeholderArgb. - * @member {number} placeholderArgb - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.placeholderArgb = 0; - - /** - * PaymentBackground textArgb. - * @member {number} textArgb - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.textArgb = 0; - - /** - * PaymentBackground subtextArgb. - * @member {number} subtextArgb - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.subtextArgb = 0; - - /** - * Creates a new PaymentBackground instance using the specified properties. + * Creates a new ADVSignedDeviceIdentityHMAC instance using the specified properties. * @function create - * @memberof proto.PaymentBackground + * @memberof proto.ADVSignedDeviceIdentityHMAC * @static - * @param {proto.IPaymentBackground=} [properties] Properties to set - * @returns {proto.PaymentBackground} PaymentBackground instance + * @param {proto.IADVSignedDeviceIdentityHMAC=} [properties] Properties to set + * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC instance */ - PaymentBackground.create = function create(properties) { - return new PaymentBackground(properties); + ADVSignedDeviceIdentityHMAC.create = function create(properties) { + return new ADVSignedDeviceIdentityHMAC(properties); }; /** - * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * Encodes the specified ADVSignedDeviceIdentityHMAC message. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages. * @function encode - * @memberof proto.PaymentBackground + * @memberof proto.ADVSignedDeviceIdentityHMAC * @static - * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode + * @param {proto.IADVSignedDeviceIdentityHMAC} message ADVSignedDeviceIdentityHMAC message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - PaymentBackground.encode = function encode(message, writer) { + ADVSignedDeviceIdentityHMAC.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); - if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength")) - writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.fileLength); - if (message.width != null && Object.hasOwnProperty.call(message, "width")) - writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.width); - if (message.height != null && Object.hasOwnProperty.call(message, "height")) - writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.height); - if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype")) - writer.uint32(/* id 5, wireType 2 =*/42).string(message.mimetype); - if (message.placeholderArgb != null && Object.hasOwnProperty.call(message, "placeholderArgb")) - writer.uint32(/* id 6, wireType 5 =*/53).fixed32(message.placeholderArgb); - if (message.textArgb != null && Object.hasOwnProperty.call(message, "textArgb")) - writer.uint32(/* id 7, wireType 5 =*/61).fixed32(message.textArgb); - if (message.subtextArgb != null && Object.hasOwnProperty.call(message, "subtextArgb")) - writer.uint32(/* id 8, wireType 5 =*/69).fixed32(message.subtextArgb); + if (message.details != null && Object.hasOwnProperty.call(message, "details")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); + if (message.hmac != null && Object.hasOwnProperty.call(message, "hmac")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.hmac); return writer; }; /** - * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * Encodes the specified ADVSignedDeviceIdentityHMAC message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages. * @function encodeDelimited - * @memberof proto.PaymentBackground + * @memberof proto.ADVSignedDeviceIdentityHMAC * @static - * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode + * @param {proto.IADVSignedDeviceIdentityHMAC} message ADVSignedDeviceIdentityHMAC message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - PaymentBackground.encodeDelimited = function encodeDelimited(message, writer) { + ADVSignedDeviceIdentityHMAC.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; /** - * Decodes a PaymentBackground message from the specified reader or buffer. + * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer. * @function decode - * @memberof proto.PaymentBackground + * @memberof proto.ADVSignedDeviceIdentityHMAC * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from * @param {number} [length] Message length if known beforehand - * @returns {proto.PaymentBackground} PaymentBackground + * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - PaymentBackground.decode = function decode(reader, length) { + ADVSignedDeviceIdentityHMAC.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentBackground(); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVSignedDeviceIdentityHMAC(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.id = reader.string(); + message.details = reader.bytes(); break; case 2: - message.fileLength = reader.uint64(); - break; - case 3: - message.width = reader.uint32(); - break; - case 4: - message.height = reader.uint32(); - break; - case 5: - message.mimetype = reader.string(); - break; - case 6: - message.placeholderArgb = reader.fixed32(); - break; - case 7: - message.textArgb = reader.fixed32(); - break; - case 8: - message.subtextArgb = reader.fixed32(); + message.hmac = reader.bytes(); break; default: reader.skipType(tag & 7); @@ -27069,180 +44741,671 @@ $root.proto = (function() { }; /** - * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. + * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer, length delimited. * @function decodeDelimited - * @memberof proto.PaymentBackground + * @memberof proto.ADVSignedDeviceIdentityHMAC * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.PaymentBackground} PaymentBackground + * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - PaymentBackground.decodeDelimited = function decodeDelimited(reader) { + ADVSignedDeviceIdentityHMAC.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; /** - * Verifies a PaymentBackground message. + * Verifies a ADVSignedDeviceIdentityHMAC message. * @function verify - * @memberof proto.PaymentBackground + * @memberof proto.ADVSignedDeviceIdentityHMAC * @static * @param {Object.} message Plain object to verify * @returns {string|null} `null` if valid, otherwise the reason why it is not */ - PaymentBackground.verify = function verify(message) { + ADVSignedDeviceIdentityHMAC.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.id != null && message.hasOwnProperty("id")) - if (!$util.isString(message.id)) - return "id: string expected"; - if (message.fileLength != null && message.hasOwnProperty("fileLength")) - if (!$util.isInteger(message.fileLength) && !(message.fileLength && $util.isInteger(message.fileLength.low) && $util.isInteger(message.fileLength.high))) - return "fileLength: integer|Long expected"; - if (message.width != null && message.hasOwnProperty("width")) - if (!$util.isInteger(message.width)) - return "width: integer expected"; - if (message.height != null && message.hasOwnProperty("height")) - if (!$util.isInteger(message.height)) - return "height: integer expected"; - if (message.mimetype != null && message.hasOwnProperty("mimetype")) - if (!$util.isString(message.mimetype)) - return "mimetype: string expected"; - if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) - if (!$util.isInteger(message.placeholderArgb)) - return "placeholderArgb: integer expected"; - if (message.textArgb != null && message.hasOwnProperty("textArgb")) - if (!$util.isInteger(message.textArgb)) - return "textArgb: integer expected"; - if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) - if (!$util.isInteger(message.subtextArgb)) - return "subtextArgb: integer expected"; + if (message.details != null && message.hasOwnProperty("details")) + if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) + return "details: buffer expected"; + if (message.hmac != null && message.hasOwnProperty("hmac")) + if (!(message.hmac && typeof message.hmac.length === "number" || $util.isString(message.hmac))) + return "hmac: buffer expected"; return null; }; /** - * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. + * Creates a ADVSignedDeviceIdentityHMAC message from a plain object. Also converts values to their respective internal types. * @function fromObject - * @memberof proto.PaymentBackground + * @memberof proto.ADVSignedDeviceIdentityHMAC * @static * @param {Object.} object Plain object - * @returns {proto.PaymentBackground} PaymentBackground + * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC */ - PaymentBackground.fromObject = function fromObject(object) { - if (object instanceof $root.proto.PaymentBackground) + ADVSignedDeviceIdentityHMAC.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ADVSignedDeviceIdentityHMAC) return object; - var message = new $root.proto.PaymentBackground(); - if (object.id != null) - message.id = String(object.id); - if (object.fileLength != null) - if ($util.Long) - (message.fileLength = $util.Long.fromValue(object.fileLength)).unsigned = true; - else if (typeof object.fileLength === "string") - message.fileLength = parseInt(object.fileLength, 10); - else if (typeof object.fileLength === "number") - message.fileLength = object.fileLength; - else if (typeof object.fileLength === "object") - message.fileLength = new $util.LongBits(object.fileLength.low >>> 0, object.fileLength.high >>> 0).toNumber(true); - if (object.width != null) - message.width = object.width >>> 0; - if (object.height != null) - message.height = object.height >>> 0; - if (object.mimetype != null) - message.mimetype = String(object.mimetype); - if (object.placeholderArgb != null) - message.placeholderArgb = object.placeholderArgb >>> 0; - if (object.textArgb != null) - message.textArgb = object.textArgb >>> 0; - if (object.subtextArgb != null) - message.subtextArgb = object.subtextArgb >>> 0; + var message = new $root.proto.ADVSignedDeviceIdentityHMAC(); + if (object.details != null) + if (typeof object.details === "string") + $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); + else if (object.details.length) + message.details = object.details; + if (object.hmac != null) + if (typeof object.hmac === "string") + $util.base64.decode(object.hmac, message.hmac = $util.newBuffer($util.base64.length(object.hmac)), 0); + else if (object.hmac.length) + message.hmac = object.hmac; return message; }; /** - * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. + * Creates a plain object from a ADVSignedDeviceIdentityHMAC message. Also converts values to other types if specified. * @function toObject - * @memberof proto.PaymentBackground + * @memberof proto.ADVSignedDeviceIdentityHMAC * @static - * @param {proto.PaymentBackground} message PaymentBackground + * @param {proto.ADVSignedDeviceIdentityHMAC} message ADVSignedDeviceIdentityHMAC * @param {$protobuf.IConversionOptions} [options] Conversion options * @returns {Object.} Plain object */ - PaymentBackground.toObject = function toObject(message, options) { + ADVSignedDeviceIdentityHMAC.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { - object.id = ""; + if (options.bytes === String) + object.details = ""; + else { + object.details = []; + if (options.bytes !== Array) + object.details = $util.newBuffer(object.details); + } + if (options.bytes === String) + object.hmac = ""; + else { + object.hmac = []; + if (options.bytes !== Array) + object.hmac = $util.newBuffer(object.hmac); + } + } + if (message.details != null && message.hasOwnProperty("details")) + object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; + if (message.hmac != null && message.hasOwnProperty("hmac")) + object.hmac = options.bytes === String ? $util.base64.encode(message.hmac, 0, message.hmac.length) : options.bytes === Array ? Array.prototype.slice.call(message.hmac) : message.hmac; + return object; + }; + + /** + * Converts this ADVSignedDeviceIdentityHMAC to JSON. + * @function toJSON + * @memberof proto.ADVSignedDeviceIdentityHMAC + * @instance + * @returns {Object.} JSON object + */ + ADVSignedDeviceIdentityHMAC.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ADVSignedDeviceIdentityHMAC; + })(); + + proto.ADVSignedDeviceIdentity = (function() { + + /** + * Properties of a ADVSignedDeviceIdentity. + * @memberof proto + * @interface IADVSignedDeviceIdentity + * @property {Uint8Array|null} [details] ADVSignedDeviceIdentity details + * @property {Uint8Array|null} [accountSignatureKey] ADVSignedDeviceIdentity accountSignatureKey + * @property {Uint8Array|null} [accountSignature] ADVSignedDeviceIdentity accountSignature + * @property {Uint8Array|null} [deviceSignature] ADVSignedDeviceIdentity deviceSignature + */ + + /** + * Constructs a new ADVSignedDeviceIdentity. + * @memberof proto + * @classdesc Represents a ADVSignedDeviceIdentity. + * @implements IADVSignedDeviceIdentity + * @constructor + * @param {proto.IADVSignedDeviceIdentity=} [properties] Properties to set + */ + function ADVSignedDeviceIdentity(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ADVSignedDeviceIdentity details. + * @member {Uint8Array} details + * @memberof proto.ADVSignedDeviceIdentity + * @instance + */ + ADVSignedDeviceIdentity.prototype.details = $util.newBuffer([]); + + /** + * ADVSignedDeviceIdentity accountSignatureKey. + * @member {Uint8Array} accountSignatureKey + * @memberof proto.ADVSignedDeviceIdentity + * @instance + */ + ADVSignedDeviceIdentity.prototype.accountSignatureKey = $util.newBuffer([]); + + /** + * ADVSignedDeviceIdentity accountSignature. + * @member {Uint8Array} accountSignature + * @memberof proto.ADVSignedDeviceIdentity + * @instance + */ + ADVSignedDeviceIdentity.prototype.accountSignature = $util.newBuffer([]); + + /** + * ADVSignedDeviceIdentity deviceSignature. + * @member {Uint8Array} deviceSignature + * @memberof proto.ADVSignedDeviceIdentity + * @instance + */ + ADVSignedDeviceIdentity.prototype.deviceSignature = $util.newBuffer([]); + + /** + * Creates a new ADVSignedDeviceIdentity instance using the specified properties. + * @function create + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {proto.IADVSignedDeviceIdentity=} [properties] Properties to set + * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity instance + */ + ADVSignedDeviceIdentity.create = function create(properties) { + return new ADVSignedDeviceIdentity(properties); + }; + + /** + * Encodes the specified ADVSignedDeviceIdentity message. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages. + * @function encode + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {proto.IADVSignedDeviceIdentity} message ADVSignedDeviceIdentity message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVSignedDeviceIdentity.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.details != null && Object.hasOwnProperty.call(message, "details")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); + if (message.accountSignatureKey != null && Object.hasOwnProperty.call(message, "accountSignatureKey")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.accountSignatureKey); + if (message.accountSignature != null && Object.hasOwnProperty.call(message, "accountSignature")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.accountSignature); + if (message.deviceSignature != null && Object.hasOwnProperty.call(message, "deviceSignature")) + writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.deviceSignature); + return writer; + }; + + /** + * Encodes the specified ADVSignedDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {proto.IADVSignedDeviceIdentity} message ADVSignedDeviceIdentity message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVSignedDeviceIdentity.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer. + * @function decode + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVSignedDeviceIdentity.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVSignedDeviceIdentity(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.details = reader.bytes(); + break; + case 2: + message.accountSignatureKey = reader.bytes(); + break; + case 3: + message.accountSignature = reader.bytes(); + break; + case 4: + message.deviceSignature = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVSignedDeviceIdentity.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ADVSignedDeviceIdentity message. + * @function verify + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ADVSignedDeviceIdentity.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.details != null && message.hasOwnProperty("details")) + if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) + return "details: buffer expected"; + if (message.accountSignatureKey != null && message.hasOwnProperty("accountSignatureKey")) + if (!(message.accountSignatureKey && typeof message.accountSignatureKey.length === "number" || $util.isString(message.accountSignatureKey))) + return "accountSignatureKey: buffer expected"; + if (message.accountSignature != null && message.hasOwnProperty("accountSignature")) + if (!(message.accountSignature && typeof message.accountSignature.length === "number" || $util.isString(message.accountSignature))) + return "accountSignature: buffer expected"; + if (message.deviceSignature != null && message.hasOwnProperty("deviceSignature")) + if (!(message.deviceSignature && typeof message.deviceSignature.length === "number" || $util.isString(message.deviceSignature))) + return "deviceSignature: buffer expected"; + return null; + }; + + /** + * Creates a ADVSignedDeviceIdentity message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {Object.} object Plain object + * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity + */ + ADVSignedDeviceIdentity.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ADVSignedDeviceIdentity) + return object; + var message = new $root.proto.ADVSignedDeviceIdentity(); + if (object.details != null) + if (typeof object.details === "string") + $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); + else if (object.details.length) + message.details = object.details; + if (object.accountSignatureKey != null) + if (typeof object.accountSignatureKey === "string") + $util.base64.decode(object.accountSignatureKey, message.accountSignatureKey = $util.newBuffer($util.base64.length(object.accountSignatureKey)), 0); + else if (object.accountSignatureKey.length) + message.accountSignatureKey = object.accountSignatureKey; + if (object.accountSignature != null) + if (typeof object.accountSignature === "string") + $util.base64.decode(object.accountSignature, message.accountSignature = $util.newBuffer($util.base64.length(object.accountSignature)), 0); + else if (object.accountSignature.length) + message.accountSignature = object.accountSignature; + if (object.deviceSignature != null) + if (typeof object.deviceSignature === "string") + $util.base64.decode(object.deviceSignature, message.deviceSignature = $util.newBuffer($util.base64.length(object.deviceSignature)), 0); + else if (object.deviceSignature.length) + message.deviceSignature = object.deviceSignature; + return message; + }; + + /** + * Creates a plain object from a ADVSignedDeviceIdentity message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ADVSignedDeviceIdentity + * @static + * @param {proto.ADVSignedDeviceIdentity} message ADVSignedDeviceIdentity + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ADVSignedDeviceIdentity.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.details = ""; + else { + object.details = []; + if (options.bytes !== Array) + object.details = $util.newBuffer(object.details); + } + if (options.bytes === String) + object.accountSignatureKey = ""; + else { + object.accountSignatureKey = []; + if (options.bytes !== Array) + object.accountSignatureKey = $util.newBuffer(object.accountSignatureKey); + } + if (options.bytes === String) + object.accountSignature = ""; + else { + object.accountSignature = []; + if (options.bytes !== Array) + object.accountSignature = $util.newBuffer(object.accountSignature); + } + if (options.bytes === String) + object.deviceSignature = ""; + else { + object.deviceSignature = []; + if (options.bytes !== Array) + object.deviceSignature = $util.newBuffer(object.deviceSignature); + } + } + if (message.details != null && message.hasOwnProperty("details")) + object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; + if (message.accountSignatureKey != null && message.hasOwnProperty("accountSignatureKey")) + object.accountSignatureKey = options.bytes === String ? $util.base64.encode(message.accountSignatureKey, 0, message.accountSignatureKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.accountSignatureKey) : message.accountSignatureKey; + if (message.accountSignature != null && message.hasOwnProperty("accountSignature")) + object.accountSignature = options.bytes === String ? $util.base64.encode(message.accountSignature, 0, message.accountSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.accountSignature) : message.accountSignature; + if (message.deviceSignature != null && message.hasOwnProperty("deviceSignature")) + object.deviceSignature = options.bytes === String ? $util.base64.encode(message.deviceSignature, 0, message.deviceSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.deviceSignature) : message.deviceSignature; + return object; + }; + + /** + * Converts this ADVSignedDeviceIdentity to JSON. + * @function toJSON + * @memberof proto.ADVSignedDeviceIdentity + * @instance + * @returns {Object.} JSON object + */ + ADVSignedDeviceIdentity.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ADVSignedDeviceIdentity; + })(); + + proto.ADVDeviceIdentity = (function() { + + /** + * Properties of a ADVDeviceIdentity. + * @memberof proto + * @interface IADVDeviceIdentity + * @property {number|null} [rawId] ADVDeviceIdentity rawId + * @property {number|Long|null} [timestamp] ADVDeviceIdentity timestamp + * @property {number|null} [keyIndex] ADVDeviceIdentity keyIndex + */ + + /** + * Constructs a new ADVDeviceIdentity. + * @memberof proto + * @classdesc Represents a ADVDeviceIdentity. + * @implements IADVDeviceIdentity + * @constructor + * @param {proto.IADVDeviceIdentity=} [properties] Properties to set + */ + function ADVDeviceIdentity(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ADVDeviceIdentity rawId. + * @member {number} rawId + * @memberof proto.ADVDeviceIdentity + * @instance + */ + ADVDeviceIdentity.prototype.rawId = 0; + + /** + * ADVDeviceIdentity timestamp. + * @member {number|Long} timestamp + * @memberof proto.ADVDeviceIdentity + * @instance + */ + ADVDeviceIdentity.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * ADVDeviceIdentity keyIndex. + * @member {number} keyIndex + * @memberof proto.ADVDeviceIdentity + * @instance + */ + ADVDeviceIdentity.prototype.keyIndex = 0; + + /** + * Creates a new ADVDeviceIdentity instance using the specified properties. + * @function create + * @memberof proto.ADVDeviceIdentity + * @static + * @param {proto.IADVDeviceIdentity=} [properties] Properties to set + * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity instance + */ + ADVDeviceIdentity.create = function create(properties) { + return new ADVDeviceIdentity(properties); + }; + + /** + * Encodes the specified ADVDeviceIdentity message. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages. + * @function encode + * @memberof proto.ADVDeviceIdentity + * @static + * @param {proto.IADVDeviceIdentity} message ADVDeviceIdentity message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVDeviceIdentity.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.rawId != null && Object.hasOwnProperty.call(message, "rawId")) + writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.rawId); + if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.timestamp); + if (message.keyIndex != null && Object.hasOwnProperty.call(message, "keyIndex")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.keyIndex); + return writer; + }; + + /** + * Encodes the specified ADVDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ADVDeviceIdentity + * @static + * @param {proto.IADVDeviceIdentity} message ADVDeviceIdentity message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ADVDeviceIdentity.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ADVDeviceIdentity message from the specified reader or buffer. + * @function decode + * @memberof proto.ADVDeviceIdentity + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVDeviceIdentity.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVDeviceIdentity(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.rawId = reader.uint32(); + break; + case 2: + message.timestamp = reader.uint64(); + break; + case 3: + message.keyIndex = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ADVDeviceIdentity message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ADVDeviceIdentity + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ADVDeviceIdentity.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ADVDeviceIdentity message. + * @function verify + * @memberof proto.ADVDeviceIdentity + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ADVDeviceIdentity.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.rawId != null && message.hasOwnProperty("rawId")) + if (!$util.isInteger(message.rawId)) + return "rawId: integer expected"; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) + return "timestamp: integer|Long expected"; + if (message.keyIndex != null && message.hasOwnProperty("keyIndex")) + if (!$util.isInteger(message.keyIndex)) + return "keyIndex: integer expected"; + return null; + }; + + /** + * Creates a ADVDeviceIdentity message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ADVDeviceIdentity + * @static + * @param {Object.} object Plain object + * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity + */ + ADVDeviceIdentity.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ADVDeviceIdentity) + return object; + var message = new $root.proto.ADVDeviceIdentity(); + if (object.rawId != null) + message.rawId = object.rawId >>> 0; + if (object.timestamp != null) + if ($util.Long) + (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = true; + else if (typeof object.timestamp === "string") + message.timestamp = parseInt(object.timestamp, 10); + else if (typeof object.timestamp === "number") + message.timestamp = object.timestamp; + else if (typeof object.timestamp === "object") + message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(true); + if (object.keyIndex != null) + message.keyIndex = object.keyIndex >>> 0; + return message; + }; + + /** + * Creates a plain object from a ADVDeviceIdentity message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ADVDeviceIdentity + * @static + * @param {proto.ADVDeviceIdentity} message ADVDeviceIdentity + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ADVDeviceIdentity.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.rawId = 0; if ($util.Long) { var long = new $util.Long(0, 0, true); - object.fileLength = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; } else - object.fileLength = options.longs === String ? "0" : 0; - object.width = 0; - object.height = 0; - object.mimetype = ""; - object.placeholderArgb = 0; - object.textArgb = 0; - object.subtextArgb = 0; + object.timestamp = options.longs === String ? "0" : 0; + object.keyIndex = 0; } - if (message.id != null && message.hasOwnProperty("id")) - object.id = message.id; - if (message.fileLength != null && message.hasOwnProperty("fileLength")) - if (typeof message.fileLength === "number") - object.fileLength = options.longs === String ? String(message.fileLength) : message.fileLength; + if (message.rawId != null && message.hasOwnProperty("rawId")) + object.rawId = message.rawId; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (typeof message.timestamp === "number") + object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; else - object.fileLength = options.longs === String ? $util.Long.prototype.toString.call(message.fileLength) : options.longs === Number ? new $util.LongBits(message.fileLength.low >>> 0, message.fileLength.high >>> 0).toNumber(true) : message.fileLength; - if (message.width != null && message.hasOwnProperty("width")) - object.width = message.width; - if (message.height != null && message.hasOwnProperty("height")) - object.height = message.height; - if (message.mimetype != null && message.hasOwnProperty("mimetype")) - object.mimetype = message.mimetype; - if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) - object.placeholderArgb = message.placeholderArgb; - if (message.textArgb != null && message.hasOwnProperty("textArgb")) - object.textArgb = message.textArgb; - if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) - object.subtextArgb = message.subtextArgb; + object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber(true) : message.timestamp; + if (message.keyIndex != null && message.hasOwnProperty("keyIndex")) + object.keyIndex = message.keyIndex; return object; }; /** - * Converts this PaymentBackground to JSON. + * Converts this ADVDeviceIdentity to JSON. * @function toJSON - * @memberof proto.PaymentBackground + * @memberof proto.ADVDeviceIdentity * @instance * @returns {Object.} JSON object */ - PaymentBackground.prototype.toJSON = function toJSON() { + ADVDeviceIdentity.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - return PaymentBackground; + return ADVDeviceIdentity; })(); - proto.Money = (function() { + proto.ADVSignedKeyIndexList = (function() { /** - * Properties of a Money. + * Properties of a ADVSignedKeyIndexList. * @memberof proto - * @interface IMoney - * @property {number|Long|null} [value] Money value - * @property {number|null} [offset] Money offset - * @property {string|null} [currencyCode] Money currencyCode + * @interface IADVSignedKeyIndexList + * @property {Uint8Array|null} [details] ADVSignedKeyIndexList details + * @property {Uint8Array|null} [accountSignature] ADVSignedKeyIndexList accountSignature */ /** - * Constructs a new Money. + * Constructs a new ADVSignedKeyIndexList. * @memberof proto - * @classdesc Represents a Money. - * @implements IMoney + * @classdesc Represents a ADVSignedKeyIndexList. + * @implements IADVSignedKeyIndexList * @constructor - * @param {proto.IMoney=} [properties] Properties to set + * @param {proto.IADVSignedKeyIndexList=} [properties] Properties to set */ - function Money(properties) { + function ADVSignedKeyIndexList(properties) { if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -27250,101 +45413,88 @@ $root.proto = (function() { } /** - * Money value. - * @member {number|Long} value - * @memberof proto.Money + * ADVSignedKeyIndexList details. + * @member {Uint8Array} details + * @memberof proto.ADVSignedKeyIndexList * @instance */ - Money.prototype.value = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + ADVSignedKeyIndexList.prototype.details = $util.newBuffer([]); /** - * Money offset. - * @member {number} offset - * @memberof proto.Money + * ADVSignedKeyIndexList accountSignature. + * @member {Uint8Array} accountSignature + * @memberof proto.ADVSignedKeyIndexList * @instance */ - Money.prototype.offset = 0; + ADVSignedKeyIndexList.prototype.accountSignature = $util.newBuffer([]); /** - * Money currencyCode. - * @member {string} currencyCode - * @memberof proto.Money - * @instance - */ - Money.prototype.currencyCode = ""; - - /** - * Creates a new Money instance using the specified properties. + * Creates a new ADVSignedKeyIndexList instance using the specified properties. * @function create - * @memberof proto.Money + * @memberof proto.ADVSignedKeyIndexList * @static - * @param {proto.IMoney=} [properties] Properties to set - * @returns {proto.Money} Money instance + * @param {proto.IADVSignedKeyIndexList=} [properties] Properties to set + * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList instance */ - Money.create = function create(properties) { - return new Money(properties); + ADVSignedKeyIndexList.create = function create(properties) { + return new ADVSignedKeyIndexList(properties); }; /** - * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. + * Encodes the specified ADVSignedKeyIndexList message. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages. * @function encode - * @memberof proto.Money + * @memberof proto.ADVSignedKeyIndexList * @static - * @param {proto.IMoney} message Money message or plain object to encode + * @param {proto.IADVSignedKeyIndexList} message ADVSignedKeyIndexList message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - Money.encode = function encode(message, writer) { + ADVSignedKeyIndexList.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.value != null && Object.hasOwnProperty.call(message, "value")) - writer.uint32(/* id 1, wireType 0 =*/8).int64(message.value); - if (message.offset != null && Object.hasOwnProperty.call(message, "offset")) - writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.offset); - if (message.currencyCode != null && Object.hasOwnProperty.call(message, "currencyCode")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.currencyCode); + if (message.details != null && Object.hasOwnProperty.call(message, "details")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details); + if (message.accountSignature != null && Object.hasOwnProperty.call(message, "accountSignature")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.accountSignature); return writer; }; /** - * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. + * Encodes the specified ADVSignedKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages. * @function encodeDelimited - * @memberof proto.Money + * @memberof proto.ADVSignedKeyIndexList * @static - * @param {proto.IMoney} message Money message or plain object to encode + * @param {proto.IADVSignedKeyIndexList} message ADVSignedKeyIndexList message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - Money.encodeDelimited = function encodeDelimited(message, writer) { + ADVSignedKeyIndexList.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; /** - * Decodes a Money message from the specified reader or buffer. + * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer. * @function decode - * @memberof proto.Money + * @memberof proto.ADVSignedKeyIndexList * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from * @param {number} [length] Message length if known beforehand - * @returns {proto.Money} Money + * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - Money.decode = function decode(reader, length) { + ADVSignedKeyIndexList.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Money(); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVSignedKeyIndexList(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.value = reader.int64(); + message.details = reader.bytes(); break; case 2: - message.offset = reader.uint32(); - break; - case 3: - message.currencyCode = reader.string(); + message.accountSignature = reader.bytes(); break; default: reader.skipType(tag & 7); @@ -27355,139 +45505,138 @@ $root.proto = (function() { }; /** - * Decodes a Money message from the specified reader or buffer, length delimited. + * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer, length delimited. * @function decodeDelimited - * @memberof proto.Money + * @memberof proto.ADVSignedKeyIndexList * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.Money} Money + * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - Money.decodeDelimited = function decodeDelimited(reader) { + ADVSignedKeyIndexList.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; /** - * Verifies a Money message. + * Verifies a ADVSignedKeyIndexList message. * @function verify - * @memberof proto.Money + * @memberof proto.ADVSignedKeyIndexList * @static * @param {Object.} message Plain object to verify * @returns {string|null} `null` if valid, otherwise the reason why it is not */ - Money.verify = function verify(message) { + ADVSignedKeyIndexList.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.value != null && message.hasOwnProperty("value")) - if (!$util.isInteger(message.value) && !(message.value && $util.isInteger(message.value.low) && $util.isInteger(message.value.high))) - return "value: integer|Long expected"; - if (message.offset != null && message.hasOwnProperty("offset")) - if (!$util.isInteger(message.offset)) - return "offset: integer expected"; - if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) - if (!$util.isString(message.currencyCode)) - return "currencyCode: string expected"; + if (message.details != null && message.hasOwnProperty("details")) + if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details))) + return "details: buffer expected"; + if (message.accountSignature != null && message.hasOwnProperty("accountSignature")) + if (!(message.accountSignature && typeof message.accountSignature.length === "number" || $util.isString(message.accountSignature))) + return "accountSignature: buffer expected"; return null; }; /** - * Creates a Money message from a plain object. Also converts values to their respective internal types. + * Creates a ADVSignedKeyIndexList message from a plain object. Also converts values to their respective internal types. * @function fromObject - * @memberof proto.Money + * @memberof proto.ADVSignedKeyIndexList * @static * @param {Object.} object Plain object - * @returns {proto.Money} Money + * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList */ - Money.fromObject = function fromObject(object) { - if (object instanceof $root.proto.Money) + ADVSignedKeyIndexList.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ADVSignedKeyIndexList) return object; - var message = new $root.proto.Money(); - if (object.value != null) - if ($util.Long) - (message.value = $util.Long.fromValue(object.value)).unsigned = false; - else if (typeof object.value === "string") - message.value = parseInt(object.value, 10); - else if (typeof object.value === "number") - message.value = object.value; - else if (typeof object.value === "object") - message.value = new $util.LongBits(object.value.low >>> 0, object.value.high >>> 0).toNumber(); - if (object.offset != null) - message.offset = object.offset >>> 0; - if (object.currencyCode != null) - message.currencyCode = String(object.currencyCode); + var message = new $root.proto.ADVSignedKeyIndexList(); + if (object.details != null) + if (typeof object.details === "string") + $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0); + else if (object.details.length) + message.details = object.details; + if (object.accountSignature != null) + if (typeof object.accountSignature === "string") + $util.base64.decode(object.accountSignature, message.accountSignature = $util.newBuffer($util.base64.length(object.accountSignature)), 0); + else if (object.accountSignature.length) + message.accountSignature = object.accountSignature; return message; }; /** - * Creates a plain object from a Money message. Also converts values to other types if specified. + * Creates a plain object from a ADVSignedKeyIndexList message. Also converts values to other types if specified. * @function toObject - * @memberof proto.Money + * @memberof proto.ADVSignedKeyIndexList * @static - * @param {proto.Money} message Money + * @param {proto.ADVSignedKeyIndexList} message ADVSignedKeyIndexList * @param {$protobuf.IConversionOptions} [options] Conversion options * @returns {Object.} Plain object */ - Money.toObject = function toObject(message, options) { + ADVSignedKeyIndexList.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.value = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.value = options.longs === String ? "0" : 0; - object.offset = 0; - object.currencyCode = ""; + if (options.bytes === String) + object.details = ""; + else { + object.details = []; + if (options.bytes !== Array) + object.details = $util.newBuffer(object.details); + } + if (options.bytes === String) + object.accountSignature = ""; + else { + object.accountSignature = []; + if (options.bytes !== Array) + object.accountSignature = $util.newBuffer(object.accountSignature); + } } - if (message.value != null && message.hasOwnProperty("value")) - if (typeof message.value === "number") - object.value = options.longs === String ? String(message.value) : message.value; - else - object.value = options.longs === String ? $util.Long.prototype.toString.call(message.value) : options.longs === Number ? new $util.LongBits(message.value.low >>> 0, message.value.high >>> 0).toNumber() : message.value; - if (message.offset != null && message.hasOwnProperty("offset")) - object.offset = message.offset; - if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) - object.currencyCode = message.currencyCode; + if (message.details != null && message.hasOwnProperty("details")) + object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details; + if (message.accountSignature != null && message.hasOwnProperty("accountSignature")) + object.accountSignature = options.bytes === String ? $util.base64.encode(message.accountSignature, 0, message.accountSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.accountSignature) : message.accountSignature; return object; }; /** - * Converts this Money to JSON. + * Converts this ADVSignedKeyIndexList to JSON. * @function toJSON - * @memberof proto.Money + * @memberof proto.ADVSignedKeyIndexList * @instance * @returns {Object.} JSON object */ - Money.prototype.toJSON = function toJSON() { + ADVSignedKeyIndexList.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - return Money; + return ADVSignedKeyIndexList; })(); - proto.HydratedQuickReplyButton = (function() { + proto.ADVKeyIndexList = (function() { /** - * Properties of a HydratedQuickReplyButton. + * Properties of a ADVKeyIndexList. * @memberof proto - * @interface IHydratedQuickReplyButton - * @property {string|null} [displayText] HydratedQuickReplyButton displayText - * @property {string|null} [id] HydratedQuickReplyButton id + * @interface IADVKeyIndexList + * @property {number|null} [rawId] ADVKeyIndexList rawId + * @property {number|Long|null} [timestamp] ADVKeyIndexList timestamp + * @property {number|null} [currentIndex] ADVKeyIndexList currentIndex + * @property {Array.|null} [validIndexes] ADVKeyIndexList validIndexes */ /** - * Constructs a new HydratedQuickReplyButton. + * Constructs a new ADVKeyIndexList. * @memberof proto - * @classdesc Represents a HydratedQuickReplyButton. - * @implements IHydratedQuickReplyButton + * @classdesc Represents a ADVKeyIndexList. + * @implements IADVKeyIndexList * @constructor - * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set + * @param {proto.IADVKeyIndexList=} [properties] Properties to set */ - function HydratedQuickReplyButton(properties) { + function ADVKeyIndexList(properties) { + this.validIndexes = []; if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -27495,88 +45644,125 @@ $root.proto = (function() { } /** - * HydratedQuickReplyButton displayText. - * @member {string} displayText - * @memberof proto.HydratedQuickReplyButton + * ADVKeyIndexList rawId. + * @member {number} rawId + * @memberof proto.ADVKeyIndexList * @instance */ - HydratedQuickReplyButton.prototype.displayText = ""; + ADVKeyIndexList.prototype.rawId = 0; /** - * HydratedQuickReplyButton id. - * @member {string} id - * @memberof proto.HydratedQuickReplyButton + * ADVKeyIndexList timestamp. + * @member {number|Long} timestamp + * @memberof proto.ADVKeyIndexList * @instance */ - HydratedQuickReplyButton.prototype.id = ""; + ADVKeyIndexList.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; /** - * Creates a new HydratedQuickReplyButton instance using the specified properties. + * ADVKeyIndexList currentIndex. + * @member {number} currentIndex + * @memberof proto.ADVKeyIndexList + * @instance + */ + ADVKeyIndexList.prototype.currentIndex = 0; + + /** + * ADVKeyIndexList validIndexes. + * @member {Array.} validIndexes + * @memberof proto.ADVKeyIndexList + * @instance + */ + ADVKeyIndexList.prototype.validIndexes = $util.emptyArray; + + /** + * Creates a new ADVKeyIndexList instance using the specified properties. * @function create - * @memberof proto.HydratedQuickReplyButton + * @memberof proto.ADVKeyIndexList * @static - * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set - * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton instance + * @param {proto.IADVKeyIndexList=} [properties] Properties to set + * @returns {proto.ADVKeyIndexList} ADVKeyIndexList instance */ - HydratedQuickReplyButton.create = function create(properties) { - return new HydratedQuickReplyButton(properties); + ADVKeyIndexList.create = function create(properties) { + return new ADVKeyIndexList(properties); }; /** - * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * Encodes the specified ADVKeyIndexList message. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages. * @function encode - * @memberof proto.HydratedQuickReplyButton + * @memberof proto.ADVKeyIndexList * @static - * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode + * @param {proto.IADVKeyIndexList} message ADVKeyIndexList message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - HydratedQuickReplyButton.encode = function encode(message, writer) { + ADVKeyIndexList.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.id); + if (message.rawId != null && Object.hasOwnProperty.call(message, "rawId")) + writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.rawId); + if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.timestamp); + if (message.currentIndex != null && Object.hasOwnProperty.call(message, "currentIndex")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.currentIndex); + if (message.validIndexes != null && message.validIndexes.length) { + writer.uint32(/* id 4, wireType 2 =*/34).fork(); + for (var i = 0; i < message.validIndexes.length; ++i) + writer.uint32(message.validIndexes[i]); + writer.ldelim(); + } return writer; }; /** - * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * Encodes the specified ADVKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages. * @function encodeDelimited - * @memberof proto.HydratedQuickReplyButton + * @memberof proto.ADVKeyIndexList * @static - * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode + * @param {proto.IADVKeyIndexList} message ADVKeyIndexList message or plain object to encode * @param {$protobuf.Writer} [writer] Writer to encode to * @returns {$protobuf.Writer} Writer */ - HydratedQuickReplyButton.encodeDelimited = function encodeDelimited(message, writer) { + ADVKeyIndexList.encodeDelimited = function encodeDelimited(message, writer) { return this.encode(message, writer).ldelim(); }; /** - * Decodes a HydratedQuickReplyButton message from the specified reader or buffer. + * Decodes a ADVKeyIndexList message from the specified reader or buffer. * @function decode - * @memberof proto.HydratedQuickReplyButton + * @memberof proto.ADVKeyIndexList * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from * @param {number} [length] Message length if known beforehand - * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton + * @returns {proto.ADVKeyIndexList} ADVKeyIndexList * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - HydratedQuickReplyButton.decode = function decode(reader, length) { + ADVKeyIndexList.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedQuickReplyButton(); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVKeyIndexList(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.displayText = reader.string(); + message.rawId = reader.uint32(); break; case 2: - message.id = reader.string(); + message.timestamp = reader.uint64(); + break; + case 3: + message.currentIndex = reader.uint32(); + break; + case 4: + if (!(message.validIndexes && message.validIndexes.length)) + message.validIndexes = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.validIndexes.push(reader.uint32()); + } else + message.validIndexes.push(reader.uint32()); break; default: reader.skipType(tag & 7); @@ -27587,1192 +45773,393 @@ $root.proto = (function() { }; /** - * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited. + * Decodes a ADVKeyIndexList message from the specified reader or buffer, length delimited. * @function decodeDelimited - * @memberof proto.HydratedQuickReplyButton + * @memberof proto.ADVKeyIndexList * @static * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton + * @returns {proto.ADVKeyIndexList} ADVKeyIndexList * @throws {Error} If the payload is not a reader or valid buffer * @throws {$protobuf.util.ProtocolError} If required fields are missing */ - HydratedQuickReplyButton.decodeDelimited = function decodeDelimited(reader) { + ADVKeyIndexList.decodeDelimited = function decodeDelimited(reader) { if (!(reader instanceof $Reader)) reader = new $Reader(reader); return this.decode(reader, reader.uint32()); }; /** - * Verifies a HydratedQuickReplyButton message. + * Verifies a ADVKeyIndexList message. * @function verify - * @memberof proto.HydratedQuickReplyButton + * @memberof proto.ADVKeyIndexList * @static * @param {Object.} message Plain object to verify * @returns {string|null} `null` if valid, otherwise the reason why it is not */ - HydratedQuickReplyButton.verify = function verify(message) { + ADVKeyIndexList.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.displayText != null && message.hasOwnProperty("displayText")) - if (!$util.isString(message.displayText)) - return "displayText: string expected"; + if (message.rawId != null && message.hasOwnProperty("rawId")) + if (!$util.isInteger(message.rawId)) + return "rawId: integer expected"; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high))) + return "timestamp: integer|Long expected"; + if (message.currentIndex != null && message.hasOwnProperty("currentIndex")) + if (!$util.isInteger(message.currentIndex)) + return "currentIndex: integer expected"; + if (message.validIndexes != null && message.hasOwnProperty("validIndexes")) { + if (!Array.isArray(message.validIndexes)) + return "validIndexes: array expected"; + for (var i = 0; i < message.validIndexes.length; ++i) + if (!$util.isInteger(message.validIndexes[i])) + return "validIndexes: integer[] expected"; + } + return null; + }; + + /** + * Creates a ADVKeyIndexList message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ADVKeyIndexList + * @static + * @param {Object.} object Plain object + * @returns {proto.ADVKeyIndexList} ADVKeyIndexList + */ + ADVKeyIndexList.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ADVKeyIndexList) + return object; + var message = new $root.proto.ADVKeyIndexList(); + if (object.rawId != null) + message.rawId = object.rawId >>> 0; + if (object.timestamp != null) + if ($util.Long) + (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = true; + else if (typeof object.timestamp === "string") + message.timestamp = parseInt(object.timestamp, 10); + else if (typeof object.timestamp === "number") + message.timestamp = object.timestamp; + else if (typeof object.timestamp === "object") + message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(true); + if (object.currentIndex != null) + message.currentIndex = object.currentIndex >>> 0; + if (object.validIndexes) { + if (!Array.isArray(object.validIndexes)) + throw TypeError(".proto.ADVKeyIndexList.validIndexes: array expected"); + message.validIndexes = []; + for (var i = 0; i < object.validIndexes.length; ++i) + message.validIndexes[i] = object.validIndexes[i] >>> 0; + } + return message; + }; + + /** + * Creates a plain object from a ADVKeyIndexList message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ADVKeyIndexList + * @static + * @param {proto.ADVKeyIndexList} message ADVKeyIndexList + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ADVKeyIndexList.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.validIndexes = []; + if (options.defaults) { + object.rawId = 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.timestamp = options.longs === String ? "0" : 0; + object.currentIndex = 0; + } + if (message.rawId != null && message.hasOwnProperty("rawId")) + object.rawId = message.rawId; + if (message.timestamp != null && message.hasOwnProperty("timestamp")) + if (typeof message.timestamp === "number") + object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp; + else + object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber(true) : message.timestamp; + if (message.currentIndex != null && message.hasOwnProperty("currentIndex")) + object.currentIndex = message.currentIndex; + if (message.validIndexes && message.validIndexes.length) { + object.validIndexes = []; + for (var j = 0; j < message.validIndexes.length; ++j) + object.validIndexes[j] = message.validIndexes[j]; + } + return object; + }; + + /** + * Converts this ADVKeyIndexList to JSON. + * @function toJSON + * @memberof proto.ADVKeyIndexList + * @instance + * @returns {Object.} JSON object + */ + ADVKeyIndexList.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ADVKeyIndexList; + })(); + + proto.MessageKey = (function() { + + /** + * Properties of a MessageKey. + * @memberof proto + * @interface IMessageKey + * @property {string|null} [remoteJid] MessageKey remoteJid + * @property {boolean|null} [fromMe] MessageKey fromMe + * @property {string|null} [id] MessageKey id + * @property {string|null} [participant] MessageKey participant + */ + + /** + * Constructs a new MessageKey. + * @memberof proto + * @classdesc Represents a MessageKey. + * @implements IMessageKey + * @constructor + * @param {proto.IMessageKey=} [properties] Properties to set + */ + function MessageKey(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MessageKey remoteJid. + * @member {string} remoteJid + * @memberof proto.MessageKey + * @instance + */ + MessageKey.prototype.remoteJid = ""; + + /** + * MessageKey fromMe. + * @member {boolean} fromMe + * @memberof proto.MessageKey + * @instance + */ + MessageKey.prototype.fromMe = false; + + /** + * MessageKey id. + * @member {string} id + * @memberof proto.MessageKey + * @instance + */ + MessageKey.prototype.id = ""; + + /** + * MessageKey participant. + * @member {string} participant + * @memberof proto.MessageKey + * @instance + */ + MessageKey.prototype.participant = ""; + + /** + * Creates a new MessageKey instance using the specified properties. + * @function create + * @memberof proto.MessageKey + * @static + * @param {proto.IMessageKey=} [properties] Properties to set + * @returns {proto.MessageKey} MessageKey instance + */ + MessageKey.create = function create(properties) { + return new MessageKey(properties); + }; + + /** + * Encodes the specified MessageKey message. Does not implicitly {@link proto.MessageKey.verify|verify} messages. + * @function encode + * @memberof proto.MessageKey + * @static + * @param {proto.IMessageKey} message MessageKey message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MessageKey.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.remoteJid != null && Object.hasOwnProperty.call(message, "remoteJid")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.remoteJid); + if (message.fromMe != null && Object.hasOwnProperty.call(message, "fromMe")) + writer.uint32(/* id 2, wireType 0 =*/16).bool(message.fromMe); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.id); + if (message.participant != null && Object.hasOwnProperty.call(message, "participant")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.participant); + return writer; + }; + + /** + * Encodes the specified MessageKey message, length delimited. Does not implicitly {@link proto.MessageKey.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MessageKey + * @static + * @param {proto.IMessageKey} message MessageKey message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MessageKey.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MessageKey message from the specified reader or buffer. + * @function decode + * @memberof proto.MessageKey + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MessageKey} MessageKey + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MessageKey.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MessageKey(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.remoteJid = reader.string(); + break; + case 2: + message.fromMe = reader.bool(); + break; + case 3: + message.id = reader.string(); + break; + case 4: + message.participant = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MessageKey message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MessageKey + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MessageKey} MessageKey + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MessageKey.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MessageKey message. + * @function verify + * @memberof proto.MessageKey + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MessageKey.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.remoteJid != null && message.hasOwnProperty("remoteJid")) + if (!$util.isString(message.remoteJid)) + return "remoteJid: string expected"; + if (message.fromMe != null && message.hasOwnProperty("fromMe")) + if (typeof message.fromMe !== "boolean") + return "fromMe: boolean expected"; if (message.id != null && message.hasOwnProperty("id")) if (!$util.isString(message.id)) return "id: string expected"; + if (message.participant != null && message.hasOwnProperty("participant")) + if (!$util.isString(message.participant)) + return "participant: string expected"; return null; }; /** - * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types. + * Creates a MessageKey message from a plain object. Also converts values to their respective internal types. * @function fromObject - * @memberof proto.HydratedQuickReplyButton + * @memberof proto.MessageKey * @static * @param {Object.} object Plain object - * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton + * @returns {proto.MessageKey} MessageKey */ - HydratedQuickReplyButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HydratedQuickReplyButton) + MessageKey.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MessageKey) return object; - var message = new $root.proto.HydratedQuickReplyButton(); - if (object.displayText != null) - message.displayText = String(object.displayText); + var message = new $root.proto.MessageKey(); + if (object.remoteJid != null) + message.remoteJid = String(object.remoteJid); + if (object.fromMe != null) + message.fromMe = Boolean(object.fromMe); if (object.id != null) message.id = String(object.id); + if (object.participant != null) + message.participant = String(object.participant); return message; }; /** - * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified. + * Creates a plain object from a MessageKey message. Also converts values to other types if specified. * @function toObject - * @memberof proto.HydratedQuickReplyButton + * @memberof proto.MessageKey * @static - * @param {proto.HydratedQuickReplyButton} message HydratedQuickReplyButton + * @param {proto.MessageKey} message MessageKey * @param {$protobuf.IConversionOptions} [options] Conversion options * @returns {Object.} Plain object */ - HydratedQuickReplyButton.toObject = function toObject(message, options) { + MessageKey.toObject = function toObject(message, options) { if (!options) options = {}; var object = {}; if (options.defaults) { - object.displayText = ""; + object.remoteJid = ""; + object.fromMe = false; object.id = ""; + object.participant = ""; } - if (message.displayText != null && message.hasOwnProperty("displayText")) - object.displayText = message.displayText; + if (message.remoteJid != null && message.hasOwnProperty("remoteJid")) + object.remoteJid = message.remoteJid; + if (message.fromMe != null && message.hasOwnProperty("fromMe")) + object.fromMe = message.fromMe; if (message.id != null && message.hasOwnProperty("id")) object.id = message.id; + if (message.participant != null && message.hasOwnProperty("participant")) + object.participant = message.participant; return object; }; /** - * Converts this HydratedQuickReplyButton to JSON. + * Converts this MessageKey to JSON. * @function toJSON - * @memberof proto.HydratedQuickReplyButton + * @memberof proto.MessageKey * @instance * @returns {Object.} JSON object */ - HydratedQuickReplyButton.prototype.toJSON = function toJSON() { + MessageKey.prototype.toJSON = function toJSON() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - return HydratedQuickReplyButton; - })(); - - proto.HydratedURLButton = (function() { - - /** - * Properties of a HydratedURLButton. - * @memberof proto - * @interface IHydratedURLButton - * @property {string|null} [displayText] HydratedURLButton displayText - * @property {string|null} [url] HydratedURLButton url - */ - - /** - * Constructs a new HydratedURLButton. - * @memberof proto - * @classdesc Represents a HydratedURLButton. - * @implements IHydratedURLButton - * @constructor - * @param {proto.IHydratedURLButton=} [properties] Properties to set - */ - function HydratedURLButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HydratedURLButton displayText. - * @member {string} displayText - * @memberof proto.HydratedURLButton - * @instance - */ - HydratedURLButton.prototype.displayText = ""; - - /** - * HydratedURLButton url. - * @member {string} url - * @memberof proto.HydratedURLButton - * @instance - */ - HydratedURLButton.prototype.url = ""; - - /** - * Creates a new HydratedURLButton instance using the specified properties. - * @function create - * @memberof proto.HydratedURLButton - * @static - * @param {proto.IHydratedURLButton=} [properties] Properties to set - * @returns {proto.HydratedURLButton} HydratedURLButton instance - */ - HydratedURLButton.create = function create(properties) { - return new HydratedURLButton(properties); - }; - - /** - * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. - * @function encode - * @memberof proto.HydratedURLButton - * @static - * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedURLButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); - if (message.url != null && Object.hasOwnProperty.call(message, "url")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.url); - return writer; - }; - - /** - * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HydratedURLButton - * @static - * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedURLButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HydratedURLButton message from the specified reader or buffer. - * @function decode - * @memberof proto.HydratedURLButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HydratedURLButton} HydratedURLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedURLButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedURLButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.displayText = reader.string(); - break; - case 2: - message.url = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HydratedURLButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HydratedURLButton} HydratedURLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedURLButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HydratedURLButton message. - * @function verify - * @memberof proto.HydratedURLButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HydratedURLButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.displayText != null && message.hasOwnProperty("displayText")) - if (!$util.isString(message.displayText)) - return "displayText: string expected"; - if (message.url != null && message.hasOwnProperty("url")) - if (!$util.isString(message.url)) - return "url: string expected"; - return null; - }; - - /** - * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HydratedURLButton - * @static - * @param {Object.} object Plain object - * @returns {proto.HydratedURLButton} HydratedURLButton - */ - HydratedURLButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HydratedURLButton) - return object; - var message = new $root.proto.HydratedURLButton(); - if (object.displayText != null) - message.displayText = String(object.displayText); - if (object.url != null) - message.url = String(object.url); - return message; - }; - - /** - * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HydratedURLButton - * @static - * @param {proto.HydratedURLButton} message HydratedURLButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HydratedURLButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.displayText = ""; - object.url = ""; - } - if (message.displayText != null && message.hasOwnProperty("displayText")) - object.displayText = message.displayText; - if (message.url != null && message.hasOwnProperty("url")) - object.url = message.url; - return object; - }; - - /** - * Converts this HydratedURLButton to JSON. - * @function toJSON - * @memberof proto.HydratedURLButton - * @instance - * @returns {Object.} JSON object - */ - HydratedURLButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HydratedURLButton; - })(); - - proto.HydratedCallButton = (function() { - - /** - * Properties of a HydratedCallButton. - * @memberof proto - * @interface IHydratedCallButton - * @property {string|null} [displayText] HydratedCallButton displayText - * @property {string|null} [phoneNumber] HydratedCallButton phoneNumber - */ - - /** - * Constructs a new HydratedCallButton. - * @memberof proto - * @classdesc Represents a HydratedCallButton. - * @implements IHydratedCallButton - * @constructor - * @param {proto.IHydratedCallButton=} [properties] Properties to set - */ - function HydratedCallButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HydratedCallButton displayText. - * @member {string} displayText - * @memberof proto.HydratedCallButton - * @instance - */ - HydratedCallButton.prototype.displayText = ""; - - /** - * HydratedCallButton phoneNumber. - * @member {string} phoneNumber - * @memberof proto.HydratedCallButton - * @instance - */ - HydratedCallButton.prototype.phoneNumber = ""; - - /** - * Creates a new HydratedCallButton instance using the specified properties. - * @function create - * @memberof proto.HydratedCallButton - * @static - * @param {proto.IHydratedCallButton=} [properties] Properties to set - * @returns {proto.HydratedCallButton} HydratedCallButton instance - */ - HydratedCallButton.create = function create(properties) { - return new HydratedCallButton(properties); - }; - - /** - * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. - * @function encode - * @memberof proto.HydratedCallButton - * @static - * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedCallButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); - if (message.phoneNumber != null && Object.hasOwnProperty.call(message, "phoneNumber")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.phoneNumber); - return writer; - }; - - /** - * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HydratedCallButton - * @static - * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedCallButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HydratedCallButton message from the specified reader or buffer. - * @function decode - * @memberof proto.HydratedCallButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HydratedCallButton} HydratedCallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedCallButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedCallButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.displayText = reader.string(); - break; - case 2: - message.phoneNumber = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HydratedCallButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HydratedCallButton} HydratedCallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedCallButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HydratedCallButton message. - * @function verify - * @memberof proto.HydratedCallButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HydratedCallButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.displayText != null && message.hasOwnProperty("displayText")) - if (!$util.isString(message.displayText)) - return "displayText: string expected"; - if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) - if (!$util.isString(message.phoneNumber)) - return "phoneNumber: string expected"; - return null; - }; - - /** - * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HydratedCallButton - * @static - * @param {Object.} object Plain object - * @returns {proto.HydratedCallButton} HydratedCallButton - */ - HydratedCallButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HydratedCallButton) - return object; - var message = new $root.proto.HydratedCallButton(); - if (object.displayText != null) - message.displayText = String(object.displayText); - if (object.phoneNumber != null) - message.phoneNumber = String(object.phoneNumber); - return message; - }; - - /** - * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HydratedCallButton - * @static - * @param {proto.HydratedCallButton} message HydratedCallButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HydratedCallButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.displayText = ""; - object.phoneNumber = ""; - } - if (message.displayText != null && message.hasOwnProperty("displayText")) - object.displayText = message.displayText; - if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) - object.phoneNumber = message.phoneNumber; - return object; - }; - - /** - * Converts this HydratedCallButton to JSON. - * @function toJSON - * @memberof proto.HydratedCallButton - * @instance - * @returns {Object.} JSON object - */ - HydratedCallButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HydratedCallButton; - })(); - - proto.HydratedTemplateButton = (function() { - - /** - * Properties of a HydratedTemplateButton. - * @memberof proto - * @interface IHydratedTemplateButton - * @property {number|null} [index] HydratedTemplateButton index - * @property {proto.IHydratedQuickReplyButton|null} [quickReplyButton] HydratedTemplateButton quickReplyButton - * @property {proto.IHydratedURLButton|null} [urlButton] HydratedTemplateButton urlButton - * @property {proto.IHydratedCallButton|null} [callButton] HydratedTemplateButton callButton - */ - - /** - * Constructs a new HydratedTemplateButton. - * @memberof proto - * @classdesc Represents a HydratedTemplateButton. - * @implements IHydratedTemplateButton - * @constructor - * @param {proto.IHydratedTemplateButton=} [properties] Properties to set - */ - function HydratedTemplateButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HydratedTemplateButton index. - * @member {number} index - * @memberof proto.HydratedTemplateButton - * @instance - */ - HydratedTemplateButton.prototype.index = 0; - - /** - * HydratedTemplateButton quickReplyButton. - * @member {proto.IHydratedQuickReplyButton|null|undefined} quickReplyButton - * @memberof proto.HydratedTemplateButton - * @instance - */ - HydratedTemplateButton.prototype.quickReplyButton = null; - - /** - * HydratedTemplateButton urlButton. - * @member {proto.IHydratedURLButton|null|undefined} urlButton - * @memberof proto.HydratedTemplateButton - * @instance - */ - HydratedTemplateButton.prototype.urlButton = null; - - /** - * HydratedTemplateButton callButton. - * @member {proto.IHydratedCallButton|null|undefined} callButton - * @memberof proto.HydratedTemplateButton - * @instance - */ - HydratedTemplateButton.prototype.callButton = null; - - // OneOf field names bound to virtual getters and setters - var $oneOfFields; - - /** - * HydratedTemplateButton hydratedButton. - * @member {"quickReplyButton"|"urlButton"|"callButton"|undefined} hydratedButton - * @memberof proto.HydratedTemplateButton - * @instance - */ - Object.defineProperty(HydratedTemplateButton.prototype, "hydratedButton", { - get: $util.oneOfGetter($oneOfFields = ["quickReplyButton", "urlButton", "callButton"]), - set: $util.oneOfSetter($oneOfFields) - }); - - /** - * Creates a new HydratedTemplateButton instance using the specified properties. - * @function create - * @memberof proto.HydratedTemplateButton - * @static - * @param {proto.IHydratedTemplateButton=} [properties] Properties to set - * @returns {proto.HydratedTemplateButton} HydratedTemplateButton instance - */ - HydratedTemplateButton.create = function create(properties) { - return new HydratedTemplateButton(properties); - }; - - /** - * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. - * @function encode - * @memberof proto.HydratedTemplateButton - * @static - * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedTemplateButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.quickReplyButton != null && Object.hasOwnProperty.call(message, "quickReplyButton")) - $root.proto.HydratedQuickReplyButton.encode(message.quickReplyButton, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.urlButton != null && Object.hasOwnProperty.call(message, "urlButton")) - $root.proto.HydratedURLButton.encode(message.urlButton, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.callButton != null && Object.hasOwnProperty.call(message, "callButton")) - $root.proto.HydratedCallButton.encode(message.callButton, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - if (message.index != null && Object.hasOwnProperty.call(message, "index")) - writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.index); - return writer; - }; - - /** - * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HydratedTemplateButton - * @static - * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedTemplateButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HydratedTemplateButton message from the specified reader or buffer. - * @function decode - * @memberof proto.HydratedTemplateButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HydratedTemplateButton} HydratedTemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedTemplateButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedTemplateButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 4: - message.index = reader.uint32(); - break; - case 1: - message.quickReplyButton = $root.proto.HydratedQuickReplyButton.decode(reader, reader.uint32()); - break; - case 2: - message.urlButton = $root.proto.HydratedURLButton.decode(reader, reader.uint32()); - break; - case 3: - message.callButton = $root.proto.HydratedCallButton.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HydratedTemplateButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HydratedTemplateButton} HydratedTemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedTemplateButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HydratedTemplateButton message. - * @function verify - * @memberof proto.HydratedTemplateButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HydratedTemplateButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - var properties = {}; - if (message.index != null && message.hasOwnProperty("index")) - if (!$util.isInteger(message.index)) - return "index: integer expected"; - if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { - properties.hydratedButton = 1; - { - var error = $root.proto.HydratedQuickReplyButton.verify(message.quickReplyButton); - if (error) - return "quickReplyButton." + error; - } - } - if (message.urlButton != null && message.hasOwnProperty("urlButton")) { - if (properties.hydratedButton === 1) - return "hydratedButton: multiple values"; - properties.hydratedButton = 1; - { - var error = $root.proto.HydratedURLButton.verify(message.urlButton); - if (error) - return "urlButton." + error; - } - } - if (message.callButton != null && message.hasOwnProperty("callButton")) { - if (properties.hydratedButton === 1) - return "hydratedButton: multiple values"; - properties.hydratedButton = 1; - { - var error = $root.proto.HydratedCallButton.verify(message.callButton); - if (error) - return "callButton." + error; - } - } - return null; - }; - - /** - * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HydratedTemplateButton - * @static - * @param {Object.} object Plain object - * @returns {proto.HydratedTemplateButton} HydratedTemplateButton - */ - HydratedTemplateButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HydratedTemplateButton) - return object; - var message = new $root.proto.HydratedTemplateButton(); - if (object.index != null) - message.index = object.index >>> 0; - if (object.quickReplyButton != null) { - if (typeof object.quickReplyButton !== "object") - throw TypeError(".proto.HydratedTemplateButton.quickReplyButton: object expected"); - message.quickReplyButton = $root.proto.HydratedQuickReplyButton.fromObject(object.quickReplyButton); - } - if (object.urlButton != null) { - if (typeof object.urlButton !== "object") - throw TypeError(".proto.HydratedTemplateButton.urlButton: object expected"); - message.urlButton = $root.proto.HydratedURLButton.fromObject(object.urlButton); - } - if (object.callButton != null) { - if (typeof object.callButton !== "object") - throw TypeError(".proto.HydratedTemplateButton.callButton: object expected"); - message.callButton = $root.proto.HydratedCallButton.fromObject(object.callButton); - } - return message; - }; - - /** - * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HydratedTemplateButton - * @static - * @param {proto.HydratedTemplateButton} message HydratedTemplateButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HydratedTemplateButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.index = 0; - if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { - object.quickReplyButton = $root.proto.HydratedQuickReplyButton.toObject(message.quickReplyButton, options); - if (options.oneofs) - object.hydratedButton = "quickReplyButton"; - } - if (message.urlButton != null && message.hasOwnProperty("urlButton")) { - object.urlButton = $root.proto.HydratedURLButton.toObject(message.urlButton, options); - if (options.oneofs) - object.hydratedButton = "urlButton"; - } - if (message.callButton != null && message.hasOwnProperty("callButton")) { - object.callButton = $root.proto.HydratedCallButton.toObject(message.callButton, options); - if (options.oneofs) - object.hydratedButton = "callButton"; - } - if (message.index != null && message.hasOwnProperty("index")) - object.index = message.index; - return object; - }; - - /** - * Converts this HydratedTemplateButton to JSON. - * @function toJSON - * @memberof proto.HydratedTemplateButton - * @instance - * @returns {Object.} JSON object - */ - HydratedTemplateButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HydratedTemplateButton; - })(); - - proto.UserReceipt = (function() { - - /** - * Properties of a UserReceipt. - * @memberof proto - * @interface IUserReceipt - * @property {string} userJid UserReceipt userJid - * @property {number|Long|null} [receiptTimestamp] UserReceipt receiptTimestamp - * @property {number|Long|null} [readTimestamp] UserReceipt readTimestamp - * @property {number|Long|null} [playedTimestamp] UserReceipt playedTimestamp - * @property {Array.|null} [pendingDeviceJid] UserReceipt pendingDeviceJid - * @property {Array.|null} [deliveredDeviceJid] UserReceipt deliveredDeviceJid - */ - - /** - * Constructs a new UserReceipt. - * @memberof proto - * @classdesc Represents a UserReceipt. - * @implements IUserReceipt - * @constructor - * @param {proto.IUserReceipt=} [properties] Properties to set - */ - function UserReceipt(properties) { - this.pendingDeviceJid = []; - this.deliveredDeviceJid = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * UserReceipt userJid. - * @member {string} userJid - * @memberof proto.UserReceipt - * @instance - */ - UserReceipt.prototype.userJid = ""; - - /** - * UserReceipt receiptTimestamp. - * @member {number|Long} receiptTimestamp - * @memberof proto.UserReceipt - * @instance - */ - UserReceipt.prototype.receiptTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * UserReceipt readTimestamp. - * @member {number|Long} readTimestamp - * @memberof proto.UserReceipt - * @instance - */ - UserReceipt.prototype.readTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * UserReceipt playedTimestamp. - * @member {number|Long} playedTimestamp - * @memberof proto.UserReceipt - * @instance - */ - UserReceipt.prototype.playedTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * UserReceipt pendingDeviceJid. - * @member {Array.} pendingDeviceJid - * @memberof proto.UserReceipt - * @instance - */ - UserReceipt.prototype.pendingDeviceJid = $util.emptyArray; - - /** - * UserReceipt deliveredDeviceJid. - * @member {Array.} deliveredDeviceJid - * @memberof proto.UserReceipt - * @instance - */ - UserReceipt.prototype.deliveredDeviceJid = $util.emptyArray; - - /** - * Creates a new UserReceipt instance using the specified properties. - * @function create - * @memberof proto.UserReceipt - * @static - * @param {proto.IUserReceipt=} [properties] Properties to set - * @returns {proto.UserReceipt} UserReceipt instance - */ - UserReceipt.create = function create(properties) { - return new UserReceipt(properties); - }; - - /** - * Encodes the specified UserReceipt message. Does not implicitly {@link proto.UserReceipt.verify|verify} messages. - * @function encode - * @memberof proto.UserReceipt - * @static - * @param {proto.IUserReceipt} message UserReceipt message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - UserReceipt.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - writer.uint32(/* id 1, wireType 2 =*/10).string(message.userJid); - if (message.receiptTimestamp != null && Object.hasOwnProperty.call(message, "receiptTimestamp")) - writer.uint32(/* id 2, wireType 0 =*/16).int64(message.receiptTimestamp); - if (message.readTimestamp != null && Object.hasOwnProperty.call(message, "readTimestamp")) - writer.uint32(/* id 3, wireType 0 =*/24).int64(message.readTimestamp); - if (message.playedTimestamp != null && Object.hasOwnProperty.call(message, "playedTimestamp")) - writer.uint32(/* id 4, wireType 0 =*/32).int64(message.playedTimestamp); - if (message.pendingDeviceJid != null && message.pendingDeviceJid.length) - for (var i = 0; i < message.pendingDeviceJid.length; ++i) - writer.uint32(/* id 5, wireType 2 =*/42).string(message.pendingDeviceJid[i]); - if (message.deliveredDeviceJid != null && message.deliveredDeviceJid.length) - for (var i = 0; i < message.deliveredDeviceJid.length; ++i) - writer.uint32(/* id 6, wireType 2 =*/50).string(message.deliveredDeviceJid[i]); - return writer; - }; - - /** - * Encodes the specified UserReceipt message, length delimited. Does not implicitly {@link proto.UserReceipt.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.UserReceipt - * @static - * @param {proto.IUserReceipt} message UserReceipt message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - UserReceipt.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a UserReceipt message from the specified reader or buffer. - * @function decode - * @memberof proto.UserReceipt - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.UserReceipt} UserReceipt - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - UserReceipt.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.UserReceipt(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.userJid = reader.string(); - break; - case 2: - message.receiptTimestamp = reader.int64(); - break; - case 3: - message.readTimestamp = reader.int64(); - break; - case 4: - message.playedTimestamp = reader.int64(); - break; - case 5: - if (!(message.pendingDeviceJid && message.pendingDeviceJid.length)) - message.pendingDeviceJid = []; - message.pendingDeviceJid.push(reader.string()); - break; - case 6: - if (!(message.deliveredDeviceJid && message.deliveredDeviceJid.length)) - message.deliveredDeviceJid = []; - message.deliveredDeviceJid.push(reader.string()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - if (!message.hasOwnProperty("userJid")) - throw $util.ProtocolError("missing required 'userJid'", { instance: message }); - return message; - }; - - /** - * Decodes a UserReceipt message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.UserReceipt - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.UserReceipt} UserReceipt - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - UserReceipt.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a UserReceipt message. - * @function verify - * @memberof proto.UserReceipt - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - UserReceipt.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (!$util.isString(message.userJid)) - return "userJid: string expected"; - if (message.receiptTimestamp != null && message.hasOwnProperty("receiptTimestamp")) - if (!$util.isInteger(message.receiptTimestamp) && !(message.receiptTimestamp && $util.isInteger(message.receiptTimestamp.low) && $util.isInteger(message.receiptTimestamp.high))) - return "receiptTimestamp: integer|Long expected"; - if (message.readTimestamp != null && message.hasOwnProperty("readTimestamp")) - if (!$util.isInteger(message.readTimestamp) && !(message.readTimestamp && $util.isInteger(message.readTimestamp.low) && $util.isInteger(message.readTimestamp.high))) - return "readTimestamp: integer|Long expected"; - if (message.playedTimestamp != null && message.hasOwnProperty("playedTimestamp")) - if (!$util.isInteger(message.playedTimestamp) && !(message.playedTimestamp && $util.isInteger(message.playedTimestamp.low) && $util.isInteger(message.playedTimestamp.high))) - return "playedTimestamp: integer|Long expected"; - if (message.pendingDeviceJid != null && message.hasOwnProperty("pendingDeviceJid")) { - if (!Array.isArray(message.pendingDeviceJid)) - return "pendingDeviceJid: array expected"; - for (var i = 0; i < message.pendingDeviceJid.length; ++i) - if (!$util.isString(message.pendingDeviceJid[i])) - return "pendingDeviceJid: string[] expected"; - } - if (message.deliveredDeviceJid != null && message.hasOwnProperty("deliveredDeviceJid")) { - if (!Array.isArray(message.deliveredDeviceJid)) - return "deliveredDeviceJid: array expected"; - for (var i = 0; i < message.deliveredDeviceJid.length; ++i) - if (!$util.isString(message.deliveredDeviceJid[i])) - return "deliveredDeviceJid: string[] expected"; - } - return null; - }; - - /** - * Creates a UserReceipt message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.UserReceipt - * @static - * @param {Object.} object Plain object - * @returns {proto.UserReceipt} UserReceipt - */ - UserReceipt.fromObject = function fromObject(object) { - if (object instanceof $root.proto.UserReceipt) - return object; - var message = new $root.proto.UserReceipt(); - if (object.userJid != null) - message.userJid = String(object.userJid); - if (object.receiptTimestamp != null) - if ($util.Long) - (message.receiptTimestamp = $util.Long.fromValue(object.receiptTimestamp)).unsigned = false; - else if (typeof object.receiptTimestamp === "string") - message.receiptTimestamp = parseInt(object.receiptTimestamp, 10); - else if (typeof object.receiptTimestamp === "number") - message.receiptTimestamp = object.receiptTimestamp; - else if (typeof object.receiptTimestamp === "object") - message.receiptTimestamp = new $util.LongBits(object.receiptTimestamp.low >>> 0, object.receiptTimestamp.high >>> 0).toNumber(); - if (object.readTimestamp != null) - if ($util.Long) - (message.readTimestamp = $util.Long.fromValue(object.readTimestamp)).unsigned = false; - else if (typeof object.readTimestamp === "string") - message.readTimestamp = parseInt(object.readTimestamp, 10); - else if (typeof object.readTimestamp === "number") - message.readTimestamp = object.readTimestamp; - else if (typeof object.readTimestamp === "object") - message.readTimestamp = new $util.LongBits(object.readTimestamp.low >>> 0, object.readTimestamp.high >>> 0).toNumber(); - if (object.playedTimestamp != null) - if ($util.Long) - (message.playedTimestamp = $util.Long.fromValue(object.playedTimestamp)).unsigned = false; - else if (typeof object.playedTimestamp === "string") - message.playedTimestamp = parseInt(object.playedTimestamp, 10); - else if (typeof object.playedTimestamp === "number") - message.playedTimestamp = object.playedTimestamp; - else if (typeof object.playedTimestamp === "object") - message.playedTimestamp = new $util.LongBits(object.playedTimestamp.low >>> 0, object.playedTimestamp.high >>> 0).toNumber(); - if (object.pendingDeviceJid) { - if (!Array.isArray(object.pendingDeviceJid)) - throw TypeError(".proto.UserReceipt.pendingDeviceJid: array expected"); - message.pendingDeviceJid = []; - for (var i = 0; i < object.pendingDeviceJid.length; ++i) - message.pendingDeviceJid[i] = String(object.pendingDeviceJid[i]); - } - if (object.deliveredDeviceJid) { - if (!Array.isArray(object.deliveredDeviceJid)) - throw TypeError(".proto.UserReceipt.deliveredDeviceJid: array expected"); - message.deliveredDeviceJid = []; - for (var i = 0; i < object.deliveredDeviceJid.length; ++i) - message.deliveredDeviceJid[i] = String(object.deliveredDeviceJid[i]); - } - return message; - }; - - /** - * Creates a plain object from a UserReceipt message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.UserReceipt - * @static - * @param {proto.UserReceipt} message UserReceipt - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - UserReceipt.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) { - object.pendingDeviceJid = []; - object.deliveredDeviceJid = []; - } - if (options.defaults) { - object.userJid = ""; - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.receiptTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.receiptTimestamp = options.longs === String ? "0" : 0; - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.readTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.readTimestamp = options.longs === String ? "0" : 0; - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.playedTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.playedTimestamp = options.longs === String ? "0" : 0; - } - if (message.userJid != null && message.hasOwnProperty("userJid")) - object.userJid = message.userJid; - if (message.receiptTimestamp != null && message.hasOwnProperty("receiptTimestamp")) - if (typeof message.receiptTimestamp === "number") - object.receiptTimestamp = options.longs === String ? String(message.receiptTimestamp) : message.receiptTimestamp; - else - object.receiptTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.receiptTimestamp) : options.longs === Number ? new $util.LongBits(message.receiptTimestamp.low >>> 0, message.receiptTimestamp.high >>> 0).toNumber() : message.receiptTimestamp; - if (message.readTimestamp != null && message.hasOwnProperty("readTimestamp")) - if (typeof message.readTimestamp === "number") - object.readTimestamp = options.longs === String ? String(message.readTimestamp) : message.readTimestamp; - else - object.readTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.readTimestamp) : options.longs === Number ? new $util.LongBits(message.readTimestamp.low >>> 0, message.readTimestamp.high >>> 0).toNumber() : message.readTimestamp; - if (message.playedTimestamp != null && message.hasOwnProperty("playedTimestamp")) - if (typeof message.playedTimestamp === "number") - object.playedTimestamp = options.longs === String ? String(message.playedTimestamp) : message.playedTimestamp; - else - object.playedTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.playedTimestamp) : options.longs === Number ? new $util.LongBits(message.playedTimestamp.low >>> 0, message.playedTimestamp.high >>> 0).toNumber() : message.playedTimestamp; - if (message.pendingDeviceJid && message.pendingDeviceJid.length) { - object.pendingDeviceJid = []; - for (var j = 0; j < message.pendingDeviceJid.length; ++j) - object.pendingDeviceJid[j] = message.pendingDeviceJid[j]; - } - if (message.deliveredDeviceJid && message.deliveredDeviceJid.length) { - object.deliveredDeviceJid = []; - for (var j = 0; j < message.deliveredDeviceJid.length; ++j) - object.deliveredDeviceJid[j] = message.deliveredDeviceJid[j]; - } - return object; - }; - - /** - * Converts this UserReceipt to JSON. - * @function toJSON - * @memberof proto.UserReceipt - * @instance - * @returns {Object.} JSON object - */ - UserReceipt.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return UserReceipt; + return MessageKey; })(); proto.PhotoChange = (function() { @@ -29260,7 +46647,6 @@ $root.proto = (function() { * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeralAllowGroupMembers] WebFeatures ephemeralAllowGroupMembers * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeral24HDuration] WebFeatures ephemeral24HDuration * @property {proto.WebFeatures.WebFeaturesFlag|null} [mdForceUpgrade] WebFeatures mdForceUpgrade - * @property {proto.WebFeatures.WebFeaturesFlag|null} [disappearingMode] WebFeatures disappearingMode */ /** @@ -29614,14 +47000,6 @@ $root.proto = (function() { */ WebFeatures.prototype.mdForceUpgrade = 0; - /** - * WebFeatures disappearingMode. - * @member {proto.WebFeatures.WebFeaturesFlag} disappearingMode - * @memberof proto.WebFeatures - * @instance - */ - WebFeatures.prototype.disappearingMode = 0; - /** * Creates a new WebFeatures instance using the specified properties. * @function create @@ -29730,8 +47108,6 @@ $root.proto = (function() { writer.uint32(/* id 45, wireType 0 =*/360).int32(message.ephemeral24HDuration); if (message.mdForceUpgrade != null && Object.hasOwnProperty.call(message, "mdForceUpgrade")) writer.uint32(/* id 46, wireType 0 =*/368).int32(message.mdForceUpgrade); - if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode")) - writer.uint32(/* id 47, wireType 0 =*/376).int32(message.disappearingMode); return writer; }; @@ -29892,9 +47268,6 @@ $root.proto = (function() { case 46: message.mdForceUpgrade = reader.int32(); break; - case 47: - message.disappearingMode = reader.int32(); - break; default: reader.skipType(tag & 7); break; @@ -30350,16 +47723,6 @@ $root.proto = (function() { case 3: break; } - if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) - switch (message.disappearingMode) { - default: - return "disappearingMode: enum value expected"; - case 0: - case 1: - case 2: - case 3: - break; - } return null; }; @@ -31131,24 +48494,6 @@ $root.proto = (function() { message.mdForceUpgrade = 3; break; } - switch (object.disappearingMode) { - case "NOT_STARTED": - case 0: - message.disappearingMode = 0; - break; - case "FORCE_UPGRADE": - case 1: - message.disappearingMode = 1; - break; - case "DEVELOPMENT": - case 2: - message.disappearingMode = 2; - break; - case "PRODUCTION": - case 3: - message.disappearingMode = 3; - break; - } return message; }; @@ -31208,7 +48553,6 @@ $root.proto = (function() { object.ephemeralAllowGroupMembers = options.enums === String ? "NOT_STARTED" : 0; object.ephemeral24HDuration = options.enums === String ? "NOT_STARTED" : 0; object.mdForceUpgrade = options.enums === String ? "NOT_STARTED" : 0; - object.disappearingMode = options.enums === String ? "NOT_STARTED" : 0; } if (message.labelsDisplay != null && message.hasOwnProperty("labelsDisplay")) object.labelsDisplay = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.labelsDisplay] : message.labelsDisplay; @@ -31294,8 +48638,6 @@ $root.proto = (function() { object.ephemeral24HDuration = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.ephemeral24HDuration] : message.ephemeral24HDuration; if (message.mdForceUpgrade != null && message.hasOwnProperty("mdForceUpgrade")) object.mdForceUpgrade = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.mdForceUpgrade] : message.mdForceUpgrade; - if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) - object.disappearingMode = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.disappearingMode] : message.disappearingMode; return object; }; @@ -32784,7 +50126,6 @@ $root.proto = (function() { * @property {string|null} [verifiedBizName] WebMessageInfo verifiedBizName * @property {proto.IMediaData|null} [mediaData] WebMessageInfo mediaData * @property {proto.IPhotoChange|null} [photoChange] WebMessageInfo photoChange - * @property {Array.|null} [userReceipt] WebMessageInfo userReceipt */ /** @@ -32798,7 +50139,6 @@ $root.proto = (function() { function WebMessageInfo(properties) { this.messageStubParameters = []; this.labels = []; - this.userReceipt = []; if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -33045,14 +50385,6 @@ $root.proto = (function() { */ WebMessageInfo.prototype.photoChange = null; - /** - * WebMessageInfo userReceipt. - * @member {Array.} userReceipt - * @memberof proto.WebMessageInfo - * @instance - */ - WebMessageInfo.prototype.userReceipt = $util.emptyArray; - /** * Creates a new WebMessageInfo instance using the specified properties. * @function create @@ -33138,9 +50470,6 @@ $root.proto = (function() { $root.proto.MediaData.encode(message.mediaData, writer.uint32(/* id 38, wireType 2 =*/306).fork()).ldelim(); if (message.photoChange != null && Object.hasOwnProperty.call(message, "photoChange")) $root.proto.PhotoChange.encode(message.photoChange, writer.uint32(/* id 39, wireType 2 =*/314).fork()).ldelim(); - if (message.userReceipt != null && message.userReceipt.length) - for (var i = 0; i < message.userReceipt.length; ++i) - $root.proto.UserReceipt.encode(message.userReceipt[i], writer.uint32(/* id 40, wireType 2 =*/322).fork()).ldelim(); return writer; }; @@ -33269,11 +50598,6 @@ $root.proto = (function() { case 39: message.photoChange = $root.proto.PhotoChange.decode(reader, reader.uint32()); break; - case 40: - if (!(message.userReceipt && message.userReceipt.length)) - message.userReceipt = []; - message.userReceipt.push($root.proto.UserReceipt.decode(reader, reader.uint32())); - break; default: reader.skipType(tag & 7); break; @@ -33500,7 +50824,6 @@ $root.proto = (function() { case 127: case 128: case 129: - case 130: break; } if (message.clearMedia != null && message.hasOwnProperty("clearMedia")) @@ -33573,15 +50896,6 @@ $root.proto = (function() { if (error) return "photoChange." + error; } - if (message.userReceipt != null && message.hasOwnProperty("userReceipt")) { - if (!Array.isArray(message.userReceipt)) - return "userReceipt: array expected"; - for (var i = 0; i < message.userReceipt.length; ++i) { - var error = $root.proto.UserReceipt.verify(message.userReceipt[i]); - if (error) - return "userReceipt." + error; - } - } return null; }; @@ -34193,10 +51507,6 @@ $root.proto = (function() { case 129: message.messageStubType = 129; break; - case "DISAPPEARING_MODE": - case 130: - message.messageStubType = 130; - break; } if (object.clearMedia != null) message.clearMedia = Boolean(object.clearMedia); @@ -34276,16 +51586,6 @@ $root.proto = (function() { throw TypeError(".proto.WebMessageInfo.photoChange: object expected"); message.photoChange = $root.proto.PhotoChange.fromObject(object.photoChange); } - if (object.userReceipt) { - if (!Array.isArray(object.userReceipt)) - throw TypeError(".proto.WebMessageInfo.userReceipt: array expected"); - message.userReceipt = []; - for (var i = 0; i < object.userReceipt.length; ++i) { - if (typeof object.userReceipt[i] !== "object") - throw TypeError(".proto.WebMessageInfo.userReceipt: object expected"); - message.userReceipt[i] = $root.proto.UserReceipt.fromObject(object.userReceipt[i]); - } - } return message; }; @@ -34305,7 +51605,6 @@ $root.proto = (function() { if (options.arrays || options.defaults) { object.messageStubParameters = []; object.labels = []; - object.userReceipt = []; } if (options.defaults) { object.key = null; @@ -34430,11 +51729,6 @@ $root.proto = (function() { object.mediaData = $root.proto.MediaData.toObject(message.mediaData, options); if (message.photoChange != null && message.hasOwnProperty("photoChange")) object.photoChange = $root.proto.PhotoChange.toObject(message.photoChange, options); - if (message.userReceipt && message.userReceipt.length) { - object.userReceipt = []; - for (var j = 0; j < message.userReceipt.length; ++j) - object.userReceipt[j] = $root.proto.UserReceipt.toObject(message.userReceipt[j], options); - } return object; }; @@ -34605,7 +51899,6 @@ $root.proto = (function() { * @property {number} BIZ_PRIVACY_MODE_INIT_BSP=127 BIZ_PRIVACY_MODE_INIT_BSP value * @property {number} BIZ_PRIVACY_MODE_TO_FB=128 BIZ_PRIVACY_MODE_TO_FB value * @property {number} BIZ_PRIVACY_MODE_TO_BSP=129 BIZ_PRIVACY_MODE_TO_BSP value - * @property {number} DISAPPEARING_MODE=130 DISAPPEARING_MODE value */ WebMessageInfo.WebMessageInfoStubType = (function() { var valuesById = {}, values = Object.create(valuesById); @@ -34739,7 +52032,6 @@ $root.proto = (function() { values[valuesById[127] = "BIZ_PRIVACY_MODE_INIT_BSP"] = 127; values[valuesById[128] = "BIZ_PRIVACY_MODE_TO_FB"] = 128; values[valuesById[129] = "BIZ_PRIVACY_MODE_TO_BSP"] = 129; - values[valuesById[130] = "DISAPPEARING_MODE"] = 130; return values; })(); diff --git a/WASignalGroup/ciphertext_message.js b/WASignalGroup/ciphertext_message.js new file mode 100644 index 0000000..f9bb771 --- /dev/null +++ b/WASignalGroup/ciphertext_message.js @@ -0,0 +1,16 @@ +class CiphertextMessage { + UNSUPPORTED_VERSION = 1; + + CURRENT_VERSION = 3; + + WHISPER_TYPE = 2; + + PREKEY_TYPE = 3; + + SENDERKEY_TYPE = 4; + + SENDERKEY_DISTRIBUTION_TYPE = 5; + + ENCRYPTED_MESSAGE_OVERHEAD = 53; +} +module.exports = CiphertextMessage; \ No newline at end of file diff --git a/WASignalGroup/group.proto b/WASignalGroup/group.proto new file mode 100644 index 0000000..a83c11e --- /dev/null +++ b/WASignalGroup/group.proto @@ -0,0 +1,41 @@ +package groupproto; + +message SenderKeyMessage { + optional uint32 id = 1; + optional uint32 iteration = 2; + optional bytes ciphertext = 3; + } + + message SenderKeyDistributionMessage { + optional uint32 id = 1; + optional uint32 iteration = 2; + optional bytes chainKey = 3; + optional bytes signingKey = 4; + } + + +message SenderKeyStateStructure { + message SenderChainKey { + optional uint32 iteration = 1; + optional bytes seed = 2; + } + + message SenderMessageKey { + optional uint32 iteration = 1; + optional bytes seed = 2; + } + + message SenderSigningKey { + optional bytes public = 1; + optional bytes private = 2; + } + + optional uint32 senderKeyId = 1; + optional SenderChainKey senderChainKey = 2; + optional SenderSigningKey senderSigningKey = 3; + repeated SenderMessageKey senderMessageKeys = 4; +} + +message SenderKeyRecordStructure { + repeated SenderKeyStateStructure senderKeyStates = 1; +} \ No newline at end of file diff --git a/WASignalGroup/group_cipher.js b/WASignalGroup/group_cipher.js new file mode 100644 index 0000000..a10de25 --- /dev/null +++ b/WASignalGroup/group_cipher.js @@ -0,0 +1,106 @@ +const SenderKeyMessage = require('./sender_key_message'); +const crypto = require('libsignal/src/crypto'); + +class GroupCipher { + constructor(senderKeyStore, senderKeyName) { + this.senderKeyStore = senderKeyStore; + this.senderKeyName = senderKeyName; + } + + async encrypt(paddedPlaintext) { + try { + const record = await this.senderKeyStore.loadSenderKey(this.senderKeyName); + const senderKeyState = record.getSenderKeyState(); + const senderKey = senderKeyState.getSenderChainKey().getSenderMessageKey(); + + const ciphertext = await this.getCipherText( + senderKey.getIv(), + senderKey.getCipherKey(), + paddedPlaintext + ); + + const senderKeyMessage = new SenderKeyMessage( + senderKeyState.getKeyId(), + senderKey.getIteration(), + ciphertext, + senderKeyState.getSigningKeyPrivate() + ); + senderKeyState.setSenderChainKey(senderKeyState.getSenderChainKey().getNext()); + await this.senderKeyStore.storeSenderKey(this.senderKeyName, record); + return senderKeyMessage.serialize(); + } catch (e) { + //console.log(e.stack); + throw new Error('NoSessionException'); + } + } + + async decrypt(senderKeyMessageBytes) { + const record = await this.senderKeyStore.loadSenderKey(this.senderKeyName); + if (!record) throw new Error(`No sender key for: ${this.senderKeyName}`); + + const senderKeyMessage = new SenderKeyMessage(null, null, null, null, senderKeyMessageBytes); + + const senderKeyState = record.getSenderKeyState(senderKeyMessage.getKeyId()); + //senderKeyMessage.verifySignature(senderKeyState.getSigningKeyPublic()); + const senderKey = this.getSenderKey(senderKeyState, senderKeyMessage.getIteration()); + // senderKeyState.senderKeyStateStructure.senderSigningKey.private = + + const plaintext = await this.getPlainText( + senderKey.getIv(), + senderKey.getCipherKey(), + senderKeyMessage.getCipherText() + ); + + await this.senderKeyStore.storeSenderKey(this.senderKeyName, record); + + return plaintext; + } + + getSenderKey(senderKeyState, iteration) { + let senderChainKey = senderKeyState.getSenderChainKey(); + if (senderChainKey.getIteration() > iteration) { + if (senderKeyState.hasSenderMessageKey(iteration)) { + return senderKeyState.removeSenderMessageKey(iteration); + } + throw new Error( + `Received message with old counter: ${senderChainKey.getIteration()}, ${iteration}` + ); + } + + if (senderChainKey.getIteration() - iteration > 2000) { + throw new Error('Over 2000 messages into the future!'); + } + + while (senderChainKey.getIteration() < iteration) { + senderKeyState.addSenderMessageKey(senderChainKey.getSenderMessageKey()); + senderChainKey = senderChainKey.getNext(); + } + + senderKeyState.setSenderChainKey(senderChainKey.getNext()); + return senderChainKey.getSenderMessageKey(); + } + + getPlainText(iv, key, ciphertext) { + try { + const plaintext = crypto.decrypt(key, ciphertext, iv); + return plaintext; + } catch (e) { + //console.log(e.stack); + throw new Error('InvalidMessageException'); + } + } + + getCipherText(iv, key, plaintext) { + try { + iv = typeof iv === 'string' ? Buffer.from(iv, 'base64') : iv; + key = typeof key === 'string' ? Buffer.from(key, 'base64') : key; + const crypted = crypto.encrypt(key, Buffer.from(plaintext), iv); + return crypted; + } catch (e) { + //console.log(e.stack); + throw new Error('InvalidMessageException'); + } + } +} + +module.exports = GroupCipher; \ No newline at end of file diff --git a/WASignalGroup/group_session_builder.js b/WASignalGroup/group_session_builder.js new file mode 100644 index 0000000..60c152f --- /dev/null +++ b/WASignalGroup/group_session_builder.js @@ -0,0 +1,51 @@ +//const utils = require('../../common/utils'); +const SenderKeyDistributionMessage = require('./sender_key_distribution_message'); + +const keyhelper = require("libsignal/src/keyhelper"); +class GroupSessionBuilder { + constructor(senderKeyStore) { + this.senderKeyStore = senderKeyStore; + } + + async process(senderKeyName, senderKeyDistributionMessage) { + //console.log('GroupSessionBuilder process', senderKeyName, senderKeyDistributionMessage); + const senderKeyRecord = await this.senderKeyStore.loadSenderKey(senderKeyName); + senderKeyRecord.addSenderKeyState( + senderKeyDistributionMessage.getId(), + senderKeyDistributionMessage.getIteration(), + senderKeyDistributionMessage.getChainKey(), + senderKeyDistributionMessage.getSignatureKey() + ); + await this.senderKeyStore.storeSenderKey(senderKeyName, senderKeyRecord); + } + + // [{"senderKeyId":1742199468,"senderChainKey":{"iteration":0,"seed":"yxMY9VFQcXEP34olRAcGCtsgx1XoKsHfDIh+1ea4HAQ="},"senderSigningKey":{"public":""}}] + async create(senderKeyName) { + try { + const senderKeyRecord = await this.senderKeyStore.loadSenderKey(senderKeyName); + //console.log('GroupSessionBuilder create session', senderKeyName, senderKeyRecord); + + if (senderKeyRecord.isEmpty()) { + const keyId = keyhelper.generateSenderKeyId(); + const senderKey = keyhelper.generateSenderKey(); + const signingKey = keyhelper.generateSenderSigningKey(); + + senderKeyRecord.setSenderKeyState(keyId, 0, senderKey, signingKey); + await this.senderKeyStore.storeSenderKey(senderKeyName, senderKeyRecord); + } + + const state = senderKeyRecord.getSenderKeyState(); + + return new SenderKeyDistributionMessage( + state.getKeyId(), + state.getSenderChainKey().getIteration(), + state.getSenderChainKey().getSeed(), + state.getSigningKeyPublic() + ); + } catch (e) { + //console.log(e.stack); + throw new Error(e); + } + } +} +module.exports = GroupSessionBuilder; \ No newline at end of file diff --git a/WASignalGroup/index.js b/WASignalGroup/index.js new file mode 100644 index 0000000..69b935d --- /dev/null +++ b/WASignalGroup/index.js @@ -0,0 +1,5 @@ +module.exports.GroupSessionBuilder = require('./group_session_builder') +module.exports.SenderKeyDistributionMessage = require('./sender_key_distribution_message') +module.exports.SenderKeyRecord = require('./sender_key_record') +module.exports.SenderKeyName = require('./sender_key_name') +module.exports.GroupCipher = require('./group_cipher') \ No newline at end of file diff --git a/WASignalGroup/protobufs.js b/WASignalGroup/protobufs.js new file mode 100644 index 0000000..797bd73 --- /dev/null +++ b/WASignalGroup/protobufs.js @@ -0,0 +1,13 @@ +const path = require('path'); +const protobuf = require('protobufjs'); + +const protodir = path.resolve(__dirname); +const group = protobuf.loadSync(path.join(protodir, 'group.proto')).lookup('groupproto'); + +module.exports = { + SenderKeyDistributionMessage: group.lookup('SenderKeyDistributionMessage'), + SenderKeyMessage: group.lookup('SenderKeyMessage'), + SenderKeyStateStructure: group.lookup('SenderKeyStateStructure'), + SenderChainKey: group.lookup('SenderChainKey'), + SenderSigningKey: group.lookup('SenderSigningKey'), +}; diff --git a/WASignalGroup/readme.md b/WASignalGroup/readme.md new file mode 100644 index 0000000..8290d9c --- /dev/null +++ b/WASignalGroup/readme.md @@ -0,0 +1,6 @@ +# Signal-Group + +This contains the code to decrypt/encrypt WA group messages. +Originally from [pokearaujo/libsignal-node](https://github.com/pokearaujo/libsignal-node) + +The code has been moved outside the signal package as I felt it didn't belong in ths signal package, as it isn't inherently a part of signal but of WA. \ No newline at end of file diff --git a/WASignalGroup/sender_chain_key.js b/WASignalGroup/sender_chain_key.js new file mode 100644 index 0000000..9a3125b --- /dev/null +++ b/WASignalGroup/sender_chain_key.js @@ -0,0 +1,50 @@ +const SenderMessageKey = require('./sender_message_key'); +//const HKDF = require('./hkdf'); +const crypto = require('libsignal/src/crypto'); + +class SenderChainKey { + MESSAGE_KEY_SEED = Buffer.from([0x01]); + + CHAIN_KEY_SEED = Buffer.from([0x02]); + + iteration = 0; + + chainKey = Buffer.alloc(0); + + constructor(iteration, chainKey) { + this.iteration = iteration; + this.chainKey = chainKey; + } + + getIteration() { + return this.iteration; + } + + getSenderMessageKey() { + return new SenderMessageKey( + this.iteration, + this.getDerivative(this.MESSAGE_KEY_SEED, this.chainKey) + ); + } + + getNext() { + return new SenderChainKey( + this.iteration + 1, + this.getDerivative(this.CHAIN_KEY_SEED, this.chainKey) + ); + } + + getSeed() { + return typeof this.chainKey === 'string' ? Buffer.from(this.chainKey, 'base64') : this.chainKey; + } + + getDerivative(seed, key) { + key = typeof key === 'string' ? Buffer.from(key, 'base64') : key; + const hash = crypto.calculateMAC(key, seed); + //const hash = new Hash().hmac_hash(key, seed, 'sha256', ''); + + return hash; + } +} + +module.exports = SenderChainKey; \ No newline at end of file diff --git a/WASignalGroup/sender_key_distribution_message.js b/WASignalGroup/sender_key_distribution_message.js new file mode 100644 index 0000000..9c1400f --- /dev/null +++ b/WASignalGroup/sender_key_distribution_message.js @@ -0,0 +1,78 @@ +const CiphertextMessage = require('./ciphertext_message'); +const protobufs = require('./protobufs'); + +class SenderKeyDistributionMessage extends CiphertextMessage { + constructor( + id = null, + iteration = null, + chainKey = null, + signatureKey = null, + serialized = null + ) { + super(); + if (serialized) { + try { + const version = serialized[0]; + const message = serialized.slice(1); + + const distributionMessage = protobufs.SenderKeyDistributionMessage.decode( + message + ).toJSON(); + this.serialized = serialized; + this.id = distributionMessage.id; + this.iteration = distributionMessage.iteration; + this.chainKey = distributionMessage.chainKey; + this.signatureKey = distributionMessage.signingKey; + } catch (e) { + throw new Error(e); + } + } else { + const version = this.intsToByteHighAndLow(this.CURRENT_VERSION, this.CURRENT_VERSION); + this.id = id; + this.iteration = iteration; + this.chainKey = chainKey; + this.signatureKey = signatureKey; + const message = protobufs.SenderKeyDistributionMessage.encode( + protobufs.SenderKeyDistributionMessage.create({ + id, + iteration, + chainKey, + signingKey: this.signatureKey, + }) + ).finish(); + this.serialized = Buffer.concat([Buffer.from([version]), message]); + } + } + + intsToByteHighAndLow(highValue, lowValue) { + return (((highValue << 4) | lowValue) & 0xff) % 256; + } + + serialize() { + return this.serialized; + } + + getType() { + return this.SENDERKEY_DISTRIBUTION_TYPE; + } + + getIteration() { + return this.iteration; + } + + getChainKey() { + return typeof this.chainKey === 'string' ? Buffer.from(this.chainKey, 'base64') : this.chainKey; + } + + getSignatureKey() { + return typeof this.signatureKey === 'string' + ? Buffer.from(this.signatureKey, 'base64') + : this.signatureKey; + } + + getId() { + return this.id; + } +} + +module.exports = SenderKeyDistributionMessage; \ No newline at end of file diff --git a/WASignalGroup/sender_key_message.js b/WASignalGroup/sender_key_message.js new file mode 100644 index 0000000..80683a6 --- /dev/null +++ b/WASignalGroup/sender_key_message.js @@ -0,0 +1,92 @@ +const CiphertextMessage = require('./ciphertext_message'); +const curve = require('libsignal/src/curve'); +const protobufs = require('./protobufs'); + +class SenderKeyMessage extends CiphertextMessage { + SIGNATURE_LENGTH = 64; + + constructor( + keyId = null, + iteration = null, + ciphertext = null, + signatureKey = null, + serialized = null + ) { + super(); + if (serialized) { + const version = serialized[0]; + const message = serialized.slice(1, serialized.length - this.SIGNATURE_LENGTH); + const signature = serialized.slice(-1 * this.SIGNATURE_LENGTH); + const senderKeyMessage = protobufs.SenderKeyMessage.decode(message).toJSON(); + senderKeyMessage.ciphertext = Buffer.from(senderKeyMessage.ciphertext, 'base64'); + + this.serialized = serialized; + this.messageVersion = (version & 0xff) >> 4; + + this.keyId = senderKeyMessage.id; + this.iteration = senderKeyMessage.iteration; + this.ciphertext = senderKeyMessage.ciphertext; + this.signature = signature; + } else { + const version = (((this.CURRENT_VERSION << 4) | this.CURRENT_VERSION) & 0xff) % 256; + ciphertext = Buffer.from(ciphertext); // .toString('base64'); + const message = protobufs.SenderKeyMessage.encode( + protobufs.SenderKeyMessage.create({ + id: keyId, + iteration, + ciphertext, + }) + ).finish(); + + const signature = this.getSignature( + signatureKey, + Buffer.concat([Buffer.from([version]), message]) + ); + this.serialized = Buffer.concat([Buffer.from([version]), message, Buffer.from(signature)]); + this.messageVersion = this.CURRENT_VERSION; + this.keyId = keyId; + this.iteration = iteration; + this.ciphertext = ciphertext; + this.signature = signature; + } + } + + getKeyId() { + return this.keyId; + } + + getIteration() { + return this.iteration; + } + + getCipherText() { + return this.ciphertext; + } + + verifySignature(signatureKey) { + const part1 = this.serialized.slice(0, this.serialized.length - this.SIGNATURE_LENGTH + 1); + const part2 = this.serialized.slice(-1 * this.SIGNATURE_LENGTH); + const res = curve.verifySignature(signatureKey, part1, part2); + if (!res) throw new Error('Invalid signature!'); + } + + getSignature(signatureKey, serialized) { + const signature = Buffer.from( + curve.calculateSignature( + signatureKey, + serialized + ) + ); + return signature; + } + + serialize() { + return this.serialized; + } + + getType() { + return 4; + } +} + +module.exports = SenderKeyMessage; \ No newline at end of file diff --git a/WASignalGroup/sender_key_name.js b/WASignalGroup/sender_key_name.js new file mode 100644 index 0000000..e7f5290 --- /dev/null +++ b/WASignalGroup/sender_key_name.js @@ -0,0 +1,70 @@ +function isNull(str) { + return str === null || str.value === ''; +} + +/** + * java String hashCode 的实现 + * @param strKey + * @return intValue + */ +function intValue(num) { + const MAX_VALUE = 0x7fffffff; + const MIN_VALUE = -0x80000000; + if (num > MAX_VALUE || num < MIN_VALUE) { + // eslint-disable-next-line + return (num &= 0xffffffff); + } + return num; +} + +function hashCode(strKey) { + let hash = 0; + if (!isNull(strKey)) { + for (let i = 0; i < strKey.length; i++) { + hash = hash * 31 + strKey.charCodeAt(i); + hash = intValue(hash); + } + } + return hash; +} + +/** + * 将js页面的number类型转换为java的int类型 + * @param num + * @return intValue + */ + +class SenderKeyName { + constructor(groupId, sender) { + this.groupId = groupId; + this.sender = sender; + } + + getGroupId() { + return this.groupId; + } + + getSender() { + return this.sender; + } + + serialize() { + return `${this.groupId}::${this.sender.id}::${this.sender.deviceId}`; + } + + toString() { + return this.serialize(); + } + + equals(other) { + if (other === null) return false; + if (!(other instanceof SenderKeyName)) return false; + return this.groupId === other.groupId && this.sender.toString() === other.sender.toString(); + } + + hashCode() { + return hashCode(this.groupId) ^ hashCode(this.sender.toString()); + } +} + +module.exports = SenderKeyName; \ No newline at end of file diff --git a/WASignalGroup/sender_key_record.js b/WASignalGroup/sender_key_record.js new file mode 100644 index 0000000..e17f290 --- /dev/null +++ b/WASignalGroup/sender_key_record.js @@ -0,0 +1,54 @@ +const SenderKeyState = require('./sender_key_state'); + +class SenderKeyRecord { + MAX_STATES = 5; + + constructor(serialized) { + this.senderKeyStates = []; + + if (serialized) { + const list = serialized; + for (let i = 0; i < list.length; i++) { + const structure = list[i]; + this.senderKeyStates.push( + new SenderKeyState(null, null, null, null, null, null, structure) + ); + } + } + } + + isEmpty() { + return this.senderKeyStates.length === 0; + } + + getSenderKeyState(keyId) { + if (!keyId && this.senderKeyStates.length) return this.senderKeyStates[0]; + for (let i = 0; i < this.senderKeyStates.length; i++) { + const state = this.senderKeyStates[i]; + if (state.getKeyId() === keyId) { + return state; + } + } + throw new Error(`No keys for: ${keyId}`); + } + + addSenderKeyState(id, iteration, chainKey, signatureKey) { + this.senderKeyStates.push(new SenderKeyState(id, iteration, chainKey, null, signatureKey)); + } + + setSenderKeyState(id, iteration, chainKey, keyPair) { + this.senderKeyStates.length = 0; + this.senderKeyStates.push(new SenderKeyState(id, iteration, chainKey, keyPair)); + } + + serialize() { + const recordStructure = []; + for (let i = 0; i < this.senderKeyStates.length; i++) { + const senderKeyState = this.senderKeyStates[i]; + recordStructure.push(senderKeyState.getStructure()); + } + return recordStructure; + } + } + + module.exports = SenderKeyRecord; \ No newline at end of file diff --git a/WASignalGroup/sender_key_state.js b/WASignalGroup/sender_key_state.js new file mode 100644 index 0000000..c3e0fc9 --- /dev/null +++ b/WASignalGroup/sender_key_state.js @@ -0,0 +1,129 @@ +const SenderChainKey = require('./sender_chain_key'); +const SenderMessageKey = require('./sender_message_key'); + +const protobufs = require('./protobufs'); + +class SenderKeyState { + MAX_MESSAGE_KEYS = 2000; + + constructor( + id = null, + iteration = null, + chainKey = null, + signatureKeyPair = null, + signatureKeyPublic = null, + signatureKeyPrivate = null, + senderKeyStateStructure = null + ) { + if (senderKeyStateStructure) { + this.senderKeyStateStructure = senderKeyStateStructure; + } else { + if (signatureKeyPair) { + signatureKeyPublic = signatureKeyPair.public; + signatureKeyPrivate = signatureKeyPair.private; + } + + chainKey = typeof chainKey === 'string' ? Buffer.from(chainKey, 'base64') : chainKey; + this.senderKeyStateStructure = protobufs.SenderKeyStateStructure.create(); + const senderChainKeyStructure = protobufs.SenderChainKey.create(); + senderChainKeyStructure.iteration = iteration; + senderChainKeyStructure.seed = chainKey; + this.senderKeyStateStructure.senderChainKey = senderChainKeyStructure; + + const signingKeyStructure = protobufs.SenderSigningKey.create(); + signingKeyStructure.public = + typeof signatureKeyPublic === 'string' ? + Buffer.from(signatureKeyPublic, 'base64') : + signatureKeyPublic; + if (signatureKeyPrivate) { + signingKeyStructure.private = + typeof signatureKeyPrivate === 'string' ? + Buffer.from(signatureKeyPrivate, 'base64') : + signatureKeyPrivate; + } + this.senderKeyStateStructure.senderKeyId = id; + this.senderChainKey = senderChainKeyStructure; + this.senderKeyStateStructure.senderSigningKey = signingKeyStructure; + } + this.senderKeyStateStructure.senderMessageKeys = + this.senderKeyStateStructure.senderMessageKeys || []; + } + + SenderKeyState(senderKeyStateStructure) { + this.senderKeyStateStructure = senderKeyStateStructure; + } + + getKeyId() { + return this.senderKeyStateStructure.senderKeyId; + } + + getSenderChainKey() { + return new SenderChainKey( + this.senderKeyStateStructure.senderChainKey.iteration, + this.senderKeyStateStructure.senderChainKey.seed + ); + } + + setSenderChainKey(chainKey) { + const senderChainKeyStructure = protobufs.SenderChainKey.create({ + iteration: chainKey.getIteration(), + seed: chainKey.getSeed(), + }); + this.senderKeyStateStructure.senderChainKey = senderChainKeyStructure; + } + + getSigningKeyPublic() { + return typeof this.senderKeyStateStructure.senderSigningKey.public === 'string' ? + Buffer.from(this.senderKeyStateStructure.senderSigningKey.public, 'base64') : + this.senderKeyStateStructure.senderSigningKey.public; + } + + getSigningKeyPrivate() { + return typeof this.senderKeyStateStructure.senderSigningKey.private === 'string' ? + Buffer.from(this.senderKeyStateStructure.senderSigningKey.private, 'base64') : + this.senderKeyStateStructure.senderSigningKey.private; + } + + hasSenderMessageKey(iteration) { + const list = this.senderKeyStateStructure.senderMessageKeys; + for (let o = 0; o < list.length; o++) { + const senderMessageKey = list[o]; + if (senderMessageKey.iteration === iteration) return true; + } + return false; + } + + addSenderMessageKey(senderMessageKey) { + const senderMessageKeyStructure = protobufs.SenderKeyStateStructure.create({ + iteration: senderMessageKey.getIteration(), + seed: senderMessageKey.getSeed(), + }); + this.senderKeyStateStructure.senderMessageKeys.push(senderMessageKeyStructure); + + if (this.senderKeyStateStructure.senderMessageKeys.length > this.MAX_MESSAGE_KEYS) { + this.senderKeyStateStructure.senderMessageKeys.shift(); + } + } + + removeSenderMessageKey(iteration) { + let result = null; + + this.senderKeyStateStructure.senderMessageKeys = this.senderKeyStateStructure.senderMessageKeys.filter( + senderMessageKey => { + if (senderMessageKey.iteration === iteration) result = senderMessageKey; + return senderMessageKey.iteration !== iteration; + } + ); + + if (result != null) { + return new SenderMessageKey(result.iteration, result.seed); + } + return null; + } + + getStructure() { + return this.senderKeyStateStructure; + } +} + +module.exports = SenderKeyState; \ No newline at end of file diff --git a/WASignalGroup/sender_message_key.js b/WASignalGroup/sender_message_key.js new file mode 100644 index 0000000..7639704 --- /dev/null +++ b/WASignalGroup/sender_message_key.js @@ -0,0 +1,39 @@ +const { deriveSecrets } = require('libsignal/src/crypto'); +class SenderMessageKey { + iteration = 0; + + iv = Buffer.alloc(0); + + cipherKey = Buffer.alloc(0); + + seed = Buffer.alloc(0); + + constructor(iteration, seed) { + const derivative = deriveSecrets(seed, Buffer.alloc(32), Buffer.from('WhisperGroup')); + const keys = new Uint8Array(32); + keys.set(new Uint8Array(derivative[0].slice(16))); + keys.set(new Uint8Array(derivative[1].slice(0, 16)), 16); + this.iv = Buffer.from(derivative[0].slice(0, 16)); + this.cipherKey = Buffer.from(keys.buffer); + + this.iteration = iteration; + this.seed = seed; + } + + getIteration() { + return this.iteration; + } + + getIv() { + return this.iv; + } + + getCipherKey() { + return this.cipherKey; + } + + getSeed() { + return this.seed; + } +} +module.exports = SenderMessageKey; \ No newline at end of file diff --git a/package.json b/package.json index 1a277fd..06b5ebd 100644 --- a/package.json +++ b/package.json @@ -33,10 +33,9 @@ }, "dependencies": { "@hapi/boom": "^9.1.3", - "curve25519-js": "^0.0.4", - "futoin-hkdf": "^1.3.2", "got": "^11.8.1", "jimp": "^0.16.1", + "libsignal": "^2.0.1", "music-metadata": "^7.4.1", "pino": "^6.7.0", "protobufjs": "^6.10.1", @@ -48,7 +47,9 @@ }, "files": [ "lib/*", - "WAMessage/*" + "WAProto/*", + "WASignalGroup/*", + "WABinary/*" ], "devDependencies": { "@adiwajshing/keyed-db": "^0.2.4", @@ -57,7 +58,6 @@ "@types/node": "^14.6.2", "@types/pino": "^6.3.2", "@types/ws": "^7.2.6", - "https-proxy-agent": "^5.0.0", "jest": "^27.0.6", "qrcode-terminal": "^0.12.0", "ts-jest": "^27.0.3", diff --git a/src/BinaryNode/decode.ts b/src/BinaryNode/decode.ts deleted file mode 100644 index 7f26239..0000000 --- a/src/BinaryNode/decode.ts +++ /dev/null @@ -1,204 +0,0 @@ -import { proto } from '../../WAMessage' -import { BinaryNode, DoubleByteTokens, SingleByteTokens, Tags } from './types' - -function decode(buffer: Buffer, makeNode: () => T, indexRef: { index: number }) { - - const checkEOS = (length: number) => { - if (indexRef.index + length > buffer.length) { - throw new Error('end of stream') - } - } - const next = () => { - const value = buffer[indexRef.index] - indexRef.index += 1 - return value - } - const readByte = () => { - checkEOS(1) - return next() - } - const readStringFromChars = (length: number) => { - checkEOS(length) - const value = buffer.slice(indexRef.index, indexRef.index + length) - - indexRef.index += length - return value.toString('utf-8') - } - const readBytes = (n: number) => { - checkEOS(n) - const value = buffer.slice(indexRef.index, indexRef.index + n) - indexRef.index += n - return value - } - const readInt = (n: number, littleEndian = false) => { - checkEOS(n) - let val = 0 - for (let i = 0; i < n; i++) { - const shift = littleEndian ? i : n - 1 - i - val |= next() << (shift * 8) - } - return val - } - const readInt20 = () => { - checkEOS(3) - return ((next() & 15) << 16) + (next() << 8) + next() - } - const unpackHex = (value: number) => { - if (value >= 0 && value < 16) { - return value < 10 ? '0'.charCodeAt(0) + value : 'A'.charCodeAt(0) + value - 10 - } - throw new Error('invalid hex: ' + value) - } - const unpackNibble = (value: number) => { - if (value >= 0 && value <= 9) { - return '0'.charCodeAt(0) + value - } - switch (value) { - case 10: - return '-'.charCodeAt(0) - case 11: - return '.'.charCodeAt(0) - case 15: - return '\0'.charCodeAt(0) - default: - throw new Error('invalid nibble: ' + value) - } - } - const unpackByte = (tag: number, value: number) => { - if (tag === Tags.NIBBLE_8) { - return unpackNibble(value) - } else if (tag === Tags.HEX_8) { - return unpackHex(value) - } else { - throw new Error('unknown tag: ' + tag) - } - } - const readPacked8 = (tag: number) => { - const startByte = readByte() - let value = '' - - for (let i = 0; i < (startByte & 127); i++) { - const curByte = readByte() - value += String.fromCharCode(unpackByte(tag, (curByte & 0xf0) >> 4)) - value += String.fromCharCode(unpackByte(tag, curByte & 0x0f)) - } - if (startByte >> 7 !== 0) { - value = value.slice(0, -1) - } - return value - } - const isListTag = (tag: number) => { - return tag === Tags.LIST_EMPTY || tag === Tags.LIST_8 || tag === Tags.LIST_16 - } - const readListSize = (tag: number) => { - switch (tag) { - case Tags.LIST_EMPTY: - return 0 - case Tags.LIST_8: - return readByte() - case Tags.LIST_16: - return readInt(2) - default: - throw new Error('invalid tag for list size: ' + tag) - } - } - const getToken = (index: number) => { - if (index < 3 || index >= SingleByteTokens.length) { - throw new Error('invalid token index: ' + index) - } - return SingleByteTokens[index] - } - const readString = (tag: number) => { - if (tag >= 3 && tag <= 235) { - const token = getToken(tag) - return token// === 's.whatsapp.net' ? 'c.us' : token - } - - switch (tag) { - case Tags.DICTIONARY_0: - case Tags.DICTIONARY_1: - case Tags.DICTIONARY_2: - case Tags.DICTIONARY_3: - return getTokenDouble(tag - Tags.DICTIONARY_0, readByte()) - case Tags.LIST_EMPTY: - return null - case Tags.BINARY_8: - return readStringFromChars(readByte()) - case Tags.BINARY_20: - return readStringFromChars(readInt20()) - case Tags.BINARY_32: - return readStringFromChars(readInt(4)) - case Tags.JID_PAIR: - const i = readString(readByte()) - const j = readString(readByte()) - if (typeof i === 'string' && j) { - return i + '@' + j - } - throw new Error('invalid jid pair: ' + i + ', ' + j) - case Tags.HEX_8: - case Tags.NIBBLE_8: - return readPacked8(tag) - default: - throw new Error('invalid string with tag: ' + tag) - } - } - const readList = (tag: number) => ( - [...new Array(readListSize(tag))].map(() => decode(buffer, makeNode, indexRef)) - ) - const getTokenDouble = (index1: number, index2: number) => { - const n = 256 * index1 + index2 - if (n < 0 || n > DoubleByteTokens.length) { - throw new Error('invalid double token index: ' + n) - } - return DoubleByteTokens[n] - } - const node = makeNode() - const listSize = readListSize(readByte()) - const descrTag = readByte() - if (descrTag === Tags.STREAM_END) { - throw new Error('unexpected stream end') - } - node.header = readString(descrTag) - if (listSize === 0 || !node.header) { - throw new Error('invalid node') - } - // read the attributes in - const attributesLength = (listSize - 1) >> 1 - for (let i = 0; i < attributesLength; i++) { - const key = readString(readByte()) - const b = readByte() - - node.attributes[key] = readString(b) - } - - if (listSize % 2 === 0) { - const tag = readByte() - if (isListTag(tag)) { - node.data = readList(tag) - } else { - let decoded: Buffer | string - switch (tag) { - case Tags.BINARY_8: - decoded = readBytes(readByte()) - break - case Tags.BINARY_20: - decoded = readBytes(readInt20()) - break - case Tags.BINARY_32: - decoded = readBytes(readInt(4)) - break - default: - decoded = readString(tag) - break - } - - if (node.header === 'message' && Buffer.isBuffer(decoded)) { - node.data = proto.WebMessageInfo.decode(decoded) - } else { - node.data = decoded - } - } - } - return node -} -export default decode \ No newline at end of file diff --git a/src/BinaryNode/encode.ts b/src/BinaryNode/encode.ts deleted file mode 100644 index 4499236..0000000 --- a/src/BinaryNode/encode.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { proto } from "../../WAMessage"; -import { BinaryNode, SingleByteTokens, Tags } from "./types"; - -const encode = ({ header, attributes, data }: BinaryNode, buffer: number[] = []) => { - - const pushByte = (value: number) => buffer.push(value & 0xff) - - const pushInt = (value: number, n: number, littleEndian=false) => { - for (let i = 0; i < n; i++) { - const curShift = littleEndian ? i : n - 1 - i - buffer.push((value >> (curShift * 8)) & 0xff) - } - } - const pushBytes = (bytes: Uint8Array | Buffer | number[]) => ( - bytes.forEach (b => buffer.push(b)) - ) - const pushInt20 = (value: number) => ( - pushBytes([(value >> 16) & 0x0f, (value >> 8) & 0xff, value & 0xff]) - ) - const writeByteLength = (length: number) => { - if (length >= 4294967296) throw new Error('string too large to encode: ' + length) - - if (length >= 1 << 20) { - pushByte(Tags.BINARY_32) - pushInt(length, 4) // 32 bit integer - } else if (length >= 256) { - pushByte(Tags.BINARY_20) - pushInt20(length) - } else { - pushByte(Tags.BINARY_8) - pushByte(length) - } - } - const writeStringRaw = (str: string) => { - const bytes = Buffer.from (str, 'utf-8') - writeByteLength(bytes.length) - pushBytes(bytes) - } - const writeToken = (token: number) => { - if (token < 245) { - pushByte(token) - } else if (token <= 500) { - throw new Error('invalid token') - } - } - const writeString = (token: string, i?: boolean) => { - if (token === 'c.us') token = 's.whatsapp.net' - - const tokenIndex = SingleByteTokens.indexOf(token) - if (!i && token === 's.whatsapp.net') { - writeToken(tokenIndex) - } else if (tokenIndex >= 0) { - if (tokenIndex < Tags.SINGLE_BYTE_MAX) { - writeToken(tokenIndex) - } else { - const overflow = tokenIndex - Tags.SINGLE_BYTE_MAX - const dictionaryIndex = overflow >> 8 - if (dictionaryIndex < 0 || dictionaryIndex > 3) { - throw new Error('double byte dict token out of range: ' + token + ', ' + tokenIndex) - } - writeToken(Tags.DICTIONARY_0 + dictionaryIndex) - writeToken(overflow % 256) - } - } else if (token) { - const jidSepIndex = token.indexOf('@') - if (jidSepIndex <= 0) { - writeStringRaw(token) - } else { - writeJid(token.slice(0, jidSepIndex), token.slice(jidSepIndex + 1, token.length)) - } - } - } - const writeJid = (left: string, right: string) => { - pushByte(Tags.JID_PAIR) - left && left.length > 0 ? writeString(left) : writeToken(Tags.LIST_EMPTY) - writeString(right) - } - const writeListStart = (listSize: number) => { - if (listSize === 0) { - pushByte(Tags.LIST_EMPTY) - } else if (listSize < 256) { - pushBytes([Tags.LIST_8, listSize]) - } else { - pushBytes([Tags.LIST_16, listSize]) - } - } - const validAttributes = Object.keys(attributes).filter(k => ( - typeof attributes[k] !== 'undefined' && attributes[k] !== null - )) - - writeListStart(2*validAttributes.length + 1 + (typeof data !== 'undefined' && data !== null ? 1 : 0)) - writeString(header) - - validAttributes.forEach((key) => { - if(typeof attributes[key] === 'string') { - writeString(key) - writeString(attributes[key]) - } - }) - - if(data instanceof proto.WebMessageInfo && !Buffer.isBuffer(data)) { - data = Buffer.from(proto.WebMessageInfo.encode(data).finish()) - } - - if (typeof data === 'string') { - writeString(data, true) - } else if (Buffer.isBuffer(data)) { - writeByteLength(data.length) - pushBytes(data) - } else if (Array.isArray(data)) { - writeListStart(data.length) - for(const item of data) { - if(item) encode(item, buffer) - } - } else if(typeof data === 'undefined' || data === null) { - - } else { - throw new Error(`invalid children for header "${header}": ${data} (${typeof data})`) - } - - return Buffer.from(buffer) -} -export default encode \ No newline at end of file diff --git a/src/BinaryNode/index.ts b/src/BinaryNode/index.ts deleted file mode 100644 index 3eb830b..0000000 --- a/src/BinaryNode/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import decode from './decode' -import encode from './encode' -import { BinaryNode as BinaryNodeType } from './types' - -export default class BinaryNode extends BinaryNodeType { - toBuffer = () => encode(this, []) - static from = (buffer: Buffer) => decode(buffer, () => new BinaryNode(), { index: 0 }) -} \ No newline at end of file diff --git a/src/BinaryNode/types.ts b/src/BinaryNode/types.ts deleted file mode 100644 index 8e5e56a..0000000 --- a/src/BinaryNode/types.ts +++ /dev/null @@ -1,212 +0,0 @@ -import { proto } from "../../WAMessage" - -export type Attributes = { [key: string]: string } -export type BinaryNodeData = BinaryNode[] | string | Buffer | proto.IWebMessageInfo | undefined -export class BinaryNode { - header: string - attributes: Attributes = {} - data?: BinaryNodeData - - constructor(header?: string, attrs?: Attributes, data?: BinaryNodeData) { - this.header = header - this.attributes = attrs || {} - this.data = data - } -} -export const Tags = { - LIST_EMPTY: 0, - STREAM_END: 2, - DICTIONARY_0: 236, - DICTIONARY_1: 237, - DICTIONARY_2: 238, - DICTIONARY_3: 239, - LIST_8: 248, - LIST_16: 249, - JID_PAIR: 250, - HEX_8: 251, - BINARY_8: 252, - BINARY_20: 253, - BINARY_32: 254, - NIBBLE_8: 255, - SINGLE_BYTE_MAX: 256, - PACKED_MAX: 254, -} -export const DoubleByteTokens = [] -export const SingleByteTokens = [ - null, - null, - null, - '200', - '400', - '404', - '500', - '501', - '502', - 'action', - 'add', - 'after', - 'archive', - 'author', - 'available', - 'battery', - 'before', - 'body', - 'broadcast', - 'chat', - 'clear', - 'code', - 'composing', - 'contacts', - 'count', - 'create', - 'debug', - 'delete', - 'demote', - 'duplicate', - 'encoding', - 'error', - 'false', - 'filehash', - 'from', - 'g.us', - 'group', - 'groups_v2', - 'height', - 'id', - 'image', - 'in', - 'index', - 'invis', - 'item', - 'jid', - 'kind', - 'last', - 'leave', - 'live', - 'log', - 'media', - 'message', - 'mimetype', - 'missing', - 'modify', - 'name', - 'notification', - 'notify', - 'out', - 'owner', - 'participant', - 'paused', - 'picture', - 'played', - 'presence', - 'preview', - 'promote', - 'query', - 'raw', - 'read', - 'receipt', - 'received', - 'recipient', - 'recording', - 'relay', - 'remove', - 'response', - 'resume', - 'retry', - 's.whatsapp.net', - 'seconds', - 'set', - 'size', - 'status', - 'subject', - 'subscribe', - 't', - 'text', - 'to', - 'true', - 'type', - 'unarchive', - 'unavailable', - 'url', - 'user', - 'value', - 'web', - 'width', - 'mute', - 'read_only', - 'admin', - 'creator', - 'short', - 'update', - 'powersave', - 'checksum', - 'epoch', - 'block', - 'previous', - '409', - 'replaced', - 'reason', - 'spam', - 'modify_tag', - 'message_info', - 'delivery', - 'emoji', - 'title', - 'description', - 'canonical-url', - 'matched-text', - 'star', - 'unstar', - 'media_key', - 'filename', - 'identity', - 'unread', - 'page', - 'page_count', - 'search', - 'media_message', - 'security', - 'call_log', - 'profile', - 'ciphertext', - 'invite', - 'gif', - 'vcard', - 'frequent', - 'privacy', - 'blacklist', - 'whitelist', - 'verify', - 'location', - 'document', - 'elapsed', - 'revoke_invite', - 'expiration', - 'unsubscribe', - 'disable', - 'vname', - 'old_jid', - 'new_jid', - 'announcement', - 'locked', - 'prop', - 'label', - 'color', - 'call', - 'offer', - 'call-id', - 'quick_reply', - 'sticker', - 'pay_t', - 'accept', - 'reject', - 'sticker_pack', - 'invalid', - 'canceled', - 'missed', - 'connected', - 'result', - 'audio', - 'video', - 'recent', -] \ No newline at end of file diff --git a/src/BrowserMessageDecoding.ts b/src/BrowserMessageDecoding.ts deleted file mode 100644 index 1a59c19..0000000 --- a/src/BrowserMessageDecoding.ts +++ /dev/null @@ -1,41 +0,0 @@ -import fs from 'fs' -import { decodeWAMessage } from './Utils/decode-wa-message' - -interface BrowserMessagesInfo { - bundle: { encKey: string, macKey: string } - harFilePath: string -} -interface WSMessage { - type: 'send' | 'receive', - data: string -} -const file = fs.readFileSync ('./browser-messages.json', {encoding: 'utf-8'}) -const json: BrowserMessagesInfo = JSON.parse (file) - -const encKey = Buffer.from (json.bundle.encKey, 'base64') -const macKey = Buffer.from (json.bundle.macKey, 'base64') - -const harFile = JSON.parse ( fs.readFileSync( json.harFilePath , {encoding: 'utf-8'})) -const entries = harFile['log']['entries'] -let wsMessages: WSMessage[] = [] -entries.forEach ((e, i) => { - if ('_webSocketMessages' in e) { - wsMessages.push (...e['_webSocketMessages']) - } -}) -const decrypt = (buffer, fromMe) => decodeWAMessage(buffer, { macKey, encKey }, fromMe) - -console.log ('parsing ' + wsMessages.length + ' messages') -const list = wsMessages.map ((item, i) => { - const buffer = item.data.includes(',') ? item.data : Buffer.from (item.data, 'base64') - try { - const [tag, json, binaryTags] = decrypt (buffer, item.type === 'send') - - return {tag, json: json && JSON.stringify(json), binaryTags} - } catch (error) { - return { error: error.message, data: buffer.toString('utf-8') } - } -}) -.filter (Boolean) -const str = JSON.stringify (list, null, '\t') -fs.writeFileSync ('decoded-ws.json', str) \ No newline at end of file diff --git a/src/Connection/auth.ts b/src/Connection/auth.ts deleted file mode 100644 index 547340b..0000000 --- a/src/Connection/auth.ts +++ /dev/null @@ -1,275 +0,0 @@ -import { Boom } from '@hapi/boom' -import EventEmitter from "events" -import * as Curve from 'curve25519-js' -import { BaileysEventEmitter, BaileysEventMap, SocketConfig, CurveKeyPair, WAInitResponse, ConnectionState, DisconnectReason } from "../Types" -import { makeSocket } from "./socket" -import { generateClientID, promiseTimeout, normalizedAuthInfo, computeChallengeResponse, validateNewConnection } from "../Utils" -import { randomBytes } from "crypto" -import { AuthenticationCredentials } from "../Types" - -const makeAuthSocket = (config: SocketConfig) => { - const { - logger, - version, - browser, - connectTimeoutMs, - pendingRequestTimeoutMs, - maxQRCodes, - printQRInTerminal, - credentials: anyAuthInfo - } = config - const ev = new EventEmitter() as BaileysEventEmitter - - let authInfo = normalizedAuthInfo(anyAuthInfo) || - // generate client id if not there - { clientID: generateClientID() } as AuthenticationCredentials - - const state: ConnectionState = { - phoneConnected: false, - connection: 'connecting', - } - - const socket = makeSocket({ - ...config, - phoneConnectionChanged: phoneConnected => { - if(phoneConnected !== state.phoneConnected) { - updateState({ phoneConnected }) - } - } - }) - const { ws } = socket - let curveKeys: CurveKeyPair - let initTimeout: NodeJS.Timeout - // add close listener - ws.on('ws-close', (error: Boom | Error) => { - logger.info({ error }, 'Closed connection to WhatsApp') - initTimeout && clearTimeout(initTimeout) - // if no reconnects occur - // send close event - updateState({ - connection: 'close', - qr: undefined, - connectionTriesLeft: undefined, - lastDisconnect: { - error, - date: new Date() - } - }) - }) - /** Can you login to WA without scanning the QR */ - const canLogin = () => !!authInfo?.encKey && !!authInfo?.macKey - - const updateState = (update: Partial) => { - Object.assign(state, update) - ev.emit('connection.update', update) - } - - /** - * Logs you out from WA - * If connected, invalidates the credentials with the server - */ - const logout = async() => { - if(state.connection === 'open') { - await socket.sendMessage({ - json: ['admin', 'Conn', 'disconnect'], - tag: 'goodbye' - }) - } - // will call state update to close connection - socket?.end( - new Boom('Logged Out', { statusCode: DisconnectReason.credentialsInvalidated }) - ) - authInfo = undefined - } - /** Waits for the connection to WA to open up */ - const waitForConnection = async(waitInfinitely: boolean = false) => { - if(state.connection === 'open') return - - let listener: (item: BaileysEventMap['connection.update']) => void - const timeout = waitInfinitely ? undefined : pendingRequestTimeoutMs - if(timeout < 0) { - throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) - } - - await ( - promiseTimeout( - timeout, - (resolve, reject) => { - listener = ({ connection, lastDisconnect }) => { - if(connection === 'open') resolve() - else if(connection == 'close') { - reject(lastDisconnect.error || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) - } - } - ev.on('connection.update', listener) - } - ) - .finally(() => ( - ev.off('connection.update', listener) - )) - ) - } - - const updateEncKeys = () => { - // update the keys so we can decrypt traffic - socket.updateKeys({ encKey: authInfo!.encKey, macKey: authInfo!.macKey }) - } - - const generateKeysForAuth = async(ref: string, ttl?: number) => { - curveKeys = Curve.generateKeyPair(randomBytes(32)) - const publicKey = Buffer.from(curveKeys.public).toString('base64') - let qrGens = 0 - - const qrLoop = ttl => { - const qr = [ref, publicKey, authInfo.clientID].join(',') - updateState({ qr }) - - initTimeout = setTimeout(async () => { - if(state.connection !== 'connecting') return - - logger.debug('regenerating QR') - try { - if(qrGens >= maxQRCodes) { - throw new Boom( - 'Too many QR codes', - { statusCode: 429 } - ) - } - // request new QR - const {ref: newRef, ttl: newTTL} = await socket.query({ - json: ['admin', 'Conn', 'reref'], - expect200: true, - longTag: true, - requiresPhoneConnection: false - }) - ttl = newTTL - ref = newRef - } catch (error) { - logger.error({ error }, `error in QR gen`) - if (error.output?.statusCode === 429) { // too many QR requests - socket.end(error) - return - } - } - qrGens += 1 - qrLoop(ttl) - }, ttl || 20_000) // default is 20s, on the off-chance ttl is not present - } - qrLoop(ttl) - } - const onOpen = async() => { - const canDoLogin = canLogin() - const initQuery = (async () => { - const {ref, ttl} = await socket.query({ - json: ['admin', 'init', version, browser, authInfo.clientID, true], - expect200: true, - longTag: true, - requiresPhoneConnection: false - }) as WAInitResponse - - if (!canDoLogin) { - generateKeysForAuth(ref, ttl) - } - })(); - let loginTag: string - if(canDoLogin) { - updateEncKeys() - // if we have the info to restore a closed session - const json = [ - 'admin', - 'login', - authInfo.clientToken, - authInfo.serverToken, - authInfo.clientID, - 'takeover' - ] - loginTag = socket.generateMessageTag(true) - // send login every 10s - const sendLoginReq = () => { - if(state.connection === 'open') { - logger.warn('Received login timeout req when state=open, ignoring...') - return - } - logger.info('sending login request') - socket.sendMessage({ - json, - tag: loginTag - }) - initTimeout = setTimeout(sendLoginReq, 10_000) - } - sendLoginReq() - } - await initQuery - - // wait for response with tag "s1" - let response = await Promise.race( - [ - socket.waitForMessage('s1', false, undefined), - ...(loginTag ? [socket.waitForMessage(loginTag, false, connectTimeoutMs)] : []) - - ] - ) - initTimeout && clearTimeout(initTimeout) - initTimeout = undefined - - if(response.status && response.status !== 200) { - throw new Boom(`Unexpected error in login`, { data: response, statusCode: response.status }) - } - // if its a challenge request (we get it when logging in) - if(response[1]?.challenge) { - const json = computeChallengeResponse(response[1].challenge, authInfo) - logger.info('resolving login challenge') - - await socket.query({ json, expect200: true, timeoutMs: connectTimeoutMs }) - - response = await socket.waitForMessage('s2', true) - } - // validate the new connection - const {user, auth, phone} = validateNewConnection(response[1], authInfo, curveKeys)// validate the connection - const isNewLogin = user.jid !== state.user?.jid - - authInfo = auth - updateEncKeys() - - logger.info({ user }, 'logged in') - - updateState({ - connection: 'open', - phoneConnected: true, - user, - isNewLogin, - phoneInfo: phone, - connectionTriesLeft: undefined, - qr: undefined - }) - ev.emit('credentials.update', auth) - } - ws.once('open', async() => { - try { - await onOpen() - } catch(error) { - socket.end(error) - } - }) - - if(printQRInTerminal) { - ev.on('connection.update', async({ qr }) => { - if(qr) { - const QR = await import('qrcode-terminal').catch(err => { - logger.error('QR code terminal not added as dependency') - }) - QR?.generate(qr, { small: true }) - } - }) - } - return { - ...socket, - ev, - getState: () => state, - getAuthInfo: () => authInfo, - waitForConnection, - canLogin, - logout - } -} -export default makeAuthSocket \ No newline at end of file diff --git a/src/Connection/chats.ts b/src/Connection/chats.ts deleted file mode 100644 index d23d0e8..0000000 --- a/src/Connection/chats.ts +++ /dev/null @@ -1,478 +0,0 @@ -import BinaryNode from "../BinaryNode"; -import { Chat, Contact, Presence, PresenceData, SocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessage, WAMessageUpdate, BaileysEventMap } from "../Types"; -import { debouncedTimeout, unixTimestampSeconds, whatsappID } from "../Utils/generics"; -import makeAuthSocket from "./auth"; -import { Attributes, BinaryNode as BinaryNodeBase } from "../BinaryNode/types"; - -const makeChatsSocket = (config: SocketConfig) => { - const { logger } = config - const sock = makeAuthSocket(config) - const { - ev, - ws: socketEvents, - currentEpoch, - setQuery, - query, - sendMessage, - getState - } = sock - - const chatsDebounceTimeout = debouncedTimeout(10_000, () => sendChatsQuery(1)) - - const sendChatsQuery = (epoch: number) => ( - sendMessage({ - json: new BinaryNode('query', {type: 'chat', epoch: epoch.toString()}), - binaryTag: [ WAMetric.queryChat, WAFlag.ignore ] - }) - ) - - const fetchImageUrl = async(jid: string) => { - const response = await query({ - json: ['query', 'ProfilePicThumb', jid], - expect200: false, - requiresPhoneConnection: false - }) - return response.eurl as string | undefined - } - - const executeChatModification = (node: BinaryNodeBase) => { - const { attributes } = node - const updateType = attributes.type - const jid = whatsappID(attributes?.jid) - - switch(updateType) { - case 'delete': - ev.emit('chats.delete', [jid]) - break - case 'clear': - if(node.data) { - const ids = (node.data as BinaryNode[]).map( - ({ attributes }) => attributes.index - ) - ev.emit('messages.delete', { jid, ids }) - } else { - ev.emit('messages.delete', { jid, all: true }) - } - break - case 'archive': - ev.emit('chats.update', [ { jid, archive: 'true' } ]) - break - case 'unarchive': - ev.emit('chats.update', [ { jid, archive: 'false' } ]) - break - case 'pin': - ev.emit('chats.update', [ { jid, pin: attributes.pin } ]) - break - case 'star': - case 'unstar': - const starred = updateType === 'star' - const updates: WAMessageUpdate[] = (node.data as BinaryNode[]).map( - ({ attributes }) => ({ - key: { - remoteJid: jid, - id: attributes.index, - fromMe: attributes.owner === 'true' - }, - update: { starred } - }) - ) - ev.emit('messages.update', updates) - break - case 'mute': - if(attributes.mute === '0') { - ev.emit('chats.update', [{ jid, mute: null }]) - } else { - ev.emit('chats.update', [{ jid, mute: attributes.mute }]) - } - break - default: - logger.warn({ node }, `received unrecognized chat update`) - break - } - } - - const applyingPresenceUpdate = (update: Attributes): BaileysEventMap['presence.update'] => { - const jid = whatsappID(update.id) - const participant = whatsappID(update.participant || update.id) - - const presence: PresenceData = { - lastSeen: update.t ? +update.t : undefined, - lastKnownPresence: update.type as Presence - } - return { jid, presences: { [participant]: presence } } - } - - ev.on('connection.update', async({ connection }) => { - if(connection !== 'open') return - try { - await Promise.all([ - sendMessage({ - json: new BinaryNode('query', {type: 'contacts', epoch: '1'}), - binaryTag: [ WAMetric.queryContact, WAFlag.ignore ] - }), - sendMessage({ - json: new BinaryNode('query', {type: 'status', epoch: '1'}), - binaryTag: [ WAMetric.queryStatus, WAFlag.ignore ] - }), - sendMessage({ - json: new BinaryNode('query', {type: 'quick_reply', epoch: '1'}), - binaryTag: [ WAMetric.queryQuickReply, WAFlag.ignore ] - }), - sendMessage({ - json: new BinaryNode('query', {type: 'label', epoch: '1'}), - binaryTag: [ WAMetric.queryLabel, WAFlag.ignore ] - }), - sendMessage({ - json: new BinaryNode('query', {type: 'emoji', epoch: '1'}), - binaryTag: [ WAMetric.queryEmoji, WAFlag.ignore ] - }), - sendMessage({ - json: new BinaryNode( - 'action', - { type: 'set', epoch: '1' }, - [ - new BinaryNode('presence', {type: 'available'}) - ] - ), - binaryTag: [ WAMetric.presence, WAFlag.available ] - }) - ]) - chatsDebounceTimeout.start() - - logger.debug('sent init queries') - } catch(error) { - logger.error(`error in sending init queries: ${error}`) - } - }) - socketEvents.on('CB:response,type:chat', async ({ data }: BinaryNode) => { - chatsDebounceTimeout.cancel() - if(Array.isArray(data)) { - const chats = data.map(({ attributes }) => { - return { - ...attributes, - jid: whatsappID(attributes.jid), - t: +attributes.t, - count: +attributes.count - } as Chat - }) - - logger.info(`got ${chats.length} chats`) - ev.emit('chats.set', { chats }) - } - }) - // got all contacts from phone - socketEvents.on('CB:response,type:contacts', async ({ data }: BinaryNode) => { - if(Array.isArray(data)) { - const contacts = data.map(({ attributes }) => { - const contact = attributes as any as Contact - contact.jid = whatsappID(contact.jid) - return contact - }) - - logger.info(`got ${contacts.length} contacts`) - ev.emit('contacts.set', { contacts }) - } - }) - // status updates - socketEvents.on('CB:Status,status', json => { - const jid = whatsappID(json[1].id) - ev.emit('contacts.update', [ { jid, status: json[1].status } ]) - }) - // User Profile Name Updates - socketEvents.on('CB:Conn,pushname', json => { - const { user, connection } = getState() - if(connection === 'open' && json[1].pushname !== user.name) { - user.name = json[1].pushname - ev.emit('connection.update', { user }) - } - }) - // read updates - socketEvents.on ('CB:action,,read', async ({ data }: BinaryNode) => { - if(Array.isArray(data)) { - const { attributes } = data[0] - - const update: Partial = { - jid: whatsappID(attributes.jid) - } - if (attributes.type === 'false') update.count = -1 - else update.count = 0 - - ev.emit('chats.update', [update]) - } - }) - - socketEvents.on('CB:Cmd,type:picture', async json => { - json = json[1] - const jid = whatsappID(json.jid) - const imgUrl = await fetchImageUrl(jid).catch(() => '') - - ev.emit('contacts.update', [ { jid, imgUrl } ]) - }) - - // chat archive, pin etc. - socketEvents.on('CB:action,,chat', ({ data }: BinaryNode) => { - if(Array.isArray(data)) { - const [node] = data - executeChatModification(node) - } - }) - - socketEvents.on('CB:action,,user', (json: BinaryNode) => { - if(Array.isArray(json.data)) { - const user = json.data[0].attributes as any as Contact - user.jid = whatsappID(user.jid) - - ev.emit('contacts.upsert', [user]) - } - }) - - // presence updates - socketEvents.on('CB:Presence', json => { - const update = applyingPresenceUpdate(json[1]) - ev.emit('presence.update', update) - }) - - // blocklist updates - socketEvents.on('CB:Blocklist', json => { - json = json[1] - const blocklist = json.blocklist - ev.emit('blocklist.set', { blocklist }) - }) - - return { - ...sock, - sendChatsQuery, - fetchImageUrl, - chatRead: async(fromMessage: WAMessageKey, count: number) => { - await setQuery ( - [ - new BinaryNode( - 'read', - { - jid: fromMessage.remoteJid, - count: count.toString(), - index: fromMessage.id, - owner: fromMessage.fromMe ? 'true' : 'false' - } - ) - ], - [ WAMetric.read, WAFlag.ignore ] - ) - ev.emit ('chats.update', [{ jid: fromMessage.remoteJid, count: count < 0 ? -1 : 0 }]) - }, - /** - * Modify a given chat (archive, pin etc.) - * @param jid the ID of the person/group you are modifiying - */ - modifyChat: async(jid: string, modification: ChatModification, index?: WAMessageKey) => { - let chatAttrs: Attributes = { jid: jid } - let data: BinaryNode[] | undefined = undefined - const stamp = unixTimestampSeconds() - - if('archive' in modification) { - chatAttrs.type = modification.archive ? 'archive' : 'unarchive' - } else if('pin' in modification) { - chatAttrs.type = 'pin' - if(typeof modification.pin === 'object') { - chatAttrs.previous = modification.pin.remove.toString() - } else { - chatAttrs.pin = stamp.toString() - } - } else if('mute' in modification) { - chatAttrs.type = 'mute' - if(typeof modification.mute === 'object') { - chatAttrs.previous = modification.mute.remove.toString() - } else { - chatAttrs.mute = (stamp + modification.mute).toString() - } - } else if('clear' in modification) { - chatAttrs.type = 'clear' - chatAttrs.modify_tag = Math.round(Math.random ()*1000000).toString() - if(modification.clear !== 'all') { - data = modification.clear.messages.map(({ id, fromMe }) => ( - new BinaryNode( - 'item', - { owner: (!!fromMe).toString(), index: id } - ) - )) - } - } else if('star' in modification) { - chatAttrs.type = modification.star.star ? 'star' : 'unstar' - data = modification.star.messages.map(({ id, fromMe }) => ( - new BinaryNode( - 'item', - { owner: (!!fromMe).toString(), index: id } - ) - )) - } - - if(index) { - chatAttrs.index = index.id - chatAttrs.owner = index.fromMe ? 'true' : 'false' - } - - const node = new BinaryNode('chat', chatAttrs, data) - const response = await setQuery([node], [ WAMetric.chat, WAFlag.ignore ]) - // apply it and emit events - executeChatModification(node) - return response - }, - /** - * Query whether a given number is registered on WhatsApp - * @param str phone number/jid you want to check for - * @returns undefined if the number doesn't exists, otherwise the correctly formatted jid - */ - isOnWhatsApp: async (str: string) => { - const { status, jid, biz } = await query({ - json: ['query', 'exist', str], - requiresPhoneConnection: false - }) - if (status === 200) { - return { - exists: true, - jid: whatsappID(jid), - isBusiness: biz as boolean - } - } - }, - /** - * Tell someone about your presence -- online, typing, offline etc. - * @param jid the ID of the person/group who you are updating - * @param type your presence - */ - updatePresence: (jid: string | undefined, type: Presence) => ( - sendMessage({ - binaryTag: [WAMetric.presence, WAFlag[type]], // weird stuff WA does - json: new BinaryNode( - 'action', - { epoch: currentEpoch().toString(), type: 'set' }, - [ - new BinaryNode( - 'presence', - { type: type, to: jid } - ) - ] - ) - }) - ), - /** - * Request updates on the presence of a user - * this returns nothing, you'll receive updates in chats.update event - * */ - requestPresenceUpdate: async (jid: string) => ( - sendMessage({ json: ['action', 'presence', 'subscribe', jid] }) - ), - /** Query the status of the person (see groupMetadata() for groups) */ - getStatus: async(jid: string) => { - const status: { status: string } = await query({ json: ['query', 'Status', jid], requiresPhoneConnection: false }) - return status - }, - setStatus: async(status: string) => { - const response = await setQuery( - [ - new BinaryNode( - 'status', - {}, - Buffer.from (status, 'utf-8') - ) - ] - ) - ev.emit('contacts.update', [{ jid: getState().user!.jid, status }]) - return response - }, - /** Updates business profile. */ - updateBusinessProfile: async(profile: WABusinessProfile) => { - if (profile.business_hours?.config) { - profile.business_hours.business_config = profile.business_hours.config - delete profile.business_hours.config - } - const json = ['action', "editBusinessProfile", {...profile, v: 2}] - await query({ json, expect200: true, requiresPhoneConnection: true }) - }, - updateProfileName: async(name: string) => { - const response = (await setQuery( - [ - new BinaryNode( - 'profile', - { name } - ) - ] - )) as any as {status: number, pushname: string} - - if (response.status === 200) { - const user = { ...getState().user!, name } - ev.emit('connection.update', { user }) - ev.emit('contacts.update', [{ jid: user.jid, name }]) - } - return response - }, - /** - * Update the profile picture - * @param jid - * @param img - */ - async updateProfilePicture (jid: string, img: Buffer) { - jid = whatsappID (jid) - const data = { img: Buffer.from([]), preview: Buffer.from([]) } //await generateProfilePicture(img) TODO - const tag = this.generateMessageTag () - const query = new BinaryNode( - 'picture', - { jid: jid, id: tag, type: 'set' }, - [ - new BinaryNode('image', {}, data.img), - new BinaryNode('preview', {}, data.preview) - ] - ) - const user = getState().user - const { eurl } = await this.setQuery ([query], [WAMetric.picture, 136], tag) as { eurl: string, status: number } - - if (jid === user.jid) { - user.imgUrl = eurl - ev.emit('connection.update', { user }) - } - ev.emit('contacts.update', [ { jid, imgUrl: eurl } ]) - }, - /** - * Add or remove user from blocklist - * @param jid the ID of the person who you are blocking/unblocking - * @param type type of operation - */ - blockUser: async(jid: string, type: 'add' | 'remove' = 'add') => { - const json = new BinaryNode( - 'block', - { type }, - [ new BinaryNode('user', { jid }) ] - ) - await setQuery ([json], [WAMetric.block, WAFlag.ignore]) - ev.emit('blocklist.update', { blocklist: [jid], type }) - }, - /** - * Query Business Profile (Useful for VCards) - * @param jid Business Jid - * @returns profile object or undefined if not business account - */ - getBusinessProfile: async(jid: string) => { - jid = whatsappID(jid) - const { - profiles: [{ - profile, - wid - }] - } = await query({ - json: [ - "query", "businessProfile", - [ { "wid": jid.replace('@s.whatsapp.net', '@c.us') } ], - 84 - ], - expect200: true, - requiresPhoneConnection: false, - }) - - return { - ...profile, - wid: whatsappID(wid) - } as WABusinessProfile - } - } -} -export default makeChatsSocket \ No newline at end of file diff --git a/src/Connection/groups.ts b/src/Connection/groups.ts deleted file mode 100644 index 9ee0a1c..0000000 --- a/src/Connection/groups.ts +++ /dev/null @@ -1,237 +0,0 @@ -import BinaryNode from "../BinaryNode"; -import { SocketConfig, GroupModificationResponse, ParticipantAction, GroupMetadata, WAFlag, WAMetric, WAGroupCreateResponse, GroupParticipant } from "../Types"; -import { generateMessageID, unixTimestampSeconds, whatsappID } from "../Utils/generics"; -import makeMessagesSocket from "./messages"; - -const makeGroupsSocket = (config: SocketConfig) => { - const { logger } = config - const sock = makeMessagesSocket(config) - const { - ev, - ws: socketEvents, - query, - generateMessageTag, - currentEpoch, - setQuery, - getState - } = sock - - /** Generic function for group queries */ - const groupQuery = async(type: string, jid?: string, subject?: string, participants?: string[], additionalNodes?: BinaryNode[]) => { - const tag = generateMessageTag() - const result = await setQuery ([ - new BinaryNode( - 'group', - { - author: getState().user?.jid, - id: tag, - type: type, - jid: jid, - subject: subject, - }, - participants ? - participants.map(jid => ( - new BinaryNode('participant', { jid }) - )) : - additionalNodes - ) - ], [WAMetric.group, 136], tag) - return result - } - - /** Get the metadata of the group from WA */ - const groupMetadataFull = async (jid: string) => { - const metadata = await query({ - json: ['query', 'GroupMetadata', jid], - expect200: true - }) - metadata.participants = metadata.participants.map(p => ( - { ...p, id: undefined, jid: whatsappID(p.id) } - )) - metadata.owner = whatsappID(metadata.owner) - return metadata as GroupMetadata - } - /** Get the metadata (works after you've left the group also) */ - const groupMetadataMinimal = async (jid: string) => { - const { attributes, data }:BinaryNode = await query({ - json: new BinaryNode( - 'query', - {type: 'group', jid: jid, epoch: currentEpoch().toString()} - ), - binaryTag: [WAMetric.group, WAFlag.ignore], - expect200: true - }) - const participants: GroupParticipant[] = [] - let desc: string | undefined - if(Array.isArray(data) && Array.isArray(data[0].data)) { - const nodes = data[0].data - for(const item of nodes) { - if(item.header === 'participant') { - participants.push({ - jid: item.attributes.jid, - isAdmin: item.attributes.type === 'admin', - isSuperAdmin: false - }) - } else if(item.header === 'description') { - desc = (item.data as Buffer).toString('utf-8') - } - } - } - return { - id: jid, - owner: attributes?.creator, - creator: attributes?.creator, - creation: +attributes?.create, - subject: null, - desc, - participants - } as GroupMetadata - } - - socketEvents.on('CB:Chat,cmd:action', (json: BinaryNode) => { - /*const data = json[1].data - if (data) { - const emitGroupParticipantsUpdate = (action: WAParticipantAction) => this.emitParticipantsUpdate - (json[1].id, data[2].participants.map(whatsappID), action) - const emitGroupUpdate = (data: Partial) => this.emitGroupUpdate(json[1].id, data) - - switch (data[0]) { - case "promote": - emitGroupParticipantsUpdate('promote') - break - case "demote": - emitGroupParticipantsUpdate('demote') - break - case "desc_add": - emitGroupUpdate({ ...data[2], descOwner: data[1] }) - break - default: - this.logger.debug({ unhandled: true }, json) - break - } - }*/ - }) - - return { - ...sock, - groupMetadata: async(jid: string, minimal: boolean) => { - let result: GroupMetadata - - if(minimal) result = await groupMetadataMinimal(jid) - else result = await groupMetadataFull(jid) - - return result - }, - /** - * Create a group - * @param title like, the title of the group - * @param participants people to include in the group - */ - groupCreate: async (title: string, participants: string[]) => { - const response = await groupQuery('create', null, title, participants) as WAGroupCreateResponse - const gid = response.gid - let metadata: GroupMetadata - try { - metadata = await groupMetadataFull(gid) - } catch (error) { - logger.warn (`error in group creation: ${error}, switching gid & checking`) - // if metadata is not available - const comps = gid.replace ('@g.us', '').split ('-') - response.gid = `${comps[0]}-${+comps[1] + 1}@g.us` - - metadata = await groupMetadataFull(gid) - logger.warn (`group ID switched from ${gid} to ${response.gid}`) - } - ev.emit('chats.upsert', [ - { - jid: response.gid, - name: title, - t: unixTimestampSeconds(), - count: 0 - } - ]) - return metadata - }, - /** - * Leave a group - * @param jid the ID of the group - */ - groupLeave: async (jid: string) => { - await groupQuery('leave', jid) - ev.emit('chats.update', [ { jid, read_only: 'true' } ]) - }, - /** - * Update the subject of the group - * @param {string} jid the ID of the group - * @param {string} title the new title of the group - */ - groupUpdateSubject: async (jid: string, title: string) => { - await groupQuery('subject', jid, title) - ev.emit('chats.update', [ { jid, name: title } ]) - ev.emit('contacts.update', [ { jid, name: title } ]) - ev.emit('groups.update', [ { id: jid, subject: title } ]) - }, - /** - * Update the group description - * @param {string} jid the ID of the group - * @param {string} title the new title of the group - */ - groupUpdateDescription: async (jid: string, description: string) => { - const metadata = await groupMetadataFull(jid) - const node = new BinaryNode( - 'description', - {id: generateMessageID(), prev: metadata?.descId}, - Buffer.from (description, 'utf-8') - ) - const response = await groupQuery ('description', jid, null, null, [node]) - ev.emit('groups.update', [ { id: jid, desc: description } ]) - return response - }, - /** - * Update participants in the group - * @param jid the ID of the group - * @param participants the people to add - */ - groupParticipantsUpdate: async(jid: string, participants: string[], action: ParticipantAction) => { - const result: GroupModificationResponse = await groupQuery(action, jid, null, participants) - const jids = Object.keys(result.participants || {}) - ev.emit('group-participants.update', { jid, participants: jids, action }) - return jids - }, - /** Query broadcast list info */ - getBroadcastListInfo: async(jid: string) => { - interface WABroadcastListInfo { - status: number - name: string - recipients?: {id: string}[] - } - - const result = await query({ - json: ['query', 'contact', jid], - expect200: true, - requiresPhoneConnection: true - }) as WABroadcastListInfo - - const metadata: GroupMetadata = { - subject: result.name, - id: jid, - creation: undefined, - owner: getState().user?.jid, - participants: result.recipients!.map(({id}) => ( - { jid: whatsappID(id), isAdmin: false, isSuperAdmin: false } - )) - } - return metadata - }, - inviteCode: async(jid: string) => { - const response = await sock.query({ - json: ['query', 'inviteCode', jid], - expect200: true, - requiresPhoneConnection: false - }) - return response.code as string - } - } - -} -export default makeGroupsSocket \ No newline at end of file diff --git a/src/Connection/index.ts b/src/Connection/index.ts deleted file mode 100644 index b305b20..0000000 --- a/src/Connection/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { SocketConfig } from '../Types' -import { DEFAULT_CONNECTION_CONFIG } from '../Defaults' -import _makeConnection from './groups' -// export the last socket layer -const makeConnection = (config: Partial) => ( - _makeConnection({ - ...DEFAULT_CONNECTION_CONFIG, - ...config - }) -) - -export type Connection = ReturnType - -export default makeConnection \ No newline at end of file diff --git a/src/Connection/messages.ts b/src/Connection/messages.ts deleted file mode 100644 index 9432eb0..0000000 --- a/src/Connection/messages.ts +++ /dev/null @@ -1,577 +0,0 @@ -import BinaryNode from "../BinaryNode"; -import { Boom } from '@hapi/boom' -import { EventEmitter } from 'events' -import { Chat, Presence, WAMessageCursor, SocketConfig, WAMessage, WAMessageKey, ParticipantAction, WAMessageProto, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo, MessageInfoUpdate, WAMediaUploadFunction, MediaType, WAMessageUpdate } from "../Types"; -import { isGroupID, toNumber, whatsappID, generateWAMessage, decryptMediaMessageBuffer, extractMessageContent } from "../Utils"; -import makeChatsSocket from "./chats"; -import { DEFAULT_ORIGIN, MEDIA_PATH_MAP, WA_DEFAULT_EPHEMERAL } from "../Defaults"; -import got from "got"; - -const STATUS_MAP = { - read: WAMessageStatus.READ, - message: WAMessageStatus.DELIVERY_ACK, - error: WAMessageStatus.ERROR -} as { [_: string]: WAMessageStatus } - -const makeMessagesSocket = (config: SocketConfig) => { - const { logger } = config - const sock = makeChatsSocket(config) - const { - ev, - ws: socketEvents, - query, - generateMessageTag, - currentEpoch, - setQuery, - getState - } = sock - - let mediaConn: Promise - const refreshMediaConn = async(forceGet = false) => { - let media = await mediaConn - if (!media || forceGet || (new Date().getTime()-media.fetchDate.getTime()) > media.ttl*1000) { - mediaConn = (async() => { - const {media_conn} = await query({ - json: ['query', 'mediaConn'], - requiresPhoneConnection: false - }) - media_conn.fetchDate = new Date() - return media_conn as MediaConnInfo - })() - } - return mediaConn - } - - const fetchMessagesFromWA = async( - jid: string, - count: number, - cursor?: WAMessageCursor - ) => { - let key: WAMessageKey - if(cursor) { - key = 'before' in cursor ? cursor.before : cursor.after - } - const { data }:BinaryNode = await query({ - json: new BinaryNode( - 'query', - { - epoch: currentEpoch().toString(), - type: 'message', - jid: jid, - kind: !cursor || 'before' in cursor ? 'before' : 'after', - count: count.toString(), - index: key?.id, - owner: key?.fromMe === false ? 'false' : 'true', - } - ), - binaryTag: [WAMetric.queryMessages, WAFlag.ignore], - expect200: false, - requiresPhoneConnection: true - }) - if(Array.isArray(data)) { - return data.map(data => data.data as WAMessage) - } - return [] - } - - const updateMediaMessage = async(message: WAMessage) => { - const content = message.message?.audioMessage || message.message?.videoMessage || message.message?.imageMessage || message.message?.stickerMessage || message.message?.documentMessage - if (!content) throw new Boom( - `given message ${message.key.id} is not a media message`, - { statusCode: 400, data: message } - ) - - const response: BinaryNode = await query ({ - json: new BinaryNode( - 'query', - { - type: 'media', - index: message.key.id, - owner: message.key.fromMe ? 'true' : 'false', - jid: message.key.remoteJid, - epoch: currentEpoch().toString() - } - ), - binaryTag: [WAMetric.queryMedia, WAFlag.ignore], - expect200: true, - requiresPhoneConnection: true - }) - const attrs = response.attributes - Object.keys(attrs).forEach (key => content[key] = attrs[key]) // update message - - ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]) - - return response - } - - const onMessage = (message: WAMessage, type: MessageUpdateType | 'update') => { - const jid = message.key.remoteJid! - // store chat updates in this - const chatUpdate: Partial = { - jid, - } - - const emitGroupUpdate = (update: Partial) => { - ev.emit('groups.update', [ { id: jid, ...update } ]) - } - - if(message.message) { - chatUpdate.t = +toNumber(message.messageTimestamp) - // add to count if the message isn't from me & there exists a message - if(!message.key.fromMe) { - chatUpdate.count = 1 - const participant = whatsappID(message.participant || jid) - - ev.emit( - 'presence.update', - { - jid, - presences: { [participant]: { lastKnownPresence: Presence.available } } - } - ) - } - } - - const ephemeralProtocolMsg = message.message?.ephemeralMessage?.message?.protocolMessage - if ( - ephemeralProtocolMsg && - ephemeralProtocolMsg.type === WAMessageProto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING - ) { - chatUpdate.eph_setting_ts = message.messageTimestamp.toString() - chatUpdate.ephemeral = ephemeralProtocolMsg.ephemeralExpiration.toString() - - if(isGroupID(jid)) { - emitGroupUpdate({ ephemeralDuration: ephemeralProtocolMsg.ephemeralExpiration || null }) - } - } - const protocolMessage = message.message?.protocolMessage - // if it's a message to delete another message - if (protocolMessage) { - switch (protocolMessage.type) { - case WAMessageProto.ProtocolMessage.ProtocolMessageType.REVOKE: - const key = protocolMessage.key - const messageStubType = WAMessageStubType.REVOKE - ev.emit('messages.update', [ - { - // the key of the deleted message is updated - update: { message: null, key: message.key, messageStubType }, - key - } - ]) - return - default: - break - } - } - - // check if the message is an action - if (message.messageStubType) { - const { user } = getState() - //let actor = whatsappID (message.participant) - let participants: string[] - const emitParticipantsUpdate = (action: ParticipantAction) => ( - ev.emit('group-participants.update', { jid, participants, action }) - ) - - switch (message.messageStubType) { - case WAMessageStubType.CHANGE_EPHEMERAL_SETTING: - chatUpdate.eph_setting_ts = message.messageTimestamp.toString() - chatUpdate.ephemeral = message.messageStubParameters[0] - if(isGroupID(jid)) { - emitGroupUpdate({ ephemeralDuration: +message.messageStubParameters[0] || null }) - } - break - case WAMessageStubType.GROUP_PARTICIPANT_LEAVE: - case WAMessageStubType.GROUP_PARTICIPANT_REMOVE: - participants = message.messageStubParameters.map (whatsappID) - emitParticipantsUpdate('remove') - // mark the chat read only if you left the group - if (participants.includes(user.jid)) { - chatUpdate.read_only = 'true' - } - break - case WAMessageStubType.GROUP_PARTICIPANT_ADD: - case WAMessageStubType.GROUP_PARTICIPANT_INVITE: - case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN: - participants = message.messageStubParameters.map (whatsappID) - if (participants.includes(user.jid)) { - chatUpdate.read_only = 'false' - } - emitParticipantsUpdate('add') - break - case WAMessageStubType.GROUP_CHANGE_ANNOUNCE: - const announce = message.messageStubParameters[0] === 'on' ? 'true' : 'false' - emitGroupUpdate({ announce }) - break - case WAMessageStubType.GROUP_CHANGE_RESTRICT: - const restrict = message.messageStubParameters[0] === 'on' ? 'true' : 'false' - emitGroupUpdate({ restrict }) - break - case WAMessageStubType.GROUP_CHANGE_SUBJECT: - case WAMessageStubType.GROUP_CREATE: - chatUpdate.name = message.messageStubParameters[0] - emitGroupUpdate({ subject: chatUpdate.name }) - break - } - } - - if(Object.keys(chatUpdate).length > 1) { - ev.emit('chats.update', [chatUpdate]) - } - if(type === 'update') { - ev.emit('messages.update', [ { update: message, key: message.key } ]) - } else { - ev.emit('messages.upsert', { messages: [message], type }) - } - } - - const waUploadToServer: WAMediaUploadFunction = async(stream, { mediaType, fileEncSha256B64 }) => { - // send a query JSON to obtain the url & auth token to upload our media - let uploadInfo = await refreshMediaConn(false) - - let mediaUrl: string - for (let host of uploadInfo.hosts) { - const auth = encodeURIComponent(uploadInfo.auth) // the auth token - const url = `https://${host.hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` - - try { - const {body: responseText} = await got.post( - url, - { - headers: { - 'Content-Type': 'application/octet-stream', - 'Origin': DEFAULT_ORIGIN - }, - agent: { - https: config.agent - }, - body: stream - } - ) - const result = JSON.parse(responseText) - mediaUrl = result?.url - - if (mediaUrl) break - else { - uploadInfo = await refreshMediaConn(true) - throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) - } - } catch (error) { - const isLast = host.hostname === uploadInfo.hosts[uploadInfo.hosts.length-1].hostname - logger.debug(`Error in uploading to ${host.hostname} (${error}) ${isLast ? '' : ', retrying...'}`) - } - } - if (!mediaUrl) { - throw new Boom( - 'Media upload failed on all hosts', - { statusCode: 500 } - ) - } - return { mediaUrl } - } - - /** Query a string to check if it has a url, if it does, return WAUrlInfo */ - const generateUrlInfo = async(text: string) => { - const response: BinaryNode = await query({ - json: new BinaryNode( - 'query', - { - type: 'url', - url: text, - epoch: currentEpoch().toString() - } - ), - binaryTag: [26, WAFlag.ignore], - expect200: true, - requiresPhoneConnection: false - }) - const urlInfo = { ...response.attributes } as any as WAUrlInfo - if(response && response.data) { - urlInfo.jpegThumbnail = response.data as Buffer - } - return urlInfo - } - - /** Relay (send) a WAMessage; more advanced functionality to send a built WA Message, you may want to stick with sendMessage() */ - const relayWAMessage = async(message: WAMessage, { waitForAck } = { waitForAck: true }) => { - const json = new BinaryNode( - 'action', - { epoch: currentEpoch().toString(), type: 'relay' }, - [ new BinaryNode('message', {}, message) ] - ) - const isMsgToMe = message.key.remoteJid === getState().user?.jid - const flag = isMsgToMe ? WAFlag.acknowledge : WAFlag.ignore // acknowledge when sending message to oneself - const mID = message.key.id - const finalState = isMsgToMe ? WAMessageStatus.READ : WAMessageStatus.SERVER_ACK - - message.status = WAMessageStatus.PENDING - const promise = query({ - json, - binaryTag: [WAMetric.message, flag], - tag: mID, - expect200: true, - requiresPhoneConnection: true - }) - - if(waitForAck) { - await promise - message.status = finalState - } else { - const emitUpdate = (status: WAMessageStatus) => { - message.status = status - ev.emit('messages.update', [ { key: message.key, update: { status } } ]) - } - promise - .then(() => emitUpdate(finalState)) - .catch(() => emitUpdate(WAMessageStatus.ERROR)) - } - - onMessage(message, 'append') - } - - // messages received - const messagesUpdate = ({ data }: BinaryNode, type: 'prepend' | 'last') => { - if(Array.isArray(data)) { - const messages: WAMessage[] = [] - for(let i = data.length-1; i >= 0;i--) { - messages.push(data[i].data as WAMessage) - } - ev.emit('messages.upsert', { messages, type }) - } - } - - socketEvents.on('CB:action,add:last', json => messagesUpdate(json, 'last')) - socketEvents.on('CB:action,add:unread', json => messagesUpdate(json, 'prepend')) - socketEvents.on('CB:action,add:before', json => messagesUpdate(json, 'prepend')) - - // new messages - socketEvents.on('CB:action,add:relay,message', ({data}: BinaryNode) => { - if(Array.isArray(data)) { - for(const { data: msg } of data) { - onMessage(msg as WAMessage, 'notify') - } - } - }) - // If a message has been updated (usually called when a video message gets its upload url, or live locations) - socketEvents.on ('CB:action,add:update,message', ({ data }: BinaryNode) => { - if(Array.isArray(data)) { - for(const { data: msg } of data) { - onMessage(msg as WAMessage, 'update') - } - } - }) - // message status updates - const onMessageStatusUpdate = ({ data }: BinaryNode) => { - if(Array.isArray(data)) { - const updates: WAMessageUpdate[] = [] - for(const { attributes: json } of data) { - const key: WAMessageKey = { - remoteJid: whatsappID(json.jid), - id: json.index, - fromMe: json.owner === 'true' - } - const status = STATUS_MAP[json.type] - - if(status) { - updates.push({ key, update: { status } }) - } else { - logger.warn({ data }, 'got unknown status update for message') - } - } - ev.emit('messages.update', updates) - } - } - const onMessageInfoUpdate = ([,attributes]: [string,{[_: string]: any}]) => { - let ids = attributes.id as string[] | string - if(typeof ids === 'string') { - ids = [ids] - } - let updateKey: keyof MessageInfoUpdate['update'] - switch(attributes.ack.toString()) { - case '2': - updateKey = 'deliveries' - break - case '3': - updateKey = 'reads' - break - default: - logger.warn({ attributes }, `received unknown message info update`) - return - } - const keyPartial = { - remoteJid: whatsappID(attributes.to), - fromMe: whatsappID(attributes.from) === getState().user?.jid, - } - const updates = ids.map(id => ({ - key: { ...keyPartial, id }, - update: { - [updateKey]: { [whatsappID(attributes.participant)]: new Date(+attributes.t) } - } - })) - ev.emit('message-info.update', updates) - // for individual messages - // it means the message is marked read/delivered - if(!isGroupID(keyPartial.remoteJid)) { - ev.emit('messages.update', ids.map(id => ( - { - key: { ...keyPartial, id }, - update: { - status: updateKey === 'deliveries' ? WAMessageStatus.DELIVERY_ACK : WAMessageStatus.READ - } - } - ))) - } - } - - socketEvents.on('CB:action,add:relay,received', onMessageStatusUpdate) - socketEvents.on('CB:action,,received', onMessageStatusUpdate) - - socketEvents.on('CB:Msg', onMessageInfoUpdate) - socketEvents.on('CB:MsgInfo', onMessageInfoUpdate) - - return { - ...sock, - relayWAMessage, - generateUrlInfo, - messageInfo: async(jid: string, messageID: string) => { - const { data }: BinaryNode = await query({ - json: new BinaryNode( - 'query', - {type: 'message_info', index: messageID, jid: jid, epoch: currentEpoch().toString()} - ), - binaryTag: [WAMetric.queryRead, WAFlag.ignore], - expect200: true, - requiresPhoneConnection: true - }) - const info: MessageInfo = { reads: {}, deliveries: {} } - if(Array.isArray(data)) { - for(const { header, data: innerData } of data) { - const [{ attributes }] = (innerData as BinaryNode[]) - const jid = whatsappID(attributes.jid) - const date = new Date(+attributes.t * 1000) - switch(header) { - case 'read': - info.reads[jid] = date - break - case 'delivery': - info.deliveries[jid] = date - break - } - } - } - return info - }, - downloadMediaMessage: async(message: WAMessage, type: 'buffer' | 'stream' = 'buffer') => { - - const downloadMediaMessage = async () => { - let mContent = extractMessageContent(message.message) - if (!mContent) throw new Boom('No message present', { statusCode: 400, data: message }) - - const stream = await decryptMediaMessageBuffer(mContent) - if(type === 'buffer') { - let buffer = Buffer.from([]) - for await(const chunk of stream) { - buffer = Buffer.concat([buffer, chunk]) - } - return buffer - } - return stream - } - - try { - const result = await downloadMediaMessage() - return result - } catch (error) { - if(error.message.includes('404')) { // media needs to be updated - logger.info (`updating media of message: ${message.key.id}`) - - await updateMediaMessage(message) - - const result = await downloadMediaMessage() - return result - } - throw error - } - }, - updateMediaMessage, - fetchMessagesFromWA, - /** Load a single message specified by the ID */ - loadMessageFromWA: async(jid: string, id: string) => { - let message: WAMessage - - // load the message before the given message - let messages = (await fetchMessagesFromWA(jid, 1, { before: {id, fromMe: true} })) - if(!messages[0]) messages = (await fetchMessagesFromWA(jid, 1, { before: {id, fromMe: false} })) - // the message after the loaded message is the message required - const [actual] = await fetchMessagesFromWA(jid, 1, { after: messages[0] && messages[0].key }) - message = actual - return message - }, - searchMessages: async(txt: string, inJid: string | null, count: number, page: number) => { - const {data, attributes}: BinaryNode = await query({ - json: new BinaryNode( - 'query', - { - epoch: currentEpoch().toString(), - type: 'search', - search: txt, - count: count.toString(), - page: page.toString(), - jid: inJid - } - ), - binaryTag: [24, WAFlag.ignore], - expect200: true - }) // encrypt and send off - - const messages = Array.isArray(data) ? data.map(item => item.data as WAMessage) : [] - return { - last: attributes?.last === 'true', - messages - } - }, - sendWAMessage: async( - jid: string, - content: AnyMessageContent, - options: MiscMessageGenerationOptions & { waitForAck?: boolean } - ) => { - const userJid = getState().user?.jid - if( - typeof content === 'object' && - 'disappearingMessagesInChat' in content && - typeof content['disappearingMessagesInChat'] !== 'undefined' && - isGroupID(jid) - ) { - const { disappearingMessagesInChat } = content - const value = typeof disappearingMessagesInChat === 'boolean' ? - (disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : - disappearingMessagesInChat - const tag = generateMessageTag(true) - await setQuery([ - new BinaryNode( - 'group', - { id: tag, jid, type: 'prop', author: userJid }, - [ new BinaryNode('ephemeral', { value: value.toString() }) ] - ) - ], [WAMetric.group, WAFlag.other], tag) - } else { - const msg = await generateWAMessage( - jid, - content, - { - ...options, - logger, - userJid: userJid, - getUrlInfo: generateUrlInfo, - upload: waUploadToServer - } - ) - - await relayWAMessage(msg, { waitForAck: options.waitForAck }) - return msg - } - } - } -} - -export default makeMessagesSocket \ No newline at end of file diff --git a/src/Connection/socket.ts b/src/Connection/socket.ts deleted file mode 100644 index a192638..0000000 --- a/src/Connection/socket.ts +++ /dev/null @@ -1,367 +0,0 @@ -import { Boom } from '@hapi/boom' -import { STATUS_CODES } from "http" -import { promisify } from "util" -import WebSocket from "ws" -import BinaryNode from "../BinaryNode" -import { DisconnectReason, SocketConfig, SocketQueryOptions, SocketSendMessageOptions } from "../Types" -import { aesEncrypt, hmacSign, promiseTimeout, unixTimestampSeconds, decodeWAMessage } from "../Utils" -import { WAFlag, WAMetric, WATag } from "../Types" -import { DEFAULT_ORIGIN, DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, PHONE_CONNECTION_CB } from "../Defaults" - -/** - * Connects to WA servers and performs: - * - simple queries (no retry mechanism, wait for connection establishment) - * - listen to messages and emit events - * - query phone connection - */ -export const makeSocket = ({ - waWebSocketUrl, - connectTimeoutMs, - phoneResponseTimeMs, - logger, - agent, - keepAliveIntervalMs, - expectResponseTimeout, - phoneConnectionChanged -}: SocketConfig) => { - // for generating tags - const referenceDateSeconds = unixTimestampSeconds(new Date()) - const ws = new WebSocket(waWebSocketUrl, undefined, { - origin: DEFAULT_ORIGIN, - timeout: connectTimeoutMs, - agent, - headers: { - 'Accept-Encoding': 'gzip, deflate, br', - 'Accept-Language': 'en-US,en;q=0.9', - 'Cache-Control': 'no-cache', - 'Host': 'web.whatsapp.com', - 'Pragma': 'no-cache', - 'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits', - } - }) - ws.setMaxListeners(0) - let lastDateRecv: Date - let epoch = 0 - let authInfo: { encKey: Buffer, macKey: Buffer } - let keepAliveReq: NodeJS.Timeout - - let phoneCheckInterval: NodeJS.Timeout - let phoneCheckListeners = 0 - - const sendPromise = promisify(ws.send) - /** generate message tag and increment epoch */ - const generateMessageTag = (longTag: boolean = false) => { - const tag = `${longTag ? referenceDateSeconds : (referenceDateSeconds%1000)}.--${epoch}` - epoch += 1 // increment message count, it makes the 'epoch' field when sending binary messages - return tag - } - const sendRawMessage = (data: Buffer | string) => sendPromise.call(ws, data) as Promise - /** - * Send a message to the WA servers - * @returns the tag attached in the message - * */ - const sendMessage = async( - { json, binaryTag, tag, longTag }: SocketSendMessageOptions - ) => { - tag = tag || generateMessageTag(longTag) - let data: Buffer | string - if(logger.level === 'trace') { - logger.trace({ tag, fromMe: true, json, binaryTag }, 'communication') - } - - if(binaryTag) { - if(!(json instanceof BinaryNode)) { - throw new Boom(`Invalid binary message of type "${typeof json}". Must be BinaryNode`, { statusCode: 400 }) - } - if(!authInfo) { - throw new Boom('No encryption/mac keys to encrypt node with', { statusCode: 400 }) - } - const binary = json.toBuffer() // encode the JSON to the WhatsApp binary format - - const buff = aesEncrypt(binary, authInfo.encKey) // encrypt it using AES and our encKey - const sign = hmacSign(buff, authInfo.macKey) // sign the message using HMAC and our macKey - - data = Buffer.concat([ - Buffer.from(tag + ','), // generate & prefix the message tag - Buffer.from(binaryTag), // prefix some bytes that tell whatsapp what the message is about - sign, // the HMAC sign of the message - buff, // the actual encrypted buffer - ]) - } else { - data = `${tag},${JSON.stringify(json)}` - } - await sendRawMessage(data) - return tag - } - const end = (error: Error | undefined) => { - logger.debug({ error }, 'connection closed') - - ws.removeAllListeners('close') - ws.removeAllListeners('error') - ws.removeAllListeners('open') - ws.removeAllListeners('message') - - phoneCheckListeners = 0 - clearInterval(keepAliveReq) - clearPhoneCheckInterval() - - if(ws.readyState !== ws.CLOSED && ws.readyState !== ws.CLOSING) { - try { ws.close() } catch { } - } - - ws.emit('ws-close', error) - ws.removeAllListeners('ws-close') - } - const onMessageRecieved = (message: string | Buffer) => { - if(message[0] === '!') { - // when the first character in the message is an '!', the server is sending a pong frame - const timestamp = message.slice(1, message.length).toString ('utf-8') - lastDateRecv = new Date(parseInt(timestamp)) - ws.emit('received-pong') - } else { - let messageTag: string - let json: any - try { - const dec = decodeWAMessage(message, authInfo) - messageTag = dec[0] - json = dec[1] - if (!json) return - } catch (error) { - end(error) - return - } - //if (this.shouldLogMessages) this.messageLog.push ({ tag: messageTag, json: JSON.stringify(json), fromMe: false }) - - if (logger.level === 'trace') { - logger.trace({ tag: messageTag, fromMe: false, json }, 'communication') - } - - let anyTriggered = false - /* Check if this is a response to a message we sent */ - anyTriggered = ws.emit(`${DEF_TAG_PREFIX}${messageTag}`, json) - /* Check if this is a response to a message we are expecting */ - const l0 = json.header || json[0] || '' - const l1 = json?.attributes || json?.[1] || { } - const l2 = json?.data?.[0]?.header || json[2]?.[0] || '' - - Object.keys(l1).forEach(key => { - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, json) || anyTriggered - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, json) || anyTriggered - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, json) || anyTriggered - }) - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, json) || anyTriggered - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0}`, json) || anyTriggered - - if (!anyTriggered && logger.level === 'debug') { - logger.debug({ unhandled: true, tag: messageTag, fromMe: false, json }, 'communication recv') - } - } - } - - /** Exits a query if the phone connection is active and no response is still found */ - const exitQueryIfResponseNotExpected = (tag: string, cancel: (error: Boom) => void) => { - let timeout: NodeJS.Timeout - const listener = ([, connected]) => { - if(connected) { - timeout = setTimeout(() => { - logger.info({ tag }, `cancelling wait for message as a response is no longer expected from the phone`) - cancel(new Boom('Not expecting a response', { statusCode: 422 })) - }, expectResponseTimeout) - ws.off(PHONE_CONNECTION_CB, listener) - } - } - ws.on(PHONE_CONNECTION_CB, listener) - return () => { - ws.off(PHONE_CONNECTION_CB, listener) - timeout && clearTimeout(timeout) - } - } - /** interval is started when a query takes too long to respond */ - const startPhoneCheckInterval = () => { - phoneCheckListeners += 1 - if (!phoneCheckInterval) { - // if its been a long time and we haven't heard back from WA, send a ping - phoneCheckInterval = setInterval(() => { - if(phoneCheckListeners <= 0) { - logger.warn('phone check called without listeners') - return - } - logger.info('checking phone connection...') - sendAdminTest() - - phoneConnectionChanged(false) - }, phoneResponseTimeMs) - } - } - const clearPhoneCheckInterval = () => { - phoneCheckListeners -= 1 - if (phoneCheckListeners <= 0) { - clearInterval(phoneCheckInterval) - phoneCheckInterval = undefined - phoneCheckListeners = 0 - } - } - /** checks for phone connection */ - const sendAdminTest = () => sendMessage({ json: ['admin', 'test'] }) - /** - * Wait for a message with a certain tag to be received - * @param tag the message tag to await - * @param json query that was sent - * @param timeoutMs timeout after which the promise will reject - */ - const waitForMessage = async(tag: string, requiresPhoneConnection: boolean, timeoutMs?: number) => { - let onRecv: (json) => void - let onErr: (err) => void - let cancelPhoneChecker: () => void - try { - const result = await promiseTimeout(timeoutMs, - (resolve, reject) => { - onRecv = resolve - onErr = err => { - reject(err || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) - } - - if(requiresPhoneConnection) { - startPhoneCheckInterval() - cancelPhoneChecker = exitQueryIfResponseNotExpected(tag, onErr) - } - - ws.on(`TAG:${tag}`, onRecv) - ws.on('ws-close', onErr) // if the socket closes, you'll never receive the message - }, - ) - return result as any - } finally { - requiresPhoneConnection && clearPhoneCheckInterval() - cancelPhoneChecker && cancelPhoneChecker() - - ws.off(`TAG:${tag}`, onRecv) - ws.off('ws-close', onErr) // if the socket closes, you'll never receive the message - } - } - /** - * Query something from the WhatsApp servers - * @param json the query itself - * @param binaryTags the tags to attach if the query is supposed to be sent encoded in binary - * @param timeoutMs timeout after which the query will be failed (set to null to disable a timeout) - * @param tag the tag to attach to the message - */ - const query = async( - {json, timeoutMs, expect200, tag, longTag, binaryTag, requiresPhoneConnection}: SocketQueryOptions - ) => { - tag = tag || generateMessageTag(longTag) - const promise = waitForMessage(tag, requiresPhoneConnection, timeoutMs) - - await sendMessage({ json, tag, binaryTag }) - const response = await promise - const responseStatusCode = +(response.status ? response.status : 200) // default status - // read here: http://getstatuscode.com/599 - if(responseStatusCode === 599) { // the connection has gone bad - end(new Boom('WA server overloaded', { statusCode: 599, data: { query: json, response } })) - } - if(expect200 && Math.floor(responseStatusCode/100) !== 2) { - const message = STATUS_CODES[responseStatusCode] || 'unknown' - throw new Boom( - `Unexpected status in '${Array.isArray(json) ? json[0] : (json?.header || 'query')}': ${message}(${responseStatusCode})`, - { data: { query: json, message }, statusCode: response.status } - ) - } - return response - } - const startKeepAliveRequest = () => ( - keepAliveReq = setInterval(() => { - if (!lastDateRecv) lastDateRecv = new Date() - const diff = Date.now() - lastDateRecv.getTime() - /* - check if it's been a suspicious amount of time since the server responded with our last seen - it could be that the network is down - */ - if (diff > keepAliveIntervalMs+5000) { - end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost })) - } else if(ws.readyState === ws.OPEN) { - sendRawMessage('?,,') // if its all good, send a keep alive request - } else { - logger.warn('keep alive called when WS not open') - } - }, keepAliveIntervalMs) - ) - - const waitForSocketOpen = async() => { - if(ws.readyState === ws.OPEN) return - if(ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { - throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) - } - let onOpen: () => void - let onClose: (err: Error) => void - await new Promise((resolve, reject) => { - onOpen = () => resolve(undefined) - onClose = reject - ws.on('open', onOpen) - ws.on('close', onClose) - ws.on('error', onClose) - }) - .finally(() => { - ws.off('open', onOpen) - ws.off('close', onClose) - ws.off('error', onClose) - }) - } - - ws.on('message', onMessageRecieved) - ws.on('open', () => { - startKeepAliveRequest() - logger.info('Opened WS connection to WhatsApp Web') - }) - ws.on('error', end) - ws.on('close', () => end(new Boom('Connection Terminated', { statusCode: DisconnectReason.connectionLost }))) - - ws.on(PHONE_CONNECTION_CB, json => { - if (!json[1]) { - end(new Boom('Connection terminated by phone', { statusCode: DisconnectReason.connectionLost })) - logger.info('Connection terminated by phone, closing...') - } else { - phoneConnectionChanged(true) - } - }) - ws.on('CB:Cmd,type:disconnect', json => { - const {kind} = json[1] - let reason: DisconnectReason - switch(kind) { - case 'replaced': - reason = DisconnectReason.connectionReplaced - break - default: - reason = DisconnectReason.connectionLost - break - } - end(new Boom( - `Connection terminated by server: "${kind || 'unknown'}"`, - { statusCode: reason } - )) - }) - - return { - ws, - updateKeys: (info: { encKey: Buffer, macKey: Buffer }) => authInfo = info, - waitForSocketOpen, - sendRawMessage, - sendMessage, - generateMessageTag, - waitForMessage, - query, - /** Generic function for action, set queries */ - setQuery: async(nodes: BinaryNode[], binaryTag: WATag = [WAMetric.group, WAFlag.ignore], tag?: string) => { - const json = new BinaryNode('action', { epoch: epoch.toString(), type: 'set' }, nodes) - return query({ - json, - binaryTag, - tag, - expect200: true, - requiresPhoneConnection: true - }) as Promise<{ status: number }> - }, - currentEpoch: () => epoch, - end - } -} -export type Socket = ReturnType \ No newline at end of file diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index d0c7751..ca14a72 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -1,6 +1,6 @@ import P from "pino" import type { MediaType, SocketConfig } from "../Types" -import { Browsers } from "../Utils/generics" +import { Browsers } from "../Utils" export const UNAUTHORIZED_CODES = [401, 403, 419] @@ -13,35 +13,32 @@ export const PHONE_CONNECTION_CB = 'CB:Pong' export const WA_DEFAULT_EPHEMERAL = 7*24*60*60 +export const NOISE_MODE = 'Noise_XX_25519_AESGCM_SHA256\0\0\0\0' +export const NOISE_WA_HEADER = new Uint8Array([87, 65, 5, 2]) // last is "DICT_VERSION" + /** from: https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url */ export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { - version: [2, 2130, 9], + version: [2, 2136, 9], browser: Browsers.baileys('Chrome'), - waWebSocketUrl: 'wss://web.whatsapp.com/ws', + waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', + connectTimeoutMs: 20_000, keepAliveIntervalMs: 25_000, - phoneResponseTimeMs: 15_000, - connectTimeoutMs: 30_000, - expectResponseTimeout: 12_000, logger: P().child({ class: 'baileys' }), - phoneConnectionChanged: () => { }, - maxRetries: 5, - connectCooldownMs: 2500, - pendingRequestTimeoutMs: undefined, - reconnectMode: 'on-connection-error', - maxQRCodes: Infinity, printQRInTerminal: false, } - export const MEDIA_PATH_MAP: { [T in MediaType]: string } = { image: '/mms/image', video: '/mms/video', document: '/mms/document', audio: '/mms/audio', sticker: '/mms/image', + history: '' } -export const MEDIA_KEYS = Object.keys(MEDIA_PATH_MAP) as MediaType[] \ No newline at end of file +export const MEDIA_KEYS = Object.keys(MEDIA_PATH_MAP) as MediaType[] + +export const KEY_BUNDLE_TYPE = '' \ No newline at end of file diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts new file mode 100644 index 0000000..d8c2ec1 --- /dev/null +++ b/src/Socket/chats.ts @@ -0,0 +1,430 @@ +import { decodeSyncdPatch, encodeSyncdPatch } from "../Utils/chat-utils"; +import { SocketConfig, WAPresence, PresenceData, Chat, ChatModification, WAMediaUpload } from "../Types"; +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET } from "../WABinary"; +import { makeSocket } from "./socket"; +import { proto } from '../../WAProto' +import { toNumber } from "../Utils/generics"; +import { compressImage, generateProfilePicture } from ".."; + +export const makeChatsSocket = (config: SocketConfig) => { + const { logger } = config + const sock = makeSocket(config) + const { + ev, + ws, + authState, + generateMessageTag, + sendNode, + query + } = sock + + const interactiveQuery = async(userNodes: BinaryNode[], queryNode: BinaryNode) => { + const result = await query({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'get', + xmlns: 'usync', + + }, + content: [ + { + tag: 'usync', + attrs: { + sid: generateMessageTag(), + mode: 'query', + last: 'true', + index: '0', + context: 'interactive', + }, + content: [ + { + tag: 'query', + attrs: { }, + content: [ queryNode ] + }, + { + tag: 'list', + attrs: { }, + content: userNodes + } + ] + } + ], + }) + + const usyncNode = getBinaryNodeChild(result, 'usync') + const listNode = getBinaryNodeChild(usyncNode, 'list') + const users = getBinaryNodeChildren(listNode, 'user') + + return users + } + + const onWhatsApp = async(...jids: string[]) => { + const results = await interactiveQuery( + [ + { + tag: 'user', + attrs: { }, + content: jids.map( + jid => ({ + tag: 'contact', + attrs: { }, + content: `+${jid}` + }) + ) + } + ], + { tag: 'contact', attrs: { } } + ) + + return results.map(user => { + const contact = getBinaryNodeChild(user, 'contact') + return { exists: contact.attrs.type === 'in', jid: user.attrs.jid } + }).filter(item => item.exists) + } + + const fetchStatus = async(jid: string) => { + const [result] = await interactiveQuery( + [{ tag: 'user', attrs: { jid } }], + { tag: 'status', attrs: { } } + ) + if(result) { + const status = getBinaryNodeChild(result, 'status') + return { + status: status.content!.toString(), + setAt: new Date(+status.attrs.t * 1000) + } + } + } + + const updateProfilePicture = async(jid: string, content: WAMediaUpload) => { + const { img } = await generateProfilePicture('url' in content ? content.url.toString() : content) + await query({ + tag: 'iq', + attrs: { + to: jidNormalizedUser(jid), + type: 'set', + xmlns: 'w:profile:picture' + }, + content: [ + { + tag: 'picture', + attrs: { type: 'image' }, + content: img + } + ] + }) + } + + const fetchBlocklist = async() => { + const result = await query({ + tag: 'iq', + attrs: { + xmlns: 'blocklist', + to: S_WHATSAPP_NET, + type: 'get' + } + }) + console.log('blocklist', result) + } + + const updateBlockStatus = async(jid: string, action: 'block' | 'unblock') => { + await query({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'set' + }, + content: [ + { + tag: 'item', + attrs: { + action, + jid + } + } + ] + }) + } + + const fetchPrivacySettings = async() => { + const result = await query({ + tag: 'iq', + attrs: { + xmlns: 'privacy', + to: S_WHATSAPP_NET, + type: 'get' + } + }) + console.log('privacy', result) + } + + const updateAccountSyncTimestamp = async() => { + await sendNode({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'set', + xmlns: 'urn:xmpp:whatsapp:dirty', + id: generateMessageTag(), + }, + content: [ + { + tag: 'clean', + attrs: { } + } + ] + }) + } + + const collectionSync = async() => { + const COLLECTIONS = ['critical_block', 'critical_unblock_low', 'regular_low', 'regular_high'] + await sendNode({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + xmlns: 'w:sync:app:state', + type: 'set', + id: generateMessageTag(), + }, + content: [ + { + tag: 'sync', + attrs: { }, + content: COLLECTIONS.map( + name => ({ + tag: 'collection', + attrs: { name, version: '0', return_snapshot: 'true' } + }) + ) + } + ] + }) + logger.info('synced collection') + } + + const profilePictureUrl = async(jid: string) => { + const result = await query({ + tag: 'iq', + attrs: { + to: jid, + type: 'get', + xmlns: 'w:profile:picture' + }, + content: [ + { tag: 'picture', attrs: { type: 'preview', query: 'url' } } + ] + }) + const child = getBinaryNodeChild(result, 'picture') + return child?.attrs?.url + } + + const sendPresenceUpdate = async(type: WAPresence, toJid?: string) => { + if(type === 'available' || type === 'unavailable') { + await sendNode({ + tag: 'presence', + attrs: { + name: authState.creds.me!.name, + type + } + }) + } else { + await sendNode({ + tag: 'chatstate', + attrs: { + from: authState.creds.me!.id!, + to: toJid, + }, + content: [ + { tag: type, attrs: { } } + ] + }) + } + } + + const presenceSubscribe = (toJid: string) => ( + sendNode({ + tag: 'presence', + attrs: { + to: toJid, + id: generateMessageTag(), + type: 'subscribe' + } + }) + ) + + const handlePresenceUpdate = ({ tag, attrs, content }: BinaryNode) => { + let presence: PresenceData + const jid = attrs.from + const participant = attrs.participant || attrs.from + if(tag === 'presence') { + presence = { + lastKnownPresence: attrs.type === 'unavailable' ? 'unavailable' : 'available', + lastSeen: attrs.t ? +attrs.t : undefined + } + } else if(Array.isArray(content)) { + const [firstChild] = content + let type = firstChild.tag as WAPresence + if(type === 'paused') { + type = 'available' + } + presence = { lastKnownPresence: type } + } else { + logger.error({ tag, attrs, content }, 'recv invalid presence node') + } + if(presence) { + ev.emit('presence.update', { id: jid, presences: { [participant]: presence } }) + } + } + + const processSyncActions = (actions: { action: proto.ISyncActionValue, index: [string, string] }[]) => { + const updates: Partial[] = [] + for(const { action, index: [_, id] } of actions) { + const update: Partial = { id } + if(action?.muteAction) { + update.mute = action.muteAction?.muted ? + toNumber(action.muteAction!.muteEndTimestamp!) : + undefined + } else if(action?.archiveChatAction) { + update.archive = !!action.archiveChatAction?.archived + } else if(action?.markChatAsReadAction) { + update.unreadCount = !!action.markChatAsReadAction?.read ? 0 : -1 + } else if(action?.clearChatAction) { + console.log(action.clearChatAction) + } else if(action?.contactAction) { + ev.emit('contacts.update', [{ id, name: action.contactAction!.fullName }]) + } else if(action?.pushNameSetting) { + authState.creds.me!.name = action?.pushNameSetting?.name! + ev.emit('auth-state.update', authState) + } else { + logger.warn({ action, id }, 'unprocessable update') + } + updates.push(update) + } + ev.emit('chats.update', updates) + } + + const patchChat = async( + jid: string, + modification: ChatModification + ) => { + const patch = encodeSyncdPatch(modification, { remoteJid: jid }, authState) + const type = 'regular_high' + const ver = authState.creds.appStateVersion![type] || 0 + const node: BinaryNode = { + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'set', + xmlns: 'w:sync:app:state' + }, + content: [ + { + tag: 'patch', + attrs: { + name: type, + version: (ver+1).toString(), + return_snapshot: 'false' + }, + content: proto.SyncdPatch.encode(patch).finish() + } + ] + } + await query(node) + + authState.creds.appStateVersion![type] += 1 + ev.emit('auth-state.update', authState) + } + + const resyncState = async(name: 'regular_high' | 'regular_low' = 'regular_high') => { + authState.creds.appStateVersion = authState.creds.appStateVersion || { + regular_high: 0, + regular_low: 0, + critical_unblock_low: 0, + critical_block: 0 + } + const result = await query({ + tag: 'iq', + attrs: { + type: 'set', + xmlns: 'w:sync:app:state', + to: S_WHATSAPP_NET + }, + content: [ + { + tag: 'sync', + attrs: { }, + content: [ + { + tag: 'collection', + attrs: { + name, + version: authState.creds.appStateVersion[name].toString(), + return_snapshot: 'false' + } + } + ] + } + ] + }) + const syncNode = getBinaryNodeChild(result, 'sync') + const collectionNode = getBinaryNodeChild(syncNode, 'collection') + const patchesNode = getBinaryNodeChild(collectionNode, 'patches') + + const patches = getBinaryNodeChildren(patchesNode, 'patch') + const successfulMutations = patches.flatMap(({ content }) => { + if(content) { + const syncd = proto.SyncdPatch.decode(content! as Uint8Array) + const version = toNumber(syncd.version!.version!) + if(version) { + authState.creds.appStateVersion[name] = Math.max(version, authState.creds.appStateVersion[name]) + } + const { mutations, failures } = decodeSyncdPatch(syncd, authState) + if(failures.length) { + logger.info( + { failures: failures.map(f => ({ trace: f.stack, data: f.data })) }, + 'failed to decode' + ) + } + return mutations + } + return [] + }) + processSyncActions(successfulMutations) + ev.emit('auth-state.update', authState) + } + + ws.on('CB:presence', handlePresenceUpdate) + ws.on('CB:chatstate', handlePresenceUpdate) + + ws.on('CB:notification,type:server_sync', (node: BinaryNode) => { + const update = getBinaryNodeChild(node, 'collection') + if(update) { + resyncState(update.attrs.name as any) + } + }) + + ev.on('connection.update', ({ connection }) => { + if(connection === 'open') { + sendPresenceUpdate('available') + fetchBlocklist() + fetchPrivacySettings() + //collectionSync() + } + }) + + return { + ...sock, + patchChat, + sendPresenceUpdate, + presenceSubscribe, + profilePictureUrl, + onWhatsApp, + fetchBlocklist, + fetchPrivacySettings, + fetchStatus, + updateProfilePicture, + updateBlockStatus + } +} \ No newline at end of file diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts new file mode 100644 index 0000000..40eb113 --- /dev/null +++ b/src/Socket/groups.ts @@ -0,0 +1,149 @@ +import { generateMessageID } from "../Utils"; +import { SocketConfig, GroupMetadata, ParticipantAction } from "../Types"; +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidDecode, jidEncode } from "../WABinary"; +import { makeChatsSocket } from "./chats"; + +const extractGroupMetadata = (result: BinaryNode) => { + const group = getBinaryNodeChild(result, 'group') + const descChild = getBinaryNodeChild(group, 'description') + let desc: string | undefined + let descId: string | undefined + if(descChild) { + desc = getBinaryNodeChild(descChild, 'body')?.content as string + descId = descChild.attrs.id + } + + const metadata: GroupMetadata = { + id: jidEncode(jidDecode(group.attrs.id).user, 'g.us'), + subject: group.attrs.subject, + creation: +group.attrs.creation, + owner: group.attrs.creator, + desc, + descId, + restrict: !!getBinaryNodeChild(result, 'locked') ? 'true' : 'false', + announce: !!getBinaryNodeChild(result, 'announcement') ? 'true' : 'false', + participants: getBinaryNodeChildren(group, 'participant').map( + ({ attrs }) => { + return { + id: attrs.jid, + admin: attrs.type || null as any, + } + } + ) + } + return metadata +} + +export const makeGroupsSocket = (config: SocketConfig) => { + const sock = makeChatsSocket(config) + const { query } = sock + + const groupQuery = async(jid: string, type: 'get' | 'set', content: BinaryNode[]) => ( + query({ + tag: 'iq', + attrs: { + type, + xmlns: 'w:g2', + to: jid, + }, + content + }) + ) + + const groupMetadata = async(jid: string) => { + const result = await groupQuery( + jid, + 'get', + [ { tag: 'query', attrs: { request: 'interactive' } } ] + ) + return extractGroupMetadata(result) + } + + return { + ...sock, + groupMetadata, + groupCreate: async(subject: string, participants: string[]) => { + const key = generateMessageID() + const result = await groupQuery( + '@g.us', + 'set', + [ + { + tag: 'create', + attrs: { + subject, + key + }, + content: participants.map(jid => ({ + tag: 'participant', + attrs: { jid } + })) + } + ] + ) + return extractGroupMetadata(result) + }, + groupLeave: async(jid: string) => { + await groupQuery( + '@g.us', + 'set', + [ + { + tag: 'leave', + attrs: { }, + content: [ + { tag: 'group', attrs: { jid } } + ] + } + ] + ) + }, + groupUpdateSubject: async(jid: string, subject: string) => { + await groupQuery( + jid, + 'set', + [ + { + tag: 'subject', + attrs: { }, + content: Buffer.from(subject, 'utf-8') + } + ] + ) + }, + groupParticipantsUpdate: async( + jid: string, + participants: string[], + action: ParticipantAction + ) => { + const result = await groupQuery( + jid, + 'set', + participants.map( + jid => ({ + tag: action, + attrs: { }, + content: [{ tag: 'participant', attrs: { jid } }] + }) + ) + ) + const node = getBinaryNodeChild(result, action) + const participantsAffected = getBinaryNodeChildren(node!, 'participant') + return participantsAffected.map(p => p.attrs.jid) + }, + groupInviteCode: async(jid: string) => { + const result = await groupQuery(jid, 'get', [{ tag: 'invite', attrs: {} }]) + const inviteNode = getBinaryNodeChild(result, 'invite') + return inviteNode.attrs.code + }, + groupToggleEphemeral: async(jid: string, ephemeralExpiration: number) => { + const content: BinaryNode = ephemeralExpiration ? + { tag: 'ephemeral', attrs: { ephemeral: ephemeralExpiration.toString() } } : + { tag: 'not_ephemeral', attrs: { } } + await groupQuery(jid, 'set', [content]) + }, + groupSettingUpdate: async(jid: string, setting: 'announcement' | 'not_announcement' | 'locked' | 'unlocked') => { + await groupQuery(jid, 'set', [ { tag: setting, attrs: { } } ]) + } + } +} \ No newline at end of file diff --git a/src/Socket/index.ts b/src/Socket/index.ts new file mode 100644 index 0000000..0ffddfe --- /dev/null +++ b/src/Socket/index.ts @@ -0,0 +1,13 @@ +import { SocketConfig } from '../Types' +import { DEFAULT_CONNECTION_CONFIG } from '../Defaults' +import { makeMessagesSocket as _makeSocket } from './messages-send' + +// export the last socket layer +const makeWASocket = (config: Partial) => ( + _makeSocket({ + ...DEFAULT_CONNECTION_CONFIG, + ...config + }) +) + +export default makeWASocket \ No newline at end of file diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts new file mode 100644 index 0000000..6f5a14c --- /dev/null +++ b/src/Socket/messages-recv.ts @@ -0,0 +1,437 @@ + +import { makeGroupsSocket } from "./groups" +import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata } from "../Types" +import { decodeMessageStanza, encodeBigEndian, toNumber, whatsappID } from "../Utils" +import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, S_WHATSAPP_NET, areJidsSameUser, getBinaryNodeChildren, getBinaryNodeChild } from '../WABinary' +import { downloadIfHistory } from '../Utils/history' +import { proto } from "../../WAProto" +import { generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils/signal" +import { KEY_BUNDLE_TYPE } from "../Defaults" + +export const makeMessagesRecvSocket = (config: SocketConfig) => { + const { logger } = config + const sock = makeGroupsSocket(config) + const { + ev, + authState, + ws, + assertingPreKeys, + sendNode, + } = sock + + const sendMessageAck = async({ attrs }: BinaryNode) => { + const isGroup = !!attrs.participant + const { user: meUser } = jidDecode(authState.creds.me!.id!) + const stanza: BinaryNode = { + tag: 'ack', + attrs: { + class: 'receipt', + id: attrs.id, + to: isGroup ? attrs.from : authState.creds.me!.id, + } + } + if(isGroup) { + stanza.attrs.participant = jidEncode(meUser, 's.whatsapp.net') + } + await sendNode(stanza) + } + + const sendRetryRequest = async(node: BinaryNode) => { + const retryCount = +(node.attrs.retryCount || 0) + 1 + const isGroup = !!node.attrs.participant + const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds + + const deviceIdentity = proto.ADVSignedDeviceIdentity.encode(account).finish() + await assertingPreKeys(1, async preKeys => { + const [keyId] = Object.keys(preKeys) + const key = preKeys[+keyId] + + const decFrom = node.attrs.from ? jidDecode(node.attrs.from) : undefined + const receipt: BinaryNode = { + tag: 'receipt', + attrs: { + id: node.attrs.id, + type: 'retry', + to: isGroup ? node.attrs.from : jidEncode(decFrom!.user, 's.whatsapp.net', decFrom!.device, 0) + }, + content: [ + { + tag: 'retry', + attrs: { + count: retryCount.toString(), id: node.attrs.id, + t: node.attrs.t, + v: '1' + } + }, + { + tag: 'registration', + attrs: { }, + content: encodeBigEndian(authState.creds.registrationId) + } + ] + } + if(node.attrs.recipient) { + receipt.attrs.recipient = node.attrs.recipient + } + if(node.attrs.participant) { + receipt.attrs.participant = node.attrs.participant + } + if(retryCount > 1) { + const exec = generateSignalPubKey(Buffer.from(KEY_BUNDLE_TYPE)).slice(0, 1); + + (node.content! as BinaryNode[]).push({ + tag: 'keys', + attrs: { }, + content: [ + { tag: 'type', attrs: { }, content: exec }, + { tag: 'identity', attrs: { }, content: identityKey.public }, + xmppPreKey(key, +keyId), + xmppSignedPreKey(signedPreKey), + { tag: 'device-identity', attrs: { }, content: deviceIdentity } + ] + }) + } + await sendNode(node) + + logger.info({ msgId: node.attrs.id, retryCount }, 'sent retry receipt') + + ev.emit('auth-state.update', authState) + }) + } + + const processMessage = (message: proto.IWebMessageInfo, chatUpdate: Partial) => { + const protocolMsg = message.message?.protocolMessage + if(protocolMsg) { + switch(protocolMsg.type) { + case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_SHARE: + const newKeys = JSON.parse(JSON.stringify(protocolMsg.appStateSyncKeyShare!.keys)) + authState.creds.appStateSyncKeys = [ + ...(authState.creds.appStateSyncKeys || []), + ...newKeys + ] + ev.emit('auth-state.update', authState) + break + case proto.ProtocolMessage.ProtocolMessageType.REVOKE: + ev.emit('messages.update', [ + { + key: protocolMsg.key, + update: { message: null, messageStubType: 1, key: message.key } + } + ]) + break + case proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING: + chatUpdate.ephemeralSettingTimestamp = toNumber(message.messageTimestamp) + chatUpdate.ephemeralExpiration = protocolMsg.ephemeralExpiration + break + } + } else if(message.messageStubType) { + const meJid = authState.creds.me!.id + const jid = message.key!.remoteJid! + //let actor = whatsappID (message.participant) + let participants: string[] + const emitParticipantsUpdate = (action: ParticipantAction) => ( + ev.emit('group-participants.update', { id: jid, participants, action }) + ) + const emitGroupUpdate = (update: Partial) => { + ev.emit('groups.update', [ { id: jid, ...update } ]) + } + + switch (message.messageStubType) { + case WAMessageStubType.GROUP_PARTICIPANT_LEAVE: + case WAMessageStubType.GROUP_PARTICIPANT_REMOVE: + participants = message.messageStubParameters.map(whatsappID) + emitParticipantsUpdate('remove') + // mark the chat read only if you left the group + if (participants.includes(meJid)) { + chatUpdate.readOnly = true + } + break + case WAMessageStubType.GROUP_PARTICIPANT_ADD: + case WAMessageStubType.GROUP_PARTICIPANT_INVITE: + case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN: + participants = message.messageStubParameters.map(whatsappID) + if (participants.includes(meJid)) { + chatUpdate.readOnly = false + } + emitParticipantsUpdate('add') + break + case WAMessageStubType.GROUP_CHANGE_ANNOUNCE: + const announce = message.messageStubParameters[0] === 'on' ? 'true' : 'false' + emitGroupUpdate({ announce }) + break + case WAMessageStubType.GROUP_CHANGE_RESTRICT: + const restrict = message.messageStubParameters[0] === 'on' ? 'true' : 'false' + emitGroupUpdate({ restrict }) + break + case WAMessageStubType.GROUP_CHANGE_SUBJECT: + case WAMessageStubType.GROUP_CREATE: + chatUpdate.name = message.messageStubParameters[0] + emitGroupUpdate({ subject: chatUpdate.name }) + break + } + } + } + + const processHistoryMessage = (item: proto.HistorySync) => { + switch(item.syncType) { + case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_BOOTSTRAP: + const messages: proto.IWebMessageInfo[] = [] + const chats = item.conversations!.map( + c => { + const chat: Chat = { ...c } + //@ts-expect-error + delete chat.messages + for(const item of c.messages || []) { + messages.push(item.message) + } + return chat + } + ) + ev.emit('chats.set', { chats, messages }) + break + case proto.HistorySync.HistorySyncHistorySyncType.PUSH_NAME: + const contacts = item.pushnames.map( + p => ({ notify: p.pushname, id: p.id }) + ) + ev.emit('contacts.upsert', contacts) + break + case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_STATUS_V3: + // TODO + break + } + } + + const processNotification = (node: BinaryNode): Partial => { + const result: Partial = { } + const child = (node.content as BinaryNode[])?.[0] + + if(node.attrs.type === 'w:gp2') { + switch(child?.tag) { + case 'ephemeral': + case 'not_ephemeral': + result.message = { + protocolMessage: { + type: proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING, + ephemeralExpiration: +(child.attrs.expiration || 0) + } + } + break + case 'promote': + case 'demote': + case 'remove': + case 'add': + case 'leave': + const stubType = `GROUP_PARTICIPANT_${child.tag!.toUpperCase()}` + result.messageStubType = WAMessageStubType[stubType] + result.messageStubParameters = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid) + break + case 'subject': + result.messageStubType = WAMessageStubType.GROUP_CHANGE_SUBJECT + result.messageStubParameters = [ child.attrs.subject ] + break + case 'announcement': + case 'not_announcement': + result.messageStubType = WAMessageStubType.GROUP_CHANGE_ANNOUNCE + result.messageStubParameters = [ (child.tag === 'announcement').toString() ] + break + case 'locked': + case 'unlocked': + result.messageStubType = WAMessageStubType.GROUP_CHANGE_RESTRICT + result.messageStubParameters = [ (child.tag === 'locked').toString() ] + break + + } + } else { + switch(child.tag) { + case 'count': + if(child.attrs.value === '0') { + logger.info('recv all pending notifications') + ev.emit('connection.update', { receivedPendingNotifications: true }) + } + break + case 'devices': + const devices = getBinaryNodeChildren(child, 'device') + if(areJidsSameUser(child.attrs.jid, authState.creds!.me!.id)) { + const deviceJids = devices.map(d => d.attrs.jid) + logger.info({ deviceJids }, 'got my own devices') + } + break + } + } + if(Object.keys(result).length) { + return result + } + } + // recv a message + ws.on('CB:message', async(stanza: BinaryNode) => { + const dec = await decodeMessageStanza(stanza, authState) + const fullMessages: proto.IWebMessageInfo[] = [] + for(const msg of dec.successes) { + const { attrs } = stanza + const isGroup = !!stanza.attrs.participant + const sender = (attrs.participant || attrs.from)?.toString() + const isMe = areJidsSameUser(sender, authState.creds.me!.id) + + await sendMessageAck(stanza) + + logger.debug({ msgId: dec.msgId, sender }, 'send message ack') + + // send delivery receipt + let recpAttrs: { [_: string]: any } + if(isMe) { + recpAttrs = { + type: 'sender', + id: stanza.attrs.id, + to: stanza.attrs.from, + } + if(isGroup) { + recpAttrs.participant = stanza.attrs.participant + } else { + recpAttrs.recipient = stanza.attrs.recipient + } + } else { + const isStatus = isJidStatusBroadcast(stanza.attrs.from) + recpAttrs = { + //type: 'inactive', + id: stanza.attrs.id, + to: dec.chatId, + } + if(isGroup || isStatus) { + recpAttrs.participant = stanza.attrs.participant + } + } + await sendNode({ tag: 'receipt', attrs: recpAttrs }) + + logger.debug({ msgId: dec.msgId }, 'send message receipt') + + const possibleHistory = downloadIfHistory(msg) + if(possibleHistory) { + const history = await possibleHistory + logger.info({ msgId: dec.msgId, type: history.syncType }, 'recv history') + + processHistoryMessage(history) + } else { + const message = msg.deviceSentMessage?.message || msg + fullMessages.push({ + key: { + remoteJid: dec.chatId, + fromMe: isMe, + id: dec.msgId, + participant: dec.participant + }, + message, + status: isMe ? proto.WebMessageInfo.WebMessageInfoStatus.SERVER_ACK : null, + messageTimestamp: dec.timestamp, + pushName: dec.pushname + }) + } + } + + if(dec.successes.length) { + ev.emit('auth-state.update', authState) + if(fullMessages.length) { + ev.emit( + 'messages.upsert', + { + messages: fullMessages.map(m => proto.WebMessageInfo.fromObject(m)), + type: stanza.attrs.offline ? 'append' : 'notify' + } + ) + } + } + + for(const { error } of dec.failures) { + logger.error( + { msgId: dec.msgId, trace: error.stack, data: error.data }, + 'failure in decrypting message' + ) + await sendRetryRequest(stanza) + } + }) + + ws.on('CB:ack,class:message', async(node: BinaryNode) => { + await sendNode({ + tag: 'ack', + attrs: { + class: 'receipt', + id: node.attrs.id, + from: node.attrs.from + } + }) + logger.debug({ attrs: node.attrs }, 'sending receipt for ack') + }) + + const handleReceipt = ({ attrs, content }: BinaryNode) => { + const sender = attrs.participant || attrs.from + const status = attrs.type === 'read' ? proto.WebMessageInfo.WebMessageInfoStatus.READ : proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK + const ids = [attrs.id] + if(Array.isArray(content)) { + const items = getBinaryNodeChildren(content[0], 'item') + ids.push(...items.map(i => i.attrs.id)) + } + + ev.emit('messages.update', ids.map(id => ({ + key: { + remoteJid: attrs.from, + id: id, + fromMe: areJidsSameUser(sender, authState.creds.me!.id!), + participant: attrs.participant + }, + update: { status } + }))) + } + + ws.on('CB:receipt,type:read', handleReceipt) + ws.on('CB:ack,class:receipt', handleReceipt) + + ws.on('CB:notification', async(node: BinaryNode) => { + const sendAck = async() => { + await sendNode({ + tag: 'ack', + attrs: { + class: 'notification', + id: node.attrs.id, + type: node.attrs.type, + to: node.attrs.from + } + }) + + logger.debug({ msgId: node.attrs.id }, 'ack notification') + } + + await sendAck() + + const msg = processNotification(node) + if(msg) { + const fromMe = areJidsSameUser(node.attrs.participant || node.attrs.from, authState.creds.me!.id) + msg.key = { + remoteJid: node.attrs.from, + fromMe, + participant: node.attrs.participant, + id: node.attrs.id + } + msg.messageTimestamp = +node.attrs.t + + const fullMsg = proto.WebMessageInfo.fromObject(msg) + ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) + } + }) + + ev.on('messages.upsert', ({ messages }) => { + const chat: Partial = { id: messages[0].key.remoteJid } + for(const msg of messages) { + processMessage(msg, chat) + if(!!msg.message && !msg.message!.protocolMessage) { + chat.conversationTimestamp = toNumber(msg.messageTimestamp) + if(!msg.key.fromMe) { + chat.unreadCount = (chat.unreadCount || 0) + 1 + } + } + } + if(Object.keys(chat).length > 1) { + ev.emit('chats.update', [ chat ]) + } + }) + + return sock +} \ No newline at end of file diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts new file mode 100644 index 0000000..509c4f4 --- /dev/null +++ b/src/Socket/messages-send.ts @@ -0,0 +1,392 @@ + +import { makeMessagesRecvSocket } from "./messages-recv" +import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction } from "../Types" +import { encodeWAMessage, generateMessageID, generateWAMessage } from "../Utils" +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, S_WHATSAPP_NET } from '../WABinary' +import { proto } from "../../WAProto" +import { encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESession } from "../Utils/signal" +import { WA_DEFAULT_EPHEMERAL, DEFAULT_ORIGIN, MEDIA_PATH_MAP } from "../Defaults" +import got from "got" +import { Boom } from "@hapi/boom" + +export const makeMessagesSocket = (config: SocketConfig) => { + const { logger } = config + const sock = makeMessagesRecvSocket(config) + const { + ev, + authState, + query, + generateMessageTag, + sendNode, + groupMetadata, + groupToggleEphemeral + } = sock + + let mediaConn: Promise + const refreshMediaConn = async(forceGet = false) => { + let media = await mediaConn + if (!media || forceGet || (new Date().getTime()-media.fetchDate.getTime()) > media.ttl*1000) { + mediaConn = (async() => { + const result = await query({ + tag: 'iq', + attrs: { + type: 'set', + xmlns: 'w:m', + to: S_WHATSAPP_NET, + }, + content: [ { tag: 'media_conn', attrs: { } } ] + }) + const mediaConnNode = getBinaryNodeChild(result, 'media_conn') + const node: MediaConnInfo = { + hosts: getBinaryNodeChildren(mediaConnNode, 'host').map( + item => item.attrs as any + ), + auth: mediaConnNode.attrs.auth, + ttl: +mediaConnNode.attrs.ttl, + fetchDate: new Date() + } + logger.debug('fetched media conn') + return node + })() + } + return mediaConn + } + + const sendReadReceipt = async(jid: string, participant: string | undefined, messageIds: string[]) => { + const node: BinaryNode = { + tag: 'receipt', + attrs: { + id: messageIds[0], + t: Date.now().toString(), + to: jid, + type: 'read' + }, + } + if(participant) { + node.attrs.participant = participant + } + messageIds = messageIds.slice(1) + if(messageIds.length) { + node.content = [ + { + tag: 'list', + attrs: { }, + content: messageIds.map(id => ({ + tag: 'item', + attrs: { id } + })) + } + ] + } + + logger.debug({ jid, messageIds }, 'reading messages') + await sendNode(node) + } + + const getUSyncDevices = async(jids: string[], ignoreZeroDevices: boolean) => { + const users = jids.map(jid => ({ tag: 'user', attrs: { jid } })) + const iq: BinaryNode = { + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'get', + xmlns: 'usync', + }, + content: [ + { + tag: 'usync', + attrs: { + sid: generateMessageTag(), + mode: 'query', + last: 'true', + index: '0', + context: 'message', + }, + content: [ + { + tag: 'query', + attrs: { }, + content: [ + { + tag: 'devices', + attrs: { version: '2' } + } + ] + }, + { tag: 'list', attrs: { }, content: users } + ] + }, + ], + } + const result = await query(iq) + let resultJids = extractDeviceJids(result) + if(ignoreZeroDevices) { + resultJids = resultJids.filter(item => item.device !== 0) + } + + return resultJids + } + + const assertSession = async(jid: string, force: boolean) => { + const addr = jidToSignalProtocolAddress(jid).toString() + const session = await authState.keys.getSession(addr) + if(!session || force) { + logger.debug({ jid }, `fetching session`) + const identity: BinaryNode = { + tag: 'user', + attrs: { jid, reason: 'identity' }, + } + const result = await query({ + tag: 'iq', + attrs: { + xmlns: 'encrypt', + type: 'get', + to: S_WHATSAPP_NET, + }, + content: [ + { + tag: 'key', + attrs: { }, + content: [ identity ] + } + ] + }) + await parseAndInjectE2ESession(result, authState) + return true + } + return false + } + + const createParticipantNode = async(jid: string, bytes: Buffer) => { + await assertSession(jid, false) + + const { type, ciphertext } = await encryptSignalProto(jid, bytes, authState) + const node: BinaryNode = { + tag: 'to', + attrs: { jid }, + content: [{ + tag: 'enc', + attrs: { v: '2', type }, + content: ciphertext + }] + } + return node + } + + const relayMessage = async(jid: string, message: proto.IMessage, msgId?: string) => { + const { user, server } = jidDecode(jid) + const isGroup = server === 'g.us' + msgId = msgId || generateMessageID() + const encodedMsg = encodeWAMessage(message) + const participants: BinaryNode[] = [] + let stanza: BinaryNode + + const destinationJid = jidEncode(user, isGroup ? 'g.us' : 's.whatsapp.net') + + if(isGroup) { + const { ciphertext, senderKeyDistributionMessageKey } = await encryptSenderKeyMsgSignalProto(destinationJid, encodedMsg, authState) + const groupData = await groupMetadata(jid) + const participantsList = groupData.participants.map(p => p.id) + const devices = await getUSyncDevices(participantsList, false) + + logger.debug(`got ${devices.length} additional devices`) + + const encSenderKeyMsg = encodeWAMessage({ + senderKeyDistributionMessage: { + axolotlSenderKeyDistributionMessage: senderKeyDistributionMessageKey, + groupId: destinationJid + } + }) + + for(const {user, device, agent} of devices) { + const jid = jidEncode(user, 's.whatsapp.net', device, agent) + const participant = await createParticipantNode(jid, encSenderKeyMsg) + participants.push(participant) + } + + const binaryNodeContent: BinaryNode[] = [] + if( // if there are some participants with whom the session has not been established + // if there are, we overwrite the senderkey + !!participants.find((p) => ( + !!(p.content as BinaryNode[]).find(({ attrs }) => attrs.type == 'pkmsg') + )) + ) { + binaryNodeContent.push({ + tag: 'participants', + attrs: { }, + content: participants + }) + } + + binaryNodeContent.push({ + tag: 'enc', + attrs: { v: '2', type: 'skmsg' }, + content: ciphertext + }) + + stanza = { + tag: 'message', + attrs: { + id: msgId, + type: 'text', + to: destinationJid + }, + content: binaryNodeContent + } + } else { + const { user: meUser } = jidDecode(authState.creds.me!.id!) + + const messageToMyself: proto.IMessage = { + deviceSentMessage: { + destinationJid, + message + } + } + const encodedMeMsg = encodeWAMessage(messageToMyself) + + participants.push( + await createParticipantNode(jidEncode(user, 's.whatsapp.net'), encodedMsg) + ) + participants.push( + await createParticipantNode(jidEncode(meUser, 's.whatsapp.net'), encodedMeMsg) + ) + const devices = await getUSyncDevices([ authState.creds.me!.id!, jid ], true) + + logger.debug(`got ${devices.length} additional devices`) + + for(const { user, device, agent } of devices) { + const isMe = user === meUser + participants.push( + await createParticipantNode( + jidEncode(user, 's.whatsapp.net', device, agent), + isMe ? encodedMeMsg : encodedMsg + ) + ) + } + + stanza = { + tag: 'message', + attrs: { + id: msgId, + type: 'text', + to: destinationJid + }, + content: [ + { + tag: 'participants', + attrs: { }, + content: participants + }, + ] + } + } + + const shouldHaveIdentity = !!participants.find((p) => ( + !!(p.content as BinaryNode[]).find(({ attrs }) => attrs.type == 'pkmsg') + )) + + if(shouldHaveIdentity) { + (stanza.content as BinaryNode[]).push({ + tag: 'device-identity', + attrs: { }, + content: proto.ADVSignedDeviceIdentity.encode(authState.creds.account).finish() + }) + } + logger.debug({ msgId }, 'sending message') + + await sendNode(stanza) + + ev.emit('auth-state.update', authState) + return msgId + } + + const waUploadToServer: WAMediaUploadFunction = async(stream, { mediaType, fileEncSha256B64 }) => { + // send a query JSON to obtain the url & auth token to upload our media + let uploadInfo = await refreshMediaConn(false) + + let mediaUrl: string + for (let host of uploadInfo.hosts) { + const auth = encodeURIComponent(uploadInfo.auth) // the auth token + const url = `https://${host.hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` + + try { + const {body: responseText} = await got.post( + url, + { + headers: { + 'Content-Type': 'application/octet-stream', + 'Origin': DEFAULT_ORIGIN + }, + agent: { + https: config.agent + }, + body: stream + } + ) + const result = JSON.parse(responseText) + mediaUrl = result?.url + + if (mediaUrl) break + else { + uploadInfo = await refreshMediaConn(true) + throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) + } + } catch (error) { + const isLast = host.hostname === uploadInfo.hosts[uploadInfo.hosts.length-1].hostname + logger.debug(`Error in uploading to ${host.hostname} (${error}) ${isLast ? '' : ', retrying...'}`) + } + } + if (!mediaUrl) { + throw new Boom( + 'Media upload failed on all hosts', + { statusCode: 500 } + ) + } + return { mediaUrl } + } + + return { + ...sock, + assertSession, + relayMessage, + sendReadReceipt, + refreshMediaConn, + sendMessage: async( + jid: string, + content: AnyMessageContent, + options: MiscMessageGenerationOptions = { } + ) => { + const userJid = authState.creds.me!.id + if( + typeof content === 'object' && + 'disappearingMessagesInChat' in content && + typeof content['disappearingMessagesInChat'] !== 'undefined' && + isJidGroup(jid) + ) { + const { disappearingMessagesInChat } = content + const value = typeof disappearingMessagesInChat === 'boolean' ? + (disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : + disappearingMessagesInChat + await groupToggleEphemeral(jid, value) + } else { + const fullMsg = await generateWAMessage( + jid, + content, + { + ...options, + logger, + userJid: userJid, + // multi-device does not have this yet + //getUrlInfo: generateUrlInfo, + upload: waUploadToServer + } + ) + await relayMessage(jid, fullMsg.message) + process.nextTick(() => { + ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) + }) + return fullMsg + } + } + } +} \ No newline at end of file diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts new file mode 100644 index 0000000..e3ad179 --- /dev/null +++ b/src/Socket/socket.ts @@ -0,0 +1,469 @@ +import { Boom } from '@hapi/boom' +import EventEmitter from 'events' +import { promisify } from "util" +import WebSocket from "ws" +import { randomBytes } from 'crypto' +import { proto } from '../../WAProto' +import { DisconnectReason, SocketConfig, BaileysEventEmitter } from "../Types" +import { generateCurveKeyPair, initAuthState, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout } from "../Utils" +import { DEFAULT_ORIGIN, DEF_TAG_PREFIX, DEF_CALLBACK_PREFIX, KEY_BUNDLE_TYPE } from "../Defaults" +import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, S_WHATSAPP_NET } from '../WABinary' +import noiseHandler from '../Utils/noise-handler' +import { generateOrGetPreKeys, xmppSignedPreKey, xmppPreKey, getPreKeys } from '../Utils/signal' + +/** + * Connects to WA servers and performs: + * - simple queries (no retry mechanism, wait for connection establishment) + * - listen to messages and emit events + * - query phone connection + */ +export const makeSocket = ({ + waWebSocketUrl, + connectTimeoutMs, + logger, + agent, + keepAliveIntervalMs, + version, + browser, + auth: initialAuthState +}: SocketConfig) => { + const ws = new WebSocket(waWebSocketUrl, undefined, { + origin: DEFAULT_ORIGIN, + timeout: connectTimeoutMs, + agent, + headers: { + 'Accept-Encoding': 'gzip, deflate, br', + 'Accept-Language': 'en-US,en;q=0.9', + 'Cache-Control': 'no-cache', + 'Host': 'web.whatsapp.com', + 'Pragma': 'no-cache', + 'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits' + } + }) + ws.setMaxListeners(0) + /** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */ + const ephemeralKeyPair = generateCurveKeyPair() + /** WA noise protocol wrapper */ + const noise = noiseHandler(ephemeralKeyPair) + const authState = initialAuthState || initAuthState() + const { creds } = authState + const ev = new EventEmitter() as BaileysEventEmitter + + let lastDateRecv: Date + let epoch = 0 + let keepAliveReq: NodeJS.Timeout + + const uqTagId = `${randomBytes(1).toString('hex')[0]}.${randomBytes(1).toString('hex')[0]}-` + const generateMessageTag = () => `${uqTagId}${epoch++}` + + const sendPromise = promisify(ws.send) + /** send a raw buffer */ + const sendRawMessage = (data: Buffer | Uint8Array) => { + const bytes = noise.encodeFrame(data) + return sendPromise.call(ws, bytes) as Promise + } + /** send a binary node */ + const sendNode = (node: BinaryNode) => { + let buff = encodeBinaryNode(node) + return sendRawMessage(buff) + } + /** await the next incoming message */ + const awaitNextMessage = async(sendMsg?: Uint8Array) => { + if(ws.readyState !== ws.OPEN) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } + let onOpen: (data: any) => void + let onClose: (err: Error) => void + + const result = new Promise((resolve, reject) => { + onOpen = (data: any) => resolve(data) + onClose = reject + ws.on('frame', onOpen) + ws.on('close', onClose) + ws.on('error', onClose) + }) + .finally(() => { + ws.off('frame', onOpen) + ws.off('close', onClose) + ws.off('error', onClose) + }) + + if(sendMsg) { + sendRawMessage(sendMsg).catch(onClose) + } + + return result + } + + /** + * Wait for a message with a certain tag to be received + * @param tag the message tag to await + * @param json query that was sent + * @param timeoutMs timeout after which the promise will reject + */ + const waitForMessage = async(msgId: string, timeoutMs?: number) => { + let onRecv: (json) => void + let onErr: (err) => void + try { + const result = await promiseTimeout(timeoutMs, + (resolve, reject) => { + onRecv = resolve + onErr = err => { + reject(err || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) + } + + ws.on(`TAG:${msgId}`, onRecv) + ws.on('close', onErr) // if the socket closes, you'll never receive the message + }, + ) + return result as any + } finally { + ws.off(`TAG:${msgId}`, onRecv) + ws.off('close', onErr) // if the socket closes, you'll never receive the message + } + } + /** send a query, and wait for its response. auto-generates message ID if not provided */ + const query = async(node: BinaryNode, timeoutMs?: number) => { + if(!node.attrs.id) node.attrs.id = generateMessageTag() + + const msgId = node.attrs.id + const wait = waitForMessage(msgId, timeoutMs) + + await sendNode(node) + + const result = await (wait as Promise) + if('tag' in result) { + assertNodeErrorFree(result) + } + return result + } + /** connection handshake */ + const validateConnection = async () => { + logger.info('connected to WA Web') + + const init = proto.HandshakeMessage.encode({ + clientHello: { ephemeral: ephemeralKeyPair.public } + }).finish() + + const result = await awaitNextMessage(init) + const handshake = proto.HandshakeMessage.decode(result) + + logger.debug('handshake recv from WA Web') + + const keyEnc = noise.processHandshake(handshake, creds.noiseKey) + logger.info('handshake complete') + + let node: Uint8Array + if(!creds.me) { + logger.info('not logged in, attempting registration...') + node = generateRegistrationNode(creds, { version, browser }) + } else { + logger.info('logging in...') + node = generateLoginNode(creds.me!.id, { version, browser }) + } + const payloadEnc = noise.encrypt(node) + await sendRawMessage( + proto.HandshakeMessage.encode({ + clientFinish: { + static: new Uint8Array(keyEnc), + payload: new Uint8Array(payloadEnc), + }, + }).finish() + ) + noise.finishInit() + startKeepAliveRequest() + } + /** get some pre-keys and do something with them */ + const assertingPreKeys = async(range: number, execute: (keys: { [_: number]: any }) => Promise) => { + const { newPreKeys, lastPreKeyId, preKeysRange } = generateOrGetPreKeys(authState, range) + const preKeys = await getPreKeys(authState.keys, preKeysRange[0], preKeysRange[1]) + + await execute(preKeys) + + creds.serverHasPreKeys = true + creds.nextPreKeyId = Math.max(lastPreKeyId+1, creds.nextPreKeyId) + creds.firstUnuploadedPreKeyId = Math.max(creds.firstUnuploadedPreKeyId, lastPreKeyId+1) + await Promise.all( + Object.keys(newPreKeys).map(k => authState.keys.setPreKey(+k, newPreKeys[+k])) + ) + + ev.emit('auth-state.update', authState) + } + /** generates and uploads a set of pre-keys */ + const uploadPreKeys = async() => { + await assertingPreKeys(50, async preKeys => { + const node: BinaryNode = { + tag: 'iq', + attrs: { + id: generateMessageTag(), + xmlns: 'encrypt', + type: 'set', + to: S_WHATSAPP_NET, + }, + content: [ + { tag: 'registration', attrs: { }, content: encodeBigEndian(creds.registrationId) }, + { tag: 'type', attrs: { }, content: KEY_BUNDLE_TYPE }, + { tag: 'identity', attrs: { }, content: creds.signedIdentityKey.public }, + { tag: 'list', attrs: { }, content: Object.keys(preKeys).map(k => xmppPreKey(preKeys[+k], +k)) }, + xmppSignedPreKey(creds.signedPreKey) + ] + } + await sendNode(node) + + logger.info('uploaded pre-keys') + }) + } + + const onMessageRecieved = (data: Buffer) => { + noise.decodeFrame(data, frame => { + ws.emit('frame', frame) + // if it's a binary node + if(!(frame instanceof Uint8Array)) { + const msgId = frame.attrs.id + + if(logger.level === 'trace') { + logger.trace({ msgId, fromMe: false, frame }, 'communication') + } + + let anyTriggered = false + /* Check if this is a response to a message we sent */ + anyTriggered = ws.emit(`${DEF_TAG_PREFIX}${msgId}`, frame) + /* Check if this is a response to a message we are expecting */ + const l0 = frame.tag + const l1 = frame.attrs || { } + const l2 = Array.isArray(frame.content) ? frame.content[0]?.tag : '' + + Object.keys(l1).forEach(key => { + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, frame) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, frame) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, frame) || anyTriggered + }) + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, frame) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0}`, frame) || anyTriggered + anyTriggered = ws.emit('frame', frame) || anyTriggered + + if (!anyTriggered && logger.level === 'debug') { + logger.debug({ unhandled: true, msgId, fromMe: false, frame }, 'communication recv') + } + } + }) + } + + const end = (error: Error | undefined) => { + logger.info({ error }, 'connection closed') + + clearInterval(keepAliveReq) + + ws.removeAllListeners('close') + ws.removeAllListeners('error') + ws.removeAllListeners('open') + ws.removeAllListeners('message') + + if(ws.readyState !== ws.CLOSED && ws.readyState !== ws.CLOSING) { + try { ws.close() } catch { } + } + + ev.emit('connection.update', { + connection: 'close', + lastDisconnect: { + error, + date: new Date() + } + }) + ws.removeAllListeners('connection.update') + } + + const waitForSocketOpen = async() => { + if(ws.readyState === ws.OPEN) return + if(ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } + let onOpen: () => void + let onClose: (err: Error) => void + await new Promise((resolve, reject) => { + onOpen = () => resolve(undefined) + onClose = reject + ws.on('open', onOpen) + ws.on('close', onClose) + ws.on('error', onClose) + }) + .finally(() => { + ws.off('open', onOpen) + ws.off('close', onClose) + ws.off('error', onClose) + }) + } + + const startKeepAliveRequest = () => ( + keepAliveReq = setInterval(() => { + if (!lastDateRecv) lastDateRecv = new Date() + const diff = Date.now() - lastDateRecv.getTime() + /* + check if it's been a suspicious amount of time since the server responded with our last seen + it could be that the network is down + */ + if (diff > keepAliveIntervalMs+5000) { + end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost })) + } else if(ws.readyState === ws.OPEN) { + // if its all good, send a keep alive request + query( + { + tag: 'iq', + attrs: { + id: generateMessageTag(), + to: S_WHATSAPP_NET, + type: 'get', + xmlns: 'w:p', + }, + content: [{ tag: 'ping', attrs: { } }] + }, + keepAliveIntervalMs + ) + .then(() => { + lastDateRecv = new Date() + logger.trace('recv keep alive') + }) + .catch(err => end(err)) + } else { + logger.warn('keep alive called when WS not open') + } + }, keepAliveIntervalMs) + ) + /** i have no idea why this exists. pls enlighten me */ + const sendPassiveIq = (tag: 'passive' | 'active') => ( + sendNode({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + xmlns: 'passive', + type: 'set', + id: generateMessageTag(), + }, + content: [ + { tag, attrs: { } } + ] + }) + ) + /** logout & invalidate connection */ + const logout = async() => { + await sendNode({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'set', + id: generateMessageTag(), + xmlns: 'md' + }, + content: [ + { + tag: 'remove-companion-device', + attrs: { + jid: authState.creds.me!.id, + reason: 'user_initiated' + } + } + ] + }) + end(new Boom('Intentional Logout', { statusCode: DisconnectReason.loggedOut })) + } + + ws.on('message', onMessageRecieved) + ws.on('open', validateConnection) + ws.on('error', end) + ws.on('close', () => end(new Boom('Connection Terminated', { statusCode: DisconnectReason.connectionClosed }))) + // the server terminated the connection + ws.on('CB:xmlstreamend', () => { + end(new Boom('Connection Terminated by Server', { statusCode: DisconnectReason.connectionClosed })) + }) + // QR gen + ws.on('CB:iq,type:set,pair-device', async (stanza: BinaryNode) => { + const postQR = async() => { + const QR = await import('qrcode-terminal').catch(err => { + logger.error('add `qrcode-terminal` as a dependency to auto-print QR') + }) + QR?.generate(qr, { small: true }) + } + + const refs = ((stanza.content[0] as BinaryNode).content as BinaryNode[]).map(n => n.content as string) + const iq: BinaryNode = { + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'result', + id: stanza.attrs.id, + } + } + const noiseKeyB64 = Buffer.from(creds.noiseKey.public).toString('base64'); + const identityKeyB64 = Buffer.from(creds.signedIdentityKey.public).toString('base64') + const advB64 = creds.advSecretKey + const qr = [refs[0], noiseKeyB64, identityKeyB64, advB64].join(','); + + ev.emit('connection.update', { qr }) + await postQR() + await sendNode(iq) + }) + // device paired for the first time + // if device pairs successfully, the server asks to restart the connection + ws.on('CB:iq,,pair-success', async(stanza: BinaryNode) => { + logger.debug('pair success recv') + try { + const { reply, creds: updatedCreds } = configureSuccessfulPairing(stanza, creds) + + logger.debug('pairing configured successfully') + + const waiting = awaitNextMessage() + await sendNode(reply) + + const value = (await waiting) as BinaryNode + if(value.tag === 'stream:error') { + if(value.attrs?.code !== '515') { + throw new Boom('Authentication failed', { statusCode: +(value.attrs.code || 500) }) + } + } + Object.assign(creds, updatedCreds) + logger.info({ jid: creds.me!.id }, 'registered connection, restart server') + + ev.emit('auth-state.update', authState) + ev.emit('connection.update', { isNewLogin: true, qr: undefined }) + + end(new Boom('Restart Required', { statusCode: DisconnectReason.restartRequired })) + } catch(error) { + logger.info({ trace: error.stack }, 'error in pairing') + end(error) + } + }) + // login complete + ws.on('CB:success', async() => { + if(!creds.serverHasPreKeys) { + await uploadPreKeys() + } + await sendPassiveIq('active') + ev.emit('connection.update', { connection: 'open' }) + }) + // logged out + ws.on('CB:failure,reason:401', () => { + end(new Boom('Logged Out', { statusCode: DisconnectReason.loggedOut })) + }) + process.nextTick(() => { + ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false }) + }) + + return { + ws, + ev, + authState, + get user () { + return authState.creds.me + }, + assertingPreKeys, + generateMessageTag, + query, + waitForMessage, + waitForSocketOpen, + sendRawMessage, + sendNode, + logout, + end + } +} +export type Socket = ReturnType \ No newline at end of file diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts index 8e4ac32..371d745 100644 --- a/src/Store/in-memory-store.ts +++ b/src/Store/in-memory-store.ts @@ -1,13 +1,13 @@ import type KeyedDB from "@adiwajshing/keyed-db" import type { Comparable } from "@adiwajshing/keyed-db/lib/Types" import type { Logger } from "pino" -import type { Connection } from "../Connection" +import type { Connection } from "../Socket" import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, MessageInfo, PresenceData, WAMessage, WAMessageCursor, WAMessageKey } from "../Types" import { toNumber } from "../Utils" import makeOrderedDictionary from "./ordered-dictionary" export const waChatKey = (pin: boolean) => ({ - key: (c: Chat) => (pin ? (c.pin ? '1' : '0') : '') + (c.archive === 'true' ? '0' : '1') + c.t.toString(16).padStart(8, '0') + c.jid, + key: (c: Chat) => (pin ? (c.pin ? '1' : '0') : '') + (c.archive ? '0' : '1') + toNumber(c.conversationTimestamp).toString(16).padStart(8, '0') + c.id, compare: (k1: string, k2: string) => k2.localeCompare (k1) }) @@ -30,10 +30,7 @@ export default( const groupMetadata: { [_: string]: GroupMetadata } = { } const messageInfos: { [id: string]: MessageInfo } = { } const presences: { [id: string]: { [participant: string]: PresenceData } } = { } - const state: ConnectionState = { - connection: 'close', - phoneConnected: false - } + const state: ConnectionState = { connection: 'close' } const assertMessageList = (jid: string) => { if(!messages[jid]) messages[jid] = makeMessagesDictionary() @@ -214,7 +211,7 @@ export default( state, presences, listen, - loadMessages: async(jid: string, count: number, cursor: WAMessageCursor, sock: Connection | undefined) => { + /*loadMessages: async(jid: string, count: number, cursor: WAMessageCursor, sock: Connection | undefined) => { const list = assertMessageList(jid) const retrieve = async(count: number, cursor: WAMessageCursor) => { const result = await sock?.fetchMessagesFromWA(jid, count, cursor) @@ -291,6 +288,6 @@ export default( messageInfos[id!] = await sock?.messageInfo(remoteJid, id) } return messageInfos[id!] - } + }*/ } } \ No newline at end of file diff --git a/src/Tests/Common.ts b/src/Tests/Common.ts deleted file mode 100644 index 942f5be..0000000 --- a/src/Tests/Common.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { WAConnection, MessageOptions, MessageType, unixTimestampSeconds, toNumber, GET_MESSAGE_ID, waMessageKey } from '../WAConnection' -import * as assert from 'assert' -import {promises as fs} from 'fs' - -require ('dotenv').config () // dotenv to load test jid -export const testJid = process.env.TEST_JID || '1234@s.whatsapp.net' // set TEST_JID=xyz@s.whatsapp.net in a .env file in the root directory - -export const makeConnection = () => { - const conn = new WAConnection() - conn.connectOptions.maxIdleTimeMs = 15_000 - conn.logger.level = 'debug' - - let evCounts = {} - - conn.on ('close', ({ isReconnecting }) => { - !isReconnecting && console.log ('Events registered: ', evCounts) - }) - - const onM = conn.on - conn.on = (...args: any[]) => { - evCounts[args[0]] = (evCounts[args[0]] || 0) + 1 - return onM.apply (conn, args) - } - const offM = conn.off - conn.off = (...args: any[]) => { - evCounts[args[0]] = (evCounts[args[0]] || 0) - 1 - if (evCounts[args[0]] <= 0) delete evCounts[args[0]] - return offM.apply (conn, args) - } - return conn -} - -export async function sendAndRetrieveMessage(conn: WAConnection, content, type: MessageType, options: MessageOptions = {}, recipientJid = testJid) { - const response = await conn.sendMessage(recipientJid, content, type, options) - const {messages} = await conn.loadMessages(recipientJid, 10) - const message = messages.find (m => m.key.id === response.key.id) - assert.ok(message) - - const chat = conn.chats.get(recipientJid) - - assert.ok (chat.messages.get(GET_MESSAGE_ID(message.key))) - assert.ok (chat.t >= (unixTimestampSeconds()-5) ) - return message -} -export const WAConnectionTest = (name: string, func: (conn: WAConnection) => void) => ( - describe(name, () => { - const conn = new WAConnection() - conn.connectOptions.maxIdleTimeMs = 30_000 - conn.logger.level = 'debug' - - before(async () => { - const file = './auth_info.json' - await conn.loadAuthInfo(file).connect() - await fs.writeFile(file, JSON.stringify(conn.base64EncodedAuthInfo(), null, '\t')) - }) - after(() => conn.close()) - - afterEach (() => assertChatDBIntegrity (conn)) - - func(conn) - }) -) -export const assertChatDBIntegrity = (conn: WAConnection) => { - conn.chats.all ().forEach (chat => ( - assert.deepStrictEqual ( - [...chat.messages.all()].sort ((m1, m2) => waMessageKey.compare(waMessageKey.key(m1), waMessageKey.key(m2))), - chat.messages.all() - ) - )) - conn.chats.all ().forEach (chat => ( - assert.deepStrictEqual ( - chat.messages.all().filter (m => chat.messages.all().filter(m1 => m1.key.id === m.key.id).length > 1), - [] - ) - )) -} diff --git a/src/Tests/Tests.Binary.ts b/src/Tests/Tests.Binary.ts deleted file mode 100644 index f373d61..0000000 --- a/src/Tests/Tests.Binary.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { strict as assert } from 'assert' -import Encoder from '../Binary/Encoder' -import Decoder from '../Binary/Decoder' - -describe('Binary Coding Tests', () => { - const testVectors: [string, Object][] = [ - [ - 'f806092f5a0a10f804f80234fc6c0a350a1b39313735323938373131313740732e77686174736170702e6e657410011a143345423030393637354537454433374141424632122b0a292a7069616e6f20726f6f6d2074696d696e6773206172653a2a0a20363a3030414d2d31323a3030414d18b3faa7f3052003f80234fc4c0a410a1b39313735323938373131313740732e77686174736170702e6e657410001a20304643454335333330463634393239433645394132434646443242433845414418bdfaa7f305c00101f80234fc930a350a1b39313735323938373131313740732e77686174736170702e6e657410011a14334542303033433742353339414644303937353312520a50536f727279206672656e2c204920636f756c646e277420756e6465727374616e6420274c69627261272e2054797065202768656c702720746f206b6e6f77207768617420616c6c20492063616e20646f18c1faa7f3052003f80234fc540a410a1b39313735323938373131313740732e77686174736170702e6e657410001a20413132333042384436423041314437393345433241453245413043313638443812090a076c69627261727918c2faa7f305', - [ - 'action', - { last: 'true', add: 'before' }, - [ - [ - 'message', - null, - { - key: { remoteJid: '917529871117@s.whatsapp.net', fromMe: true, id: '3EB009675E7ED37AABF2' }, - message: { conversation: '*piano room timings are:*\n 6:00AM-12:00AM' }, - messageTimestamp: '1584004403', - status: 'DELIVERY_ACK', - }, - ], - [ - 'message', - null, - { - key: { - remoteJid: '917529871117@s.whatsapp.net', - fromMe: false, - id: '0FCEC5330F64929C6E9A2CFFD2BC8EAD', - }, - messageTimestamp: '1584004413', - messageStubType: 'REVOKE', - }, - ], - [ - 'message', - null, - { - key: { remoteJid: '917529871117@s.whatsapp.net', fromMe: true, id: '3EB003C7B539AFD09753' }, - message: { - conversation: - "Sorry fren, I couldn't understand 'Libra'. Type 'help' to know what all I can do", - }, - messageTimestamp: '1584004417', - status: 'DELIVERY_ACK', - }, - ], - [ - 'message', - null, - { - key: { - remoteJid: '917529871117@s.whatsapp.net', - fromMe: false, - id: 'A1230B8D6B0A1D793EC2AE2EA0C168D8', - }, - message: { conversation: 'library' }, - messageTimestamp: '1584004418', - }, - ], - ], - ], - ], - [ - 'f8063f2dfafc0831323334353637385027fc0431323334f801f80228fc0701020304050607', - [ - 'picture', - {jid: '12345678@c.us', id: '1234'}, - [['image', null, Buffer.from([1,2,3,4,5,6,7])]] - ] - ] - ] - const encoder = new Encoder() - const decoder = new Decoder() - - it('should decode strings', () => { - testVectors.forEach(pair => { - const buff = Buffer.from(pair[0], 'hex') - const decoded = decoder.read(buff) - //console.log((decoded[2][0][2])) - assert.deepStrictEqual(decoded, pair[1]) - - const encoded = encoder.write(decoded) - assert.deepStrictEqual(encoded, buff) - }) - console.log('all coding tests passed') - }) -}) diff --git a/src/Tests/Tests.Connect.ts b/src/Tests/Tests.Connect.ts deleted file mode 100644 index 2608ffb..0000000 --- a/src/Tests/Tests.Connect.ts +++ /dev/null @@ -1,407 +0,0 @@ -import * as assert from 'assert' -import {WAConnection} from '../WAConnection' -import { AuthenticationCredentialsBase64, BaileysError, ReconnectMode, DisconnectReason, WAChat, WAContact } from '../WAConnection/Constants' -import { delay } from '../WAConnection/Utils' -import { assertChatDBIntegrity, makeConnection, testJid } from './Common' - -describe('QR Generation', () => { - it('should generate QR', async () => { - const conn = makeConnection () - conn.connectOptions.maxRetries = 0 - - let calledQR = 0 - conn.removeAllListeners ('qr') - conn.on ('qr', () => calledQR += 1) - - await conn.connect() - .then (() => assert.fail('should not have succeeded')) - .catch (error => {}) - assert.deepStrictEqual ( - Object.keys(conn.eventNames()).filter(key => key.startsWith('TAG:')), - [] - ) - assert.ok(calledQR >= 2, 'QR not called') - }) -}) - -describe('Test Connect', () => { - let auth: AuthenticationCredentialsBase64 - it('should connect', async () => { - console.log('please be ready to scan with your phone') - - const conn = makeConnection () - - let credentialsUpdateCalled = false - conn.on ('credentials-updated', () => credentialsUpdateCalled = true) - - await conn.connect () - assert.ok(conn.user?.jid) - assert.ok(conn.user?.phone) - assert.ok (conn.user?.imgUrl || conn.user.imgUrl === '') - assert.ok (credentialsUpdateCalled) - - assertChatDBIntegrity (conn) - - conn.close() - auth = conn.base64EncodedAuthInfo() - }) - it('should restore session', async () => { - const conn = makeConnection () - - let credentialsUpdateCalled = false - conn.on ('credentials-updated', () => credentialsUpdateCalled = true) - - await conn.loadAuthInfo (auth).connect () - assert.ok(conn.user) - assert.ok(conn.user.jid) - assert.ok (credentialsUpdateCalled) - - assertChatDBIntegrity (conn) - await conn.logout() - conn.loadAuthInfo(auth) - - await conn.connect() - .then (() => assert.fail('should not have reconnected')) - .catch (err => { - assert.ok (err instanceof BaileysError) - assert.ok ((err as BaileysError).status >= 400) - }) - conn.close() - }) - it ('should disconnect & reconnect phone', async () => { - const conn = makeConnection () - conn.logger.level = 'debug' - await conn.loadAuthInfo('./auth_info.json').connect () - assert.strictEqual (conn.phoneConnected, true) - - try { - const waitForEvent = expect => new Promise (resolve => { - conn.on ('connection-phone-change', ({connected}) => { - if (connected === expect) { - conn.removeAllListeners ('connection-phone-change') - resolve(undefined) - } - }) - }) - - console.log ('disconnect your phone from the internet') - await delay (10_000) - console.log ('phone should be disconnected now, testing...') - - const messagesPromise = Promise.all ( - [ - conn.loadMessages (testJid, 50), - conn.getStatus (testJid), - conn.getProfilePicture (testJid).catch (() => '') - ] - ) - - await waitForEvent (false) - - console.log ('reconnect your phone to the internet') - await waitForEvent (true) - - console.log ('reconnected successfully') - - const final = await messagesPromise - assert.ok (final) - } finally { - conn.close () - } - }) -}) -describe ('Reconnects', () => { - const verifyConnectionOpen = async (conn: WAConnection) => { - assert.ok (conn.user.jid) - let failed = false - // check that the connection stays open - conn.on ('close', ({reason}) => { - if(reason !== DisconnectReason.intentional) failed = true - }) - await delay (60*1000) - - const status = await conn.getStatus () - assert.ok (status) - assert.ok (!conn['debounceTimeout']) // this should be null - - conn.close () - - if (failed) assert.fail ('should not have closed again') - } - it('should dispose correctly on bad_session', async () => { - const conn = makeConnection () - conn.autoReconnect = ReconnectMode.onAllErrors - conn.loadAuthInfo ('./auth_info.json') - - let gotClose0 = false - let gotClose1 = false - - conn.on ('ws-close', ({ reason }) => { - gotClose0 = true - }) - conn.on ('close', ({ reason }) => { - if (reason === DisconnectReason.badSession) gotClose1 = true - }) - setTimeout (() => conn['conn'].emit ('message', Buffer.from('some-tag,sdjjij1jo2ejo1je')), 1500) - await conn.connect () - - setTimeout (() => conn['conn'].emit ('message', Buffer.from('some-tag,sdjjij1jo2ejo1je')), 1500) - - await new Promise (resolve => { - conn.on ('open', resolve) - }) - - assert.ok (gotClose0, 'did not receive bad_session close initially') - assert.ok (gotClose1, 'did not receive bad_session close') - - conn.close () - }) - /** - * the idea is to test closing the connection at multiple points in the connection - * and see if the library cleans up resources correctly - */ - it('should cleanup correctly', async () => { - const conn = makeConnection () - conn.autoReconnect = ReconnectMode.onAllErrors - conn.loadAuthInfo ('./auth_info.json') - - let timeout = 0.1 - while (true) { - let tmout = setTimeout (() => conn.close(), timeout*1000) - try { - await conn.connect () - clearTimeout (tmout) - break - } catch (error) { - - } - // exponentially increase the timeout disconnect - timeout *= 2 - } - await verifyConnectionOpen (conn) - }) - /** - * the idea is to test closing the connection at multiple points in the connection - * and see if the library cleans up resources correctly - */ - it('should disrupt connect loop', async () => { - const conn = makeConnection () - - conn.autoReconnect = ReconnectMode.onAllErrors - conn.loadAuthInfo ('./auth_info.json') - - let timeout = 1000 - let tmout - const endConnection = async () => { - while (!conn['conn']) { - await delay(100) - } - conn['conn'].close () - - while (conn['conn']) { - await delay(100) - } - - timeout *= 2 - tmout = setTimeout (endConnection, timeout) - } - tmout = setTimeout (endConnection, timeout) - - await conn.connect () - clearTimeout (tmout) - - await verifyConnectionOpen (conn) - }) - it ('should reconnect on broken connection', async () => { - const conn = makeConnection () - conn.autoReconnect = ReconnectMode.onConnectionLost - - await conn.loadAuthInfo('./auth_info.json').connect () - assert.strictEqual (conn.phoneConnected, true) - - try { - const closeConn = () => conn['conn']?.terminate () - - const task = new Promise (resolve => { - let closes = 0 - conn.on ('close', ({reason, isReconnecting}) => { - console.log (`closed: ${reason}`) - assert.ok (reason) - assert.ok (isReconnecting) - closes += 1 - - // let it fail reconnect a few times - if (closes >= 1) { - conn.removeAllListeners ('close') - conn.removeAllListeners ('connecting') - resolve(undefined) - } - }) - conn.on ('connecting', () => { - // close again - delay (3500).then (closeConn) - }) - }) - - closeConn () - await task - - await new Promise (resolve => { - conn.on ('open', () => { - conn.removeAllListeners ('open') - resolve(undefined) - }) - }) - - conn.close () - - conn.on ('connecting', () => assert.fail('should not connect')) - await delay (2000) - } finally { - conn.removeAllListeners ('connecting') - conn.removeAllListeners ('close') - conn.removeAllListeners ('open') - conn.close () - } - }) - it ('should reconnect & stay connected', async () => { - const conn = makeConnection () - conn.autoReconnect = ReconnectMode.onConnectionLost - - await conn.loadAuthInfo('./auth_info.json').connect () - assert.strictEqual (conn.phoneConnected, true) - - await delay (30*1000) - - conn['conn']?.terminate () - - conn.on ('close', () => { - assert.ok (!conn['lastSeen']) - console.log ('connection closed') - }) - await new Promise (resolve => conn.on ('open', resolve)) - await verifyConnectionOpen (conn) - }) -}) - -describe ('Pending Requests', () => { - it ('should correctly send updates for chats', async () => { - const conn = makeConnection () - conn.pendingRequestTimeoutMs = null - conn.loadAuthInfo('./auth_info.json') - - const task = new Promise(resolve => conn.once('chats-received', resolve)) - await conn.connect () - await task - - conn.close () - - const oldChat = conn.chats.all()[0] - oldChat.archive = 'true' // mark the first chat as archived - oldChat.modify_tag = '1234' // change modify tag to detect change - - const promise = new Promise(resolve => conn.once('chats-update', resolve)) - - const result = await conn.connect () - assert.ok (!result.newConnection) - - const chats = await promise as Partial[] - const chat = chats.find (c => c.jid === oldChat.jid) - assert.ok (chat) - - assert.ok ('archive' in chat) - assert.strictEqual (Object.keys(chat).length, 3) - assert.strictEqual (Object.keys(chats).length, 1) - - conn.close () - }) - it ('should correctly send updates for contacts', async () => { - const conn = makeConnection () - conn.pendingRequestTimeoutMs = null - conn.loadAuthInfo('./auth_info.json') - - const task: any = new Promise(resolve => conn.once('contacts-received', resolve)) - await conn.connect () - const initialResult = await task - assert.strictEqual( - initialResult.updatedContacts.length, - Object.keys(conn.contacts).length - ) - - - conn.close () - - const [jid] = Object.keys(conn.contacts) - const oldContact = conn.contacts[jid] - oldContact.name = 'Lol' - oldContact.index = 'L' - - const promise = new Promise(resolve => conn.once('contacts-received', resolve)) - - const result = await conn.connect () - assert.ok (!result.newConnection) - - const {updatedContacts} = await promise as { updatedContacts: Partial[] } - const contact = updatedContacts.find (c => c.jid === jid) - assert.ok (contact) - - assert.ok ('name' in contact) - assert.strictEqual (Object.keys(contact).length, 3) - assert.strictEqual (Object.keys(updatedContacts).length, 1) - - conn.close () - }) - it('should queue requests when closed', async () => { - const conn = makeConnection () - //conn.pendingRequestTimeoutMs = null - - await conn.loadAuthInfo('./auth_info.json').connect () - - await delay (2000) - - conn.close () - - const task: Promise = conn.query({json: ['query', 'Status', conn.user.jid]}) - - await delay (2000) - - conn.connect () - const json = await task - - assert.ok (json.status) - - conn.close () - }) - it('[MANUAL] should receive query response after phone disconnect', async () => { - const conn = makeConnection () - await conn.loadAuthInfo('./auth_info.json').connect () - - console.log(`disconnect your phone from the internet!`) - await delay(5000) - const task = conn.loadMessages(testJid, 50) - setTimeout(() => console.log('reconnect your phone!'), 20_000) - - const result = await task - assert.ok(result.messages[0]) - assert.ok(!conn['phoneCheckInterval']) // should be undefined - - conn.close () - }) - it('should re-execute query on connection closed error', async () => { - const conn = makeConnection () - //conn.pendingRequestTimeoutMs = 10_000 - await conn.loadAuthInfo('./auth_info.json').connect () - const task: Promise = conn.query({json: ['query', 'Status', conn.user.jid], waitForOpen: true}) - - await delay(20) - conn['onMessageRecieved']('1234,["Pong",false]') // fake cancel the connection - - await delay(2000) - - const json = await task - - assert.ok (json.status) - - conn.close () - }) -}) \ No newline at end of file diff --git a/src/Tests/Tests.Groups.ts b/src/Tests/Tests.Groups.ts deleted file mode 100644 index 6e2339a..0000000 --- a/src/Tests/Tests.Groups.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { MessageType, GroupSettingChange, delay, ChatModification, whatsappID } from '../WAConnection' -import * as assert from 'assert' -import { WAConnectionTest, testJid, sendAndRetrieveMessage } from './Common' - -WAConnectionTest('Groups', (conn) => { - let gid: string - it('should create a group', async () => { - const response = await conn.groupCreate('Cool Test Group', [testJid]) - assert.ok (conn.chats.get(response.gid)) - - const {chats} = await conn.loadChats(10, null) - assert.strictEqual (chats[0].jid, response.gid) // first chat should be new group - - gid = response.gid - - console.log('created group: ' + JSON.stringify(response)) - }) - it('should retrieve group invite code', async () => { - const code = await conn.groupInviteCode(gid) - assert.ok(code) - assert.strictEqual(typeof code, 'string') - }) - it('should joined group via invite code', async () => { - const response = await conn.acceptInvite(gid) - assert.ok(response.status) - assert.strictEqual(response.status, response.gid) - }) - it('should retrieve group metadata', async () => { - const metadata = await conn.groupMetadata(gid) - assert.strictEqual(metadata.id, gid) - assert.strictEqual(metadata.participants.filter((obj) => obj.jid.split('@')[0] === testJid.split('@')[0]).length, 1) - assert.ok(conn.chats.get(gid)) - assert.ok(conn.chats.get(gid).metadata) - }) - it('should update the group description', async () => { - const newDesc = 'Wow this was set from Baileys' - - const waitForEvent = new Promise (resolve => ( - conn.once ('group-update', ({jid, desc}) => { - if (jid === gid && desc) { - assert.strictEqual(desc, newDesc) - assert.strictEqual( - conn.chats.get(jid).metadata.desc, - newDesc - ) - resolve(undefined) - } - }) - )) - await conn.groupUpdateDescription (gid, newDesc) - await waitForEvent - - const metadata = await conn.groupMetadata(gid) - assert.strictEqual(metadata.desc, newDesc) - }) - it('should send a message on the group', async () => { - await sendAndRetrieveMessage(conn, 'Hello!', MessageType.text, {}, gid) - }) - it('should delete a message on the group', async () => { - const message = await sendAndRetrieveMessage(conn, 'Hello!', MessageType.text, {}, gid) - await delay(1500) - await conn.deleteMessage(message.key) - }) - it('should quote a message on the group', async () => { - const {messages} = await conn.loadMessages (gid, 100) - const quotableMessage = messages.find (m => m.message) - assert.ok (quotableMessage, 'need at least one message') - - const response = await conn.sendMessage(gid, 'hello', MessageType.extendedText, {quoted: quotableMessage}) - const loaded = await conn.loadMessages(gid, 10) - const message = loaded.messages.find (m => m.key.id === response.key.id)?.message?.extendedTextMessage - assert.ok(message) - assert.strictEqual (message.contextInfo.stanzaId, quotableMessage.key.id) - }) - it('should update the subject', async () => { - const subject = 'Baileyz ' + Math.floor(Math.random()*5) - const waitForEvent = new Promise (resolve => { - conn.once ('chat-update', ({jid, name}) => { - if (jid === gid) { - assert.strictEqual(name, subject) - assert.strictEqual(conn.chats.get(jid).name, subject) - resolve(undefined) - } - }) - }) - await conn.groupUpdateSubject(gid, subject) - await waitForEvent - - const metadata = await conn.groupMetadata(gid) - assert.strictEqual(metadata.subject, subject) - }) - - it('should update the group settings', async () => { - const waitForEvent = new Promise (resolve => { - conn.once ('group-update', ({jid, announce}) => { - if (jid === gid) { - assert.strictEqual (announce, 'true') - assert.strictEqual(conn.chats.get(gid).metadata.announce, announce) - resolve(undefined) - } - }) - }) - await conn.groupSettingChange (gid, GroupSettingChange.messageSend, true) - - await waitForEvent - conn.removeAllListeners ('group-update') - - await delay (2000) - await conn.groupSettingChange (gid, GroupSettingChange.settingsChange, true) - }) - - it('should promote someone', async () => { - const waitForEvent = new Promise (resolve => { - conn.once ('group-participants-update', ({ jid, action, participants }) => { - if (jid === gid) { - assert.strictEqual (action, 'promote') - console.log(participants) - console.log(conn.chats.get(jid).metadata) - assert.ok( - conn.chats.get(jid).metadata.participants.find(({ jid, isAdmin }) => ( - whatsappID(jid) === whatsappID(participants[0]) && isAdmin - )), - ) - resolve(undefined) - } - - }) - }) - await conn.groupMakeAdmin(gid, [ testJid ]) - await waitForEvent - }) - - it('should remove someone from a group', async () => { - const metadata = await conn.groupMetadata (gid) - if (metadata.participants.find(({jid}) => whatsappID(jid) === testJid)) { - const waitForEvent = new Promise (resolve => { - conn.once ('group-participants-update', ({jid, participants, action}) => { - if (jid === gid) { - assert.strictEqual (participants[0], testJid) - assert.strictEqual (action, 'remove') - assert.deepStrictEqual( - conn.chats.get(jid).metadata.participants.find(p => whatsappID(p.jid) === whatsappID(participants[0])), - undefined - ) - resolve(undefined) - } - }) - }) - - await conn.groupRemove(gid, [testJid]) - await waitForEvent - } else console.log(`could not find testJid`) - }) - - it('should leave the group', async () => { - const waitForEvent = new Promise (resolve => { - conn.once ('chat-update', ({jid, read_only}) => { - if (jid === gid) { - assert.strictEqual (read_only, 'true') - resolve(undefined) - } - }) - }) - await conn.groupLeave(gid) - await waitForEvent - - await conn.groupMetadataMinimal (gid) - }) - it('should archive the group', async () => { - const waitForEvent = new Promise (resolve => { - conn.once ('chat-update', ({jid, archive}) => { - if (jid === gid) { - assert.strictEqual (archive, 'true') - resolve(undefined) - } - }) - }) - await conn.modifyChat(gid, ChatModification.archive) - await waitForEvent - }) - it('should delete the group', async () => { - const waitForEvent = new Promise (resolve => { - conn.once ('chat-update', (chat) => { - if (chat.jid === gid) { - assert.strictEqual (chat['delete'], 'true') - resolve(undefined) - } - }) - }) - await conn.modifyChat(gid, 'delete') - await waitForEvent - }) -}) diff --git a/src/Tests/Tests.Media.ts b/src/Tests/Tests.Media.ts deleted file mode 100644 index 6960438..0000000 --- a/src/Tests/Tests.Media.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { deepStrictEqual, strictEqual } from 'assert' -import { createWriteStream } from 'fs' -import { readFile } from 'fs/promises' -import { proto } from '../../WAMessage' -import { MessageType } from '../WAConnection' -import { aesEncrypWithIV, decryptMediaMessageBuffer, encryptedStream, getMediaKeys, getStream, hmacSign, sha256 } from '../WAConnection/Utils' -import { WAConnectionTest } from './Common' - -describe('Media Download Tests', () => { - - it('should encrypt media streams correctly', async function() { - const url = './Media/meme.jpeg' - const streamValues = await encryptedStream({ url }, MessageType.image) - - const buffer = await readFile(url) - const mediaKeys = getMediaKeys(streamValues.mediaKey, MessageType.image) - - const enc = aesEncrypWithIV(buffer, mediaKeys.cipherKey, mediaKeys.iv) - const mac = hmacSign(Buffer.concat([mediaKeys.iv, enc]), mediaKeys.macKey).slice(0, 10) - const body = Buffer.concat([enc, mac]) // body is enc + mac - const fileSha256 = sha256(buffer) - const fileEncSha256 = sha256(body) - - deepStrictEqual(streamValues.fileSha256, fileSha256) - strictEqual(streamValues.fileLength, buffer.length) - deepStrictEqual(streamValues.mac, mac) - deepStrictEqual(await readFile(streamValues.encBodyPath), body) - deepStrictEqual(streamValues.fileEncSha256, fileEncSha256) - - }) -}) -/* -WAConnectionTest('Media Upload', conn => { - - it('should upload the same file', async () => { - const FILES = [ - { url: './Media/meme.jpeg', type: MessageType.image }, - { url: './Media/ma_gif.mp4', type: MessageType.video }, - { url: './Media/sonata.mp3', type: MessageType.audio }, - ] - }) - -})*/ \ No newline at end of file diff --git a/src/Tests/Tests.Messages.ts b/src/Tests/Tests.Messages.ts deleted file mode 100644 index f271a0f..0000000 --- a/src/Tests/Tests.Messages.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { MessageType, Mimetype, delay, promiseTimeout, WA_MESSAGE_STATUS_TYPE, generateMessageID, WAMessage } from '../WAConnection' -import { promises as fs } from 'fs' -import * as assert from 'assert' -import { WAConnectionTest, testJid, sendAndRetrieveMessage } from './Common' - -WAConnectionTest('Messages', conn => { - - it('should send a text message', async () => { - const message = await sendAndRetrieveMessage(conn, 'hello fren', MessageType.text) - assert.strictEqual(message.message.conversation || message.message.extendedTextMessage?.text, 'hello fren') - }) - it('should send a pending message', async () => { - const message = await sendAndRetrieveMessage(conn, 'hello fren', MessageType.text, { waitForAck: false }) - - await new Promise(resolve => conn.on('chat-update', update => { - if (update.jid === testJid && - update.messages && - update.messages.first.key.id === message.key.id && - update.messages.first.status === WA_MESSAGE_STATUS_TYPE.SERVER_ACK) { - resolve(undefined) - } - })) - - }) - it('should forward a message', async () => { - let {messages} = await conn.loadMessages (testJid, 1) - await conn.forwardMessage (testJid, messages[0], true) - - messages = (await conn.loadMessages (testJid, 1)).messages - const message = messages.slice (-1)[0] - const content = message.message[ Object.keys(message.message)[0] ] - assert.strictEqual (content?.contextInfo?.isForwarded, true) - }) - it('should send a link preview', async () => { - const text = 'hello this is from https://www.github.com/adiwajshing/Baileys' - const message = await sendAndRetrieveMessage(conn, text, MessageType.text, { detectLinks: true }) - const received = message.message.extendedTextMessage - - assert.strictEqual(received.text, text) - assert.ok (received.canonicalUrl) - assert.ok (received.title) - assert.ok (received.description) - }) - it('should quote a message', async () => { - const quoted = (await conn.loadMessages(testJid, 2)).messages[0] - const message = await sendAndRetrieveMessage(conn, 'hello fren 2', MessageType.extendedText, { quoted }) - assert.strictEqual( - message.message.extendedTextMessage.contextInfo.stanzaId, - quoted.key.id - ) - assert.strictEqual( - message.message.extendedTextMessage.contextInfo.participant, - quoted.key.fromMe ? conn.user.jid : quoted.key.id - ) - }) - it('should upload media successfully', async () => { - const content = await fs.readFile('./Media/sonata.mp3') - // run 10 uploads - for (let i = 0; i < 10;i++) { - await conn.prepareMessageContent (content, MessageType.audio, { filename: 'audio.mp3', mimetype: Mimetype.mp4Audio }) - } - }) - it('should send a gif', async () => { - const message = await sendAndRetrieveMessage(conn, { url: './Media/ma_gif.mp4' }, MessageType.video, { mimetype: Mimetype.gif }) - - await conn.downloadAndSaveMediaMessage(message,'./Media/received_vid') - }) - it('should send an audio', async () => { - const content = await fs.readFile('./Media/sonata.mp3') - const message = await sendAndRetrieveMessage(conn, content, MessageType.audio, { mimetype: Mimetype.mp4Audio }) - // check duration was okay - assert.ok (message.message.audioMessage.seconds > 0) - await conn.downloadAndSaveMediaMessage(message,'./Media/received_aud') - }) - it('should send an audio as a voice note', async () => { - const content = await fs.readFile('./Media/sonata.mp3') - const message = await sendAndRetrieveMessage(conn, content, MessageType.audio, { mimetype: Mimetype.mp4Audio, ptt: true }) - - assert.ok (message.message.audioMessage.seconds > 0) - assert.strictEqual (message.message?.audioMessage?.ptt, true) - await conn.downloadAndSaveMediaMessage(message,'./Media/received_aud') - }) - it('should send a jpeg image', async () => { - const message = await sendAndRetrieveMessage(conn, { url: './Media/meme.jpeg' }, MessageType.image) - assert.ok(message.message.imageMessage.jpegThumbnail.length > 0) - const msg = await conn.downloadMediaMessage(message) - assert.deepStrictEqual(msg, await fs.readFile('./Media/meme.jpeg')) - }) - it('should send a remote jpeg image', async () => { - const message = await sendAndRetrieveMessage( - conn, - { url: 'https://www.memestemplates.com/wp-content/uploads/2020/05/tom-with-phone.jpg' }, - MessageType.image - ) - assert.ok (message.message?.imageMessage?.jpegThumbnail) - await conn.downloadMediaMessage(message) - }) - it('should send a png image', async () => { - const content = await fs.readFile('./Media/icon.png') - const message = await sendAndRetrieveMessage(conn, content, MessageType.image, { mimetype: 'image/png' }) - assert.ok (message.message?.imageMessage?.jpegThumbnail) - await conn.downloadMediaMessage(message) - }) - it('should send a sticker', async () => { - const content = await fs.readFile('./Media/octopus.webp') - const message = await sendAndRetrieveMessage(conn, content, MessageType.sticker) - - await conn.downloadMediaMessage(message) - }) - /*it('should send an interactive message', async () => { - - console.log ( - JSON.stringify(await conn.loadMessages (testJid, 5), null, '\t') - ) - const message = conn.prepareMessageFromContent ( - testJid, - { - templateMessage: { - fourRowTemplate: { - content: { - namespace: 'my-namespace', - localizableParams: [ - - ], - params: ['hello!'] - }, - buttons: [ - { - index: 0, - quickReplyButton: { - displayText: { - params: ['my name jeff'] - } - } - }, - { - index: 1, - quickReplyButton: { - displayText: { - params: ['my name NOT jeff'], - } - } - } - ] - } - } - }, - {} - ) - await conn.relayWAMessage (message) - })*/ - it('should send an image & quote', async () => { - const quoted = (await conn.loadMessages(testJid, 2)).messages[0] - const content = await fs.readFile('./Media/meme.jpeg') - const message = await sendAndRetrieveMessage(conn, content, MessageType.image, { quoted }) - - await conn.downloadMediaMessage(message) // check for successful decoding - assert.strictEqual(message.message.imageMessage.contextInfo.stanzaId, quoted.key.id) - }) - it('should send a message & delete it', async () => { - const message = await sendAndRetrieveMessage(conn, 'hello fren', MessageType.text) - await delay (2000) - await conn.deleteMessage (testJid, message.key) - }) - it('should clear the most recent message', async () => { - const {messages} = await conn.loadMessages (testJid, 1) - await delay (2000) - await conn.clearMessage (messages[0].key) - }) - it('should send media after close', async () => { - const content = await fs.readFile('./Media/octopus.webp') - await sendAndRetrieveMessage(conn, content, MessageType.sticker) - - conn.close () - - await conn.connect () - - const content2 = await fs.readFile('./Media/cat.jpeg') - await sendAndRetrieveMessage(conn, content2, MessageType.image) - }) - it('should fail to send a text message', async () => { - const JID = '1234-1234@g.us' - const messageId = generateMessageID() - conn.sendMessage(JID, 'hello', MessageType.text, { messageId }) - - await new Promise(resolve => ( - conn.on ('chat-update', async update => { - console.log(messageId, update.messages?.first) - if ( - update.jid === JID && - update.messages?.first.key.id === messageId && - update.messages.first.status === WA_MESSAGE_STATUS_TYPE.ERROR) { - resolve(undefined) - } - }) - )) - conn.removeAllListeners('chat-update') - }) - it('should maintain message integrity', async () => { - // loading twice does not alter the results - const results = await Promise.all ([ - conn.loadMessages (testJid, 50), - conn.loadMessages (testJid, 50) - ]) - assert.strictEqual (results[0].messages.length, results[1].messages.length) - for (let i = 0; i < results[1].messages.length;i++) { - assert.deepStrictEqual ( - results[0].messages[i].key, - results[1].messages[i].key, - `failed equal at ${i}` - ) - } - assert.ok (results[0].messages.length <= 50) - - // check if messages match server - let msgs = await conn.fetchMessagesFromWA (testJid, 50) - for (let i = 0; i < results[1].messages.length;i++) { - assert.deepStrictEqual ( - results[0].messages[i].key, - msgs[i].key, - `failed equal at ${i}` - ) - } - // check with some arbitary cursors - let cursor = results[0].messages.slice(-1)[0].key - - msgs = await conn.fetchMessagesFromWA (testJid, 20, cursor) - let {messages} = await conn.loadMessages (testJid, 20, cursor) - for (let i = 0; i < messages.length;i++) { - assert.deepStrictEqual ( - messages[i].key, - msgs[i].key, - `failed equal at ${i}` - ) - } - for (let i = 0; i < 3;i++) { - cursor = results[0].messages[i].key - - msgs = await conn.fetchMessagesFromWA (testJid, 20, cursor) - messages = (await conn.loadMessages (testJid, 20, cursor)).messages - for (let i = 0; i < messages.length;i++) { - assert.deepStrictEqual (messages[i].key, msgs[i].key, `failed equal at ${i}`) - } - - cursor = msgs[0].key - - msgs = await conn.fetchMessagesFromWA (testJid, 20, cursor) - messages = (await conn.loadMessages (testJid, 20, cursor)).messages - for (let i = 0; i < messages.length;i++) { - assert.deepStrictEqual (messages[i].key, msgs[i].key, `failed equal at ${i}`) - } - } - }) - it('should deliver a message', async () => { - const response = await conn.sendMessage(testJid, 'My Name Jeff', MessageType.text) - const waitForUpdate = - promiseTimeout(15000, resolve => { - conn.on('chat-update', update => { - if (update.messages?.first.key.id === response.key.id) { - resolve(update.messages.first) - } - }) - }) as Promise - - const m = await waitForUpdate - assert.ok (m.status >= WA_MESSAGE_STATUS_TYPE.DELIVERY_ACK) - }) -}) diff --git a/src/Tests/Tests.Misc.ts b/src/Tests/Tests.Misc.ts deleted file mode 100644 index 8b09bc6..0000000 --- a/src/Tests/Tests.Misc.ts +++ /dev/null @@ -1,430 +0,0 @@ -import { Presence, ChatModification, delay, newMessagesDB, WA_DEFAULT_EPHEMERAL, MessageType, WAMessage } from '../WAConnection' -import { promises as fs } from 'fs' -import * as assert from 'assert' -import got from 'got' -import { WAConnectionTest, testJid, sendAndRetrieveMessage } from './Common' - -WAConnectionTest('Misc', conn => { - - it('should tell if someone has an account on WhatsApp', async () => { - const response = await conn.isOnWhatsApp(testJid) - assert.strictEqual(response, true) - - const responseFail = await conn.isOnWhatsApp('abcd@s.whatsapp.net') - assert.strictEqual(responseFail, false) - }) - it('should return the status', async () => { - const response = await conn.getStatus(testJid) - assert.strictEqual(typeof response.status, 'string') - }) - it('should update status', async () => { - const newStatus = 'v cool status' - - const waitForEvent = new Promise (resolve => { - conn.on ('contact-update', ({jid, status}) => { - if (jid === conn.user.jid) { - assert.strictEqual (status, newStatus) - conn.removeAllListeners ('contact-update') - resolve(undefined) - } - }) - }) - - const response = await conn.getStatus() - assert.strictEqual(typeof response.status, 'string') - - await delay (1000) - - await conn.setStatus (newStatus) - const response2 = await conn.getStatus() - assert.strictEqual (response2.status, newStatus) - - await waitForEvent - - await delay (1000) - - await conn.setStatus (response.status) // update back - }) - it('should update profile name', async () => { - const newName = 'v cool name' - - await delay (1000) - - const originalName = conn.user.name! - - const waitForEvent = new Promise (resolve => { - conn.on ('contact-update', ({name}) => { - assert.strictEqual (name, newName) - conn.removeAllListeners ('contact-update') - resolve () - }) - }) - - await conn.updateProfileName (newName) - - await waitForEvent - - await delay (1000) - - assert.strictEqual (conn.user.name, newName) - - await delay (1000) - - await conn.updateProfileName (originalName) // update back - }) - it('should return the stories', async () => { - await conn.getStories() - }) - - it('should return the profile picture correctly', async () => { - // wait for chats - await new Promise(resolve => ( - conn.once('initial-data-received', resolve) - )) - const pictures = await Promise.all( - conn.chats.all().slice(0, 15).map(({ jid }) => ( - conn.getProfilePicture(jid) - .catch(err => '') - )) - ) - // pictures should return correctly - const truePictures = pictures.filter(pp => !!pp) - assert.strictEqual( - new Set(truePictures).size, - truePictures.length - ) - }) - - it('should change the profile picture', async () => { - await delay (5000) - - const ppUrl = await conn.getProfilePicture(conn.user.jid) - const {rawBody: oldPP} = await got(ppUrl) - - const newPP = await fs.readFile('./Media/cat.jpeg') - await conn.updateProfilePicture(conn.user.jid, newPP) - - await delay (10000) - - await conn.updateProfilePicture (conn.user.jid, oldPP) // revert back - }) - it('should send typing indicator', async () => { - const response = await conn.updatePresence(testJid, Presence.composing) - assert.ok(response) - }) - it('should change a chat read status', async () => { - const jids = conn.chats.all ().map (c => c.jid) - for (let jid of jids.slice(0, 5)) { - console.log (`changing read status for ${jid}`) - const waitForEvent = new Promise (resolve => { - conn.once ('chat-update', ({jid: tJid, count}) => { - if (jid === tJid) { - assert.ok (count < 0) - resolve(undefined) - } - }) - }) - await conn.chatRead (jid, 'unread') - await waitForEvent - - await delay (5000) - - await conn.chatRead (jid, 'read') - } - }) - it('should archive & unarchive', async () => { - // wait for chats - await new Promise(resolve => ( - conn.once('chats-received', ({ }) => resolve(undefined)) - )) - - const idx = conn.chats.all().findIndex(chat => chat.jid === testJid) - await conn.modifyChat (testJid, ChatModification.archive) - const idx2 = conn.chats.all().findIndex(chat => chat.jid === testJid) - assert.ok(idx < idx2) // should move further down the array - - await delay (2000) - await conn.modifyChat (testJid, ChatModification.unarchive) - const idx3 = conn.chats.all().findIndex(chat => chat.jid === testJid) - assert.strictEqual(idx, idx3) // should be back there - }) - it('should archive & unarchive on new message', async () => { - // wait for chats - await new Promise(resolve => ( - conn.once('chats-received', ({ }) => resolve(undefined)) - )) - - const idx = conn.chats.all().findIndex(chat => chat.jid === testJid) - await conn.modifyChat (testJid, ChatModification.archive) - const idx2 = conn.chats.all().findIndex(chat => chat.jid === testJid) - assert.ok(idx < idx2) // should move further down the array - - await delay (2000) - await sendAndRetrieveMessage(conn, 'test', MessageType.text) - // should be unarchived - const idx3 = conn.chats.all().findIndex(chat => chat.jid === testJid) - assert.strictEqual(idx, idx3) // should be back there - }) - it('should pin & unpin a chat', async () => { - await conn.modifyChat (testJid, ChatModification.pin) - await delay (2000) - await conn.modifyChat (testJid, ChatModification.unpin) - }) - it('should mute & unmute a chat', async () => { - const waitForEvent = new Promise (resolve => { - conn.on ('chat-update', ({jid, mute}) => { - if (jid === testJid ) { - assert.ok (mute) - conn.removeAllListeners ('chat-update') - resolve(undefined) - } - }) - }) - await conn.modifyChat (testJid, ChatModification.mute, 8*60*60*1000) // 8 hours in the future - await waitForEvent - await delay (2000) - await conn.modifyChat (testJid, ChatModification.unmute) - }) - it('should star/unstar messages', async () => { - for (let i = 1; i <= 5; i++) { - await conn.sendMessage(testJid, `Message ${i}`, MessageType.text) - await delay(1000) - } - - let response = await conn.loadMessages(testJid, 5) - let starred = response.messages.filter(m => m.starred) - assert.strictEqual(starred.length, 0) - - conn.starMessage(response.messages[2].key) - await delay(2000) - conn.starMessage(response.messages[4].key) - await delay(2000) - - response = await conn.loadMessages(testJid, 5) - starred = response.messages.filter(m => m.starred) - assert.strictEqual(starred.length, 2) - await delay(2000) - - conn.starMessage(response.messages[2].key, 'unstar') - await delay(2000) - - response = await conn.loadMessages(testJid, 5) - starred = response.messages.filter(m => m.starred) - assert.strictEqual(starred.length, 1) - }) - it('should clear a chat', async () => { - // Uses chat with yourself to avoid losing chats - const selfJid = conn.user.jid - - for (let i = 1; i <= 5; i++) { - await conn.sendMessage(selfJid, `Message ${i}`, MessageType.text) - await delay(1000) - } - - let response = await conn.loadMessages(selfJid, 50) - const initialCount = response.messages.length - - assert.ok(response.messages.length >= 0) - - conn.starMessage(response.messages[2].key) - await delay(2000) - conn.starMessage(response.messages[4].key) - await delay(2000) - - await conn.modifyChat(selfJid, ChatModification.clear) - await delay(2000) - - response = await conn.loadMessages(selfJid, 50) - await delay(2000) - assert.ok(response.messages.length < initialCount) - assert.ok(response.messages.length > 1) - - await conn.modifyChat(selfJid, ChatModification.clear, true) - await delay(2000) - - response = await conn.loadMessages(selfJid, 50) - assert.strictEqual(response.messages.length, 1) - }) - it('should return search results', async () => { - const jids = [null, testJid] - for (let i in jids) { - let response = await conn.searchMessages('Hello', jids[i], 25, 1) - assert.ok (response.messages) - assert.ok (response.messages.length >= 0) - - response = await conn.searchMessages('剛剛試咗😋一個字', jids[i], 25, 1) - assert.ok (response.messages) - assert.ok (response.messages.length >= 0) - } - }) - - it('should load a single message', async () => { - const {messages} = await conn.loadMessages (testJid, 25) - for (var message of messages) { - const loaded = await conn.loadMessage (testJid, message.key.id) - assert.strictEqual (loaded.key.id, message.key.id, `loaded message ${JSON.stringify(message)} incorrectly`) - await delay (500) - } - }) - // open the other phone and look at the updates to really verify stuff - it('should send presence updates', async () => { - conn.shouldLogMessages = true - conn.requestPresenceUpdate(testJid) - - const sequence = [ Presence.available, Presence.composing, Presence.paused, Presence.recording, Presence.paused, Presence.unavailable ] - for (const presence of sequence) { - await delay(5000) - await conn.updatePresence(presence !== Presence.unavailable ? testJid : null, presence) - //console.log(conn.messageLog.slice(-1)) - console.log('sent update ', presence) - } - }) - it('should generate link previews correctly', async () => { - await conn.generateLinkPreview ('hello this is from https://www.github.com/adiwajshing/Baileys') - // two links should fail - await assert.rejects ( - conn.generateLinkPreview ('I sent links to https://teachyourselfcs.com/ and https://www.fast.ai/') - ) - }) - // this test requires quite a few messages with the test JID - it('should detect overlaps and clear messages accordingly', async () => { - // wait for chats - await new Promise(resolve => ( - conn.once('initial-data-received', resolve) - )) - - conn.maxCachedMessages = 100 - - const chat = conn.chats.get(testJid) - const oldCount = chat.messages.length - console.log(`test chat has ${oldCount} pre-loaded messages`) - // load 100 messages - await conn.loadMessages(testJid, 100, undefined) - assert.strictEqual(chat.messages.length, 100) - - conn.close() - // remove all latest messages - chat.messages = newMessagesDB( chat.messages.all().slice(0, 20) ) - - const task = new Promise(resolve => ( - conn.on('initial-data-received', ({ chatsWithMissingMessages }) => { - assert.strictEqual(Object.keys(chatsWithMissingMessages).length, 1) - const missing = chatsWithMissingMessages.find(({ jid }) => jid === testJid) - assert.ok(missing, 'missing message not detected') - assert.strictEqual( - conn.chats.get(testJid).messages.length, - missing.count - ) - assert.strictEqual(missing.count, oldCount) - resolve(undefined) - }) - )) - - await conn.connect() - - await task - }) - - it('should toggle disappearing messages', async () => { - let chat = conn.chats.get(testJid) - if (!chat) { - // wait for chats - await new Promise(resolve => ( - conn.once('chats-received', resolve) - )) - chat = conn.chats.get(testJid) - } - - const waitForChatUpdate = (ephemeralOn: boolean) => ( - new Promise(resolve => ( - conn.on('chat-update', ({ jid, ephemeral }) => { - if (jid === testJid && typeof ephemeral !== 'undefined') { - assert.strictEqual(!!(+ephemeral), ephemeralOn) - assert.strictEqual(!!(+chat.ephemeral), ephemeralOn) - resolve(undefined) - conn.removeAllListeners('chat-update') - } - }) - )) - ) - const toggleDisappearingMessages = async (on: boolean) => { - const update = waitForChatUpdate(on) - await conn.toggleDisappearingMessages(testJid, on ? WA_DEFAULT_EPHEMERAL : 0) - await update - } - - if (!chat.eph_setting_ts) { - await toggleDisappearingMessages(true) - } - - await delay(1000) - - let msg = await sendAndRetrieveMessage( - conn, - 'This will go poof 😱', - MessageType.text - ) - assert.ok(msg.message?.ephemeralMessage) - - const contextInfo = msg.message?.ephemeralMessage?.message?.extendedTextMessage?.contextInfo - assert.strictEqual(contextInfo.expiration, chat.ephemeral) - assert.strictEqual(+contextInfo.ephemeralSettingTimestamp, +chat.eph_setting_ts) - // test message deletion - await conn.deleteMessage(testJid, msg.key) - - await delay(1000) - - await toggleDisappearingMessages(false) - - await delay(1000) - - msg = await sendAndRetrieveMessage( - conn, - 'This will not go poof 😔', - MessageType.text - ) - assert.ok(msg.message.extendedTextMessage) - }) - it('should block & unblock a user', async () => { - const blockedCount = conn.blocklist.length; - - const waitForEventAdded = new Promise (resolve => { - conn.once ('blocklist-update', ({added}) => { - assert.ok (added.length) - resolve () - }) - }) - - await conn.blockUser (testJid, 'add') - assert.strictEqual(conn.blocklist.length, blockedCount + 1); - await waitForEventAdded - - await delay (2000) - const waitForEventRemoved = new Promise (resolve => { - conn.once ('blocklist-update', ({removed}) => { - assert.ok (removed.length) - resolve () - }) - }) - - await conn.blockUser (testJid, 'remove') - assert.strictEqual(conn.blocklist.length, blockedCount); - await waitForEventRemoved - }) - it('should exit an invalid query', async () => { - // try and send an already sent message - let msg: WAMessage - await conn.findMessage(testJid, 5, m => { - if(m.key.fromMe) { - msg = m - return true - } - }) - try { - await conn.relayWAMessage(msg) - assert.fail('should not have sent') - } catch(error) { - assert.strictEqual(error.status, 422) - } - }) -}) diff --git a/src/Tests/Tests.Mutex.ts b/src/Tests/Tests.Mutex.ts deleted file mode 100644 index d4e2992..0000000 --- a/src/Tests/Tests.Mutex.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { strict as assert } from 'assert' -import { Mutex } from '../WAConnection/Mutex' - -const DEFAULT_WAIT = 1000 - -class MyClass { - didDoWork = false - values: { [k: string]: number } = {} - counter = 0 - - @Mutex () - async myFunction () { - if (this.didDoWork) return - - await new Promise (resolve => setTimeout(resolve, DEFAULT_WAIT)) - if (this.didDoWork) { - throw new Error ('work already done') - } - this.didDoWork = true - } - @Mutex (key => key) - async myKeyedFunction (key: string) { - if (!this.values[key]) { - await new Promise (resolve => setTimeout(resolve, DEFAULT_WAIT)) - if (this.values[key]) throw new Error ('value already set for ' + key) - this.values[key] = Math.floor(Math.random ()*100) - } - return this.values[key] - } - @Mutex (key => key) - async myQueingFunction (key: string) { - await new Promise (resolve => setTimeout(resolve, DEFAULT_WAIT)) - } - @Mutex () - async myErrorFunction () { - await new Promise (resolve => setTimeout(resolve, 100)) - this.counter += 1 - if (this.counter % 2 === 0) { - throw new Error ('failed') - } - } -} - -describe ('garbage', () => { - it ('should only execute once', async () => { - const stuff = new MyClass () - const start = new Date () - await Promise.all ([...Array(1000)].map(() => stuff.myFunction ())) - const diff = new Date ().getTime()-start.getTime() - assert.ok (diff < DEFAULT_WAIT*1.25) - }) - it ('should only execute once based on the key', async () => { - const stuff = new MyClass () - const start = new Date () - /* - In this test, the mutex will lock the function based on the key. - - So, if the function with argument `key1` is underway - and another function with key `key1` is called, - the call is blocked till the first function completes. - However, if argument `key2` is passed, the function is allowed to pass. - */ - const keys = ['key1', 'key2', 'key3'] - const duplicates = 1000 - const results = await Promise.all ( - keys.flatMap (key => ( - [...Array(duplicates)].map(() => stuff.myKeyedFunction (key)) - )) - ) - assert.deepStrictEqual ( - results.slice(0, duplicates).filter (r => r !== results[0]), - [] - ) - - const diff = new Date ().getTime()-start.getTime() - assert.ok (diff < DEFAULT_WAIT*1.25) - }) - it ('should execute operations in a queue', async () => { - const stuff = new MyClass () - const start = new Date () - - const keys = ['key1', 'key2', 'key3'] - - await Promise.all ( - keys.flatMap (key => ( - [...Array(2)].map(() => stuff.myQueingFunction (key)) - )) - ) - - const diff = new Date ().getTime()-start.getTime() - assert.ok (diff < DEFAULT_WAIT*2.2 && diff > DEFAULT_WAIT*1.5) - }) - it ('should throw an error on selected items', async () => { - const stuff = new MyClass () - const start = new Date () - - const WAIT = 100 - const FUNCS = 40 - const results = await Promise.all ( - [...Array(FUNCS)].map(() => stuff.myErrorFunction ().catch(err => err.message)) - ) - - const diff = new Date ().getTime()-start.getTime() - assert.ok (diff < WAIT*FUNCS*1.1) - - assert.strictEqual ( - results.filter (r => r === 'failed').length, - FUNCS/2 // half should fail - ) - }) -}) \ No newline at end of file diff --git a/src/Tests/_test.manual_tests.ts b/src/Tests/_test.manual_tests.ts deleted file mode 100644 index 367999a..0000000 --- a/src/Tests/_test.manual_tests.ts +++ /dev/null @@ -1,112 +0,0 @@ - -describe ('Reconnects', () => { - const verifyConnectionOpen = async (conn: Connection) => { - expect((await conn.getState()).user).toBeDefined() - let failed = false - // check that the connection stays open - conn.ev.on('state.update', ({ connection, lastDisconnect }) => { - if(connection === 'close' && !!lastDisconnect.error) { - failed = true - } - }) - await delay (60*1000) - conn.close () - - expect(failed).toBe(false) - } - it('should dispose correctly on bad_session', async () => { - const conn = makeConnection({ - reconnectMode: 'on-any-error', - credentials: './auth_info.json', - maxRetries: 2, - connectCooldownMs: 500 - }) - let gotClose0 = false - let gotClose1 = false - - const openPromise = conn.open() - - conn.getSocket().ev.once('ws-close', () => { - gotClose0 = true - }) - conn.ev.on('state.update', ({ lastDisconnect }) => { - //@ts-ignore - if(lastDisconnect?.error?.output?.statusCode === DisconnectReason.badSession) { - gotClose1 = true - } - }) - setTimeout (() => conn.getSocket().ws.emit ('message', Buffer.from('some-tag,sdjjij1jo2ejo1je')), 1500) - await openPromise - - console.log('opened connection') - - await delay(1000) - conn.getSocket().ws.emit ('message', Buffer.from('some-tag,sdjjij1jo2ejo1je')) - - await delay(2000) - await conn.waitForConnection() - - conn.close() - - expect(gotClose0).toBe(true) - expect(gotClose1).toBe(true) - }, 20_000) - /** - * the idea is to test closing the connection at multiple points in the connection - * and see if the library cleans up resources correctly - */ - it('should cleanup correctly', async () => { - const conn = makeConnection({ - reconnectMode: 'on-any-error', - credentials: './auth_info.json' - }) - let timeoutMs = 100 - while (true) { - let tmout = setTimeout (() => { - conn.close() - }, timeoutMs) - try { - await conn.open() - clearTimeout (tmout) - break - } catch (error) { - - } - // exponentially increase the timeout disconnect - timeoutMs *= 2 - } - await verifyConnectionOpen(conn) - }, 120_000) - /** - * the idea is to test closing the connection at multiple points in the connection - * and see if the library cleans up resources correctly - */ - it('should disrupt connect loop', async () => { - const conn = makeConnection({ - reconnectMode: 'on-any-error', - credentials: './auth_info.json' - }) - - let timeout = 1000 - let tmout - const endConnection = async () => { - while (!conn.getSocket()) { - await delay(100) - } - conn.getSocket().end(Boom.preconditionRequired('conn close')) - - while (conn.getSocket()) { - await delay(100) - } - - timeout *= 2 - tmout = setTimeout (endConnection, timeout) - } - tmout = setTimeout (endConnection, timeout) - - await conn.open() - clearTimeout (tmout) - - await verifyConnectionOpen(conn) - }, 120_000) -}) \ No newline at end of file diff --git a/src/Tests/test.binary.ts b/src/Tests/test.binary.ts deleted file mode 100644 index 7263626..0000000 --- a/src/Tests/test.binary.ts +++ /dev/null @@ -1,95 +0,0 @@ -import BinaryNode from '../BinaryNode' - -describe('Binary Coding Tests', () => { - - const TEST_VECTORS: [string, BinaryNode][] = [ - [ - 'f806092f5a0a10f804f80234fc6c0a350a1b39313735323938373131313740732e77686174736170702e6e657410011a143345423030393637354537454433374141424632122b0a292a7069616e6f20726f6f6d2074696d696e6773206172653a2a0a20363a3030414d2d31323a3030414d18b3faa7f3052003f80234fc4c0a410a1b39313735323938373131313740732e77686174736170702e6e657410001a20304643454335333330463634393239433645394132434646443242433845414418bdfaa7f305c00101f80234fc930a350a1b39313735323938373131313740732e77686174736170702e6e657410011a14334542303033433742353339414644303937353312520a50536f727279206672656e2c204920636f756c646e277420756e6465727374616e6420274c69627261272e2054797065202768656c702720746f206b6e6f77207768617420616c6c20492063616e20646f18c1faa7f3052003f80234fc540a410a1b39313735323938373131313740732e77686174736170702e6e657410001a20413132333042384436423041314437393345433241453245413043313638443812090a076c69627261727918c2faa7f305', - new BinaryNode( - 'action', - { last: 'true', add: 'before' }, - [ - new BinaryNode( - 'message', - {}, - { - key: { remoteJid: '917529871117@s.whatsapp.net', fromMe: true, id: '3EB009675E7ED37AABF2' }, - message: { conversation: '*piano room timings are:*\n 6:00AM-12:00AM' }, - messageTimestamp: '1584004403', - status: 'DELIVERY_ACK', - } as any - ), - new BinaryNode( - 'message', - {}, - { - key: { - remoteJid: '917529871117@s.whatsapp.net', - fromMe: false, - id: '0FCEC5330F64929C6E9A2CFFD2BC8EAD', - }, - messageTimestamp: '1584004413', - messageStubType: 'REVOKE', - } as any - ), - new BinaryNode( - 'message', - {}, - { - key: { remoteJid: '917529871117@s.whatsapp.net', fromMe: true, id: '3EB003C7B539AFD09753' }, - message: { - conversation: - "Sorry fren, I couldn't understand 'Libra'. Type 'help' to know what all I can do", - }, - messageTimestamp: '1584004417', - status: 'DELIVERY_ACK', - } as any - ), - new BinaryNode( - 'message', - {}, - { - key: { - remoteJid: '917529871117@s.whatsapp.net', - fromMe: false, - id: 'A1230B8D6B0A1D793EC2AE2EA0C168D8', - }, - message: { conversation: 'library' }, - messageTimestamp: '1584004418', - } as any - ), - ] - ) - ], - [ - 'f8063f2dfafc0831323334353637385027fc0431323334f801f80228fc0701020304050607', - new BinaryNode( - 'picture', - {jid: '12345678@s.whatsapp.net', id: '1234'}, - [ - new BinaryNode( - 'image', - {}, - Buffer.from([1,2,3,4,5,6,7]) - ) - ] - ) - ] - ] - it('should encode/decode strings', () => { - for(const [input, output] of TEST_VECTORS) { - const buff = Buffer.from(input, 'hex') - const node = BinaryNode.from(buff) - expect( - JSON.parse(JSON.stringify(node)) - ).toStrictEqual( - JSON.parse(JSON.stringify(output)) - ) - expect( - node.toBuffer().toString('hex') - ).toStrictEqual( - input - ) - } - }) -}) diff --git a/src/Tests/test.connect.ts b/src/Tests/test.connect.ts deleted file mode 100644 index 4903c2d..0000000 --- a/src/Tests/test.connect.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Boom } from '@hapi/boom' -import P from 'pino' -import BinaryNode from '../BinaryNode' -import makeConnection from '../Connection' -import { delay } from '../Utils/generics' - -describe('QR Generation', () => { - it('should generate QR', async () => { - const QR_GENS = 1 - const {ev} = makeConnection({ - maxRetries: 0, - maxQRCodes: QR_GENS, - logger: P({ level: 'trace' }) - }) - let calledQR = 0 - ev.on('connection.update', ({ qr }) => { - if(qr) calledQR += 1 - }) - - await expect(open()).rejects.toThrowError('Too many QR codes') - expect(calledQR).toBeGreaterThanOrEqual(QR_GENS) - }, 60_000) -}) - -describe('Test Connect', () => { - - const logger = P({ level: 'trace' }) - - it('should connect', async () => { - - logger.info('please be ready to scan with your phone') - - const conn = makeConnection({ - logger, - printQRInTerminal: true - }) - await conn.waitForConnection(true) - const { user, isNewLogin } = await conn.getState() - expect(user).toHaveProperty('jid') - expect(user).toHaveProperty('name') - expect(isNewLogin).toBe(true) - - conn.end(undefined) - }, 65_000) - - it('should restore session', async () => { - let conn = makeConnection({ - printQRInTerminal: true, - logger, - }) - await conn.waitForConnection(true) - conn.end(undefined) - - await delay(2500) - - conn = makeConnection({ - printQRInTerminal: true, - logger, - }) - await conn.waitForConnection(true) - - const { user, isNewLogin, qr } = await conn.getState() - expect(user).toHaveProperty('jid') - expect(user).toHaveProperty('name') - expect(isNewLogin).toBe(false) - expect(qr).toBe(undefined) - - conn.end(undefined) - }, 65_000) - - it('should logout', async () => { - let conn = makeConnection({ - printQRInTerminal: true, - logger, - }) - await conn.waitForConnection(true) - - const { user, qr } = await conn.getState() - expect(user).toHaveProperty('jid') - expect(user).toHaveProperty('name') - expect(qr).toBe(undefined) - - const credentials = conn.getAuthInfo() - await conn.logout() - - conn = makeConnection({ - credentials, - logger - }) - await expect( - conn.waitForConnection() - ).rejects.toThrowError('Unexpected error in login') - }, 65_000) -}) \ No newline at end of file diff --git a/src/Tests/test.message-gen.ts b/src/Tests/test.message-gen.ts deleted file mode 100644 index 6b325b4..0000000 --- a/src/Tests/test.message-gen.ts +++ /dev/null @@ -1,8 +0,0 @@ - -describe('Message Generation', () => { - - it('should generate a text message', () => { - - }) - -}) \ No newline at end of file diff --git a/src/Tests/test.queries.ts b/src/Tests/test.queries.ts deleted file mode 100644 index f9e28ed..0000000 --- a/src/Tests/test.queries.ts +++ /dev/null @@ -1,165 +0,0 @@ -import BinaryNode from '../BinaryNode' -import makeConnection from '../makeConnection' -import { delay } from '../WAConnection/Utils' - -describe('Queries', () => { - /*it ('should correctly send updates for chats', async () => { - const conn = makeConnection({ - pendingRequestTimeoutMs: undefined, - credentials: './auth_info.json' - }) - const task = new Promise(resolve => conn.once('chats-received', resolve)) - await conn.connect () - await task - - conn.close () - - const oldChat = conn.chats.all()[0] - oldChat.archive = 'true' // mark the first chat as archived - oldChat.modify_tag = '1234' // change modify tag to detect change - - const promise = new Promise(resolve => conn.once('chats-update', resolve)) - - const result = await conn.connect () - assert.ok (!result.newConnection) - - const chats = await promise as Partial[] - const chat = chats.find (c => c.jid === oldChat.jid) - assert.ok (chat) - - assert.ok ('archive' in chat) - assert.strictEqual (Object.keys(chat).length, 3) - assert.strictEqual (Object.keys(chats).length, 1) - - conn.close () - }) - it ('should correctly send updates for contacts', async () => { - const conn = makeConnection () - conn.pendingRequestTimeoutMs = null - conn.loadAuthInfo('./auth_info.json') - - const task: any = new Promise(resolve => conn.once('contacts-received', resolve)) - await conn.connect () - const initialResult = await task - assert.strictEqual( - initialResult.updatedContacts.length, - Object.keys(conn.contacts).length - ) - - - conn.close () - - const [jid] = Object.keys(conn.contacts) - const oldContact = conn.contacts[jid] - oldContact.name = 'Lol' - oldContact.index = 'L' - - const promise = new Promise(resolve => conn.once('contacts-received', resolve)) - - const result = await conn.connect () - assert.ok (!result.newConnection) - - const {updatedContacts} = await promise as { updatedContacts: Partial[] } - const contact = updatedContacts.find (c => c.jid === jid) - assert.ok (contact) - - assert.ok ('name' in contact) - assert.strictEqual (Object.keys(contact).length, 3) - assert.strictEqual (Object.keys(updatedContacts).length, 1) - - conn.close () - })*/ - it('should queue requests when closed', async () => { - const conn = makeConnection({ - credentials: './auth_info.json' - }) - await conn.open() - await delay(2000) - - conn.close() - const { user: { jid } } = await conn.getState() - const task: Promise = conn.query({ - json: ['query', 'Status', jid] - }) - - await delay(2000) - - conn.open() - const json = await task - - expect(json.status).toBeDefined() - - conn.close() - }, 65_000) - - it('[MANUAL] should recieve query response after phone disconnect', async () => { - const conn = makeConnection ({ - printQRInTerminal: true, - credentials: './auth_info.json' - }) - await conn.open() - const { phoneConnected } = await conn.getState() - expect(phoneConnected).toBe(true) - - try { - const waitForEvent = expect => new Promise (resolve => { - conn.ev.on('state.update', ({phoneConnected}) => { - if (phoneConnected === expect) { - conn.ev.removeAllListeners('state.update') - resolve(undefined) - } - }) - }) - - console.log('disconnect your phone from the internet') - await delay(10_000) - console.log('phone should be disconnected now, testing...') - - const query = conn.query({ - json: new BinaryNode( - 'query', - { - epoch: conn.getSocket().currentEpoch().toString(), - type: 'message', - jid: '1234@s.whatsapp.net', - kind: 'before', - count: '10', - } - ), - requiresPhoneConnection: true, - expect200: false - }) - await waitForEvent(false) - - console.log('reconnect your phone to the internet') - await waitForEvent(true) - - console.log('reconnected successfully') - - await expect(query).resolves.toBeDefined() - } finally { - conn.close() - } - }, 65_000) - - it('should re-execute query on connection closed error', async () => { - const conn = makeConnection({ - credentials: './auth_info.json' - }) - await conn.open() - const { user: { jid } } = await conn.getState() - const task: Promise = conn.query({ json: ['query', 'Status', jid], waitForOpen: true }) - - await delay(20) - // fake cancel the connection - conn.getSocket().ev.emit('message', '1234,["Pong",false]') - - await delay(2000) - - const json = await task - - expect(json.status).toBeDefined() - - conn.close() - }, 65_000) -}) \ No newline at end of file diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts index aeaa907..5ff963e 100644 --- a/src/Types/Auth.ts +++ b/src/Types/Auth.ts @@ -1,22 +1,51 @@ +import type { Contact } from "./Contact" +import type { proto } from "../../WAProto" -export interface AuthenticationCredentials { - clientID: string - serverToken: string - clientToken: string - encKey: Buffer - macKey: Buffer +export type KeyPair = { public: Uint8Array, private: Uint8Array } +export type SignedKeyPair = { keyPair: KeyPair, signature: Uint8Array, keyId: number } + +export type ProtocolAddress = { + name: string // jid + deviceId: number } -export interface AuthenticationCredentialsBase64 { - clientID: string - serverToken: string - clientToken: string - encKey: string - macKey: string +export type SignalIdentity = { + identifier: ProtocolAddress + identifierKey: Uint8Array } -export interface AuthenticationCredentialsBrowser { - WABrowserId: string - WASecretBundle: {encKey: string, macKey: string} | string - WAToken1: string - WAToken2: string + +export type CollectionType = 'regular_high' | 'regular_low' | 'critical_unblock_low' | 'critical_block' + +export type AuthenticationCreds = { + noiseKey: KeyPair + signedIdentityKey: KeyPair + signedPreKey: SignedKeyPair + registrationId: number + advSecretKey: string + me?: Contact + account?: proto.ADVSignedDeviceIdentity + signalIdentities?: SignalIdentity[] + appStateSyncKeys?: proto.IAppStateSyncKey[] + appStateVersion?: { + [T in CollectionType]: number + } + + firstUnuploadedPreKeyId: number + serverHasPreKeys: boolean + nextPreKeyId: number } -export type AnyAuthenticationCredentials = AuthenticationCredentialsBrowser | AuthenticationCredentialsBase64 | AuthenticationCredentials \ No newline at end of file +type Awaitable = T | Promise +export type SignalKeyStore = { + getPreKey: (keyId: number) => Awaitable + setPreKey: (keyId: number, pair: KeyPair | null) => Awaitable + + getSession: (sessionId: string) => Awaitable + setSession: (sessionId: string, item: any | null) => Awaitable + + getSenderKey: (id: string) => Awaitable + setSenderKey: (id: string, item: any | null) => Awaitable +} + +export type AuthenticationState = { + creds: AuthenticationCreds + keys: SignalKeyStore +} \ No newline at end of file diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 5815b5a..3fbad52 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -1,46 +1,30 @@ +import type { proto } from "../../WAProto" + /** set of statuses visible to other people; see updatePresence() in WhatsAppWeb.Send */ -export enum Presence { - unavailable = 'unavailable', // "offline" - available = 'available', // "online" - composing = 'composing', // "typing..." - recording = 'recording', // "recording..." - paused = 'paused', // stop typing -} +export type WAPresence = 'unavailable' | 'available' | 'composing' | 'recording' | 'paused' export interface PresenceData { - lastKnownPresence: Presence + lastKnownPresence: WAPresence lastSeen?: number } -export interface Chat { - jid: string - - t: number - /** number of unread messages, is < 0 if the chat is manually marked unread */ - count: number - archive?: 'true' | 'false' - clear?: 'true' | 'false' - read_only?: 'true' | 'false' - mute?: string - pin?: string - spam?: 'false' | 'true' - modify_tag?: string - name?: string - /** when ephemeral messages were toggled on */ - eph_setting_ts?: string - /** how long each message lasts for */ - ephemeral?: string +export type Chat = Omit & { + /** unix timestamp of date when mute ends, if applicable */ + mute?: number | null + /** timestamp of when pinned */ + pin?: number | null + archive?: boolean } export type ChatModification = { archive: boolean } | { /** pin at current timestamp, or provide timestamp of pin to remove */ - pin: true | { remove: number } + pin: number | null } | { /** mute for duration, or provide timestamp of mute to remove*/ - mute: number | { remove: number } + mute: number | null } | { clear: 'all' | { messages: { id: string, fromMe?: boolean }[] } @@ -51,4 +35,7 @@ export type ChatModification = star: boolean } } | + { + markRead: boolean + } | { delete: true } \ No newline at end of file diff --git a/src/Types/Contact.ts b/src/Types/Contact.ts index cb24f02..f5e74b3 100644 --- a/src/Types/Contact.ts +++ b/src/Types/Contact.ts @@ -1,15 +1,11 @@ export interface Contact { - verify?: string - /** name of the contact, the contact has set on their own on WA */ - notify?: string - jid: string - /** I have no idea */ - vname?: string + id: string /** name of the contact, you have saved on your WA */ name?: string - index?: string - /** short name for the contact */ - short?: string + /** name of the contact, the contact has set on their own on WA */ + notify?: string + /** I have no idea */ + verifiedName?: string // Baileys Added imgUrl?: string status?: string diff --git a/src/Types/GroupMetadata.ts b/src/Types/GroupMetadata.ts index 5e86b97..13b2442 100644 --- a/src/Types/GroupMetadata.ts +++ b/src/Types/GroupMetadata.ts @@ -1,6 +1,6 @@ import { Contact } from "./Contact"; -export type GroupParticipant = (Contact & { isAdmin: boolean; isSuperAdmin: boolean }) +export type GroupParticipant = (Contact & { isAdmin?: boolean; isSuperAdmin?: boolean, admin?: 'admin' | 'superadmin' | null }) export type ParticipantAction = 'add' | 'remove' | 'promote' | 'demote' diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 7deb27e..934e4b5 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -1,18 +1,18 @@ import type { ReadStream } from "fs" import type { Logger } from "pino" import type { URL } from "url" -import { proto } from '../../WAMessage' +import { proto } from '../../WAProto' // export the WAMessage Prototypes -export { proto as WAMessageProto } -export type WAMessage = proto.WebMessageInfo +export { proto as WAProto } +export type WAMessage = proto.IWebMessageInfo export type WAMessageContent = proto.IMessage -export type WAContactMessage = proto.ContactMessage -export type WAContactsArrayMessage = proto.ContactsArrayMessage +export type WAContactMessage = proto.IContactMessage +export type WAContactsArrayMessage = proto.IContactsArrayMessage export type WAMessageKey = proto.IMessageKey -export type WATextMessage = proto.ExtendedTextMessage +export type WATextMessage = proto.IExtendedTextMessage export type WAContextInfo = proto.IContextInfo -export type WALocationMessage = proto.LocationMessage +export type WALocationMessage = proto.ILocationMessage export type WAGenericMediaMessage = proto.IVideoMessage | proto.IImageMessage | proto.IAudioMessage | proto.IDocumentMessage | proto.IStickerMessage export import WAMessageStubType = proto.WebMessageInfo.WebMessageInfoStubType export import WAMessageStatus = proto.WebMessageInfo.WebMessageInfoStatus @@ -23,20 +23,10 @@ export type MessageType = keyof proto.Message export type MediaConnInfo = { auth: string ttl: number - hosts: { - hostname: string - }[] + hosts: { hostname: string }[] fetchDate: Date } -/** Reverse stub type dictionary */ -export const WA_MESSAGE_STUB_TYPES = function () { - const types = WAMessageStubType - const dict: Record = {} - Object.keys(types).forEach(element => dict[ types[element] ] = element) - return dict -}() - export interface WAUrlInfo { 'canonical-url': string 'matched-text': string @@ -61,7 +51,7 @@ type WithDimensions = { width?: number height?: number } -export type MediaType = 'image' | 'video' | 'sticker' | 'audio' | 'document' +export type MediaType = 'image' | 'video' | 'sticker' | 'audio' | 'document' | 'history' export type AnyMediaMessageContent = ( ({ image: WAMediaUpload @@ -121,10 +111,7 @@ export type MiscMessageGenerationOptions = { /** the message you want to quote */ quoted?: WAMessage /** disappearing messages settings */ - ephemeralOptions?: { - expiration: number | string - eph_setting_ts?: number | string - } + ephemeralExpiration?: number | string } export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & { userJid: string @@ -143,7 +130,7 @@ export type MessageContentGenerationOptions = MediaGenerationOptions & { } export type MessageGenerationOptions = MessageContentGenerationOptions & MessageGenerationOptionsFromContent -export type MessageUpdateType = 'prepend' | 'append' | 'notify' | 'last' +export type MessageUpdateType = 'append' | 'notify' export type MessageInfoEventMap = { [jid: string]: Date } export interface MessageInfo { diff --git a/src/Types/State.ts b/src/Types/State.ts new file mode 100644 index 0000000..754ff32 --- /dev/null +++ b/src/Types/State.ts @@ -0,0 +1,17 @@ +export type WAConnectionState = 'open' | 'connecting' | 'close' + +export type ConnectionState = { + /** connection is now open, connecting or closed */ + connection: WAConnectionState + /** the error that caused the connection to close */ + lastDisconnect?: { + error: Error + date: Date + } + /** is this a new login */ + isNewLogin?: boolean + /** the current QR code */ + qr?: string + /** has the device received all pending notifications while it was offline */ + receivedPendingNotifications?: boolean +} \ No newline at end of file diff --git a/src/Types/Store.ts b/src/Types/Store.ts deleted file mode 100644 index 9c5c65e..0000000 --- a/src/Types/Store.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type KeyedDB from '@adiwajshing/keyed-db' -import type { Chat } from './Chat' -import type { Contact } from './Contact' - -export type WAConnectionState = 'open' | 'connecting' | 'close' - -export type ConnectionState = { - user?: Contact - phoneConnected: boolean - phoneInfo?: any - connection: WAConnectionState - lastDisconnect?: { - error: Error, - date: Date - }, - isNewLogin?: boolean - connectionTriesLeft?: number - qr?: string -} - -export type BaileysState = { - connection: ConnectionState - chats: KeyedDB - contacts: { [jid: string]: Contact } -} \ No newline at end of file diff --git a/src/Types/index.ts b/src/Types/index.ts index 5b0008f..3822933 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -2,134 +2,56 @@ export * from './Auth' export * from './GroupMetadata' export * from './Chat' export * from './Contact' -export * from './Store' +export * from './State' export * from './Message' import type EventEmitter from "events" import type { Agent } from "https" import type { Logger } from "pino" import type { URL } from "url" -import type BinaryNode from "../BinaryNode" -import { AnyAuthenticationCredentials, AuthenticationCredentials } from './Auth' + +import { AuthenticationState } from './Auth' import { Chat, PresenceData } from './Chat' import { Contact } from './Contact' -import { ConnectionState } from './Store' +import { ConnectionState } from './State' import { GroupMetadata, ParticipantAction } from './GroupMetadata' -import { MessageInfo, MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageKey, WAMessageUpdate } from './Message' -import { proto } from '../../WAMessage' - -/** used for binary messages */ -export enum WAMetric { - debugLog = 1, - queryResume = 2, - liveLocation = 3, - queryMedia = 4, - queryChat = 5, - queryContact = 6, - queryMessages = 7, - presence = 8, - presenceSubscribe = 9, - group = 10, - read = 11, - chat = 12, - received = 13, - picture = 14, - status = 15, - message = 16, - queryActions = 17, - block = 18, - queryGroup = 19, - queryPreview = 20, - queryEmoji = 21, - queryRead = 22, - queryVCard = 29, - queryStatus = 30, - queryStatusUpdate = 31, - queryLiveLocation = 33, - queryLabel = 36, - queryQuickReply = 39 -} - -/** used for binary messages */ -export enum WAFlag { - available = 160, - other = 136, // don't know this one - ignore = 1 << 7, - acknowledge = 1 << 6, - unavailable = 1 << 4, - expires = 1 << 3, - composing = 1 << 2, - recording = 1 << 2, - paused = 1 << 2 -} - -/** Tag used with binary queries */ -export type WATag = [WAMetric, WAFlag] - -export type SocketSendMessageOptions = { - json: BinaryNode | any[] - binaryTag?: WATag - tag?: string - longTag?: boolean -} +import { MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageUpdate } from './Message' export type WAVersion = [number, number, number] export type WABrowserDescription = [string, string, string] export type ReconnectMode = 'no-reconnects' | 'on-any-error' | 'on-connection-error' export type SocketConfig = { + /** provide an auth state object to maintain the auth state */ + auth?: AuthenticationState /** the WS url to connect to WA */ waWebSocketUrl: string | URL - /** Fails the connection if the connection times out in this time interval or no data is received */ + /** Fails the connection if the socket times out in this interval */ connectTimeoutMs: number - /** max time for the phone to respond to a connectivity test */ - phoneResponseTimeMs: number /** ping-pong interval for WS connection */ keepAliveIntervalMs: number - - expectResponseTimeout: number /** proxy agent */ agent?: Agent + /** pino logger */ logger: Logger - + /** version to connect with */ version: WAVersion + /** override browser config */ browser: WABrowserDescription - /** maximum attempts to connect */ - maxRetries: number - connectCooldownMs: number /** agent used for fetch requests -- uploading/downloading media */ fetchAgent?: Agent - /** credentials used to sign back in */ - credentials?: AnyAuthenticationCredentials | string - /** - * Sometimes WA does not send the chats, - * this keeps pinging the phone to send the chats over - * */ - queryChatsTillReceived?: boolean - /** */ - pendingRequestTimeoutMs: number - reconnectMode: ReconnectMode - maxQRCodes: number /** should the QR be printed in the terminal */ printQRInTerminal: boolean - - phoneConnectionChanged: (connected: boolean) => void -} - -export type SocketQueryOptions = SocketSendMessageOptions & { - timeoutMs?: number - expect200?: boolean - requiresPhoneConnection?: boolean } export enum DisconnectReason { connectionClosed = 428, - connectionReplaced = 440, connectionLost = 408, timedOut = 408, - credentialsInvalidated = 401, - badSession = 500 + loggedOut = 401, + badSession = 500, + restartRequired = 410 } export type WAInitResponse = { @@ -160,36 +82,40 @@ export type WABusinessProfile = { wid?: string } -export type QueryOptions = SocketQueryOptions & { - waitForOpen?: boolean - maxRetries?: number - startDebouncedTimeout?: boolean -} export type CurveKeyPair = { private: Uint8Array; public: Uint8Array } export type BaileysEventMap = { + /** connection state has been updated -- WS closed, opened, connecting etc. */ 'connection.update': Partial - 'credentials.update': AuthenticationCredentials - - 'chats.set': { chats: Chat[] } + /** auth state updated -- some pre keys, or identity keys etc. */ + 'auth-state.update': AuthenticationState + /** set chats (history sync), messages are reverse chronologically sorted */ + 'chats.set': { chats: Chat[], messages: WAMessage[] } + /** upsert chats */ 'chats.upsert': Chat[] + /** update the given chats */ 'chats.update': Partial[] + /** delete chats with given ID */ 'chats.delete': string[] + /** presence of contact in a chat updated */ + 'presence.update': { id: string, presences: { [participant: string]: PresenceData } } - 'presence.update': { jid: string, presences: { [participant: string]: PresenceData } } - - 'contacts.set': { contacts: Contact[] } 'contacts.upsert': Contact[] 'contacts.update': Partial[] 'messages.delete': { jid: string, ids: string[] } | { jid: string, all: true } 'messages.update': WAMessageUpdate[] + /** + * add/update the given messages. If they were received while the connection was online, + * the update will have type: "notify" + * */ 'messages.upsert': { messages: WAMessage[], type: MessageUpdateType } 'message-info.update': MessageInfoUpdate[] 'groups.update': Partial[] - 'group-participants.update': { jid: string, participants: string[], action: ParticipantAction } + /** apply an action to participants in a group */ + 'group-participants.update': { id: string, participants: string[], action: ParticipantAction } 'blocklist.set': { blocklist: string[] } 'blocklist.update': { blocklist: string[], type: 'add' | 'remove' } diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts new file mode 100644 index 0000000..075fa91 --- /dev/null +++ b/src/Utils/chat-utils.ts @@ -0,0 +1,198 @@ +import { Boom } from '@hapi/boom' +import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./generics" +import { AuthenticationState, ChatModification } from "../Types" +import { proto } from '../../WAProto' +import { LT_HASH_ANTI_TAMPERING } from '../WABinary/LTHash' + +type SyncdType = 'regular_high' | 'regular_low' + +const mutationKeys = (keydata: string) => { + const expanded = hkdf(Buffer.from(keydata, 'base64'), 160, { info: 'WhatsApp Mutation Keys' }) + return { + indexKey: expanded.slice(0, 32), + valueEncryptionKey: expanded.slice(32, 64), + valueMacKey: expanded.slice(64, 96), + snapshotMacKey: expanded.slice(96, 128), + patchMacKey: expanded.slice(128, 160) + } +} + +const generateMac = (operation: proto.SyncdMutation.SyncdMutationSyncdOperation, data: Buffer, keyId: Uint8Array | string, key: Buffer) => { + const getKeyData = () => { + let r: number + switch (operation) { + case proto.SyncdMutation.SyncdMutationSyncdOperation.SET: + r = 0x01 + break + case proto.SyncdMutation.SyncdMutationSyncdOperation.REMOVE: + r = 0x02 + break + } + const buff = Buffer.from([r]) + return Buffer.concat([ buff, Buffer.from(keyId as any, 'base64') ]) + } + const keyData = getKeyData() + + const last = Buffer.alloc(8) // 8 bytes + last.set([ keyData.length ], last.length-1) + + const total = Buffer.concat([ keyData, data, last ]) + const hmac = hmacSign(total, key, 'sha512') + + return hmac.slice(0, 32) +} + +const to64BitNetworkOrder = function(e) { + const t = new ArrayBuffer(8) + new DataView(t).setUint32(4, e, !1) + return Buffer.from(t) +} + +const generateSnapshotMac = (version: number, indexMac: Uint8Array, valueMac: Uint8Array, type: SyncdType, key: Buffer) => { + + const ltHash = () => { + const result = LT_HASH_ANTI_TAMPERING.subtractThenAdd(new Uint8Array(128).buffer, [ new Uint8Array(valueMac).buffer, new Uint8Array(indexMac).buffer ], []) + const buff = Buffer.from(result) + console.log(buff.toString('hex')) + return buff + } + const total = Buffer.concat([ + ltHash(), + to64BitNetworkOrder(version), + Buffer.from(type, 'utf-8') + ]) + return hmacSign(total, key) +} +const generatePatchMac = (snapshotMac: Uint8Array, valueMacs: Uint8Array[], version: number, type: SyncdType, key: Buffer) => { + const total = Buffer.concat([ + snapshotMac, + ...valueMacs, + to64BitNetworkOrder(version), + Buffer.from(type, 'utf-8') + ]) + return hmacSign(total, key) +} + +export const encodeSyncdPatch = (action: ChatModification, lastMessageKey: proto.IMessageKey, { creds: { appStateSyncKeys: [key], appStateVersion } }: AuthenticationState) => { + let syncAction: proto.ISyncActionValue = { } + if('archive' in action) { + syncAction.archiveChatAction = { + archived: action.archive, + messageRange: { + messages: [ + { key: lastMessageKey } + ] + } + } + } else if('mute' in action) { + const value = typeof action.mute === 'number' ? true : false + syncAction.muteAction = { + muted: value, + muteEndTimestamp: typeof action.mute === 'number' ? action.mute : undefined + } + } else if('delete' in action) { + syncAction.deleteChatAction = { } + } else if('markRead' in action) { + syncAction.markChatAsReadAction = { + read: action.markRead + } + } else if('pin' in action) { + throw new Boom('Pin not supported on multi-device yet', { statusCode: 400 }) + } + + const encoded = proto.SyncActionValue.encode(syncAction).finish() + + const index = JSON.stringify([Object.keys(action)[0], lastMessageKey.remoteJid]) + const keyValue = mutationKeys(key.keyData!.keyData! as any) + + const encValue = aesEncrypt(encoded, keyValue.valueEncryptionKey) + const macValue = generateMac(1, encValue, key.keyId!.keyId, keyValue.valueMacKey) + const indexMacValue = hmacSign(Buffer.from(index), keyValue.indexKey) + + const type = 'regular_high' + const v = appStateVersion[type]+1 + + const snapshotMac = generateSnapshotMac(v, indexMacValue, macValue, type, keyValue.snapshotMacKey) + + const patch: proto.ISyncdPatch = { + patchMac: generatePatchMac(snapshotMac, [macValue], v, type, keyValue.patchMacKey), + snapshotMac: snapshotMac, + keyId: { id: key.keyId.keyId }, + mutations: [ + { + operation: 1, + record: { + index: { + blob: indexMacValue + }, + value: { + blob: Buffer.concat([ encValue, macValue ]) + }, + keyId: { id: key.keyId.keyId } + } + } + ] + } + return patch +} + +export const decodeSyncdPatch = (msg: proto.ISyncdPatch, {creds}: AuthenticationState) => { + const keyCache: { [_: string]: ReturnType } = { } + const getKey = (keyId: Uint8Array) => { + const base64Key = Buffer.from(keyId!).toString('base64') + + let key = keyCache[base64Key] + if(!key) { + const keyEnc = creds.appStateSyncKeys?.find(k => ( + (k.keyId!.keyId as any) === base64Key + )) + if(!keyEnc) { + throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500, data: msg }) + } + const result = mutationKeys(keyEnc.keyData!.keyData as any) + keyCache[base64Key] = result + key = result + } + return key + } + + const mutations: { action: proto.ISyncActionValue, index: [string, string] }[] = [] + const failures: Boom[] = [] + + /*const mainKey = getKey(msg.keyId!.id) + const mutation = msg.mutations![0]!.record + + const patchMac = generatePatchMac(msg.snapshotMac, [ mutation.value!.blob!.slice(-32) ], toNumber(msg.version!.version), 'regular_low', mainKey.patchMacKey) + console.log(patchMac) + console.log(msg.patchMac)*/ + + // indexKey used to HMAC sign record.index.blob + // valueEncryptionKey used to AES-256-CBC encrypt record.value.blob[0:-32] + // the remaining record.value.blob[0:-32] is the mac, it the HMAC sign of key.keyId + decoded proto data + length of bytes in keyId + for(const { operation, record } of msg.mutations!) { + try { + const key = getKey(record.keyId!.id!) + const content = Buffer.from(record.value!.blob!) + const encContent = content.slice(0, -32) + const contentHmac = generateMac(operation, encContent, record.keyId!.id!, key.valueMacKey) + if(Buffer.compare(contentHmac, content.slice(-32)) !== 0) { + throw new Boom('HMAC content verification failed') + } + + const result = aesDecrypt(encContent, key.valueEncryptionKey) + const syncAction = proto.SyncActionData.decode(result) + + const hmac = hmacSign(syncAction.index, key.indexKey) + if(Buffer.compare(hmac, record.index!.blob) !== 0) { + throw new Boom('HMAC index verification failed') + } + + const indexStr = Buffer.from(syncAction.index).toString() + mutations.push({ action: syncAction.value!, index: JSON.parse(indexStr) }) + } catch(error) { + failures.push(new Boom(error, { data: { operation, record } })) + } + } + + return { mutations, failures } +} \ No newline at end of file diff --git a/src/Utils/decode-wa-message.ts b/src/Utils/decode-wa-message.ts index a8e3e97..130c774 100644 --- a/src/Utils/decode-wa-message.ts +++ b/src/Utils/decode-wa-message.ts @@ -1,63 +1,103 @@ import { Boom } from '@hapi/boom' -import BinaryNode from "../BinaryNode" -import { aesDecrypt, hmacSign } from "./generics" -import { DisconnectReason, WATag } from "../Types" +import { unpadRandomMax16 } from "./generics" +import { AuthenticationState } from "../Types" +import { areJidsSameUser, BinaryNode as BinaryNodeM, encodeBinaryNode, isJidBroadcast, isJidGroup, isJidStatusBroadcast, isJidUser } from '../WABinary' +import { decryptGroupSignalProto, decryptSignalProto, processSenderKeyMessage } from './signal' +import { proto } from '../../WAProto' -export const decodeWAMessage = ( - message: string | Buffer, - auth: { macKey: Buffer, encKey: Buffer }, - fromMe: boolean=false -) => { +type MessageType = 'chat' | 'peer_broadcast' | 'other_broadcast' | 'group' | 'direct_peer_status' | 'other_status' - let commaIndex = message.indexOf(',') // all whatsapp messages have a tag and a comma, followed by the actual message - if (commaIndex < 0) throw new Boom('invalid message', { data: message }) // if there was no comma, then this message must be not be valid - - if (message[commaIndex+1] === ',') commaIndex += 1 - let data = message.slice(commaIndex+1, message.length) - - // get the message tag. - // If a query was done, the server will respond with the same message tag we sent the query with - const messageTag: string = message.slice(0, commaIndex).toString() - let json: any - let tags: WATag - if (data.length > 0) { - if (typeof data === 'string') { - json = JSON.parse(data) // parse the JSON +export const decodeMessageStanza = async(stanza: BinaryNodeM, auth: AuthenticationState) => { + const deviceIdentity = (stanza.content as BinaryNodeM[])?.find(m => m.tag === 'device-identity') + const deviceIdentityBytes = deviceIdentity ? deviceIdentity.content as Buffer : undefined + + let msgType: MessageType + let chatId: string + let author: string + + const msgId: string = stanza.attrs.id + const from: string = stanza.attrs.from + const participant: string | undefined = stanza.attrs.participant + const recipient: string | undefined = stanza.attrs.recipient + + const isMe = (jid: string) => areJidsSameUser(jid, auth.creds.me!.id) + + if(isJidUser(from)) { + if(recipient) { + if(!isMe(from)) { + throw new Boom('') + } + chatId = recipient } else { - const { macKey, encKey } = auth || {} - if (!macKey || !encKey) { - throw new Boom('recieved encrypted buffer when auth creds unavailable', { data: message, statusCode: DisconnectReason.badSession }) - } - /* - If the data recieved was not a JSON, then it must be an encrypted message. - Such a message can only be decrypted if we're connected successfully to the servers & have encryption keys - */ - if (fromMe) { - tags = [data[0], data[1]] - data = data.slice(2, data.length) - } - - const checksum = data.slice(0, 32) // the first 32 bytes of the buffer are the HMAC sign of the message - data = data.slice(32, data.length) // the actual message - const computedChecksum = hmacSign(data, macKey) // compute the sign of the message we recieved using our macKey - - if (checksum.equals(computedChecksum)) { - // the checksum the server sent, must match the one we computed for the message to be valid - const decrypted = aesDecrypt(data, encKey) // decrypt using AES - json = BinaryNode.from(decrypted) // decode the binary message into a JSON array - } else { - throw new Boom('Bad checksum', { - data: { - received: checksum.toString('hex'), - computed: computedChecksum.toString('hex'), - data: data.slice(0, 80).toString(), - tag: messageTag, - message: message.slice(0, 80).toString() - }, - statusCode: DisconnectReason.badSession - }) - } - } + chatId = from + } + msgType = 'chat' + author = from + } else if(isJidGroup(from)) { + if(!participant) { + throw new Boom('No participant in group message') + } + msgType = 'group' + author = participant + chatId = from + } else if(isJidBroadcast(from)) { + if(!participant) { + throw new Boom('No participant in group message') + } + const isParticipantMe = isMe(participant) + if(isJidStatusBroadcast(from)) { + msgType = isParticipantMe ? 'direct_peer_status' : 'other_status' + } else { + msgType = isParticipantMe ? 'peer_broadcast' : 'other_broadcast' + } + chatId = from + author = participant + } + const sender = msgType === 'chat' ? author : chatId + + const successes: proto.Message[] = [] + const failures: { error: Boom }[] = [] + if(Array.isArray(stanza.content)) { + for(const { tag, attrs, content } of stanza.content as BinaryNodeM[]) { + if(tag !== 'enc') continue + if(!Buffer.isBuffer(content) && !(content instanceof Uint8Array)) continue + + try { + let msgBuffer: Buffer + + const e2eType = attrs.type + switch(e2eType) { + case 'skmsg': + msgBuffer = await decryptGroupSignalProto(sender, author, content, auth) + break + case 'pkmsg': + case 'msg': + const user = isJidUser(sender) ? sender : author + msgBuffer = await decryptSignalProto(user, e2eType, content as Buffer, auth) + break + } + const msg = proto.Message.decode(unpadRandomMax16(msgBuffer)) + if(msg.senderKeyDistributionMessage) { + await processSenderKeyMessage(author, msg.senderKeyDistributionMessage, auth) + } + + successes.push(msg) + } catch(error) { + failures.push({ error: new Boom(error, { data: Buffer.from(encodeBinaryNode(stanza)).toString('base64') }) }) + } + } + } + + return { + msgId, + chatId, + author, + from, + timestamp: +stanza.attrs.t, + participant, + recipient, + pushname: stanza.attrs.notify, + successes, + failures } - return [messageTag, json, tags] as const } \ No newline at end of file diff --git a/src/Utils/generics.ts b/src/Utils/generics.ts index 3435a85..242c60b 100644 --- a/src/Utils/generics.ts +++ b/src/Utils/generics.ts @@ -1,7 +1,10 @@ import { Boom } from '@hapi/boom' +import CurveCrypto from 'libsignal/src/curve25519_wrapper' import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes } from 'crypto' -import HKDF from 'futoin-hkdf' import { platform, release } from 'os' +import { KeyPair } from '../Types' +import { proto } from '../../WAProto' +import { Binary } from '../WABinary' const PLATFORM_MAP = { 'aix': 'AIX', @@ -9,6 +12,7 @@ const PLATFORM_MAP = { 'win32': 'Windows', 'android': 'Android' } + export const Browsers = { ubuntu: browser => ['Ubuntu', browser, '18.04'] as [string, string, string], macOS: browser => ['Mac OS', browser, '10.15.3'] as [string, string, string], @@ -16,6 +20,118 @@ export const Browsers = { /** The appropriate browser based on your OS & release */ appropriate: browser => [ PLATFORM_MAP[platform()] || 'Ubuntu', browser, release() ] as [string, string, string] } + +export const BufferJSON = { + replacer: (k, value: any) => { + if(Buffer.isBuffer(value) || value instanceof Uint8Array || value?.type === 'Buffer') { + return { type: 'Buffer', data: Buffer.from(value?.data || value).toString('base64') } + } + return value + }, + reviver: (_, value: any) => { + if(typeof value === 'object' && !!value && (value.buffer === true || value.type === 'Buffer')) { + const val = value.data || value.value + return typeof val === 'string' ? Buffer.from(val, 'base64') : Buffer.from(val) + } + return value + } +} + + +export const writeRandomPadMax16 = function(e: Binary) { + function r(e: Binary, t: number) { + for (var r = 0; r < t; r++) + e.writeUint8(t) + } + + var t = randomBytes(1) + r(e, 1 + (15 & t[0])) + return e +} + +export const unpadRandomMax16 = (e: Uint8Array | Buffer) => { + const t = new Uint8Array(e); + if (0 === t.length) { + throw new Error('unpadPkcs7 given empty bytes'); + } + + var r = t[t.length - 1]; + if (r > t.length) { + throw new Error(`unpad given ${t.length} bytes, but pad is ${r}`); + } + + return new Uint8Array(t.buffer, t.byteOffset, t.length - r); +} + +export const encodeWAMessage = (message: proto.IMessage) => ( + Buffer.from( + writeRandomPadMax16( + new Binary(proto.Message.encode(message).finish()) + ).readByteArray() + ) +) + +export const generateCurveKeyPair = (): KeyPair => { + const { pubKey, privKey } = CurveCrypto.keyPair(randomBytes(32)) + return { + private: Buffer.from(privKey), + public: Buffer.from(pubKey) + } +} + +export const generateSharedKey = (privateKey: Uint8Array, publicKey: Uint8Array) => { + const shared = CurveCrypto.sharedSecret(publicKey, privateKey) + return Buffer.from(shared) +} + +export const curveSign = (privateKey: Uint8Array, buf: Uint8Array) => ( + Buffer.from(CurveCrypto.sign(privateKey, buf)) +) + +export const curveVerify = (pubKey: Uint8Array, message: Uint8Array, signature: Uint8Array) => { + try { + CurveCrypto.verify(pubKey, message, signature) + return true + } catch(error) { + if(error.message.includes('Invalid')) { + return false + } + throw error + } +} + +export const signedKeyPair = (keyPair: KeyPair, keyId: number) => { + const signKeys = generateCurveKeyPair() + const pubKey = new Uint8Array(33) + pubKey.set([5], 0) + pubKey.set(signKeys.public, 1) + + const signature = curveSign(keyPair.private, pubKey) + + return { keyPair: signKeys, signature, keyId } +} + +export const generateRegistrationId = () => ( + Uint16Array.from(randomBytes(2))[0] & 0x3fff +) + +export const encodeInt = (e: number, t: number) => { + for (var r = t, a = new Uint8Array(e), i = e - 1; i >= 0; i--) { + a[i] = 255 & r + r >>>= 8 + } + return a +} +export const encodeBigEndian = (e: number, t=4) => { + let r = e; + let a = new Uint8Array(t); + for (let i = t - 1; i >= 0; i--) { + a[i] = 255 & r + r >>>= 8 + } + return a +} + export const toNumber = (t: Long | number) => (typeof t?.['low'] !== 'undefined' ? t['low'] : t) as number export const whatsappID = (jid: string) => jid?.replace ('@c.us', '@s.whatsapp.net') @@ -48,7 +164,7 @@ export function aesDecryptWithIV(buffer: Buffer, key: Buffer, IV: Buffer) { return Buffer.concat([aes.update(buffer), aes.final()]) } // encrypt AES 256 CBC; where a random IV is prefixed to the buffer -export function aesEncrypt(buffer: Buffer, key: Buffer) { +export function aesEncrypt(buffer: Buffer | Uint8Array, key: Buffer) { const IV = randomBytes(16) const aes = createCipheriv('aes-256-cbc', key, IV) return Buffer.concat([IV, aes.update(buffer), aes.final()]) // prefix IV to the buffer @@ -59,20 +175,47 @@ export function aesEncrypWithIV(buffer: Buffer, key: Buffer, IV: Buffer) { return Buffer.concat([aes.update(buffer), aes.final()]) // prefix IV to the buffer } // sign HMAC using SHA 256 -export function hmacSign(buffer: Buffer, key: Buffer) { - return createHmac('sha256', key).update(buffer).digest() +export function hmacSign(buffer: Buffer | Uint8Array, key: Buffer | Uint8Array, variant: 'sha256' | 'sha512' = 'sha256') { + return createHmac(variant, key).update(buffer).digest() } export function sha256(buffer: Buffer) { return createHash('sha256').update(buffer).digest() } // HKDF key expansion -export function hkdf(buffer: Buffer, expandedLength: number, info = null) { - return HKDF(buffer, expandedLength, { salt: Buffer.alloc(32), info: info, hash: 'SHA-256' }) +// from: https://github.com/benadida/node-hkdf +export function hkdf(buffer: Buffer, expandedLength: number, { info, salt }: { salt?: Buffer, info?: string }) { + const hashAlg = 'sha256' + const hashLength = 32 + salt = salt || Buffer.alloc(hashLength) + // now we compute the PRK + const prk = createHmac(hashAlg, salt).update(buffer).digest() + + let prev = Buffer.from([]) + const buffers = [] + const num_blocks = Math.ceil(expandedLength / hashLength) + + const infoBuff = Buffer.from(info || []) + + for (var i=0; i Math.floor(date.getTime()/1000) export type DebouncedTimeout = ReturnType + export const debouncedTimeout = (intervalMs: number = 1000, task: () => void = undefined) => { let timeout: NodeJS.Timeout return { @@ -135,14 +278,5 @@ export async function promiseTimeout(ms: number, promise: (resolve: (v?: T)=> .finally (cancel) return p as Promise } -// whatsapp requires a message tag for every message, we just use the timestamp as one -export function generateMessageTag(epoch?: number) { - let tag = unixTimestampSeconds().toString() - if (epoch) tag += '.--' + epoch // attach epoch if provided - return tag -} -// generate a random 16 byte client ID -export const generateClientID = () => randomBytes(16).toString('base64') // generate a random ID to attach to a message -// this is the format used for WA Web 4 byte hex prefixed with 3EB0 -export const generateMessageID = () => '3EB0' + randomBytes(4).toString('hex').toUpperCase() \ No newline at end of file +export const generateMessageID = () => 'BAE5' + randomBytes(6).toString('hex').toUpperCase() \ No newline at end of file diff --git a/src/Utils/history.ts b/src/Utils/history.ts new file mode 100644 index 0000000..b304c0a --- /dev/null +++ b/src/Utils/history.ts @@ -0,0 +1,25 @@ +import { downloadContentFromMessage } from "./messages-media"; +import { proto } from "../../WAProto"; +import { promisify } from 'util' +import { inflate } from "zlib"; + +const inflatePromise = promisify(inflate) + +export const downloadIfHistory = (message: proto.IMessage) => { + if(message.protocolMessage?.historySyncNotification) { + return downloadHistory(message.protocolMessage!.historySyncNotification) + } +} + +export const downloadHistory = async(msg: proto.IHistorySyncNotification) => { + const stream = await downloadContentFromMessage(msg, 'history') + let buffer = Buffer.from([]) + for await(const chunk of stream) { + buffer = Buffer.concat([buffer, chunk]) + } + // decompress buffer + buffer = await inflatePromise(buffer) + + const syncData = proto.HistorySync.decode(buffer) + return syncData +} \ No newline at end of file diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 798a8ca..b987422 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -1,21 +1,18 @@ -import type { Agent } from 'https' import type { Logger } from 'pino' import type { IAudioMetadata } from 'music-metadata' +import { Boom } from '@hapi/boom' import * as Crypto from 'crypto' import { Readable, Transform } from 'stream' import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs' import { exec } from 'child_process' import { tmpdir } from 'os' -import HttpsProxyAgent from 'https-proxy-agent' import { URL } from 'url' -import { MessageType, WAMessageContent, WAMessageProto, WAGenericMediaMessage, WAMediaUpload } from '../Types' -import got, { Options, Response } from 'got' import { join } from 'path' -import { generateMessageID, hkdf } from './generics' -import { Boom } from '@hapi/boom' -import { MediaType } from '../Types' -import { DEFAULT_ORIGIN } from '../Defaults' import { once } from 'events' +import got, { Options, Response } from 'got' +import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType } from '../Types' +import { generateMessageID, hkdf } from './generics' +import { DEFAULT_ORIGIN } from '../Defaults' export const hkdfInfoKey = (type: MediaType) => { if(type === 'sticker') type = 'image' @@ -29,7 +26,7 @@ export function getMediaKeys(buffer, mediaType: MediaType) { buffer = Buffer.from(buffer.replace('data:;base64,', ''), 'base64') } // expand using HKDF to 112 bytes, also pass in the relevant app info - const expandedMediaKey = hkdf(buffer, 112, hkdfInfoKey(mediaType)) + const expandedMediaKey = hkdf(buffer, 112, { info: hkdfInfoKey(mediaType) }) return { iv: expandedMediaKey.slice(0, 16), cipherKey: expandedMediaKey.slice(16, 48), @@ -54,20 +51,18 @@ const extractVideoThumb = async ( export const compressImage = async (bufferOrFilePath: Buffer | string) => { const { read, MIME_JPEG } = await import('jimp') const jimp = await read(bufferOrFilePath as any) - const result = await jimp.resize(48, 48).getBufferAsync(MIME_JPEG) + const result = await jimp.resize(32, 32).getBufferAsync(MIME_JPEG) return result } -export const generateProfilePicture = async (buffer: Buffer) => { +export const generateProfilePicture = async (bufferOrFilePath: Buffer | string) => { const { read, MIME_JPEG } = await import('jimp') - const jimp = await read (buffer) + const jimp = await read(bufferOrFilePath as any) const min = Math.min(jimp.getWidth (), jimp.getHeight ()) const cropped = jimp.crop (0, 0, min, min) return { - img: await cropped.resize(640, 640).getBufferAsync (MIME_JPEG), - preview: await cropped.resize(96, 96).getBufferAsync (MIME_JPEG) + img: await cropped.resize(640, 640).getBufferAsync(MIME_JPEG), } } -export const ProxyAgent = (host: string | URL) => HttpsProxyAgent(host) as any as Agent /** gets the SHA256 of the given media message */ export const mediaMessageSHA256B64 = (message: WAMessageContent) => { const media = Object.values(message)[0] as WAGenericMediaMessage @@ -113,7 +108,7 @@ export async function generateThumbnail( } else if(mediaType === 'video') { const imgFilename = join(tmpdir(), generateMessageID() + '.jpg') try { - await extractVideoThumb(file, imgFilename, '00:00:00', { width: 48, height: 48 }) + await extractVideoThumb(file, imgFilename, '00:00:00', { width: 32, height: 32 }) const buff = await fs.readFile(imgFilename) thumbnail = buff.toString('base64') @@ -205,6 +200,47 @@ export const encryptedStream = async(media: WAMediaUpload, mediaType: MediaType, didSaveToTmpPath } } +const DEF_HOST = 'mmg.whatsapp.net' +export const downloadContentFromMessage = async( + { mediaKey, directPath, url }: { mediaKey?: Uint8Array, directPath?: string, url?: string }, + type: MediaType +) => { + const downloadUrl = url || `https://${DEF_HOST}${directPath}` + // download the message + const fetched = await getGotStream(downloadUrl, { + headers: { Origin: DEFAULT_ORIGIN } + }) + let remainingBytes = Buffer.from([]) + const { cipherKey, iv } = getMediaKeys(mediaKey, type) + const aes = Crypto.createDecipheriv("aes-256-cbc", cipherKey, iv) + + const output = new Transform({ + transform(chunk, _, callback) { + let data = Buffer.concat([remainingBytes, chunk]) + const decryptLength = + Math.floor(data.length / 16) * 16 + remainingBytes = data.slice(decryptLength) + data = data.slice(0, decryptLength) + + try { + this.push(aes.update(data)) + callback() + } catch(error) { + callback(error) + } + }, + final(callback) { + try { + this.push(aes.final()) + callback() + } catch(error) { + callback(error) + } + }, + }) + return fetched.pipe(output, { end: true }) +} + /** * Decode a media message (video, image, document, audio) & return decrypted buffer * @param message the media message you want to decode @@ -237,39 +273,7 @@ export async function decryptMediaMessageBuffer(message: WAMessageContent): Prom } else { messageContent = message[type] } - // download the message - const fetched = await getGotStream(messageContent.url, { - headers: { Origin: DEFAULT_ORIGIN } - }) - let remainingBytes = Buffer.from([]) - const { cipherKey, iv } = getMediaKeys(messageContent.mediaKey, type.replace('Message', '') as MediaType) - const aes = Crypto.createDecipheriv("aes-256-cbc", cipherKey, iv) - - const output = new Transform({ - transform(chunk, _, callback) { - let data = Buffer.concat([remainingBytes, chunk]) - const decryptLength = - Math.floor(data.length / 16) * 16 - remainingBytes = data.slice(decryptLength) - data = data.slice(0, decryptLength) - - try { - this.push(aes.update(data)) - callback() - } catch(error) { - callback(error) - } - }, - final(callback) { - try { - this.push(aes.final()) - callback() - } catch(error) { - callback(error) - } - }, - }) - return fetched.pipe(output, { end: true }) + return downloadContentFromMessage(messageContent, type.replace('Message', '') as MediaType) } export function extensionForMediaMessage(message: WAMessageContent) { const getExtension = (mimetype: string) => mimetype.split(';')[0].split('/')[1] @@ -283,10 +287,10 @@ export function extensionForMediaMessage(message: WAMessageContent) { extension = '.jpeg' } else { const messageContent = message[type] as - | WAMessageProto.VideoMessage - | WAMessageProto.ImageMessage - | WAMessageProto.AudioMessage - | WAMessageProto.DocumentMessage + | WAProto.VideoMessage + | WAProto.ImageMessage + | WAProto.AudioMessage + | WAProto.DocumentMessage extension = getExtension (messageContent.mimetype) } return extension diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 7e81860..13c58ec 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -1,6 +1,6 @@ import { Boom } from '@hapi/boom' import { createReadStream, promises as fs } from "fs" -import { proto } from '../../WAMessage' +import { proto } from '../../WAProto' import { MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from "../Defaults" import { AnyMediaMessageContent, @@ -13,7 +13,7 @@ import { WAMediaUpload, WAMessage, WAMessageContent, - WAMessageProto, + WAProto, WATextMessage, MediaType, WAMessageStatus @@ -38,14 +38,15 @@ const MIMETYPE_MAP: { [T in MediaType]: string } = { document: 'application/pdf', audio: 'audio/ogg; codecs=opus', sticker: 'image/webp', + history: 'application/x-protobuf' } const MessageTypeProto = { - 'image': WAMessageProto.ImageMessage, - 'video': WAMessageProto.VideoMessage, - 'audio': WAMessageProto.AudioMessage, - 'sticker': WAMessageProto.StickerMessage, - 'document': WAMessageProto.DocumentMessage, + 'image': WAProto.ImageMessage, + 'video': WAProto.VideoMessage, + 'audio': WAProto.AudioMessage, + 'sticker': WAProto.StickerMessage, + 'document': WAProto.DocumentMessage, } as const const ButtonType = proto.ButtonsMessage.ButtonsMessageHeaderType @@ -69,7 +70,7 @@ export const prepareWAMessageMedia = async( if(typeof uploadData.media === 'object' && 'url' in uploadData.media) { const result = !!options.mediaCache && await options.mediaCache!(uploadData.media.url?.toString()) if(result) { - return WAMessageProto.Message.fromObject({ + return WAProto.Message.fromObject({ [`${mediaType}Message`]: result }) } @@ -136,7 +137,7 @@ export const prepareWAMessageMedia = async( } ) } - return WAMessageProto.Message.fromObject(content) + return WAProto.Message.fromObject(content) } export const prepareDisappearingMessageSettingContent = (ephemeralExpiration?: number) => { ephemeralExpiration = ephemeralExpiration || 0 @@ -144,13 +145,13 @@ export const prepareDisappearingMessageSettingContent = (ephemeralExpiration?: n ephemeralMessage: { message: { protocolMessage: { - type: WAMessageProto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING, + type: WAProto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING, ephemeralExpiration } } } } - return WAMessageProto.Message.fromObject(content) + return WAProto.Message.fromObject(content) } /** * Generate forwarded message content like WA does @@ -207,14 +208,14 @@ export const generateWAMessageContent = async( throw new Boom('require atleast 1 contact', { statusCode: 400 }) } if(contactLen === 1) { - m.contactMessage = WAMessageProto.ContactMessage.fromObject(message.contacts.contacts[0]) + m.contactMessage = WAProto.ContactMessage.fromObject(message.contacts.contacts[0]) } } else if('location' in message) { - m.locationMessage = WAMessageProto.LocationMessage.fromObject(message.location) + m.locationMessage = WAProto.LocationMessage.fromObject(message.location) } else if('delete' in message) { m.protocolMessage = { key: message.delete, - type: WAMessageProto.ProtocolMessage.ProtocolMessageType.REVOKE + type: WAProto.ProtocolMessage.ProtocolMessageType.REVOKE } } else if('forward' in message) { m = generateForwardMessageContent( @@ -259,7 +260,7 @@ export const generateWAMessageContent = async( m[messageType].contextInfo = m[messageType] || { } m[messageType].contextInfo.mentionedJid = message.mentions } - return WAMessageProto.Message.fromObject(m) + return WAProto.Message.fromObject(m) } export const generateWAMessageFromContent = ( jid: string, @@ -290,7 +291,7 @@ export const generateWAMessageFromContent = ( } if( // if we want to send a disappearing message - !!options?.ephemeralOptions && + !!options?.ephemeralExpiration && // and it's not a protocol message -- delete, toggle disappear message key !== 'protocolMessage' && // already not converted to disappearing message @@ -298,8 +299,8 @@ export const generateWAMessageFromContent = ( ) { message[key].contextInfo = { ...(message[key].contextInfo || {}), - expiration: options.ephemeralOptions.expiration || WA_DEFAULT_EPHEMERAL, - ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts?.toString() + expiration: options.ephemeralExpiration || WA_DEFAULT_EPHEMERAL, + //ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts?.toString() } message = { ephemeralMessage: { @@ -307,7 +308,7 @@ export const generateWAMessageFromContent = ( } } } - message = WAMessageProto.Message.fromObject (message) + message = WAProto.Message.fromObject (message) const messageJSON = { key: { @@ -321,7 +322,7 @@ export const generateWAMessageFromContent = ( participant: jid.includes('@g.us') ? userJid : undefined, status: WAMessageStatus.PENDING } - return WAMessageProto.WebMessageInfo.fromObject (messageJSON) + return WAProto.WebMessageInfo.fromObject (messageJSON) } export const generateWAMessage = async( jid: string, diff --git a/src/Utils/noise-handler.ts b/src/Utils/noise-handler.ts new file mode 100644 index 0000000..1f94871 --- /dev/null +++ b/src/Utils/noise-handler.ts @@ -0,0 +1,167 @@ +import { sha256, generateSharedKey, hkdf } from "./generics"; +import { Binary } from "../WABinary"; +import { createCipheriv, createDecipheriv } from "crypto"; +import { NOISE_MODE, NOISE_WA_HEADER } from "../Defaults"; +import { KeyPair } from "../Types"; +import { BinaryNode, decodeBinaryNode } from "../WABinary"; +import { Boom } from "@hapi/boom"; +import { proto } from '../../WAProto' + +const generateIV = (counter: number) => { + const iv = new ArrayBuffer(12); + new DataView(iv).setUint32(8, counter); + + return new Uint8Array(iv) +} + +export default ({ public: publicKey, private: privateKey }: KeyPair) => { + + const authenticate = (data: Uint8Array) => { + if(!isFinished) { + hash = sha256( Buffer.from(Binary.build(hash, data).readByteArray()) ) + } + } + const encrypt = (plaintext: Uint8Array) => { + const authTagLength = 128 >> 3 + const cipher = createCipheriv('aes-256-gcm', encKey, generateIV(writeCounter), { authTagLength }) + cipher.setAAD(hash) + + const result = Buffer.concat([cipher.update(plaintext), cipher.final(), cipher.getAuthTag()]) + + writeCounter += 1 + + authenticate(result) + return result + } + const decrypt = (ciphertext: Uint8Array) => { + // before the handshake is finished, we use the same counter + // after handshake, the counters are different + const iv = generateIV(isFinished ? readCounter : writeCounter) + const cipher = createDecipheriv('aes-256-gcm', decKey, iv) + // decrypt additional adata + const tagLength = 128 >> 3 + const enc = ciphertext.slice(0, ciphertext.length-tagLength) + const tag = ciphertext.slice(ciphertext.length-tagLength) + // set additional data + cipher.setAAD(hash) + cipher.setAuthTag(tag) + + const result = Buffer.concat([cipher.update(enc), cipher.final()]) + + if(isFinished) readCounter += 1 + else writeCounter += 1 + + authenticate(ciphertext) + return result + } + const localHKDF = (data: Uint8Array) => { + const key = hkdf(Buffer.from(data), 64, { salt, info: '' }) + return [key.slice(0, 32), key.slice(32)] + } + const mixIntoKey = (data: Uint8Array) => { + const [write, read] = localHKDF(data) + salt = write + encKey = read + decKey = read + readCounter = 0 + writeCounter = 0 + } + const finishInit = () => { + const [write, read] = localHKDF(new Uint8Array(0)) + encKey = write + decKey = read + hash = Buffer.from([]) + readCounter = 0 + writeCounter = 0 + isFinished = true + } + + const data = Binary.build(NOISE_MODE).readBuffer() + let hash = Buffer.from(data.byteLength === 32 ? data : sha256(Buffer.from(data))) + let salt = hash + let encKey = hash + let decKey = hash + let readCounter = 0 + let writeCounter = 0 + let isFinished = false + let sentIntro = false + + const outBinary = new Binary() + const inBinary = new Binary() + + authenticate(NOISE_WA_HEADER) + authenticate(publicKey) + + return { + encrypt, + decrypt, + authenticate, + mixIntoKey, + finishInit, + processHandshake: ({ serverHello }: proto.HandshakeMessage, noiseKey: KeyPair) => { + authenticate(serverHello!.ephemeral!) + mixIntoKey(generateSharedKey(privateKey, serverHello.ephemeral!)) + + const decStaticContent = decrypt(serverHello!.static!) + mixIntoKey(generateSharedKey(privateKey, decStaticContent)) + + const certDecoded = decrypt(serverHello!.payload!) + const { details: certDetails, signature: certSignature } = proto.NoiseCertificate.decode(certDecoded) + + const { issuer: certIssuer, key: certKey } = proto.Details.decode(certDetails) + + if(Buffer.compare(decStaticContent, certKey) !== 0) { + throw new Boom('certification match failed', { statusCode: 400 }) + } + + const keyEnc = encrypt(noiseKey.public) + mixIntoKey(generateSharedKey(noiseKey.private, serverHello!.ephemeral!)) + + return keyEnc + }, + encodeFrame: (data: Buffer | Uint8Array) => { + if(isFinished) { + data = encrypt(data) + } + const introSize = sentIntro ? 0 : NOISE_WA_HEADER.length + + outBinary.ensureAdditionalCapacity(introSize + 3 + data.byteLength) + + if (!sentIntro) { + outBinary.writeByteArray(NOISE_WA_HEADER) + sentIntro = true + } + + outBinary.writeUint8(data.byteLength >> 16) + outBinary.writeUint16(65535 & data.byteLength) + outBinary.write(data) + + const bytes = outBinary.readByteArray() + return bytes as Uint8Array + }, + decodeFrame: (newData: Buffer | Uint8Array, onFrame: (buff: Uint8Array | BinaryNode) => void) => { + // the binary protocol uses its own framing mechanism + // on top of the WS frames + // so we get this data and separate out the frames + const getBytesSize = () => { + return (inBinary.readUint8() << 16) | inBinary.readUint16() + } + const peekSize = () => { + return !(inBinary.size() < 3) && getBytesSize() <= inBinary.size() + } + + inBinary.writeByteArray(newData) + while(inBinary.peek(peekSize)) { + const bytes = getBytesSize() + let frame: Uint8Array | BinaryNode = inBinary.readByteArray(bytes) + if(isFinished) { + const result = decrypt(frame as Uint8Array) + const unpacked = new Binary(result).decompressed() + frame = decodeBinaryNode(unpacked) + } + onFrame(frame) + } + inBinary.peek(peekSize) + } + } +} \ No newline at end of file diff --git a/src/Utils/signal.ts b/src/Utils/signal.ts new file mode 100644 index 0000000..2940c7c --- /dev/null +++ b/src/Utils/signal.ts @@ -0,0 +1,253 @@ +import * as libsignal from 'libsignal' +import { encodeBigEndian, generateCurveKeyPair } from "./generics" +import { SenderKeyDistributionMessage, GroupSessionBuilder, SenderKeyRecord, SenderKeyName, GroupCipher } from '../../WASignalGroup' +import { SignalIdentity, SignalKeyStore, SignedKeyPair, KeyPair, AuthenticationState } from "../Types/Auth" +import { assertNodeErrorFree, BinaryNode, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildUInt, jidDecode } from "../WABinary" +import { proto } from "../../WAProto" + +export const generateSignalPubKey = (pubKey: Uint8Array | Buffer) => { + const newPub = Buffer.alloc(33) + newPub.set([5], 0) + newPub.set(pubKey, 1) + return newPub +} + +const jidToSignalAddress = (jid: string) => jid.split('@')[0] + +export const jidToSignalProtocolAddress = (jid: string) => { + return new libsignal.ProtocolAddress(jidToSignalAddress(jid), 0) +} + +export const jidToSignalSenderKeyName = (group: string, user: string): string => { + return new SenderKeyName(group, jidToSignalProtocolAddress(user)).toString() +} + +export const createSignalIdentity = ( + wid: string, + accountSignatureKey: Uint8Array +): SignalIdentity => { + return { + identifier: { name: wid, deviceId: 0 }, + identifierKey: generateSignalPubKey(accountSignatureKey) + } +} + +export const getPreKeys = async({ getPreKey }: SignalKeyStore, min: number, limit: number) => { + const dict: { [id: number]: KeyPair } = { } + for(let id = min; id < limit;id++) { + const key = await getPreKey(id) + if(key) dict[+id] = key + } + return dict +} + +export const generateOrGetPreKeys = ({ creds }: AuthenticationState, range: number) => { + const avaliable = creds.nextPreKeyId - creds.firstUnuploadedPreKeyId + const remaining = range - avaliable + const lastPreKeyId = creds.nextPreKeyId + remaining - 1 + const newPreKeys: { [id: number]: KeyPair } = { } + if(remaining > 0) { + for(let i = creds.nextPreKeyId;i <= lastPreKeyId;i++) { + newPreKeys[i] = generateCurveKeyPair() + } + } + return { + newPreKeys, + lastPreKeyId, + preKeysRange: [creds.firstUnuploadedPreKeyId, range] as const, + } +} + + +export const xmppSignedPreKey = (key: SignedKeyPair): BinaryNode => ( + { + tag: 'skey', + attrs: { }, + content: [ + { tag: 'id', attrs: { }, content: encodeBigEndian(key.keyId, 3) }, + { tag: 'value', attrs: { }, content: key.keyPair.public }, + { tag: 'signature', attrs: { }, content: key.signature } + ] + } +) + +export const xmppPreKey = (pair: KeyPair, id: number): BinaryNode => ( + { + tag: 'key', + attrs: { }, + content: [ + { tag: 'id', attrs: { }, content: encodeBigEndian(id, 3) }, + { tag: 'value', attrs: { }, content: pair.public } + ] + } +) + +export const signalStorage = ({ creds, keys }: AuthenticationState) => ({ + loadSession: async id => { + const sess = await keys.getSession(id) + if(sess) { + return libsignal.SessionRecord.deserialize(sess) + } + }, + storeSession: async(id, session) => { + await keys.setSession(id, session.serialize()) + }, + isTrustedIdentity: () => { + return true + }, + loadPreKey: async(id: number) => { + const key = await keys.getPreKey(id) + if(key) { + return { + privKey: Buffer.from(key.private), + pubKey: Buffer.from(key.public) + } + } + }, + removePreKey: (id: number) => keys.setPreKey(id, null), + loadSignedPreKey: (keyId: number) => { + const key = creds.signedPreKey + return { + privKey: Buffer.from(key.keyPair.private), + pubKey: Buffer.from(key.keyPair.public) + } + }, + loadSenderKey: async(keyId) => { + const key = await keys.getSenderKey(keyId) + if(key) return new SenderKeyRecord(key) + }, + storeSenderKey: async(keyId, key) => { + await keys.setSenderKey(keyId, key.serialize()) + }, + getOurRegistrationId: () => ( + creds.registrationId + ), + getOurIdentity: () => { + const { signedIdentityKey } = creds + return { + privKey: Buffer.from(signedIdentityKey.private), + pubKey: generateSignalPubKey(signedIdentityKey.public), + } + } +}) + +export const decryptGroupSignalProto = (group: string, user: string, msg: Buffer | Uint8Array, auth: AuthenticationState) => { + const senderName = jidToSignalSenderKeyName(group, user) + const cipher = new GroupCipher(signalStorage(auth), senderName) + + return cipher.decrypt(Buffer.from(msg)) +} + +export const processSenderKeyMessage = async( + authorJid: string, + item: proto.ISenderKeyDistributionMessage, + auth: AuthenticationState +) => { + const builder = new GroupSessionBuilder(signalStorage(auth)) + const senderName = jidToSignalSenderKeyName(item.groupId, authorJid) + + const senderMsg = new SenderKeyDistributionMessage(null, null, null, null, item.axolotlSenderKeyDistributionMessage) + const senderKey = await auth.keys.getSenderKey(senderName) + if(!senderKey) { + const record = new SenderKeyRecord() + await auth.keys.setSenderKey(senderName, record) + } + await builder.process(senderName, senderMsg) +} + +export const decryptSignalProto = async(user: string, type: 'pkmsg' | 'msg', msg: Buffer | Uint8Array, auth: AuthenticationState) => { + const addr = jidToSignalProtocolAddress(user) + const session = new libsignal.SessionCipher(signalStorage(auth), addr) + let result: Buffer + switch(type) { + case 'pkmsg': + result = await session.decryptPreKeyWhisperMessage(msg) + break + case 'msg': + result = await session.decryptWhisperMessage(msg) + break + } + return result +} + + +export const encryptSignalProto = async(user: string, buffer: Buffer, auth: AuthenticationState) => { + const addr = jidToSignalProtocolAddress(user) + const cipher = new libsignal.SessionCipher(signalStorage(auth), addr) + + const { type, body } = await cipher.encrypt(buffer) + return { + type: type === 3 ? 'pkmsg' : 'msg', + ciphertext: Buffer.from(body, 'binary') + } +} + +export const encryptSenderKeyMsgSignalProto = async(group: string, data: Uint8Array | Buffer, auth: AuthenticationState) => { + const storage = signalStorage(auth) + const senderName = jidToSignalSenderKeyName(group, auth.creds.me!.id) + const builder = new GroupSessionBuilder(storage) + + const senderKey = await auth.keys.getSenderKey(senderName) + if(!senderKey) { + const record = new SenderKeyRecord() + await auth.keys.setSenderKey(senderName, record) + } + + const senderKeyDistributionMessage = await builder.create(senderName) + const session = new GroupCipher(storage, senderName) + return { + ciphertext: await session.encrypt(data) as Uint8Array, + senderKeyDistributionMessageKey: senderKeyDistributionMessage.serialize() as Buffer, + } +} + +export const parseAndInjectE2ESession = async(node: BinaryNode, auth: AuthenticationState) => { + const extractKey = (key: BinaryNode) => ( + key ? ({ + keyId: getBinaryNodeChildUInt(key, 'id', 3), + publicKey: generateSignalPubKey( + getBinaryNodeChildBuffer(key, 'value') + ), + signature: getBinaryNodeChildBuffer(key, 'signature'), + }) : undefined + ) + node = getBinaryNodeChild(getBinaryNodeChild(node, 'list'), 'user') + assertNodeErrorFree(node) + + const signedKey = getBinaryNodeChild(node, 'skey') + const key = getBinaryNodeChild(node, 'key') + const identity = getBinaryNodeChildBuffer(node, 'identity') + const jid = node.attrs.jid + const registrationId = getBinaryNodeChildUInt(node, 'registration', 4) + + const device = { + registrationId, + identityKey: generateSignalPubKey(identity), + signedPreKey: extractKey(signedKey), + preKey: extractKey(key) + } + const cipher = new libsignal.SessionBuilder(signalStorage(auth), jidToSignalProtocolAddress(jid)) + await cipher.initOutgoing(device) +} + +export const extractDeviceJids = (result: BinaryNode) => { + const extracted: { user: string, device?: number, agent?: number }[] = [] + for(const node of result.content as BinaryNode[]) { + const list = getBinaryNodeChild(node, 'list')?.content + if(list && Array.isArray(list)) { + for(const item of list) { + const { user } = jidDecode(item.attrs.jid) + const devicesNode = getBinaryNodeChild(item, 'devices') + const deviceListNode = getBinaryNodeChild(devicesNode, 'device-list') + if(Array.isArray(deviceListNode?.content)) { + for(const { tag, attrs } of deviceListNode!.content) { + if(tag === 'device') { + extracted.push({ user, device: +attrs.id }) + } + } + } + } + } + } + return extracted +} \ No newline at end of file diff --git a/src/Utils/validate-connection.ts b/src/Utils/validate-connection.ts index c506bd7..fa2c903 100644 --- a/src/Utils/validate-connection.ts +++ b/src/Utils/validate-connection.ts @@ -1,116 +1,204 @@ -import {Boom} from '@hapi/boom' -import * as Curve from 'curve25519-js' -import type { Contact } from '../Types/Contact' -import type { AnyAuthenticationCredentials, AuthenticationCredentials, AuthenticationCredentialsBase64, CurveKeyPair } from "../Types" -import { aesDecrypt, hkdf, hmacSign, whatsappID } from './generics' -import { readFileSync } from 'fs' +import { Boom } from '@hapi/boom' +import { randomBytes } from 'crypto' +import { proto } from '../../WAProto' +import type { AuthenticationState, SocketConfig, SignalKeyStore, AuthenticationCreds, KeyPair } from "../Types" +import { curveSign, hmacSign, curveVerify, encodeInt, generateCurveKeyPair, generateRegistrationId, signedKeyPair } from './generics' +import { BinaryNode, S_WHATSAPP_NET, jidDecode, Binary } from '../WABinary' +import { createSignalIdentity } from './signal' -export const normalizedAuthInfo = (authInfo: AnyAuthenticationCredentials | string) => { - if (!authInfo) return - - if (typeof authInfo === 'string') { - const file = readFileSync(authInfo, { encoding: 'utf-8' }) // load a closed session back if it exists - authInfo = JSON.parse(file) as AnyAuthenticationCredentials - } - if ('clientID' in authInfo) { - authInfo = { - clientID: authInfo.clientID, - serverToken: authInfo.serverToken, - clientToken: authInfo.clientToken, - encKey: Buffer.isBuffer(authInfo.encKey) ? authInfo.encKey : Buffer.from(authInfo.encKey, 'base64'), - macKey: Buffer.isBuffer(authInfo.macKey) ? authInfo.macKey : Buffer.from(authInfo.macKey, 'base64'), - } - } else { - const secretBundle: {encKey: string, macKey: string} = typeof authInfo.WASecretBundle === 'string' ? JSON.parse (authInfo.WASecretBundle): authInfo.WASecretBundle - authInfo = { - clientID: authInfo.WABrowserId.replace(/\"/g, ''), - serverToken: authInfo.WAToken2.replace(/\"/g, ''), - clientToken: authInfo.WAToken1.replace(/\"/g, ''), - encKey: Buffer.from(secretBundle.encKey, 'base64'), // decode from base64 - macKey: Buffer.from(secretBundle.macKey, 'base64'), // decode from base64 - } - } - return authInfo as AuthenticationCredentials +const ENCODED_VERSION = 'S9Kdc4pc4EJryo21snc5cg==' +const getUserAgent = ({ version, browser }: Pick) => ({ + appVersion: { + primary: version[0], + secondary: version[1], + tertiary: version[2], + }, + platform: 14, + releaseChannel: 0, + mcc: "000", + mnc: "000", + osVersion: browser[2], + manufacturer: "", + device: browser[1], + osBuildNumber: "0.1", + localeLanguageIso6391: 'en', + localeCountryIso31661Alpha2: 'en', +}) + +export const generateLoginNode = (userJid: string, config: Pick) => { + const { user, device } = jidDecode(userJid) + const payload = { + passive: true, + connectType: 1, + connectReason: 1, + userAgent: getUserAgent(config), + webInfo: { webSubPlatform: 0 }, + username: parseInt(user, 10), + device: device, + } + return proto.ClientPayload.encode(payload).finish() } -export const base64EncodedAuthenticationCredentials = (creds: AnyAuthenticationCredentials) => { - const normalized = normalizedAuthInfo(creds) - return { - ...normalized, - encKey: normalized.encKey.toString('base64'), - macKey: normalized.macKey.toString('base64') - } as AuthenticationCredentialsBase64 -} - -/** -* Once the QR code is scanned and we can validate our connection, or we resolved the challenge when logging back in -* @private -* @param json -*/ -export const validateNewConnection = ( - json: { [_: string]: any }, - auth: AuthenticationCredentials, - curveKeys: CurveKeyPair +export const generateRegistrationNode = ( + { registrationId, signedPreKey, signedIdentityKey }: Pick, + config: Pick ) => { - // set metadata: one's WhatsApp ID [cc][number]@s.whatsapp.net, name on WhatsApp, info about the phone - const onValidationSuccess = () => { - const user: Contact = { - jid: whatsappID(json.wid), - name: json.pushname - } - return { user, auth, phone: json.phone } - } - if (!json.secret) { - // if we didn't get a secret, we don't need it, we're validated - if (json.clientToken && json.clientToken !== auth.clientToken) { - auth = { ...auth, clientToken: json.clientToken } - } - if (json.serverToken && json.serverToken !== auth.serverToken) { - auth = { ...auth, serverToken: json.serverToken } - } - return onValidationSuccess() - } - const secret = Buffer.from(json.secret, 'base64') - if (secret.length !== 144) { - throw new Error ('incorrect secret length received: ' + secret.length) - } + const appVersionBuf = new Uint8Array(Buffer.from(ENCODED_VERSION, "base64")); - // generate shared key from our private key & the secret shared by the server - const sharedKey = Curve.sharedKey(curveKeys.private, secret.slice(0, 32)) - // expand the key to 80 bytes using HKDF - const expandedKey = hkdf(sharedKey as Buffer, 80) + const companion = { + os: config.browser[0], + version: { + primary: 10, + secondary: undefined, + tertiary: undefined, + }, + platformType: 1, + requireFullSync: false, + }; - // perform HMAC validation. - const hmacValidationKey = expandedKey.slice(32, 64) - const hmacValidationMessage = Buffer.concat([secret.slice(0, 32), secret.slice(64, secret.length)]) + const companionProto = proto.CompanionProps.encode(companion).finish() - const hmac = hmacSign(hmacValidationMessage, hmacValidationKey) + const registerPayload = { + connectReason: 1, + connectType: 1, + passive: false, + regData: { + buildHash: appVersionBuf, + companionProps: companionProto, + eRegid: encodeInt(4, registrationId), + eKeytype: encodeInt(1, 5), + eIdent: signedIdentityKey.public, + eSkeyId: encodeInt(3, signedPreKey.keyId), + eSkeyVal: signedPreKey.keyPair.public, + eSkeySig: signedPreKey.signature, + }, + userAgent: getUserAgent(config), + webInfo: { + webSubPlatform: 0, + }, + } - if (!hmac.equals(secret.slice(32, 64))) { - // if the checksums didn't match - throw new Boom('HMAC validation failed', { statusCode: 400 }) - } - - // computed HMAC should equal secret[32:64] - // expandedKey[64:] + secret[64:] are the keys, encrypted using AES, that are used to encrypt/decrypt the messages recieved from WhatsApp - // they are encrypted using key: expandedKey[0:32] - const encryptedAESKeys = Buffer.concat([ - expandedKey.slice(64, expandedKey.length), - secret.slice(64, secret.length), - ]) - const decryptedKeys = aesDecrypt(encryptedAESKeys, expandedKey.slice(0, 32)) - // set the credentials - auth = { - encKey: decryptedKeys.slice(0, 32), // first 32 bytes form the key to encrypt/decrypt messages - macKey: decryptedKeys.slice(32, 64), // last 32 bytes from the key to sign messages - clientToken: json.clientToken, - serverToken: json.serverToken, - clientID: auth.clientID, - } - return onValidationSuccess() + return proto.ClientPayload.encode(registerPayload).finish() } -export const computeChallengeResponse = (challenge: string, auth: AuthenticationCredentials) => { - const bytes = Buffer.from(challenge, 'base64') // decode the base64 encoded challenge string - const signed = hmacSign(bytes, auth.macKey).toString('base64') // sign the challenge string with our macKey - return[ 'admin', 'challenge', signed, auth.serverToken, auth.clientID] // prepare to send this signed string with the serverToken & clientID + +export const initInMemoryKeyStore = ( + { preKeys, sessions, senderKeys }: { + preKeys?: { [k: number]: KeyPair }, + sessions?: { [k: string]: any }, + senderKeys?: { [k: string]: any } + } = { }, +) => { + preKeys = preKeys || { } + sessions = sessions || { } + senderKeys = senderKeys || { } + return { + preKeys, + sessions, + senderKeys, + getPreKey: keyId => preKeys[keyId], + setPreKey: (keyId, pair) => { + if(pair) preKeys[keyId] = pair + else delete preKeys[keyId] + }, + getSession: id => sessions[id], + setSession: (id, item) => { + if(item) sessions[id] = item + else delete sessions[id] + }, + getSenderKey: id => { + return senderKeys[id] + }, + setSenderKey: (id, item) => { + if(item) senderKeys[id] = item + else delete senderKeys[id] + } + } as SignalKeyStore +} + +export const initAuthState = (): AuthenticationState => { + const identityKey = generateCurveKeyPair() + return { + creds: { + noiseKey: generateCurveKeyPair(), + signedIdentityKey: identityKey, + signedPreKey: signedKeyPair(identityKey, 1), + registrationId: generateRegistrationId(), + advSecretKey: randomBytes(32).toString('base64'), + + nextPreKeyId: 1, + firstUnuploadedPreKeyId: 1, + serverHasPreKeys: false + }, + keys: initInMemoryKeyStore() + } +} + +export const configureSuccessfulPairing = ( + stanza: BinaryNode, + { advSecretKey, signedIdentityKey, signalIdentities }: Pick +) => { + const pair = stanza.content[0] as BinaryNode + const pairContent = Array.isArray(pair.content) ? pair.content : [] + + const msgId = stanza.attrs.id + const deviceIdentity = pairContent.find(m => m.tag === 'device-identity')?.content + const businessName = pairContent.find(m => m.tag === 'biz')?.attrs?.name + const verifiedName = businessName || '' + const jid = pairContent.find(m => m.tag === 'device')?.attrs?.jid + + const { details, hmac } = proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentity as Buffer) + + const advSign = hmacSign(details, Buffer.from(advSecretKey, 'base64')) + + if (Buffer.compare(hmac, advSign) !== 0) { + throw new Boom('Invalid pairing') + } + + const account = proto.ADVSignedDeviceIdentity.decode(details) + const { accountSignatureKey, accountSignature } = account + + const accountMsg = Binary.build(new Uint8Array([6, 0]), account.details, signedIdentityKey.public).readByteArray() + if (!curveVerify(accountSignatureKey, accountMsg, accountSignature)) { + throw new Boom('Failed to verify account signature') + } + + const deviceMsg = Binary.build(new Uint8Array([6, 1]), account.details, signedIdentityKey.public, account.accountSignatureKey).readByteArray() + account.deviceSignature = curveSign(signedIdentityKey.private, deviceMsg) + + const identity = createSignalIdentity(jid, accountSignatureKey) + + const keyIndex = proto.ADVDeviceIdentity.decode(account.details).keyIndex + + const accountEnc = proto.ADVSignedDeviceIdentity.encode({ + ...account.toJSON(), + accountSignatureKey: undefined + }).finish() + + const reply: BinaryNode = { + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'result', + id: msgId, + }, + content: [ + { + tag: 'pair-device-sign', + attrs: { }, + content: [ + { tag: 'device-identity', attrs: { 'key-index': `${keyIndex}` }, content: accountEnc } + ] + } + ] + } + + const authUpdate: Partial = { + account, + me: { id: jid, verifiedName }, + signalIdentities: [...(signalIdentities || []), identity] + } + return { + creds: authUpdate, + reply + } } \ No newline at end of file diff --git a/src/WABinary/JidUtils.ts b/src/WABinary/JidUtils.ts new file mode 100644 index 0000000..492e050 --- /dev/null +++ b/src/WABinary/JidUtils.ts @@ -0,0 +1,47 @@ +export const S_WHATSAPP_NET = '@s.whatsapp.net' +export const OFFICIAL_BIZ_JID = '16505361212@c.us' +export const SERVER_JID = 'server@c.us' +export const PSA_WID = '0@c.us'; +export const STORIES_JID = 'status@broadcast' + +export type JidServer = 'c.us' | 'g.us' | 'broadcast' | 's.whatsapp.net' | 'call' + +export const jidEncode = (user: string | number | null, server: JidServer, device?: number, agent?: number) => { + return `${user || ''}${!!agent ? `_${agent}` : ''}${!!device ? `:${device}` : ''}@${server}` +} + +export const jidDecode = (jid: string) => { + let sepIdx = typeof jid === 'string' ? jid.indexOf('@') : -1 + if(sepIdx < 0) { + return undefined + } + const server = jid.slice(sepIdx+1) + const userCombined = jid.slice(0, sepIdx) + + const [userAgent, device] = userCombined.split(':') + const [user, agent] = userAgent.split('_') + + return { + server, + user, + agent: agent ? +agent : undefined, + device: device ? +device : undefined + } +} +/** is the jid a user */ +export const areJidsSameUser = (jid1: string, jid2: string) => ( + jidDecode(jid1)?.user === jidDecode(jid2)?.user +) +/** is the jid a user */ +export const isJidUser = (jid: string) => (jid?.endsWith('@s.whatsapp.net')) +/** is the jid a broadcast */ +export const isJidBroadcast = (jid: string) => (jid?.endsWith('@broadcast')) +/** is the jid a broadcast */ +export const isJidGroup = (jid: string) => (jid?.endsWith('@g.us')) +/** is the jid the status broadcast */ +export const isJidStatusBroadcast = (jid: string) => jid === 'status@broadcast' + +export const jidNormalizedUser = (jid: string) => { + const { user, server } = jidDecode(jid) + return jidEncode(user, server === 'c.us' ? 's.whatsapp.net' : server as JidServer) +} \ No newline at end of file diff --git a/src/WABinary/LTHash.js b/src/WABinary/LTHash.js new file mode 100644 index 0000000..c902c60 --- /dev/null +++ b/src/WABinary/LTHash.js @@ -0,0 +1,48 @@ +import { hkdf } from "../Utils/generics"; + +const o = 128; + +class d { + constructor(e) { + this.salt = e + } + add(e, t) { + var r = this; + for(const item of t) { + e = r._addSingle(e, item) + } + return e + } + subtract(e, t) { + var r = this; + for(const item of t) { + e = r._subtractSingle(e, item) + } + return e + } + subtractThenAdd(e, t, r) { + var n = this; + return n.add(n.subtract(e, r), t) + } + _addSingle(e, t) { + var r = this; + const n = new Uint8Array(hkdf(t, o, { info: r.salt })).buffer; + return r.performPointwiseWithOverflow(e, n, ((e,t)=>e + t)) + } + _subtractSingle(e, t) { + var r = this; + + const n = new Uint8Array(hkdf(t, o, { info: r.salt })).buffer; + return r.performPointwiseWithOverflow(e, n, ((e,t)=>e - t)) + } + performPointwiseWithOverflow(e, t, r) { + const n = new DataView(e) + , i = new DataView(t) + , a = new ArrayBuffer(n.byteLength) + , s = new DataView(a); + for (let e = 0; e < n.byteLength; e += 2) + s.setUint16(e, r(n.getUint16(e, !0), i.getUint16(e, !0)), !0); + return a + } +} +export const LT_HASH_ANTI_TAMPERING = new d('WhatsApp Patch Integrity') \ No newline at end of file diff --git a/src/WABinary/index.ts b/src/WABinary/index.ts new file mode 100644 index 0000000..bcb8016 --- /dev/null +++ b/src/WABinary/index.ts @@ -0,0 +1,305 @@ +import { DICTIONARIES_MAP, SINGLE_BYTE_TOKEN, SINGLE_BYTE_TOKEN_MAP, DICTIONARIES } from '../../WABinary/Constants'; +import { jidDecode, jidEncode } from './JidUtils'; +import { Binary, numUtf8Bytes } from '../../WABinary/Binary'; +import { Boom } from '@hapi/boom'; + +const LIST1 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '.', '�', '�', '�', '�']; +const LIST2 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']; + +function k(data: Binary, uint: number) { + let arr = []; + for (let a = 0; a < uint; a++) { + arr.push(decodeBinaryNode(data)); + } + return arr; +} + +function x(data: Binary, t, r, a) { + const arr = new Array(2 * a - r); + for (let n = 0; n < arr.length - 1; n += 2) { + var s = data.readUint8(); + (arr[n] = t[s >>> 4]), (arr[n + 1] = t[15 & s]); + } + + if (r) { + arr[arr.length - 1] = t[data.readUint8() >>> 4]; + } + + return arr.join(''); +} + +function D(e, t, r) { + var a = e.length % 2 == 1; + r.writeUint8(t); + var i = Math.ceil(e.length / 2); + a && (i |= 128), r.writeUint8(i); + for (var n = 0, s = 0; s < e.length; s++) { + var o = e.charCodeAt(s), + l = null; + if ((48 <= o && o <= 57 ? (l = o - 48) : 255 === t ? (45 === o ? (l = 10) : 46 === o && (l = 11)) : 251 === t && 65 <= o && o <= 70 && (l = o - 55), null == l)) + throw new Error(`Cannot nibble encode ${o}`); + s % 2 == 0 ? ((n = l << 4), s === e.length - 1 && ((n |= 15), r.writeUint8(n))) : ((n |= l), r.writeUint8(n)); + } +} + +function N(e, t) { + if (e < 256) t.writeUint8(252), t.writeUint8(e); + else if (e < 1048576) t.writeUint8(253), t.writeUint8((e >>> 16) & 255), t.writeUint8((e >>> 8) & 255), t.writeUint8(255 & e); + else { + if (!(e < 4294967296)) throw new Error(`Binary with length ${e} is too big for WAP protocol`); + t.writeUint8(254), t.writeUint32(e); + } +} + +function R(e: any, t: Binary) { + var w = null; + if ('' === e) return t.writeUint8(252), void t.writeUint8(0); + var b = SINGLE_BYTE_TOKEN_MAP; + var r = b.get(e); + var c = [236, 237, 238, 239]; + if (null == r) { + if (null == w) { + w = []; + for (var a = 0; a < DICTIONARIES_MAP.length; ++a) w.push(DICTIONARIES_MAP[a]); + } + for (var n = 0; n < w.length; ++n) { + var s = w[n].get(e); + if (null != s) return t.writeUint8(c[n]), void t.writeUint8(s); + } + var o = numUtf8Bytes(e); + if (o < 128) { + if (!/[^0-9.-]+?/.exec(e)) return void D(e, 255, t); + if (!/[^0-9A-F]+?/.exec(e)) return void D(e, 251, t); + } + N(o, t), t.writeString(e); + } else t.writeUint8(r + 1); +} + +function M(e: any, t: Binary) { + var p = 248; + var f = 249; + if (void 0 === e.tag) return t.writeUint8(p), void t.writeUint8(0); + var r = 1; + e.attrs && (r += 2 * Object.keys(e.attrs).length), + e.content && r++, + r < 256 ? (t.writeUint8(p), t.writeUint8(r)) : r < 65536 && (t.writeUint8(f), t.writeUint16(r)), + O(e.tag, t), + e.attrs && + Object.keys(e.attrs).forEach((r) => { + R(r, t), O(e.attrs[r], t); + }); + var a = e.content; + if (Array.isArray(a)) { + a.length < 256 ? (t.writeUint8(p), t.writeUint8(a.length)) : a.length < 65536 && (t.writeUint8(f), t.writeUint16(a.length)); + for (var i = 0; i < a.length; i++) M(a[i], t); + } else a && O(a, t); +} + +function L(data: Binary, t: boolean) { + const n = data.readUint8(); + if (n === 0) { + return null; + } + + if (n === 248) { + return k(data, data.readUint8()); + } + + if (n === 249) { + return k(data, data.readUint16()); + } + + if (n === 252) { + return t ? data.readString(data.readUint8()) : data.readByteArray(data.readUint8()); + } + + if (n === 253) { + const size = ((15 & data.readUint8()) << 16) + (data.readUint8() << 8) + data.readUint8(); + return t ? data.readString(size) : data.readByteArray(size); + } + + if (n === 254) { + return t ? data.readString(data.readUint32()) : data.readByteArray(data.readUint32()); + } + + if (n === 250) { + const user = L(data, true); + if (null != user && 'string' != typeof user) throw new Error(`Decode string got invalid value ${String(t)}, string expected`); + const server = decodeStanzaString(data) + return jidEncode(user, server) + } + + if (n === 247) { + const agent = data.readUint8(); + const device = data.readUint8(); + const user = decodeStanzaString(data); + + return jidEncode(user, 's.whatsapp.net', device, agent); + } + + if (n === 255) { + const number = data.readUint8(); + return x(data, LIST1, number >>> 7, 127 & number); + } + + if (n === 251) { + const number = data.readUint8(); + return x(data, LIST2, number >>> 7, 127 & number); + } + + if (n <= 0 || n >= 240) { + throw new Error('Unable to decode WAP buffer'); + } + + if (n >= 236 && n <= 239) { + const dict = DICTIONARIES[n - 236]; + if (!dict) { + throw new Error(`Missing WAP dictionary ${n - 236}`); + } + + const index = data.readUint8(); + const value = dict[index]; + if (!value) { + throw new Error(`Invalid value index ${index} in dict ${n - 236}`); + } + + return value; + } + + const singleToken = SINGLE_BYTE_TOKEN[n - 1]; + if (!singleToken) throw new Error(`Undefined token with index ${n}`); + + return singleToken; +} + +function O(e: any, t: Binary) { + if (null == e) t.writeUint8(0); + else if (typeof e === 'object' && !(e instanceof Uint8Array) && !Buffer.isBuffer(e) && !Array.isArray(e)) M(e, t); + else if ('string' == typeof e) { + const jid = jidDecode(e) + if(jid) { + if(typeof jid.agent !== 'undefined' || typeof jid.device !== 'undefined') { + var { user: a, agent: i, device: n } = jid; + t.writeUint8(247), t.writeUint8(i || 0), t.writeUint8(n || 0), O(a, t); + } else { + var { user: s, server: l } = jid; + t.writeUint8(250), null != s ? O(s, t) : t.writeUint8(0), O(l, t); + } + } else { + R(e, t); + } + } else { + if (!(e instanceof Uint8Array)) throw new Error('Invalid payload type ' + typeof e); + N(e.length, t), t.writeByteArray(e); + } +} + +function decodeStanzaString(data: Binary) { + // G + const t = L(data, true); + if (typeof t != 'string') { + throw new Error(`Decode string got invalid value ${String(t)}, string expected`); + } + + return t; +} + +function bufferToUInt(e: Uint8Array | Buffer, t: number) { + let a = 0 + for (let i = 0; i < t; i++) a = 256 * a + e[i] + return a +} +/** + * the binary node WA uses internally for communication + * + * this is manipulated soley as an object and it does not have any functions. + * This is done for easy serialization, to prevent running into issues with prototypes & + * to maintain functional code structure + * */ +export type BinaryNode = { + tag: string + attrs: { [key: string]: string } + content?: BinaryNode[] | string | Uint8Array +} +export type BinaryNodeAttributes = BinaryNode['attrs'] +export type BinaryNodeData = BinaryNode['content'] + +export const decodeBinaryNode = (data: Binary): BinaryNode => { + //U + let r = data.readUint8(); + let t = r === 248 ? data.readUint8() : data.readUint16(); + + if (!t) { + throw new Error('Failed to decode node, list cannot be empty'); + } + + const a = {}; + + const n = decodeStanzaString(data); + for (t -= 1; t > 1; ) { + const s = decodeStanzaString(data); + const l = L(data, true); + a[s] = l; + t -= 2; + } + + let i = null; + 1 === t && jidDecode(i = L(data, !1)) && (i = String(i)); + + return { + tag: n, + attrs: a, + content: i + } +} + +export const encodeBinaryNode = (node: BinaryNode) => { + const data = new Binary(); + + O(node, data); + + const dataArr = data.readByteArray(); + const result = new Uint8Array(1 + dataArr.length); + + result[0] = 0; + result.set(dataArr, 1); + + return result; +} + +// some extra useful utilities + +export const getBinaryNodeChildren = ({ content }: BinaryNode, childTag: string) => { + if(Array.isArray(content)) { + return content.filter(item => item.tag == childTag) + } + return [] +} + +export const getBinaryNodeChild = ({ content }: BinaryNode, childTag: string) => { + if(Array.isArray(content)) { + return content.find(item => item.tag == childTag) + } +} + +export const getBinaryNodeChildBuffer = (node: BinaryNode, childTag: string) => { + const child = getBinaryNodeChild(node, childTag)?.content + if(Buffer.isBuffer(child) || child instanceof Uint8Array) { + return child + } +} + +export const getBinaryNodeChildUInt = (node: BinaryNode, childTag: string, length: number) => { + const buff = getBinaryNodeChildBuffer(node, childTag) + if(buff) return bufferToUInt(buff, length) +} + +export const assertNodeErrorFree = (node: BinaryNode) => { + const errNode = getBinaryNodeChild(node, 'error') + if(errNode) { + throw new Boom(errNode.attrs.text || 'Unknown error', { data: +errNode.attrs.code }) + } +} + +export * from './JidUtils' +export { Binary } from '../../WABinary/Binary' \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 1c46348..5f0c293 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,11 @@ -import makeConnection from './Connection' +import makeWASocket from './Socket' -export * from '../WAMessage' +export * from '../WAProto' export * from './Utils' export * from './Types' -export * from './Store' +//export * from './Store' export * from './Defaults' -export default makeConnection \ No newline at end of file +export type WASocket = ReturnType + +export default makeWASocket \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index afcc087..e4c9a2a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -314,6 +314,18 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@cspotcode/source-map-consumer@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" + integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== + +"@cspotcode/source-map-support@0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz#118511f316e2e87ee4294761868e254d3da47960" + integrity sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg== + dependencies: + "@cspotcode/source-map-consumer" "0.8.0" + "@hapi/boom@^9.1.3": version "9.1.3" resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.3.tgz#22cad56e39b7a4819161a99b1db19eaaa9b6cc6e" @@ -916,10 +928,10 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== -"@tsconfig/node16@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.1.tgz#a6ca6a9a0ff366af433f42f5f0e124794ff6b8f1" - integrity sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA== +"@tsconfig/node16@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" + integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": version "7.1.15" @@ -1019,7 +1031,7 @@ dependencies: "@types/node" "*" -"@types/long@^4.0.1": +"@types/long@^4.0.0", "@types/long@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== @@ -1029,6 +1041,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.3.3.tgz#0c30adff37bbbc7a50eb9b58fae2a504d0d88038" integrity sha512-8h7k1YgQKxKXWckzFCMfsIwn0Y61UK6tlD6y2lOb3hTOIMlK3t9/QwHOhc81TwU+RMf0As5fj7NPjroERCnejQ== +"@types/node@^10.1.0": + version "10.17.60" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" + integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== + "@types/node@^14.6.2": version "14.17.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.5.tgz#b59daf6a7ffa461b5648456ca59050ba8e40ed54" @@ -1131,6 +1148,11 @@ acorn-walk@^7.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + acorn@^7.1.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" @@ -1141,6 +1163,11 @@ acorn@^8.2.4: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== +acorn@^8.4.1: + version "8.5.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" + integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -1345,11 +1372,16 @@ buffer-equal@0.0.1: resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs= -buffer-from@1.x, buffer-from@^1.0.0: +buffer-from@1.x: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + buffer@^5.2.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" @@ -1543,11 +1575,6 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -curve25519-js@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/curve25519-js/-/curve25519-js-0.0.4.tgz#e6ad967e8cd284590d657bbfc90d8b50e49ba060" - integrity sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w== - data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -1838,11 +1865,6 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -futoin-hkdf@^1.3.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/futoin-hkdf/-/futoin-hkdf-1.4.2.tgz#fd534e848e0e50339b8bfbd81250b09cbff10ba3" - integrity sha512-2BggwLEJOTfXzKq4Tl2bIT37p0IqqKkblH4e0cMp2sXTdmwg/ADBKMxvxaEytYYcgdxgng8+acsi3WgMVUl6CQ== - gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -2681,6 +2703,13 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +libsignal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/libsignal/-/libsignal-2.0.1.tgz#c276025c184ae4ebbd7d75c12c0be9f3b50cc19e" + integrity sha512-kqdl/BK5i0WCa4NxhtiBsjSzztB/FtUp3mVVLKBFicWH8rDsq95tEIqNcCaVlflLxOm6T/HRb/zv8IsCe7aopA== + dependencies: + protobufjs "6.8.8" + load-bmfont@^1.3.1, load-bmfont@^1.4.0: version "1.4.1" resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.1.tgz#c0f5f4711a1e2ccff725a7b6078087ccfcddd3e9" @@ -3126,6 +3155,25 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" +protobufjs@6.8.8: + version "6.8.8" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" + integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.0" + "@types/node" "^10.1.0" + long "^4.0.0" + protobufjs@^6.10.1: version "6.11.2" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b" @@ -3347,7 +3395,7 @@ sonic-boom@^1.0.2: atomic-sleep "^1.0.0" flatstr "^1.0.12" -source-map-support@^0.5.17, source-map-support@^0.5.6: +source-map-support@^0.5.6: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -3554,19 +3602,21 @@ ts-jest@^27.0.3: yargs-parser "20.x" ts-node@^10.0.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.1.0.tgz#e656d8ad3b61106938a867f69c39a8ba6efc966e" - integrity sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA== + version "10.2.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.2.1.tgz#4cc93bea0a7aba2179497e65bb08ddfc198b3ab5" + integrity sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw== dependencies: + "@cspotcode/source-map-support" "0.6.1" "@tsconfig/node10" "^1.0.7" "@tsconfig/node12" "^1.0.7" "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.1" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" arg "^4.1.0" create-require "^1.1.0" diff "^4.0.1" make-error "^1.1.1" - source-map-support "^0.5.17" yn "3.1.1" type-check@~0.3.2: From f1527a9f6b11ec724d989af5c1fd77aa237501bf Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 23 Sep 2021 22:37:33 +0530 Subject: [PATCH 050/311] separate out crypto utils --- README.md | 7 ++- src/Socket/chats.ts | 2 +- src/Socket/messages-recv.ts | 8 +-- src/Socket/socket.ts | 4 +- src/Utils/chat-utils.ts | 2 +- src/Utils/crypto.ts | 100 +++++++++++++++++++++++++++++ src/Utils/generics.ts | 105 +------------------------------ src/Utils/index.ts | 3 +- src/Utils/messages-media.ts | 3 +- src/Utils/messages.ts | 4 +- src/Utils/noise-handler.ts | 8 +-- src/Utils/signal.ts | 5 +- src/Utils/validate-connection.ts | 11 ++-- 13 files changed, 131 insertions(+), 131 deletions(-) create mode 100644 src/Utils/crypto.ts diff --git a/README.md b/README.md index ac52bfd..4fa4a5f 100644 --- a/README.md +++ b/README.md @@ -78,9 +78,10 @@ If the connection is successful, you will see a QR code printed on your terminal ## Notable Differences Between Baileys Web & MD -1. Baileys no longer maintains an internal state of chats/contacts/messages. You must take this on your own, simply because your state in MD is its own source of truth & there is no one-size-fits-all way to handle the storage for this. -2. A baileys "socket" is meant to be a temporary & disposable object -- this is done to maintain simplicity & prevent bugs. I felt the entire Baileys object became too bloated as it supported too many configurations. -3. Moreover, Baileys does not offer an inbuilt reconnect mechanism anymore (though it's super easy to set one up on your own with your own rules, check the example script) +1. Baileys has been written from the ground up to have a more "functional" structure. This is done primarily for simplicity & more testability +2. Baileys no longer maintains an internal state of chats/contacts/messages. You must take this on your own, simply because your state in MD is its own source of truth & there is no one-size-fits-all way to handle the storage for this. +3. A baileys "socket" is meant to be a temporary & disposable object -- this is done to maintain simplicity & prevent bugs. I felt the entire Baileys object became too bloated as it supported too many configurations. You're encouraged to write your own implementation to handle missing functionality. +4. Moreover, Baileys does not offer an inbuilt reconnect mechanism anymore (though it's super easy to set one up on your own with your own rules, check the example script) ## Configuring the Connection diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index d8c2ec1..a3c4b25 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -4,7 +4,7 @@ import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUse import { makeSocket } from "./socket"; import { proto } from '../../WAProto' import { toNumber } from "../Utils/generics"; -import { compressImage, generateProfilePicture } from ".."; +import { generateProfilePicture } from "../Utils"; export const makeChatsSocket = (config: SocketConfig) => { const { logger } = config diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 6f5a14c..33c68da 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -1,8 +1,8 @@ import { makeGroupsSocket } from "./groups" import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata } from "../Types" -import { decodeMessageStanza, encodeBigEndian, toNumber, whatsappID } from "../Utils" -import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, S_WHATSAPP_NET, areJidsSameUser, getBinaryNodeChildren, getBinaryNodeChild } from '../WABinary' +import { decodeMessageStanza, encodeBigEndian, toNumber } from "../Utils" +import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren } from '../WABinary' import { downloadIfHistory } from '../Utils/history' import { proto } from "../../WAProto" import { generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils/signal" @@ -139,7 +139,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { switch (message.messageStubType) { case WAMessageStubType.GROUP_PARTICIPANT_LEAVE: case WAMessageStubType.GROUP_PARTICIPANT_REMOVE: - participants = message.messageStubParameters.map(whatsappID) + participants = message.messageStubParameters emitParticipantsUpdate('remove') // mark the chat read only if you left the group if (participants.includes(meJid)) { @@ -149,7 +149,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { case WAMessageStubType.GROUP_PARTICIPANT_ADD: case WAMessageStubType.GROUP_PARTICIPANT_INVITE: case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN: - participants = message.messageStubParameters.map(whatsappID) + participants = message.messageStubParameters if (participants.includes(meJid)) { chatUpdate.readOnly = false } diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index e3ad179..309a1f1 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -5,7 +5,7 @@ import WebSocket from "ws" import { randomBytes } from 'crypto' import { proto } from '../../WAProto' import { DisconnectReason, SocketConfig, BaileysEventEmitter } from "../Types" -import { generateCurveKeyPair, initAuthState, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout } from "../Utils" +import { Curve, initAuthState, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout } from "../Utils" import { DEFAULT_ORIGIN, DEF_TAG_PREFIX, DEF_CALLBACK_PREFIX, KEY_BUNDLE_TYPE } from "../Defaults" import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, S_WHATSAPP_NET } from '../WABinary' import noiseHandler from '../Utils/noise-handler' @@ -42,7 +42,7 @@ export const makeSocket = ({ }) ws.setMaxListeners(0) /** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */ - const ephemeralKeyPair = generateCurveKeyPair() + const ephemeralKeyPair = Curve.generateKeyPair() /** WA noise protocol wrapper */ const noise = noiseHandler(ephemeralKeyPair) const authState = initialAuthState || initAuthState() diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 075fa91..35c02b6 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -1,5 +1,5 @@ import { Boom } from '@hapi/boom' -import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./generics" +import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./crypto" import { AuthenticationState, ChatModification } from "../Types" import { proto } from '../../WAProto' import { LT_HASH_ANTI_TAMPERING } from '../WABinary/LTHash' diff --git a/src/Utils/crypto.ts b/src/Utils/crypto.ts new file mode 100644 index 0000000..201ae7e --- /dev/null +++ b/src/Utils/crypto.ts @@ -0,0 +1,100 @@ +import CurveCrypto from 'libsignal/src/curve25519_wrapper' +import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes } from 'crypto' +import { KeyPair } from '../Types' + +export const Curve = { + generateKeyPair: (): KeyPair => { + const { pubKey, privKey } = CurveCrypto.keyPair(randomBytes(32)) + return { + private: Buffer.from(privKey), + public: Buffer.from(pubKey) + } + }, + sharedKey: (privateKey: Uint8Array, publicKey: Uint8Array) => { + const shared = CurveCrypto.sharedSecret(publicKey, privateKey) + return Buffer.from(shared) + }, + sign: (privateKey: Uint8Array, buf: Uint8Array) => ( + Buffer.from(CurveCrypto.sign(privateKey, buf)) + ), + verify: (pubKey: Uint8Array, message: Uint8Array, signature: Uint8Array) => { + try { + CurveCrypto.verify(pubKey, message, signature) + return true + } catch(error) { + if(error.message.includes('Invalid')) { + return false + } + throw error + } + } +} + +export const signedKeyPair = (keyPair: KeyPair, keyId: number) => { + const signKeys = Curve.generateKeyPair() + const pubKey = new Uint8Array(33) + pubKey.set([5], 0) + pubKey.set(signKeys.public, 1) + + const signature = Curve.sign(keyPair.private, pubKey) + + return { keyPair: signKeys, signature, keyId } +} + +/** decrypt AES 256 CBC; where the IV is prefixed to the buffer */ +export function aesDecrypt(buffer: Buffer, key: Buffer) { + return aesDecryptWithIV(buffer.slice(16, buffer.length), key, buffer.slice(0, 16)) +} +/** decrypt AES 256 CBC */ +export function aesDecryptWithIV(buffer: Buffer, key: Buffer, IV: Buffer) { + const aes = createDecipheriv('aes-256-cbc', key, IV) + return Buffer.concat([aes.update(buffer), aes.final()]) +} +// encrypt AES 256 CBC; where a random IV is prefixed to the buffer +export function aesEncrypt(buffer: Buffer | Uint8Array, key: Buffer) { + const IV = randomBytes(16) + const aes = createCipheriv('aes-256-cbc', key, IV) + return Buffer.concat([IV, aes.update(buffer), aes.final()]) // prefix IV to the buffer +} +// encrypt AES 256 CBC with a given IV +export function aesEncrypWithIV(buffer: Buffer, key: Buffer, IV: Buffer) { + const aes = createCipheriv('aes-256-cbc', key, IV) + return Buffer.concat([aes.update(buffer), aes.final()]) // prefix IV to the buffer +} +// sign HMAC using SHA 256 +export function hmacSign(buffer: Buffer | Uint8Array, key: Buffer | Uint8Array, variant: 'sha256' | 'sha512' = 'sha256') { + return createHmac(variant, key).update(buffer).digest() +} +export function sha256(buffer: Buffer) { + return createHash('sha256').update(buffer).digest() +} +// HKDF key expansion +// from: https://github.com/benadida/node-hkdf +export function hkdf(buffer: Buffer, expandedLength: number, { info, salt }: { salt?: Buffer, info?: string }) { + const hashAlg = 'sha256' + const hashLength = 32 + salt = salt || Buffer.alloc(hashLength) + // now we compute the PRK + const prk = createHmac(hashAlg, salt).update(buffer).digest() + + let prev = Buffer.from([]) + const buffers = [] + const num_blocks = Math.ceil(expandedLength / hashLength) + + const infoBuff = Buffer.from(info || []) + + for (var i=0; i ( ) ) -export const generateCurveKeyPair = (): KeyPair => { - const { pubKey, privKey } = CurveCrypto.keyPair(randomBytes(32)) - return { - private: Buffer.from(privKey), - public: Buffer.from(pubKey) - } -} - -export const generateSharedKey = (privateKey: Uint8Array, publicKey: Uint8Array) => { - const shared = CurveCrypto.sharedSecret(publicKey, privateKey) - return Buffer.from(shared) -} - -export const curveSign = (privateKey: Uint8Array, buf: Uint8Array) => ( - Buffer.from(CurveCrypto.sign(privateKey, buf)) -) - -export const curveVerify = (pubKey: Uint8Array, message: Uint8Array, signature: Uint8Array) => { - try { - CurveCrypto.verify(pubKey, message, signature) - return true - } catch(error) { - if(error.message.includes('Invalid')) { - return false - } - throw error - } -} - -export const signedKeyPair = (keyPair: KeyPair, keyId: number) => { - const signKeys = generateCurveKeyPair() - const pubKey = new Uint8Array(33) - pubKey.set([5], 0) - pubKey.set(signKeys.public, 1) - - const signature = curveSign(keyPair.private, pubKey) - - return { keyPair: signKeys, signature, keyId } -} - export const generateRegistrationId = () => ( Uint16Array.from(randomBytes(2))[0] & 0x3fff ) @@ -134,9 +92,6 @@ export const encodeBigEndian = (e: number, t=4) => { export const toNumber = (t: Long | number) => (typeof t?.['low'] !== 'undefined' ? t['low'] : t) as number -export const whatsappID = (jid: string) => jid?.replace ('@c.us', '@s.whatsapp.net') -export const isGroupID = (jid: string) => jid?.endsWith ('@g.us') - export function shallowChanges (old: T, current: T, {lookForDeletedKeys}: {lookForDeletedKeys: boolean}): Partial { let changes: Partial = {} for (let key in current) { @@ -153,64 +108,6 @@ export function shallowChanges (old: T, current: T, {lookForDeletedKeys}: {l } return changes } - -/** decrypt AES 256 CBC; where the IV is prefixed to the buffer */ -export function aesDecrypt(buffer: Buffer, key: Buffer) { - return aesDecryptWithIV(buffer.slice(16, buffer.length), key, buffer.slice(0, 16)) -} -/** decrypt AES 256 CBC */ -export function aesDecryptWithIV(buffer: Buffer, key: Buffer, IV: Buffer) { - const aes = createDecipheriv('aes-256-cbc', key, IV) - return Buffer.concat([aes.update(buffer), aes.final()]) -} -// encrypt AES 256 CBC; where a random IV is prefixed to the buffer -export function aesEncrypt(buffer: Buffer | Uint8Array, key: Buffer) { - const IV = randomBytes(16) - const aes = createCipheriv('aes-256-cbc', key, IV) - return Buffer.concat([IV, aes.update(buffer), aes.final()]) // prefix IV to the buffer -} -// encrypt AES 256 CBC with a given IV -export function aesEncrypWithIV(buffer: Buffer, key: Buffer, IV: Buffer) { - const aes = createCipheriv('aes-256-cbc', key, IV) - return Buffer.concat([aes.update(buffer), aes.final()]) // prefix IV to the buffer -} -// sign HMAC using SHA 256 -export function hmacSign(buffer: Buffer | Uint8Array, key: Buffer | Uint8Array, variant: 'sha256' | 'sha512' = 'sha256') { - return createHmac(variant, key).update(buffer).digest() -} -export function sha256(buffer: Buffer) { - return createHash('sha256').update(buffer).digest() -} -// HKDF key expansion -// from: https://github.com/benadida/node-hkdf -export function hkdf(buffer: Buffer, expandedLength: number, { info, salt }: { salt?: Buffer, info?: string }) { - const hashAlg = 'sha256' - const hashLength = 32 - salt = salt || Buffer.alloc(hashLength) - // now we compute the PRK - const prk = createHmac(hashAlg, salt).update(buffer).digest() - - let prev = Buffer.from([]) - const buffers = [] - const num_blocks = Math.ceil(expandedLength / hashLength) - - const infoBuff = Buffer.from(info || []) - - for (var i=0; i Math.floor(date.getTime()/1000) diff --git a/src/Utils/index.ts b/src/Utils/index.ts index 15973e8..8ea6ea7 100644 --- a/src/Utils/index.ts +++ b/src/Utils/index.ts @@ -2,4 +2,5 @@ export * from './decode-wa-message' export * from './generics' export * from './messages' export * from './messages-media' -export * from './validate-connection' \ No newline at end of file +export * from './validate-connection' +export * from './crypto' \ No newline at end of file diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index b987422..3df3a76 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -11,7 +11,8 @@ import { join } from 'path' import { once } from 'events' import got, { Options, Response } from 'got' import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType } from '../Types' -import { generateMessageID, hkdf } from './generics' +import { generateMessageID } from './generics' +import { hkdf } from './crypto' import { DEFAULT_ORIGIN } from '../Defaults' export const hkdfInfoKey = (type: MediaType) => { diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 13c58ec..2f845d9 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -18,7 +18,7 @@ import { MediaType, WAMessageStatus } from "../Types" -import { generateMessageID, unixTimestampSeconds, whatsappID } from "./generics" +import { generateMessageID, unixTimestampSeconds } from "./generics" import { encryptedStream, generateThumbnail, getAudioDuration } from "./messages-media" type MediaUploadData = { @@ -268,8 +268,6 @@ export const generateWAMessageFromContent = ( options: MessageGenerationOptionsFromContent ) => { if (!options.timestamp) options.timestamp = new Date() // set timestamp to now - // prevent an annoying bug (WA doesn't accept sending messages with '@c.us') - jid = whatsappID(jid) const key = Object.keys(message)[0] const timestamp = unixTimestampSeconds(options.timestamp) diff --git a/src/Utils/noise-handler.ts b/src/Utils/noise-handler.ts index 1f94871..4f60c03 100644 --- a/src/Utils/noise-handler.ts +++ b/src/Utils/noise-handler.ts @@ -1,4 +1,4 @@ -import { sha256, generateSharedKey, hkdf } from "./generics"; +import { sha256, Curve, hkdf } from "./crypto"; import { Binary } from "../WABinary"; import { createCipheriv, createDecipheriv } from "crypto"; import { NOISE_MODE, NOISE_WA_HEADER } from "../Defaults"; @@ -100,10 +100,10 @@ export default ({ public: publicKey, private: privateKey }: KeyPair) => { finishInit, processHandshake: ({ serverHello }: proto.HandshakeMessage, noiseKey: KeyPair) => { authenticate(serverHello!.ephemeral!) - mixIntoKey(generateSharedKey(privateKey, serverHello.ephemeral!)) + mixIntoKey(Curve.sharedKey(privateKey, serverHello.ephemeral!)) const decStaticContent = decrypt(serverHello!.static!) - mixIntoKey(generateSharedKey(privateKey, decStaticContent)) + mixIntoKey(Curve.sharedKey(privateKey, decStaticContent)) const certDecoded = decrypt(serverHello!.payload!) const { details: certDetails, signature: certSignature } = proto.NoiseCertificate.decode(certDecoded) @@ -115,7 +115,7 @@ export default ({ public: publicKey, private: privateKey }: KeyPair) => { } const keyEnc = encrypt(noiseKey.public) - mixIntoKey(generateSharedKey(noiseKey.private, serverHello!.ephemeral!)) + mixIntoKey(Curve.sharedKey(noiseKey.private, serverHello!.ephemeral!)) return keyEnc }, diff --git a/src/Utils/signal.ts b/src/Utils/signal.ts index 2940c7c..3eab1fc 100644 --- a/src/Utils/signal.ts +++ b/src/Utils/signal.ts @@ -1,5 +1,6 @@ import * as libsignal from 'libsignal' -import { encodeBigEndian, generateCurveKeyPair } from "./generics" +import { encodeBigEndian } from "./generics" +import { Curve } from "./crypto" import { SenderKeyDistributionMessage, GroupSessionBuilder, SenderKeyRecord, SenderKeyName, GroupCipher } from '../../WASignalGroup' import { SignalIdentity, SignalKeyStore, SignedKeyPair, KeyPair, AuthenticationState } from "../Types/Auth" import { assertNodeErrorFree, BinaryNode, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildUInt, jidDecode } from "../WABinary" @@ -48,7 +49,7 @@ export const generateOrGetPreKeys = ({ creds }: AuthenticationState, range: numb const newPreKeys: { [id: number]: KeyPair } = { } if(remaining > 0) { for(let i = creds.nextPreKeyId;i <= lastPreKeyId;i++) { - newPreKeys[i] = generateCurveKeyPair() + newPreKeys[i] = Curve.generateKeyPair() } } return { diff --git a/src/Utils/validate-connection.ts b/src/Utils/validate-connection.ts index fa2c903..02446e1 100644 --- a/src/Utils/validate-connection.ts +++ b/src/Utils/validate-connection.ts @@ -2,7 +2,8 @@ import { Boom } from '@hapi/boom' import { randomBytes } from 'crypto' import { proto } from '../../WAProto' import type { AuthenticationState, SocketConfig, SignalKeyStore, AuthenticationCreds, KeyPair } from "../Types" -import { curveSign, hmacSign, curveVerify, encodeInt, generateCurveKeyPair, generateRegistrationId, signedKeyPair } from './generics' +import { Curve, hmacSign, signedKeyPair } from './crypto' +import { encodeInt, generateRegistrationId } from './generics' import { BinaryNode, S_WHATSAPP_NET, jidDecode, Binary } from '../WABinary' import { createSignalIdentity } from './signal' @@ -116,10 +117,10 @@ export const initInMemoryKeyStore = ( } export const initAuthState = (): AuthenticationState => { - const identityKey = generateCurveKeyPair() + const identityKey = Curve.generateKeyPair() return { creds: { - noiseKey: generateCurveKeyPair(), + noiseKey: Curve.generateKeyPair(), signedIdentityKey: identityKey, signedPreKey: signedKeyPair(identityKey, 1), registrationId: generateRegistrationId(), @@ -158,12 +159,12 @@ export const configureSuccessfulPairing = ( const { accountSignatureKey, accountSignature } = account const accountMsg = Binary.build(new Uint8Array([6, 0]), account.details, signedIdentityKey.public).readByteArray() - if (!curveVerify(accountSignatureKey, accountMsg, accountSignature)) { + if (!Curve.verify(accountSignatureKey, accountMsg, accountSignature)) { throw new Boom('Failed to verify account signature') } const deviceMsg = Binary.build(new Uint8Array([6, 1]), account.details, signedIdentityKey.public, account.accountSignatureKey).readByteArray() - account.deviceSignature = curveSign(signedIdentityKey.private, deviceMsg) + account.deviceSignature = Curve.sign(signedIdentityKey.private, deviceMsg) const identity = createSignalIdentity(jid, accountSignatureKey) From 671ea3e0971be6a666e55a67419a2c6d0805eb73 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 25 Sep 2021 17:48:27 +0530 Subject: [PATCH 051/311] remove in-memory-store --- Example/example.ts | 2 + src/Store/in-memory-store.ts | 293 -------------------------------- src/Store/index.ts | 2 - src/Store/ordered-dictionary.ts | 77 --------- 4 files changed, 2 insertions(+), 372 deletions(-) delete mode 100644 src/Store/in-memory-store.ts delete mode 100644 src/Store/index.ts delete mode 100644 src/Store/ordered-dictionary.ts diff --git a/Example/example.ts b/Example/example.ts index 09545f1..266f6d6 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -63,6 +63,8 @@ import makeWASocket, { WASocket, AuthenticationState, DisconnectReason, AnyMessa await delay(2000) await sock.sendPresenceUpdate('paused', jid) + + await sock.sendMessage(jid, msg) } sock = startSock() diff --git a/src/Store/in-memory-store.ts b/src/Store/in-memory-store.ts deleted file mode 100644 index 371d745..0000000 --- a/src/Store/in-memory-store.ts +++ /dev/null @@ -1,293 +0,0 @@ -import type KeyedDB from "@adiwajshing/keyed-db" -import type { Comparable } from "@adiwajshing/keyed-db/lib/Types" -import type { Logger } from "pino" -import type { Connection } from "../Socket" -import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, MessageInfo, PresenceData, WAMessage, WAMessageCursor, WAMessageKey } from "../Types" -import { toNumber } from "../Utils" -import makeOrderedDictionary from "./ordered-dictionary" - -export const waChatKey = (pin: boolean) => ({ - key: (c: Chat) => (pin ? (c.pin ? '1' : '0') : '') + (c.archive ? '0' : '1') + toNumber(c.conversationTimestamp).toString(16).padStart(8, '0') + c.id, - compare: (k1: string, k2: string) => k2.localeCompare (k1) -}) - -export const waMessageID = (m: WAMessage) => m.key.id - -export type BaileysInMemoryStoreConfig = { - chatKey: Comparable - logger: Logger -} - -const makeMessagesDictionary = () => makeOrderedDictionary(waMessageID) - -export default( - { logger, chatKey }: BaileysInMemoryStoreConfig -) => { - const KeyedDBConstructor = require('@adiwajshing/keyed-db').default as new (...args: any[]) => KeyedDB - const chats = new KeyedDBConstructor(chatKey, c => c.jid) - const messages: { [_: string]: ReturnType } = { } - const contacts: { [_: string]: Contact } = { } - const groupMetadata: { [_: string]: GroupMetadata } = { } - const messageInfos: { [id: string]: MessageInfo } = { } - const presences: { [id: string]: { [participant: string]: PresenceData } } = { } - const state: ConnectionState = { connection: 'close' } - - const assertMessageList = (jid: string) => { - if(!messages[jid]) messages[jid] = makeMessagesDictionary() - return messages[jid] - } - - const listen = (ev: BaileysEventEmitter) => { - - const contactsUpsert = (newContacts: Contact[]) => { - const oldContacts = new Set(Object.keys(contacts)) - for(const contact of newContacts) { - oldContacts.delete(contact.jid) - contacts[contact.jid] = Object.assign( - contacts[contact.jid] || {}, - contact - ) - } - return oldContacts - } - - ev.on('connection.update', update => { - Object.assign(state, update) - }) - ev.on('contacts.set', ({ contacts: newContacts }) => { - const oldContacts = contactsUpsert(newContacts) - for(const jid of oldContacts) { - delete contacts[jid] - } - logger.debug({ deletedContacts: oldContacts.size }, 'synced contacts') - }) - ev.on('contacts.update', updates => { - for(const update of updates) { - if(contacts[update.jid!]) { - Object.assign(contacts[update.jid!], update) - } else { - logger.debug({ update }, `got update for non-existant contact`) - } - } - }) - ev.on('chats.upsert', newChats => { - chats.upsert(...newChats) - }) - ev.on('chats.set', ({ chats: newChats }) => { - chats.upsert(...newChats) - }) - ev.on('chats.update', updates => { - for(const update of updates) { - const result = chats.update(update.jid!, chat => { - Object.assign(chat, update) - }) - if(!result) { - logger.debug({ update }, `got update for non-existant chat`) - } - } - }) - ev.on('presence.update', ({ jid, presences: update }) => { - presences[jid] = presences[jid] || {} - Object.assign(presences[jid], update) - }) - ev.on('chats.delete', deletions => { - for(const item of deletions) { - chats.deleteById(item) - } - }) - ev.on('messages.upsert', ({ messages: newMessages, type }) => { - switch(type) { - case 'append': - case 'notify': - for(const msg of newMessages) { - const jid = msg.key.remoteJid! - const list = assertMessageList(jid) - list.upsert(msg, 'append') - - if(type === 'notify') { - if(!chats.get(jid)) { - ev.emit('chats.upsert', [ - { jid, t: toNumber(msg.messageTimestamp), count: 1 } - ]) - } - // add message infos if required - messageInfos[msg.key.id!] = messageInfos[msg.key.id!] || { reads: {}, deliveries: {} } - } - } - break - case 'last': - logger.info('recv last message on all chats') - for(const msg of newMessages) { - const jid = msg.key.remoteJid! - const list = assertMessageList(jid) - const [lastItem] = list.array.slice(-1) - // reset message list - if(lastItem?.key.id !== msg.key.id) { - list.clear() - list.upsert(msg, 'append') - } - } - break - case 'prepend': - for(const msg of newMessages) { - const jid = msg.key.remoteJid! - const list = assertMessageList(jid) - list.upsert(msg, 'prepend') - } - break - } - }) - ev.on('messages.update', updates => { - for(const { update, key } of updates) { - const list = assertMessageList(key.remoteJid) - const result = list.updateAssign(key.id, update) - if(!result) { - logger.debug({ update }, `got update for non-existent message`) - } - } - }) - ev.on('messages.delete', item => { - const list = assertMessageList(item.jid) - if('all' in item) { - list.clear() - } else { - const idSet = new Set(item.ids) - list.filter(m => !idSet.has(m.key.id)) - } - }) - - ev.on('groups.update', updates => { - for(const update of updates) { - if(groupMetadata[update.id]) { - Object.assign(groupMetadata[update.id!], update) - } else { - logger.debug({ update }, `got update for non-existant group metadata`) - } - } - }) - - ev.on('group-participants.update', ({ jid, participants, action }) => { - const metadata = groupMetadata[jid] - if(metadata) { - switch(action) { - case 'add': - metadata.participants.push(...participants.map(jid => ({ jid, isAdmin: false, isSuperAdmin: false }))) - break - case 'demote': - case 'promote': - for(const participant of metadata.participants) { - if(participants.includes(participant.jid)) { - participant.isAdmin = action === 'promote' - } - } - break - case 'remove': - metadata.participants = metadata.participants.filter(p => !participants.includes(p.jid)) - break - } - } - }) - - ev.on('message-info.update', updates => { - for(const { key, update } of updates) { - const obj = messageInfos[key.id!] - if(obj) { - // add reads/deliveries - for(const key in update) { - Object.assign(obj[key], update[key]) - } - } - } - }) - } - - - return { - chats, - contacts, - messages, - groupMetadata, - messageInfos, - state, - presences, - listen, - /*loadMessages: async(jid: string, count: number, cursor: WAMessageCursor, sock: Connection | undefined) => { - const list = assertMessageList(jid) - const retrieve = async(count: number, cursor: WAMessageCursor) => { - const result = await sock?.fetchMessagesFromWA(jid, count, cursor) - return result || [] - } - const mode = !cursor || 'before' in cursor ? 'before' : 'after' - const cursorKey = !!cursor ? ('before' in cursor ? cursor.before : cursor.after) : undefined - const cursorValue = cursorKey ? list.get(cursorKey.id) : undefined - - let messages: WAMessage[] - if(list && mode === 'before' && (!cursorKey || cursorValue)) { - if(cursorValue) { - const msgIdx = list.array.findIndex(m => m.key.id === cursorKey.id) - messages = list.array.slice(0, msgIdx) - } else { - messages = list.array - } - const diff = count - messages.length - if (diff < 0) { - messages = messages.slice(-count) // get the last X messages - } else if (diff > 0) { - const [fMessage] = messages - const cursor = { before: fMessage?.key || cursorKey } - const extra = await retrieve (diff, cursor) - // add to DB - for(let i = extra.length-1; i >= 0;i--) { - list.upsert(extra[i], 'prepend') - } - messages.splice(0, 0, ...extra) - } - } else messages = await retrieve(count, cursor) - - return messages - }, - loadMessage: async(jid: string, id: string, sock: Connection | undefined) => { - let message = messages[jid]?.get(id) - if(!message) { - message = await sock?.loadMessageFromWA(jid, id) - } - return message - }, - mostRecentMessage: async(jid: string, sock: Connection | undefined) => { - let message = messages[jid]?.array.slice(-1)[0] - if(!message) { - const [result] = await sock?.fetchMessagesFromWA(jid, 1, undefined) - message = result - } - return message - }, - fetchImageUrl: async(jid: string, sock: Connection | undefined) => { - const contact = contacts[jid] - if(!contact) { - return sock?.fetchImageUrl(jid) - } - if(typeof contact.imgUrl === 'undefined') { - contact.imgUrl = await sock?.fetchImageUrl(jid) - } - return contact.imgUrl - }, - fetchGroupMetadata: async(jid: string, sock: Connection | undefined) => { - if(!groupMetadata[jid]) { - groupMetadata[jid] = await sock?.groupMetadata(jid, chats.get(jid)?.read_only === 'true') - } - return groupMetadata[jid] - }, - fetchBroadcastListInfo: async(jid: string, sock: Connection | undefined) => { - if(!groupMetadata[jid]) { - groupMetadata[jid] = await sock?.getBroadcastListInfo(jid) - } - return groupMetadata[jid] - }, - fetchMessageInfo: async({remoteJid, id}: WAMessageKey, sock: Connection | undefined) => { - if(!messageInfos[id!]) { - messageInfos[id!] = await sock?.messageInfo(remoteJid, id) - } - return messageInfos[id!] - }*/ - } -} \ No newline at end of file diff --git a/src/Store/index.ts b/src/Store/index.ts deleted file mode 100644 index 1bfc30c..0000000 --- a/src/Store/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -import makeInMemoryStore from './in-memory-store' -export { makeInMemoryStore } \ No newline at end of file diff --git a/src/Store/ordered-dictionary.ts b/src/Store/ordered-dictionary.ts deleted file mode 100644 index a1a7af1..0000000 --- a/src/Store/ordered-dictionary.ts +++ /dev/null @@ -1,77 +0,0 @@ - -const makeOrderedDictionary = function(idGetter: (item: T) => string) { - const array: T[] = [] - const dict: { [_: string]: T } = { } - - const get = (id: string) => dict[id] - - const update = (item: T) => { - const id = idGetter(item) - const idx = array.findIndex(i => idGetter(i) === id) - if(idx >= 0) { - array[idx] = item - dict[id] = item - } - return false - } - - const upsert = (item: T, mode: 'append' | 'prepend') => { - const id = idGetter(item) - if(get(id)) { - update(item) - } else { - if(mode === 'append') { - array.push(item) - } else { - array.splice(0, 0, item) - } - dict[id] = item - } - } - - const remove = (item: T) => { - const id = idGetter(item) - const idx = array.findIndex(i => idGetter(i) === id) - if(idx >= 0) { - array.splice(idx, 1) - delete dict[id] - return true - } - return false - } - - return { - array, - get, - upsert, - update, - remove, - updateAssign: (id: string, update: Partial) => { - const item = get(id) - if(item) { - Object.assign(item, update) - delete dict[id] - dict[idGetter(item)] = item - return true - } - return false - }, - clear: () => { - array.splice(0, array.length) - Object.keys(dict).forEach(key => { delete dict[key] }) - }, - filter: (contain: (item: T) => boolean) => { - let i = 0 - while(i < array.length) { - if(!contain(array[i])) { - delete dict[idGetter(array[i])] - array.splice(i, 1) - } else { - i += 1 - } - } - } - } -} -export default makeOrderedDictionary -//export type OrderedDictionary = ReturnType \ No newline at end of file From fff2e589976642c0b88c9204c10487b38dbf6327 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 25 Sep 2021 18:04:26 +0530 Subject: [PATCH 052/311] fix compilation errors --- WABinary/Binary.js | 16 +++++++++------- WABinary/Constants.js | 25 +++++++++++++------------ WABinary/HexHelper.js | 34 +++++++++++++++++----------------- package.json | 5 +++-- src/WABinary/LTHash.js | 4 ++-- tsconfig.json | 4 ++-- 6 files changed, 46 insertions(+), 42 deletions(-) diff --git a/WABinary/Binary.js b/WABinary/Binary.js index 375b63c..c37e1eb 100644 --- a/WABinary/Binary.js +++ b/WABinary/Binary.js @@ -1,5 +1,5 @@ -import { hexAt, hexLongIsNegative, hexLongToHex, negateHexLong, NUM_HEX_IN_LONG } from "./HexHelper"; -import { inflateSync } from 'zlib' +const { hexAt, hexLongIsNegative, hexLongToHex, negateHexLong, NUM_HEX_IN_LONG } = require("./HexHelper"); +const { inflateSync } = require("zlib") var l = "", d = 0; @@ -236,12 +236,12 @@ function H(e, t, r) { return 128 == (192 & a) ? a : 0; } -export const numUtf8Bytes = u; -export const longFitsInDouble = c; -export const parseInt64OrThrow = j; -export const parseUint64OrThrow = W; +module.exports.numUtf8Bytes = u; +module.exports.longFitsInDouble = c; +module.exports.parseInt64OrThrow = j; +module.exports.parseUint64OrThrow = W; -export class Binary { +class Binary { /** @type {Uint8Array} */ buffer; readEndIndex; @@ -583,3 +583,5 @@ export class Binary { return this } } + +module.exports.Binary = Binary \ No newline at end of file diff --git a/WABinary/Constants.js b/WABinary/Constants.js index ea674c1..8adfeed 100644 --- a/WABinary/Constants.js +++ b/WABinary/Constants.js @@ -1,14 +1,5 @@ -export const DEVICE = { PRIMARY_DEVICE: 0, PRIMARY_VERSION: 0 } -export const SINGLE_BYTE_TOKEN = ["xmlstreamstart", "xmlstreamend", "s.whatsapp.net", "type", "participant", "from", "receipt", "id", "broadcast", "status", "message", "notification", "notify", "to", "jid", "user", "class", "offline", "g.us", "result", "mediatype", "enc", "skmsg", "off_cnt", "xmlns", "presence", "participants", "ack", "t", "iq", "device_hash", "read", "value", "media", "picture", "chatstate", "unavailable", "text", "urn:xmpp:whatsapp:push", "devices", "verified_name", "contact", "composing", "edge_routing", "routing_info", "item", "image", "verified_level", "get", "fallback_hostname", "2", "media_conn", "1", "v", "handshake", "fallback_class", "count", "config", "offline_preview", "download_buckets", "w:profile:picture", "set", "creation", "location", "fallback_ip4", "msg", "urn:xmpp:ping", "fallback_ip6", "call-creator", "relaylatency", "success", "subscribe", "video", "business_hours_config", "platform", "hostname", "version", "unknown", "0", "ping", "hash", "edit", "subject", "max_buckets", "download", "delivery", "props", "sticker", "name", "last", "contacts", "business", "primary", "preview", "w:p", "pkmsg", "call-id", "retry", "prop", "call", "auth_ttl", "available", "relay_id", "last_id", "day_of_week", "w", "host", "seen", "bits", "list", "atn", "upload", "is_new", "w:stats", "key", "paused", "specific_hours", "multicast", "stream:error", "mmg.whatsapp.net", "code", "deny", "played", "profile", "fna", "device-list", "close_time", "latency", "gcm", "pop", "audio", "26", "w:web", "open_time", "error", "auth", "ip4", "update", "profile_options", "config_value", "category", "catalog_not_created", "00", "config_code", "mode", "catalog_status", "ip6", "blocklist", "registration", "7", "web", "fail", "w:m", "cart_enabled", "ttl", "gif", "300", "device_orientation", "identity", "query", "401", "media-gig2-1.cdn.whatsapp.net", "in", "3", "te2", "add", "fallback", "categories", "ptt", "encrypt", "notice", "thumbnail-document", "item-not-found", "12", "thumbnail-image", "stage", "thumbnail-link", "usync", "out", "thumbnail-video", "8", "01", "context", "sidelist", "thumbnail-gif", "terminate", "not-authorized", "orientation", "dhash", "capability", "side_list", "md-app-state", "description", "serial", "readreceipts", "te", "business_hours", "md-msg-hist", "tag", "attribute_padding", "document", "open_24h", "delete", "expiration", "active", "prev_v_id", "true", "passive", "index", "4", "conflict", "remove", "w:gp2", "config_expo_key", "screen_height", "replaced", "02", "screen_width", "uploadfieldstat", "2:47DEQpj8", "media-bog1-1.cdn.whatsapp.net", "encopt", "url", "catalog_exists", "keygen", "rate", "offer", "opus", "media-mia3-1.cdn.whatsapp.net", "privacy", "media-mia3-2.cdn.whatsapp.net", "signature", "preaccept", "token_id", "media-eze1-1.cdn.whatsapp.net"]; -export const DICTIONARY_0_TOKEN = ["media-for1-1.cdn.whatsapp.net", "relay", "media-gru2-2.cdn.whatsapp.net", "uncompressed", "medium", "voip_settings", "device", "reason", "media-lim1-1.cdn.whatsapp.net", "media-qro1-2.cdn.whatsapp.net", "media-gru1-2.cdn.whatsapp.net", "action", "features", "media-gru2-1.cdn.whatsapp.net", "media-gru1-1.cdn.whatsapp.net", "media-otp1-1.cdn.whatsapp.net", "kyc-id", "priority", "phash", "mute", "token", "100", "media-qro1-1.cdn.whatsapp.net", "none", "media-mrs2-2.cdn.whatsapp.net", "sign_credential", "03", "media-mrs2-1.cdn.whatsapp.net", "protocol", "timezone", "transport", "eph_setting", "1080", "original_dimensions", "media-frx5-1.cdn.whatsapp.net", "background", "disable", "original_image_url", "5", "transaction-id", "direct_path", "103", "appointment_only", "request_image_url", "peer_pid", "address", "105", "104", "102", "media-cdt1-1.cdn.whatsapp.net", "101", "109", "110", "106", "background_location", "v_id", "sync", "status-old", "111", "107", "ppic", "media-scl2-1.cdn.whatsapp.net", "business_profile", "108", "invite", "04", "audio_duration", "media-mct1-1.cdn.whatsapp.net", "media-cdg2-1.cdn.whatsapp.net", "media-los2-1.cdn.whatsapp.net", "invis", "net", "voip_payload_type", "status-revoke-delay", "404", "state", "use_correct_order_for_hmac_sha1", "ver", "media-mad1-1.cdn.whatsapp.net", "order", "540", "skey", "blinded_credential", "android", "contact_remove", "enable_downlink_relay_latency_only", "duration", "enable_vid_one_way_codec_nego", "6", "media-sof1-1.cdn.whatsapp.net", "accept", "all", "signed_credential", "media-atl3-1.cdn.whatsapp.net", "media-lhr8-1.cdn.whatsapp.net", "website", "05", "latitude", "media-dfw5-1.cdn.whatsapp.net", "forbidden", "enable_audio_piggyback_network_mtu_fix", "media-dfw5-2.cdn.whatsapp.net", "note.m4r", "media-atl3-2.cdn.whatsapp.net", "jb_nack_discard_count_fix", "longitude", "Opening.m4r", "media-arn2-1.cdn.whatsapp.net", "email", "timestamp", "admin", "media-pmo1-1.cdn.whatsapp.net", "America/Sao_Paulo", "contact_add", "media-sin6-1.cdn.whatsapp.net", "interactive", "8000", "acs_public_key", "sigquit_anr_detector_release_rollover_percent", "media.fmed1-2.fna.whatsapp.net", "groupadd", "enabled_for_video_upgrade", "latency_update_threshold", "media-frt3-2.cdn.whatsapp.net", "calls_row_constraint_layout", "media.fgbb2-1.fna.whatsapp.net", "mms4_media_retry_notification_encryption_enabled", "timeout", "media-sin6-3.cdn.whatsapp.net", "audio_nack_jitter_multiplier", "jb_discard_count_adjust_pct_rc", "audio_reserve_bps", "delta", "account_sync", "default", "media.fjed4-6.fna.whatsapp.net", "06", "lock_video_orientation", "media-frt3-1.cdn.whatsapp.net", "w:g2", "media-sin6-2.cdn.whatsapp.net", "audio_nack_algo_mask", "media.fgbb2-2.fna.whatsapp.net", "media.fmed1-1.fna.whatsapp.net", "cond_range_target_bitrate", "mms4_server_error_receipt_encryption_enabled", "vid_rc_dyn", "fri", "cart_v1_1_order_message_changes_enabled", "reg_push", "jb_hist_deposit_value", "privatestats", "media.fist7-2.fna.whatsapp.net", "thu", "jb_discard_count_adjust_pct", "mon", "group_call_video_maximization_enabled", "mms_cat_v1_forward_hot_override_enabled", "audio_nack_new_rtt", "media.fsub2-3.fna.whatsapp.net", "media_upload_aggressive_retry_exponential_backoff_enabled", "tue", "wed", "media.fruh4-2.fna.whatsapp.net", "audio_nack_max_seq_req", "max_rtp_audio_packet_resends", "jb_hist_max_cdf_value", "07", "audio_nack_max_jb_delay", "mms_forward_partially_downloaded_video", "media-lcy1-1.cdn.whatsapp.net", "resume", "jb_inband_fec_aware", "new_commerce_entry_point_enabled", "480", "payments_upi_generate_qr_amount_limit", "sigquit_anr_detector_rollover_percent", "media.fsdu2-1.fna.whatsapp.net", "fbns", "aud_pkt_reorder_pct", "dec", "stop_probing_before_accept_send", "media_upload_max_aggressive_retries", "edit_business_profile_new_mode_enabled", "media.fhex4-1.fna.whatsapp.net", "media.fjed4-3.fna.whatsapp.net", "sigquit_anr_detector_64bit_rollover_percent", "cond_range_ema_jb_last_delay", "watls_enable_early_data_http_get", "media.fsdu2-2.fna.whatsapp.net", "message_qr_disambiguation_enabled", "media-mxp1-1.cdn.whatsapp.net", "sat", "vertical", "media.fruh4-5.fna.whatsapp.net", "200", "media-sof1-2.cdn.whatsapp.net", "-1", "height", "product_catalog_hide_show_items_enabled", "deep_copy_frm_last", "tsoffline", "vp8/h.264", "media.fgye5-3.fna.whatsapp.net", "media.ftuc1-2.fna.whatsapp.net", "smb_upsell_chat_banner_enabled", "canonical", "08", "9", ".", "media.fgyd4-4.fna.whatsapp.net", "media.fsti4-1.fna.whatsapp.net", "mms_vcache_aggregation_enabled", "mms_hot_content_timespan_in_seconds", "nse_ver", "rte", "third_party_sticker_web_sync", "cond_range_target_total_bitrate", "media_upload_aggressive_retry_enabled", "instrument_spam_report_enabled", "disable_reconnect_tone", "move_media_folder_from_sister_app", "one_tap_calling_in_group_chat_size", "10", "storage_mgmt_banner_threshold_mb", "enable_backup_passive_mode", "sharechat_inline_player_enabled", "media.fcnq2-1.fna.whatsapp.net", "media.fhex4-2.fna.whatsapp.net", "media.fist6-3.fna.whatsapp.net", "ephemeral_drop_column_stage", "reconnecting_after_network_change_threshold_ms", "media-lhr8-2.cdn.whatsapp.net", "cond_jb_last_delay_ema_alpha", "entry_point_block_logging_enabled", "critical_event_upload_log_config", "respect_initial_bitrate_estimate", "smaller_image_thumbs_status_enabled", "media.fbtz1-4.fna.whatsapp.net", "media.fjed4-1.fna.whatsapp.net", "width", "720", "enable_frame_dropper", "enable_one_side_mode", "urn:xmpp:whatsapp:dirty", "new_sticker_animation_behavior_v2", "media.flim3-2.fna.whatsapp.net", "media.fuio6-2.fna.whatsapp.net", "skip_forced_signaling", "dleq_proof", "status_video_max_bitrate", "lazy_send_probing_req", "enhanced_storage_management", "android_privatestats_endpoint_dit_enabled", "media.fscl13-2.fna.whatsapp.net", "video_duration"]; -export const DICTIONARY_1_TOKEN = ["group_call_discoverability_enabled", "media.faep9-2.fna.whatsapp.net", "msgr", "bloks_loggedin_access_app_id", "db_status_migration_step", "watls_prefer_ip6", "jabber:iq:privacy", "68", "media.fsaw1-11.fna.whatsapp.net", "mms4_media_conn_persist_enabled", "animated_stickers_thread_clean_up", "media.fcgk3-2.fna.whatsapp.net", "media.fcgk4-6.fna.whatsapp.net", "media.fgye5-2.fna.whatsapp.net", "media.flpb1-1.fna.whatsapp.net", "media.fsub2-1.fna.whatsapp.net", "media.fuio6-3.fna.whatsapp.net", "not-allowed", "partial_pjpeg_bw_threshold", "cap_estimated_bitrate", "mms_chatd_resume_check_over_thrift", "smb_upsell_business_profile_enabled", "product_catalog_webclient", "groups", "sigquit_anr_detector_release_updated_rollout", "syncd_key_rotation_enabled", "media.fdmm2-1.fna.whatsapp.net", "media-hou1-1.cdn.whatsapp.net", "remove_old_chat_notifications", "smb_biztools_deeplink_enabled", "use_downloadable_filters_int", "group_qr_codes_enabled", "max_receipt_processing_time", "optimistic_image_processing_enabled", "smaller_video_thumbs_status_enabled", "watls_early_data", "reconnecting_before_relay_failover_threshold_ms", "cond_range_packet_loss_pct", "groups_privacy_blacklist", "status-revoke-drop", "stickers_animated_thumbnail_download", "dedupe_transcode_shared_images", "dedupe_transcode_shared_videos", "media.fcnq2-2.fna.whatsapp.net", "media.fgyd4-1.fna.whatsapp.net", "media.fist7-1.fna.whatsapp.net", "media.flim3-3.fna.whatsapp.net", "add_contact_by_qr_enabled", "https://faq.whatsapp.com/payments", "multicast_limit_global", "sticker_notification_preview", "smb_better_catalog_list_adapters_enabled", "bloks_use_minscript_android", "pen_smoothing_enabled", "media.fcgk4-5.fna.whatsapp.net", "media.fevn1-3.fna.whatsapp.net", "media.fpoj7-1.fna.whatsapp.net", "media-arn2-2.cdn.whatsapp.net", "reconnecting_before_network_change_threshold_ms", "android_media_use_fresco_for_gifs", "cond_in_congestion", "status_image_max_edge", "sticker_search_enabled", "starred_stickers_web_sync", "db_blank_me_jid_migration_step", "media.fist6-2.fna.whatsapp.net", "media.ftuc1-1.fna.whatsapp.net", "09", "anr_fast_logs_upload_rollout", "camera_core_integration_enabled", "11", "third_party_sticker_caching", "thread_dump_contact_support", "wam_privatestats_enabled", "vcard_as_document_size_kb", "maxfpp", "fbip", "ephemeral_allow_group_members", "media-bom1-2.cdn.whatsapp.net", "media-xsp1-1.cdn.whatsapp.net", "disable_prewarm", "frequently_forwarded_max", "media.fbtz1-5.fna.whatsapp.net", "media.fevn7-1.fna.whatsapp.net", "media.fgyd4-2.fna.whatsapp.net", "sticker_tray_animation_fully_visible_items", "green_alert_banner_duration", "reconnecting_after_p2p_failover_threshold_ms", "connected", "share_biz_vcard_enabled", "stickers_animation", "0a", "1200", "WhatsApp", "group_description_length", "p_v_id", "payments_upi_intent_transaction_limit", "frequently_forwarded_messages", "media-xsp1-2.cdn.whatsapp.net", "media.faep8-1.fna.whatsapp.net", "media.faep8-2.fna.whatsapp.net", "media.faep9-1.fna.whatsapp.net", "media.fdmm2-2.fna.whatsapp.net", "media.fgzt3-1.fna.whatsapp.net", "media.flim4-2.fna.whatsapp.net", "media.frao1-1.fna.whatsapp.net", "media.fscl9-2.fna.whatsapp.net", "media.fsub2-2.fna.whatsapp.net", "superadmin", "media.fbog10-1.fna.whatsapp.net", "media.fcgh28-1.fna.whatsapp.net", "media.fjdo10-1.fna.whatsapp.net", "third_party_animated_sticker_import", "delay_fec", "attachment_picker_refresh", "android_linked_devices_re_auth_enabled", "rc_dyn", "green_alert_block_jitter", "add_contact_logging_enabled", "biz_message_logging_enabled", "conversation_media_preview_v2", "media-jnb1-1.cdn.whatsapp.net", "ab_key", "media.fcgk4-2.fna.whatsapp.net", "media.fevn1-1.fna.whatsapp.net", "media.fist6-1.fna.whatsapp.net", "media.fruh4-4.fna.whatsapp.net", "media.fsti4-2.fna.whatsapp.net", "mms_vcard_autodownload_size_kb", "watls_enabled", "notif_ch_override_off", "media.fsaw1-14.fna.whatsapp.net", "media.fscl13-1.fna.whatsapp.net", "db_group_participant_migration_step", "1020", "cond_range_sterm_rtt", "invites_logging_enabled", "triggered_block_enabled", "group_call_max_participants", "media-iad3-1.cdn.whatsapp.net", "product_catalog_open_deeplink", "shops_required_tos_version", "image_max_kbytes", "cond_low_quality_vid_mode", "db_receipt_migration_step", "jb_early_prob_hist_shrink", "media.fdmm2-3.fna.whatsapp.net", "media.fdmm2-4.fna.whatsapp.net", "media.fruh4-1.fna.whatsapp.net", "media.fsaw2-2.fna.whatsapp.net", "remove_geolocation_videos", "new_animation_behavior", "fieldstats_beacon_chance", "403", "authkey_reset_on_ban", "continuous_ptt_playback", "reconnecting_after_relay_failover_threshold_ms", "false", "group", "sun", "conversation_swipe_to_reply", "ephemeral_messages_setting", "smaller_video_thumbs_enabled", "md_device_sync_enabled", "bloks_shops_pdp_url_regex", "lasso_integration_enabled", "media-bom1-1.cdn.whatsapp.net", "new_backup_format_enabled", "256", "media.faep6-1.fna.whatsapp.net", "media.fasr1-1.fna.whatsapp.net", "media.fbtz1-7.fna.whatsapp.net", "media.fesb4-1.fna.whatsapp.net", "media.fjdo1-2.fna.whatsapp.net", "media.frba2-1.fna.whatsapp.net", "watls_no_dns", "600", "db_broadcast_me_jid_migration_step", "new_wam_runtime_enabled", "group_update", "enhanced_block_enabled", "sync_wifi_threshold_kb", "mms_download_nc_cat", "bloks_minification_enabled", "ephemeral_messages_enabled", "reject", "voip_outgoing_xml_signaling", "creator", "dl_bw", "payments_request_messages", "target_bitrate", "bloks_rendercore_enabled", "media-hbe1-1.cdn.whatsapp.net", "media-hel3-1.cdn.whatsapp.net", "media-kut2-2.cdn.whatsapp.net", "media-lax3-1.cdn.whatsapp.net", "media-lax3-2.cdn.whatsapp.net", "sticker_pack_deeplink_enabled", "hq_image_bw_threshold", "status_info", "voip", "dedupe_transcode_videos", "grp_uii_cleanup", "linked_device_max_count", "media.flim1-1.fna.whatsapp.net", "media.fsaw2-1.fna.whatsapp.net", "reconnecting_after_call_active_threshold_ms", "1140", "catalog_pdp_new_design", "media.fbtz1-10.fna.whatsapp.net", "media.fsaw1-15.fna.whatsapp.net", "0b", "consumer_rc_provider", "mms_async_fast_forward_ttl", "jb_eff_size_fix", "voip_incoming_xml_signaling", "media_provider_share_by_uuid", "suspicious_links", "dedupe_transcode_images", "green_alert_modal_start", "media-cgk1-1.cdn.whatsapp.net", "media-lga3-1.cdn.whatsapp.net", "template_doc_mime_types", "important_messages", "user_add", "vcard_max_size_kb", "media.fada2-1.fna.whatsapp.net", "media.fbog2-5.fna.whatsapp.net", "media.fbtz1-3.fna.whatsapp.net", "media.fcgk3-1.fna.whatsapp.net", "media.fcgk7-1.fna.whatsapp.net", "media.flim1-3.fna.whatsapp.net", "media.fscl9-1.fna.whatsapp.net", "ctwa_context_enterprise_enabled", "media.fsaw1-13.fna.whatsapp.net", "media.fuio11-2.fna.whatsapp.net", "status_collapse_muted", "db_migration_level_force", "recent_stickers_web_sync", "bloks_session_state", "bloks_shops_enabled", "green_alert_setting_deep_links_enabled", "restrict_groups", "battery", "green_alert_block_start", "refresh", "ctwa_context_enabled", "md_messaging_enabled", "status_image_quality", "md_blocklist_v2_server", "media-del1-1.cdn.whatsapp.net", "13", "userrate", "a_v_id", "cond_rtt_ema_alpha", "invalid"]; -export const DICTIONARY_2_TOKEN = ["media.fada1-1.fna.whatsapp.net", "media.fadb3-2.fna.whatsapp.net", "media.fbhz2-1.fna.whatsapp.net", "media.fcor2-1.fna.whatsapp.net", "media.fjed4-2.fna.whatsapp.net", "media.flhe4-1.fna.whatsapp.net", "media.frak1-2.fna.whatsapp.net", "media.fsub6-3.fna.whatsapp.net", "media.fsub6-7.fna.whatsapp.net", "media.fvvi1-1.fna.whatsapp.net", "search_v5_eligible", "wam_real_time_enabled", "report_disk_event", "max_tx_rott_based_bitrate", "product", "media.fjdo10-2.fna.whatsapp.net", "video_frame_crc_sample_interval", "media_max_autodownload", "15", "h.264", "wam_privatestats_buffer_count", "md_phash_v2_enabled", "account_transfer_enabled", "business_product_catalog", "enable_non_dyn_codec_param_fix", "is_user_under_epd_jurisdiction", "media.fbog2-4.fna.whatsapp.net", "media.fbtz1-2.fna.whatsapp.net", "media.fcfc1-1.fna.whatsapp.net", "media.fjed4-5.fna.whatsapp.net", "media.flhe4-2.fna.whatsapp.net", "media.flim1-2.fna.whatsapp.net", "media.flos5-1.fna.whatsapp.net", "android_key_store_auth_ver", "010", "anr_process_monitor", "delete_old_auth_key", "media.fcor10-3.fna.whatsapp.net", "storage_usage_enabled", "android_camera2_support_level", "dirty", "consumer_content_provider", "status_video_max_duration", "0c", "bloks_cache_enabled", "media.fadb2-2.fna.whatsapp.net", "media.fbko1-1.fna.whatsapp.net", "media.fbtz1-9.fna.whatsapp.net", "media.fcgk4-4.fna.whatsapp.net", "media.fesb4-2.fna.whatsapp.net", "media.fevn1-2.fna.whatsapp.net", "media.fist2-4.fna.whatsapp.net", "media.fjdo1-1.fna.whatsapp.net", "media.fruh4-6.fna.whatsapp.net", "media.fsrg5-1.fna.whatsapp.net", "media.fsub6-6.fna.whatsapp.net", "minfpp", "5000", "locales", "video_max_bitrate", "use_new_auth_key", "bloks_http_enabled", "heartbeat_interval", "media.fbog11-1.fna.whatsapp.net", "ephemeral_group_query_ts", "fec_nack", "search_in_storage_usage", "c", "media-amt2-1.cdn.whatsapp.net", "linked_devices_ui_enabled", "14", "async_data_load_on_startup", "voip_incoming_xml_ack", "16", "db_migration_step", "init_bwe", "max_participants", "wam_buffer_count", "media.fada2-2.fna.whatsapp.net", "media.fadb3-1.fna.whatsapp.net", "media.fcor2-2.fna.whatsapp.net", "media.fdiy1-2.fna.whatsapp.net", "media.frba3-2.fna.whatsapp.net", "media.fsaw2-3.fna.whatsapp.net", "1280", "status_grid_enabled", "w:biz", "product_catalog_deeplink", "media.fgye10-2.fna.whatsapp.net", "media.fuio11-1.fna.whatsapp.net", "optimistic_upload", "work_manager_init", "lc", "catalog_message", "cond_net_medium", "enable_periodical_aud_rr_processing", "cond_range_ema_rtt", "media-tir2-1.cdn.whatsapp.net", "frame_ms", "group_invite_sending", "payments_web_enabled", "wallpapers_v2", "0d", "browser", "hq_image_max_edge", "image_edit_zoom", "linked_devices_re_auth_enabled", "media.faly3-2.fna.whatsapp.net", "media.fdoh5-3.fna.whatsapp.net", "media.fesb3-1.fna.whatsapp.net", "media.fknu1-1.fna.whatsapp.net", "media.fmex3-1.fna.whatsapp.net", "media.fruh4-3.fna.whatsapp.net", "255", "web_upgrade_to_md_modal", "audio_piggyback_timeout_msec", "enable_audio_oob_fec_feature", "from_ip", "image_max_edge", "message_qr_enabled", "powersave", "receipt_pre_acking", "video_max_edge", "full", "011", "012", "enable_audio_oob_fec_for_sender", "md_voip_enabled", "enable_privatestats", "max_fec_ratio", "payments_cs_faq_url", "media-xsp1-3.cdn.whatsapp.net", "hq_image_quality", "media.fasr1-2.fna.whatsapp.net", "media.fbog3-1.fna.whatsapp.net", "media.ffjr1-6.fna.whatsapp.net", "media.fist2-3.fna.whatsapp.net", "media.flim4-3.fna.whatsapp.net", "media.fpbc2-4.fna.whatsapp.net", "media.fpku1-1.fna.whatsapp.net", "media.frba1-1.fna.whatsapp.net", "media.fudi1-1.fna.whatsapp.net", "media.fvvi1-2.fna.whatsapp.net", "gcm_fg_service", "enable_dec_ltr_size_check", "clear", "lg", "media.fgru11-1.fna.whatsapp.net", "18", "media-lga3-2.cdn.whatsapp.net", "pkey", "0e", "max_subject", "cond_range_lterm_rtt", "announcement_groups", "biz_profile_options", "s_t", "media.fabv2-1.fna.whatsapp.net", "media.fcai3-1.fna.whatsapp.net", "media.fcgh1-1.fna.whatsapp.net", "media.fctg1-4.fna.whatsapp.net", "media.fdiy1-1.fna.whatsapp.net", "media.fisb4-1.fna.whatsapp.net", "media.fpku1-2.fna.whatsapp.net", "media.fros9-1.fna.whatsapp.net", "status_v3_text", "usync_sidelist", "17", "announcement", "...", "md_group_notification", "0f", "animated_pack_in_store", "013", "America/Mexico_City", "1260", "media-ams4-1.cdn.whatsapp.net", "media-cgk1-2.cdn.whatsapp.net", "media-cpt1-1.cdn.whatsapp.net", "media-maa2-1.cdn.whatsapp.net", "media.fgye10-1.fna.whatsapp.net", "e", "catalog_cart", "hfm_string_changes", "init_bitrate", "packless_hsm", "group_info", "America/Belem", "50", "960", "cond_range_bwe", "decode", "encode", "media.fada1-8.fna.whatsapp.net", "media.fadb1-2.fna.whatsapp.net", "media.fasu6-1.fna.whatsapp.net", "media.fbog4-1.fna.whatsapp.net", "media.fcgk9-2.fna.whatsapp.net", "media.fdoh5-2.fna.whatsapp.net", "media.ffjr1-2.fna.whatsapp.net", "media.fgua1-1.fna.whatsapp.net", "media.fgye1-1.fna.whatsapp.net", "media.fist1-4.fna.whatsapp.net", "media.fpbc2-2.fna.whatsapp.net", "media.fres2-1.fna.whatsapp.net", "media.fsdq1-2.fna.whatsapp.net", "media.fsub6-5.fna.whatsapp.net", "profilo_enabled", "template_hsm", "use_disorder_prefetching_timer", "video_codec_priority", "vpx_max_qp", "ptt_reduce_recording_delay", "25", "iphone", "Windows", "s_o", "Africa/Lagos", "abt", "media-kut2-1.cdn.whatsapp.net", "media-mba1-1.cdn.whatsapp.net", "media-mxp1-2.cdn.whatsapp.net", "md_blocklist_v2", "url_text", "enable_short_offset", "group_join_permissions", "enable_audio_piggyback_feature", "image_quality", "media.fcgk7-2.fna.whatsapp.net", "media.fcgk8-2.fna.whatsapp.net", "media.fclo7-1.fna.whatsapp.net", "media.fcmn1-1.fna.whatsapp.net", "media.feoh1-1.fna.whatsapp.net", "media.fgyd4-3.fna.whatsapp.net", "media.fjed4-4.fna.whatsapp.net", "media.flim1-4.fna.whatsapp.net", "media.flim2-4.fna.whatsapp.net", "media.fplu6-1.fna.whatsapp.net", "media.frak1-1.fna.whatsapp.net", "media.fsdq1-1.fna.whatsapp.net", "to_ip", "015", "vp8", "19", "21", "1320", "auth_key_ver", "message_processing_dedup", "server-error", "wap4_enabled", "420", "014", "cond_range_rtt", "ptt_fast_lock_enabled", "media-ort2-1.cdn.whatsapp.net", "fwd_ui_start_ts"]; - -export const DICTIONARY_3_TOKEN = ["contact_blacklist", "Asia/Jakarta", "media.fepa10-1.fna.whatsapp.net", "media.fmex10-3.fna.whatsapp.net", "disorder_prefetching_start_when_empty", "America/Bogota", "use_local_probing_rx_bitrate", "America/Argentina/Buenos_Aires", "cross_post", "media.fabb1-1.fna.whatsapp.net", "media.fbog4-2.fna.whatsapp.net", "media.fcgk9-1.fna.whatsapp.net", "media.fcmn2-1.fna.whatsapp.net", "media.fdel3-1.fna.whatsapp.net", "media.ffjr1-1.fna.whatsapp.net", "media.fgdl5-1.fna.whatsapp.net", "media.flpb1-2.fna.whatsapp.net", "media.fmex2-1.fna.whatsapp.net", "media.frba2-2.fna.whatsapp.net", "media.fros2-2.fna.whatsapp.net", "media.fruh2-1.fna.whatsapp.net", "media.fybz2-2.fna.whatsapp.net", "options", "20", "a", "017", "018", "mute_always", "user_notice", "Asia/Kolkata", "gif_provider", "locked", "media-gua1-1.cdn.whatsapp.net", "piggyback_exclude_force_flush", "24", "media.frec39-1.fna.whatsapp.net", "user_remove", "file_max_size", "cond_packet_loss_pct_ema_alpha", "media.facc1-1.fna.whatsapp.net", "media.fadb2-1.fna.whatsapp.net", "media.faly3-1.fna.whatsapp.net", "media.fbdo6-2.fna.whatsapp.net", "media.fcmn2-2.fna.whatsapp.net", "media.fctg1-3.fna.whatsapp.net", "media.ffez1-2.fna.whatsapp.net", "media.fist1-3.fna.whatsapp.net", "media.fist2-2.fna.whatsapp.net", "media.flim2-2.fna.whatsapp.net", "media.fmct2-3.fna.whatsapp.net", "media.fpei3-1.fna.whatsapp.net", "media.frba3-1.fna.whatsapp.net", "media.fsdu8-2.fna.whatsapp.net", "media.fstu2-1.fna.whatsapp.net", "media_type", "receipt_agg", "016", "enable_pli_for_crc_mismatch", "live", "enc_rekey", "frskmsg", "d", "media.fdel11-2.fna.whatsapp.net", "proto", "2250", "audio_piggyback_enable_cache", "skip_nack_if_ltrp_sent", "mark_dtx_jb_frames", "web_service_delay", "7282", "catalog_send_all", "outgoing", "360", "30", "LIMITED", "019", "audio_picker", "bpv2_phase", "media.fada1-7.fna.whatsapp.net", "media.faep7-1.fna.whatsapp.net", "media.fbko1-2.fna.whatsapp.net", "media.fbni1-2.fna.whatsapp.net", "media.fbtz1-1.fna.whatsapp.net", "media.fbtz1-8.fna.whatsapp.net", "media.fcjs3-1.fna.whatsapp.net", "media.fesb3-2.fna.whatsapp.net", "media.fgdl5-4.fna.whatsapp.net", "media.fist2-1.fna.whatsapp.net", "media.flhe2-2.fna.whatsapp.net", "media.flim2-1.fna.whatsapp.net", "media.fmex1-1.fna.whatsapp.net", "media.fpat3-2.fna.whatsapp.net", "media.fpat3-3.fna.whatsapp.net", "media.fros2-1.fna.whatsapp.net", "media.fsdu8-1.fna.whatsapp.net", "media.fsub3-2.fna.whatsapp.net", "payments_chat_plugin", "cond_congestion_no_rtcp_thr", "green_alert", "not-a-biz", "..", "shops_pdp_urls_config", "source", "media-dus1-1.cdn.whatsapp.net", "mute_video", "01b", "currency", "max_keys", "resume_check", "contact_array", "qr_scanning", "23", "b", "media.fbfh15-1.fna.whatsapp.net", "media.flim22-1.fna.whatsapp.net", "media.fsdu11-1.fna.whatsapp.net", "media.fsdu15-1.fna.whatsapp.net", "Chrome", "fts_version", "60", "media.fada1-6.fna.whatsapp.net", "media.faep4-2.fna.whatsapp.net", "media.fbaq5-1.fna.whatsapp.net", "media.fbni1-1.fna.whatsapp.net", "media.fcai3-2.fna.whatsapp.net", "media.fdel3-2.fna.whatsapp.net", "media.fdmm3-2.fna.whatsapp.net", "media.fhex3-1.fna.whatsapp.net", "media.fisb4-2.fna.whatsapp.net", "media.fkhi5-2.fna.whatsapp.net", "media.flos2-1.fna.whatsapp.net", "media.fmct2-1.fna.whatsapp.net", "media.fntr7-1.fna.whatsapp.net", "media.frak3-1.fna.whatsapp.net", "media.fruh5-2.fna.whatsapp.net", "media.fsub6-1.fna.whatsapp.net", "media.fuab1-2.fna.whatsapp.net", "media.fuio1-1.fna.whatsapp.net", "media.fver1-1.fna.whatsapp.net", "media.fymy1-1.fna.whatsapp.net", "product_catalog", "1380", "audio_oob_fec_max_pkts", "22", "254", "media-ort2-2.cdn.whatsapp.net", "media-sjc3-1.cdn.whatsapp.net", "1600", "01a", "01c", "405", "key_frame_interval", "body", "media.fcgh20-1.fna.whatsapp.net", "media.fesb10-2.fna.whatsapp.net", "125", "2000", "media.fbsb1-1.fna.whatsapp.net", "media.fcmn3-2.fna.whatsapp.net", "media.fcpq1-1.fna.whatsapp.net", "media.fdel1-2.fna.whatsapp.net", "media.ffor2-1.fna.whatsapp.net", "media.fgdl1-4.fna.whatsapp.net", "media.fhex2-1.fna.whatsapp.net", "media.fist1-2.fna.whatsapp.net", "media.fjed5-2.fna.whatsapp.net", "media.flim6-4.fna.whatsapp.net", "media.flos2-2.fna.whatsapp.net", "media.fntr6-2.fna.whatsapp.net", "media.fpku3-2.fna.whatsapp.net", "media.fros8-1.fna.whatsapp.net", "media.fymy1-2.fna.whatsapp.net", "ul_bw", "ltrp_qp_offset", "request", "nack", "dtx_delay_state_reset", "timeoffline", "28", "01f", "32", "enable_ltr_pool", "wa_msys_crypto", "01d", "58", "dtx_freeze_hg_update", "nack_if_rpsi_throttled", "253", "840", "media.famd15-1.fna.whatsapp.net", "media.fbog17-2.fna.whatsapp.net", "media.fcai19-2.fna.whatsapp.net", "media.fcai21-4.fna.whatsapp.net", "media.fesb10-4.fna.whatsapp.net", "media.fesb10-5.fna.whatsapp.net", "media.fmaa12-1.fna.whatsapp.net", "media.fmex11-3.fna.whatsapp.net", "media.fpoa33-1.fna.whatsapp.net", "1050", "021", "clean", "cond_range_ema_packet_loss_pct", "media.fadb6-5.fna.whatsapp.net", "media.faqp4-1.fna.whatsapp.net", "media.fbaq3-1.fna.whatsapp.net", "media.fbel2-1.fna.whatsapp.net", "media.fblr4-2.fna.whatsapp.net", "media.fclo8-1.fna.whatsapp.net", "media.fcoo1-2.fna.whatsapp.net", "media.ffjr1-4.fna.whatsapp.net", "media.ffor9-1.fna.whatsapp.net", "media.fisb3-1.fna.whatsapp.net", "media.fkhi2-2.fna.whatsapp.net", "media.fkhi4-1.fna.whatsapp.net", "media.fpbc1-2.fna.whatsapp.net", "media.fruh2-2.fna.whatsapp.net", "media.fruh5-1.fna.whatsapp.net", "media.fsub3-1.fna.whatsapp.net", "payments_transaction_limit", "252", "27", "29", "tintagel", "01e", "237", "780", "callee_updated_payload", "020", "257", "price", "025", "239", "payments_cs_phone_number", "mediaretry", "w:auth:backup:token", "Glass.caf", "max_bitrate", "240", "251", "660", "media.fbog16-1.fna.whatsapp.net", "media.fcgh21-1.fna.whatsapp.net", "media.fkul19-2.fna.whatsapp.net", "media.flim21-2.fna.whatsapp.net", "media.fmex10-4.fna.whatsapp.net", "64", "33", "34", "35", "interruption", "media.fabv3-1.fna.whatsapp.net", "media.fadb6-1.fna.whatsapp.net", "media.fagr1-1.fna.whatsapp.net", "media.famd1-1.fna.whatsapp.net", "media.famm6-1.fna.whatsapp.net", "media.faqp2-3.fna.whatsapp.net"]; -export const DICTIONARIES = [DICTIONARY_0_TOKEN, DICTIONARY_1_TOKEN, DICTIONARY_2_TOKEN, DICTIONARY_3_TOKEN]; - -export const buildMap = (data) => { +const buildMap = (data) => { const map = new Map(); for (let r = 0; r < data.length; r++) { map.set(data[r], r); @@ -17,5 +8,15 @@ export const buildMap = (data) => { return map; } -export const SINGLE_BYTE_TOKEN_MAP = buildMap(SINGLE_BYTE_TOKEN); -export const DICTIONARIES_MAP = DICTIONARIES.map((dict) => buildMap(dict)) \ No newline at end of file +module.exports.DEVICE = { PRIMARY_DEVICE: 0, PRIMARY_VERSION: 0 } + +module.exports.SINGLE_BYTE_TOKEN = ["xmlstreamstart", "xmlstreamend", "s.whatsapp.net", "type", "participant", "from", "receipt", "id", "broadcast", "status", "message", "notification", "notify", "to", "jid", "user", "class", "offline", "g.us", "result", "mediatype", "enc", "skmsg", "off_cnt", "xmlns", "presence", "participants", "ack", "t", "iq", "device_hash", "read", "value", "media", "picture", "chatstate", "unavailable", "text", "urn:xmpp:whatsapp:push", "devices", "verified_name", "contact", "composing", "edge_routing", "routing_info", "item", "image", "verified_level", "get", "fallback_hostname", "2", "media_conn", "1", "v", "handshake", "fallback_class", "count", "config", "offline_preview", "download_buckets", "w:profile:picture", "set", "creation", "location", "fallback_ip4", "msg", "urn:xmpp:ping", "fallback_ip6", "call-creator", "relaylatency", "success", "subscribe", "video", "business_hours_config", "platform", "hostname", "version", "unknown", "0", "ping", "hash", "edit", "subject", "max_buckets", "download", "delivery", "props", "sticker", "name", "last", "contacts", "business", "primary", "preview", "w:p", "pkmsg", "call-id", "retry", "prop", "call", "auth_ttl", "available", "relay_id", "last_id", "day_of_week", "w", "host", "seen", "bits", "list", "atn", "upload", "is_new", "w:stats", "key", "paused", "specific_hours", "multicast", "stream:error", "mmg.whatsapp.net", "code", "deny", "played", "profile", "fna", "device-list", "close_time", "latency", "gcm", "pop", "audio", "26", "w:web", "open_time", "error", "auth", "ip4", "update", "profile_options", "config_value", "category", "catalog_not_created", "00", "config_code", "mode", "catalog_status", "ip6", "blocklist", "registration", "7", "web", "fail", "w:m", "cart_enabled", "ttl", "gif", "300", "device_orientation", "identity", "query", "401", "media-gig2-1.cdn.whatsapp.net", "in", "3", "te2", "add", "fallback", "categories", "ptt", "encrypt", "notice", "thumbnail-document", "item-not-found", "12", "thumbnail-image", "stage", "thumbnail-link", "usync", "out", "thumbnail-video", "8", "01", "context", "sidelist", "thumbnail-gif", "terminate", "not-authorized", "orientation", "dhash", "capability", "side_list", "md-app-state", "description", "serial", "readreceipts", "te", "business_hours", "md-msg-hist", "tag", "attribute_padding", "document", "open_24h", "delete", "expiration", "active", "prev_v_id", "true", "passive", "index", "4", "conflict", "remove", "w:gp2", "config_expo_key", "screen_height", "replaced", "02", "screen_width", "uploadfieldstat", "2:47DEQpj8", "media-bog1-1.cdn.whatsapp.net", "encopt", "url", "catalog_exists", "keygen", "rate", "offer", "opus", "media-mia3-1.cdn.whatsapp.net", "privacy", "media-mia3-2.cdn.whatsapp.net", "signature", "preaccept", "token_id", "media-eze1-1.cdn.whatsapp.net"]; +module.exports.DICTIONARY_0_TOKEN = ["media-for1-1.cdn.whatsapp.net", "relay", "media-gru2-2.cdn.whatsapp.net", "uncompressed", "medium", "voip_settings", "device", "reason", "media-lim1-1.cdn.whatsapp.net", "media-qro1-2.cdn.whatsapp.net", "media-gru1-2.cdn.whatsapp.net", "action", "features", "media-gru2-1.cdn.whatsapp.net", "media-gru1-1.cdn.whatsapp.net", "media-otp1-1.cdn.whatsapp.net", "kyc-id", "priority", "phash", "mute", "token", "100", "media-qro1-1.cdn.whatsapp.net", "none", "media-mrs2-2.cdn.whatsapp.net", "sign_credential", "03", "media-mrs2-1.cdn.whatsapp.net", "protocol", "timezone", "transport", "eph_setting", "1080", "original_dimensions", "media-frx5-1.cdn.whatsapp.net", "background", "disable", "original_image_url", "5", "transaction-id", "direct_path", "103", "appointment_only", "request_image_url", "peer_pid", "address", "105", "104", "102", "media-cdt1-1.cdn.whatsapp.net", "101", "109", "110", "106", "background_location", "v_id", "sync", "status-old", "111", "107", "ppic", "media-scl2-1.cdn.whatsapp.net", "business_profile", "108", "invite", "04", "audio_duration", "media-mct1-1.cdn.whatsapp.net", "media-cdg2-1.cdn.whatsapp.net", "media-los2-1.cdn.whatsapp.net", "invis", "net", "voip_payload_type", "status-revoke-delay", "404", "state", "use_correct_order_for_hmac_sha1", "ver", "media-mad1-1.cdn.whatsapp.net", "order", "540", "skey", "blinded_credential", "android", "contact_remove", "enable_downlink_relay_latency_only", "duration", "enable_vid_one_way_codec_nego", "6", "media-sof1-1.cdn.whatsapp.net", "accept", "all", "signed_credential", "media-atl3-1.cdn.whatsapp.net", "media-lhr8-1.cdn.whatsapp.net", "website", "05", "latitude", "media-dfw5-1.cdn.whatsapp.net", "forbidden", "enable_audio_piggyback_network_mtu_fix", "media-dfw5-2.cdn.whatsapp.net", "note.m4r", "media-atl3-2.cdn.whatsapp.net", "jb_nack_discard_count_fix", "longitude", "Opening.m4r", "media-arn2-1.cdn.whatsapp.net", "email", "timestamp", "admin", "media-pmo1-1.cdn.whatsapp.net", "America/Sao_Paulo", "contact_add", "media-sin6-1.cdn.whatsapp.net", "interactive", "8000", "acs_public_key", "sigquit_anr_detector_release_rollover_percent", "media.fmed1-2.fna.whatsapp.net", "groupadd", "enabled_for_video_upgrade", "latency_update_threshold", "media-frt3-2.cdn.whatsapp.net", "calls_row_constraint_layout", "media.fgbb2-1.fna.whatsapp.net", "mms4_media_retry_notification_encryption_enabled", "timeout", "media-sin6-3.cdn.whatsapp.net", "audio_nack_jitter_multiplier", "jb_discard_count_adjust_pct_rc", "audio_reserve_bps", "delta", "account_sync", "default", "media.fjed4-6.fna.whatsapp.net", "06", "lock_video_orientation", "media-frt3-1.cdn.whatsapp.net", "w:g2", "media-sin6-2.cdn.whatsapp.net", "audio_nack_algo_mask", "media.fgbb2-2.fna.whatsapp.net", "media.fmed1-1.fna.whatsapp.net", "cond_range_target_bitrate", "mms4_server_error_receipt_encryption_enabled", "vid_rc_dyn", "fri", "cart_v1_1_order_message_changes_enabled", "reg_push", "jb_hist_deposit_value", "privatestats", "media.fist7-2.fna.whatsapp.net", "thu", "jb_discard_count_adjust_pct", "mon", "group_call_video_maximization_enabled", "mms_cat_v1_forward_hot_override_enabled", "audio_nack_new_rtt", "media.fsub2-3.fna.whatsapp.net", "media_upload_aggressive_retry_exponential_backoff_enabled", "tue", "wed", "media.fruh4-2.fna.whatsapp.net", "audio_nack_max_seq_req", "max_rtp_audio_packet_resends", "jb_hist_max_cdf_value", "07", "audio_nack_max_jb_delay", "mms_forward_partially_downloaded_video", "media-lcy1-1.cdn.whatsapp.net", "resume", "jb_inband_fec_aware", "new_commerce_entry_point_enabled", "480", "payments_upi_generate_qr_amount_limit", "sigquit_anr_detector_rollover_percent", "media.fsdu2-1.fna.whatsapp.net", "fbns", "aud_pkt_reorder_pct", "dec", "stop_probing_before_accept_send", "media_upload_max_aggressive_retries", "edit_business_profile_new_mode_enabled", "media.fhex4-1.fna.whatsapp.net", "media.fjed4-3.fna.whatsapp.net", "sigquit_anr_detector_64bit_rollover_percent", "cond_range_ema_jb_last_delay", "watls_enable_early_data_http_get", "media.fsdu2-2.fna.whatsapp.net", "message_qr_disambiguation_enabled", "media-mxp1-1.cdn.whatsapp.net", "sat", "vertical", "media.fruh4-5.fna.whatsapp.net", "200", "media-sof1-2.cdn.whatsapp.net", "-1", "height", "product_catalog_hide_show_items_enabled", "deep_copy_frm_last", "tsoffline", "vp8/h.264", "media.fgye5-3.fna.whatsapp.net", "media.ftuc1-2.fna.whatsapp.net", "smb_upsell_chat_banner_enabled", "canonical", "08", "9", ".", "media.fgyd4-4.fna.whatsapp.net", "media.fsti4-1.fna.whatsapp.net", "mms_vcache_aggregation_enabled", "mms_hot_content_timespan_in_seconds", "nse_ver", "rte", "third_party_sticker_web_sync", "cond_range_target_total_bitrate", "media_upload_aggressive_retry_enabled", "instrument_spam_report_enabled", "disable_reconnect_tone", "move_media_folder_from_sister_app", "one_tap_calling_in_group_chat_size", "10", "storage_mgmt_banner_threshold_mb", "enable_backup_passive_mode", "sharechat_inline_player_enabled", "media.fcnq2-1.fna.whatsapp.net", "media.fhex4-2.fna.whatsapp.net", "media.fist6-3.fna.whatsapp.net", "ephemeral_drop_column_stage", "reconnecting_after_network_change_threshold_ms", "media-lhr8-2.cdn.whatsapp.net", "cond_jb_last_delay_ema_alpha", "entry_point_block_logging_enabled", "critical_event_upload_log_config", "respect_initial_bitrate_estimate", "smaller_image_thumbs_status_enabled", "media.fbtz1-4.fna.whatsapp.net", "media.fjed4-1.fna.whatsapp.net", "width", "720", "enable_frame_dropper", "enable_one_side_mode", "urn:xmpp:whatsapp:dirty", "new_sticker_animation_behavior_v2", "media.flim3-2.fna.whatsapp.net", "media.fuio6-2.fna.whatsapp.net", "skip_forced_signaling", "dleq_proof", "status_video_max_bitrate", "lazy_send_probing_req", "enhanced_storage_management", "android_privatestats_endpoint_dit_enabled", "media.fscl13-2.fna.whatsapp.net", "video_duration"]; +module.exports.DICTIONARY_1_TOKEN = ["group_call_discoverability_enabled", "media.faep9-2.fna.whatsapp.net", "msgr", "bloks_loggedin_access_app_id", "db_status_migration_step", "watls_prefer_ip6", "jabber:iq:privacy", "68", "media.fsaw1-11.fna.whatsapp.net", "mms4_media_conn_persist_enabled", "animated_stickers_thread_clean_up", "media.fcgk3-2.fna.whatsapp.net", "media.fcgk4-6.fna.whatsapp.net", "media.fgye5-2.fna.whatsapp.net", "media.flpb1-1.fna.whatsapp.net", "media.fsub2-1.fna.whatsapp.net", "media.fuio6-3.fna.whatsapp.net", "not-allowed", "partial_pjpeg_bw_threshold", "cap_estimated_bitrate", "mms_chatd_resume_check_over_thrift", "smb_upsell_business_profile_enabled", "product_catalog_webclient", "groups", "sigquit_anr_detector_release_updated_rollout", "syncd_key_rotation_enabled", "media.fdmm2-1.fna.whatsapp.net", "media-hou1-1.cdn.whatsapp.net", "remove_old_chat_notifications", "smb_biztools_deeplink_enabled", "use_downloadable_filters_int", "group_qr_codes_enabled", "max_receipt_processing_time", "optimistic_image_processing_enabled", "smaller_video_thumbs_status_enabled", "watls_early_data", "reconnecting_before_relay_failover_threshold_ms", "cond_range_packet_loss_pct", "groups_privacy_blacklist", "status-revoke-drop", "stickers_animated_thumbnail_download", "dedupe_transcode_shared_images", "dedupe_transcode_shared_videos", "media.fcnq2-2.fna.whatsapp.net", "media.fgyd4-1.fna.whatsapp.net", "media.fist7-1.fna.whatsapp.net", "media.flim3-3.fna.whatsapp.net", "add_contact_by_qr_enabled", "https://faq.whatsapp.com/payments", "multicast_limit_global", "sticker_notification_preview", "smb_better_catalog_list_adapters_enabled", "bloks_use_minscript_android", "pen_smoothing_enabled", "media.fcgk4-5.fna.whatsapp.net", "media.fevn1-3.fna.whatsapp.net", "media.fpoj7-1.fna.whatsapp.net", "media-arn2-2.cdn.whatsapp.net", "reconnecting_before_network_change_threshold_ms", "android_media_use_fresco_for_gifs", "cond_in_congestion", "status_image_max_edge", "sticker_search_enabled", "starred_stickers_web_sync", "db_blank_me_jid_migration_step", "media.fist6-2.fna.whatsapp.net", "media.ftuc1-1.fna.whatsapp.net", "09", "anr_fast_logs_upload_rollout", "camera_core_integration_enabled", "11", "third_party_sticker_caching", "thread_dump_contact_support", "wam_privatestats_enabled", "vcard_as_document_size_kb", "maxfpp", "fbip", "ephemeral_allow_group_members", "media-bom1-2.cdn.whatsapp.net", "media-xsp1-1.cdn.whatsapp.net", "disable_prewarm", "frequently_forwarded_max", "media.fbtz1-5.fna.whatsapp.net", "media.fevn7-1.fna.whatsapp.net", "media.fgyd4-2.fna.whatsapp.net", "sticker_tray_animation_fully_visible_items", "green_alert_banner_duration", "reconnecting_after_p2p_failover_threshold_ms", "connected", "share_biz_vcard_enabled", "stickers_animation", "0a", "1200", "WhatsApp", "group_description_length", "p_v_id", "payments_upi_intent_transaction_limit", "frequently_forwarded_messages", "media-xsp1-2.cdn.whatsapp.net", "media.faep8-1.fna.whatsapp.net", "media.faep8-2.fna.whatsapp.net", "media.faep9-1.fna.whatsapp.net", "media.fdmm2-2.fna.whatsapp.net", "media.fgzt3-1.fna.whatsapp.net", "media.flim4-2.fna.whatsapp.net", "media.frao1-1.fna.whatsapp.net", "media.fscl9-2.fna.whatsapp.net", "media.fsub2-2.fna.whatsapp.net", "superadmin", "media.fbog10-1.fna.whatsapp.net", "media.fcgh28-1.fna.whatsapp.net", "media.fjdo10-1.fna.whatsapp.net", "third_party_animated_sticker_import", "delay_fec", "attachment_picker_refresh", "android_linked_devices_re_auth_enabled", "rc_dyn", "green_alert_block_jitter", "add_contact_logging_enabled", "biz_message_logging_enabled", "conversation_media_preview_v2", "media-jnb1-1.cdn.whatsapp.net", "ab_key", "media.fcgk4-2.fna.whatsapp.net", "media.fevn1-1.fna.whatsapp.net", "media.fist6-1.fna.whatsapp.net", "media.fruh4-4.fna.whatsapp.net", "media.fsti4-2.fna.whatsapp.net", "mms_vcard_autodownload_size_kb", "watls_enabled", "notif_ch_override_off", "media.fsaw1-14.fna.whatsapp.net", "media.fscl13-1.fna.whatsapp.net", "db_group_participant_migration_step", "1020", "cond_range_sterm_rtt", "invites_logging_enabled", "triggered_block_enabled", "group_call_max_participants", "media-iad3-1.cdn.whatsapp.net", "product_catalog_open_deeplink", "shops_required_tos_version", "image_max_kbytes", "cond_low_quality_vid_mode", "db_receipt_migration_step", "jb_early_prob_hist_shrink", "media.fdmm2-3.fna.whatsapp.net", "media.fdmm2-4.fna.whatsapp.net", "media.fruh4-1.fna.whatsapp.net", "media.fsaw2-2.fna.whatsapp.net", "remove_geolocation_videos", "new_animation_behavior", "fieldstats_beacon_chance", "403", "authkey_reset_on_ban", "continuous_ptt_playback", "reconnecting_after_relay_failover_threshold_ms", "false", "group", "sun", "conversation_swipe_to_reply", "ephemeral_messages_setting", "smaller_video_thumbs_enabled", "md_device_sync_enabled", "bloks_shops_pdp_url_regex", "lasso_integration_enabled", "media-bom1-1.cdn.whatsapp.net", "new_backup_format_enabled", "256", "media.faep6-1.fna.whatsapp.net", "media.fasr1-1.fna.whatsapp.net", "media.fbtz1-7.fna.whatsapp.net", "media.fesb4-1.fna.whatsapp.net", "media.fjdo1-2.fna.whatsapp.net", "media.frba2-1.fna.whatsapp.net", "watls_no_dns", "600", "db_broadcast_me_jid_migration_step", "new_wam_runtime_enabled", "group_update", "enhanced_block_enabled", "sync_wifi_threshold_kb", "mms_download_nc_cat", "bloks_minification_enabled", "ephemeral_messages_enabled", "reject", "voip_outgoing_xml_signaling", "creator", "dl_bw", "payments_request_messages", "target_bitrate", "bloks_rendercore_enabled", "media-hbe1-1.cdn.whatsapp.net", "media-hel3-1.cdn.whatsapp.net", "media-kut2-2.cdn.whatsapp.net", "media-lax3-1.cdn.whatsapp.net", "media-lax3-2.cdn.whatsapp.net", "sticker_pack_deeplink_enabled", "hq_image_bw_threshold", "status_info", "voip", "dedupe_transcode_videos", "grp_uii_cleanup", "linked_device_max_count", "media.flim1-1.fna.whatsapp.net", "media.fsaw2-1.fna.whatsapp.net", "reconnecting_after_call_active_threshold_ms", "1140", "catalog_pdp_new_design", "media.fbtz1-10.fna.whatsapp.net", "media.fsaw1-15.fna.whatsapp.net", "0b", "consumer_rc_provider", "mms_async_fast_forward_ttl", "jb_eff_size_fix", "voip_incoming_xml_signaling", "media_provider_share_by_uuid", "suspicious_links", "dedupe_transcode_images", "green_alert_modal_start", "media-cgk1-1.cdn.whatsapp.net", "media-lga3-1.cdn.whatsapp.net", "template_doc_mime_types", "important_messages", "user_add", "vcard_max_size_kb", "media.fada2-1.fna.whatsapp.net", "media.fbog2-5.fna.whatsapp.net", "media.fbtz1-3.fna.whatsapp.net", "media.fcgk3-1.fna.whatsapp.net", "media.fcgk7-1.fna.whatsapp.net", "media.flim1-3.fna.whatsapp.net", "media.fscl9-1.fna.whatsapp.net", "ctwa_context_enterprise_enabled", "media.fsaw1-13.fna.whatsapp.net", "media.fuio11-2.fna.whatsapp.net", "status_collapse_muted", "db_migration_level_force", "recent_stickers_web_sync", "bloks_session_state", "bloks_shops_enabled", "green_alert_setting_deep_links_enabled", "restrict_groups", "battery", "green_alert_block_start", "refresh", "ctwa_context_enabled", "md_messaging_enabled", "status_image_quality", "md_blocklist_v2_server", "media-del1-1.cdn.whatsapp.net", "13", "userrate", "a_v_id", "cond_rtt_ema_alpha", "invalid"]; +module.exports.DICTIONARY_2_TOKEN = ["media.fada1-1.fna.whatsapp.net", "media.fadb3-2.fna.whatsapp.net", "media.fbhz2-1.fna.whatsapp.net", "media.fcor2-1.fna.whatsapp.net", "media.fjed4-2.fna.whatsapp.net", "media.flhe4-1.fna.whatsapp.net", "media.frak1-2.fna.whatsapp.net", "media.fsub6-3.fna.whatsapp.net", "media.fsub6-7.fna.whatsapp.net", "media.fvvi1-1.fna.whatsapp.net", "search_v5_eligible", "wam_real_time_enabled", "report_disk_event", "max_tx_rott_based_bitrate", "product", "media.fjdo10-2.fna.whatsapp.net", "video_frame_crc_sample_interval", "media_max_autodownload", "15", "h.264", "wam_privatestats_buffer_count", "md_phash_v2_enabled", "account_transfer_enabled", "business_product_catalog", "enable_non_dyn_codec_param_fix", "is_user_under_epd_jurisdiction", "media.fbog2-4.fna.whatsapp.net", "media.fbtz1-2.fna.whatsapp.net", "media.fcfc1-1.fna.whatsapp.net", "media.fjed4-5.fna.whatsapp.net", "media.flhe4-2.fna.whatsapp.net", "media.flim1-2.fna.whatsapp.net", "media.flos5-1.fna.whatsapp.net", "android_key_store_auth_ver", "010", "anr_process_monitor", "delete_old_auth_key", "media.fcor10-3.fna.whatsapp.net", "storage_usage_enabled", "android_camera2_support_level", "dirty", "consumer_content_provider", "status_video_max_duration", "0c", "bloks_cache_enabled", "media.fadb2-2.fna.whatsapp.net", "media.fbko1-1.fna.whatsapp.net", "media.fbtz1-9.fna.whatsapp.net", "media.fcgk4-4.fna.whatsapp.net", "media.fesb4-2.fna.whatsapp.net", "media.fevn1-2.fna.whatsapp.net", "media.fist2-4.fna.whatsapp.net", "media.fjdo1-1.fna.whatsapp.net", "media.fruh4-6.fna.whatsapp.net", "media.fsrg5-1.fna.whatsapp.net", "media.fsub6-6.fna.whatsapp.net", "minfpp", "5000", "locales", "video_max_bitrate", "use_new_auth_key", "bloks_http_enabled", "heartbeat_interval", "media.fbog11-1.fna.whatsapp.net", "ephemeral_group_query_ts", "fec_nack", "search_in_storage_usage", "c", "media-amt2-1.cdn.whatsapp.net", "linked_devices_ui_enabled", "14", "async_data_load_on_startup", "voip_incoming_xml_ack", "16", "db_migration_step", "init_bwe", "max_participants", "wam_buffer_count", "media.fada2-2.fna.whatsapp.net", "media.fadb3-1.fna.whatsapp.net", "media.fcor2-2.fna.whatsapp.net", "media.fdiy1-2.fna.whatsapp.net", "media.frba3-2.fna.whatsapp.net", "media.fsaw2-3.fna.whatsapp.net", "1280", "status_grid_enabled", "w:biz", "product_catalog_deeplink", "media.fgye10-2.fna.whatsapp.net", "media.fuio11-1.fna.whatsapp.net", "optimistic_upload", "work_manager_init", "lc", "catalog_message", "cond_net_medium", "enable_periodical_aud_rr_processing", "cond_range_ema_rtt", "media-tir2-1.cdn.whatsapp.net", "frame_ms", "group_invite_sending", "payments_web_enabled", "wallpapers_v2", "0d", "browser", "hq_image_max_edge", "image_edit_zoom", "linked_devices_re_auth_enabled", "media.faly3-2.fna.whatsapp.net", "media.fdoh5-3.fna.whatsapp.net", "media.fesb3-1.fna.whatsapp.net", "media.fknu1-1.fna.whatsapp.net", "media.fmex3-1.fna.whatsapp.net", "media.fruh4-3.fna.whatsapp.net", "255", "web_upgrade_to_md_modal", "audio_piggyback_timeout_msec", "enable_audio_oob_fec_feature", "from_ip", "image_max_edge", "message_qr_enabled", "powersave", "receipt_pre_acking", "video_max_edge", "full", "011", "012", "enable_audio_oob_fec_for_sender", "md_voip_enabled", "enable_privatestats", "max_fec_ratio", "payments_cs_faq_url", "media-xsp1-3.cdn.whatsapp.net", "hq_image_quality", "media.fasr1-2.fna.whatsapp.net", "media.fbog3-1.fna.whatsapp.net", "media.ffjr1-6.fna.whatsapp.net", "media.fist2-3.fna.whatsapp.net", "media.flim4-3.fna.whatsapp.net", "media.fpbc2-4.fna.whatsapp.net", "media.fpku1-1.fna.whatsapp.net", "media.frba1-1.fna.whatsapp.net", "media.fudi1-1.fna.whatsapp.net", "media.fvvi1-2.fna.whatsapp.net", "gcm_fg_service", "enable_dec_ltr_size_check", "clear", "lg", "media.fgru11-1.fna.whatsapp.net", "18", "media-lga3-2.cdn.whatsapp.net", "pkey", "0e", "max_subject", "cond_range_lterm_rtt", "announcement_groups", "biz_profile_options", "s_t", "media.fabv2-1.fna.whatsapp.net", "media.fcai3-1.fna.whatsapp.net", "media.fcgh1-1.fna.whatsapp.net", "media.fctg1-4.fna.whatsapp.net", "media.fdiy1-1.fna.whatsapp.net", "media.fisb4-1.fna.whatsapp.net", "media.fpku1-2.fna.whatsapp.net", "media.fros9-1.fna.whatsapp.net", "status_v3_text", "usync_sidelist", "17", "announcement", "...", "md_group_notification", "0f", "animated_pack_in_store", "013", "America/Mexico_City", "1260", "media-ams4-1.cdn.whatsapp.net", "media-cgk1-2.cdn.whatsapp.net", "media-cpt1-1.cdn.whatsapp.net", "media-maa2-1.cdn.whatsapp.net", "media.fgye10-1.fna.whatsapp.net", "e", "catalog_cart", "hfm_string_changes", "init_bitrate", "packless_hsm", "group_info", "America/Belem", "50", "960", "cond_range_bwe", "decode", "encode", "media.fada1-8.fna.whatsapp.net", "media.fadb1-2.fna.whatsapp.net", "media.fasu6-1.fna.whatsapp.net", "media.fbog4-1.fna.whatsapp.net", "media.fcgk9-2.fna.whatsapp.net", "media.fdoh5-2.fna.whatsapp.net", "media.ffjr1-2.fna.whatsapp.net", "media.fgua1-1.fna.whatsapp.net", "media.fgye1-1.fna.whatsapp.net", "media.fist1-4.fna.whatsapp.net", "media.fpbc2-2.fna.whatsapp.net", "media.fres2-1.fna.whatsapp.net", "media.fsdq1-2.fna.whatsapp.net", "media.fsub6-5.fna.whatsapp.net", "profilo_enabled", "template_hsm", "use_disorder_prefetching_timer", "video_codec_priority", "vpx_max_qp", "ptt_reduce_recording_delay", "25", "iphone", "Windows", "s_o", "Africa/Lagos", "abt", "media-kut2-1.cdn.whatsapp.net", "media-mba1-1.cdn.whatsapp.net", "media-mxp1-2.cdn.whatsapp.net", "md_blocklist_v2", "url_text", "enable_short_offset", "group_join_permissions", "enable_audio_piggyback_feature", "image_quality", "media.fcgk7-2.fna.whatsapp.net", "media.fcgk8-2.fna.whatsapp.net", "media.fclo7-1.fna.whatsapp.net", "media.fcmn1-1.fna.whatsapp.net", "media.feoh1-1.fna.whatsapp.net", "media.fgyd4-3.fna.whatsapp.net", "media.fjed4-4.fna.whatsapp.net", "media.flim1-4.fna.whatsapp.net", "media.flim2-4.fna.whatsapp.net", "media.fplu6-1.fna.whatsapp.net", "media.frak1-1.fna.whatsapp.net", "media.fsdq1-1.fna.whatsapp.net", "to_ip", "015", "vp8", "19", "21", "1320", "auth_key_ver", "message_processing_dedup", "server-error", "wap4_enabled", "420", "014", "cond_range_rtt", "ptt_fast_lock_enabled", "media-ort2-1.cdn.whatsapp.net", "fwd_ui_start_ts"]; + +module.exports.DICTIONARY_3_TOKEN = ["contact_blacklist", "Asia/Jakarta", "media.fepa10-1.fna.whatsapp.net", "media.fmex10-3.fna.whatsapp.net", "disorder_prefetching_start_when_empty", "America/Bogota", "use_local_probing_rx_bitrate", "America/Argentina/Buenos_Aires", "cross_post", "media.fabb1-1.fna.whatsapp.net", "media.fbog4-2.fna.whatsapp.net", "media.fcgk9-1.fna.whatsapp.net", "media.fcmn2-1.fna.whatsapp.net", "media.fdel3-1.fna.whatsapp.net", "media.ffjr1-1.fna.whatsapp.net", "media.fgdl5-1.fna.whatsapp.net", "media.flpb1-2.fna.whatsapp.net", "media.fmex2-1.fna.whatsapp.net", "media.frba2-2.fna.whatsapp.net", "media.fros2-2.fna.whatsapp.net", "media.fruh2-1.fna.whatsapp.net", "media.fybz2-2.fna.whatsapp.net", "options", "20", "a", "017", "018", "mute_always", "user_notice", "Asia/Kolkata", "gif_provider", "locked", "media-gua1-1.cdn.whatsapp.net", "piggyback_exclude_force_flush", "24", "media.frec39-1.fna.whatsapp.net", "user_remove", "file_max_size", "cond_packet_loss_pct_ema_alpha", "media.facc1-1.fna.whatsapp.net", "media.fadb2-1.fna.whatsapp.net", "media.faly3-1.fna.whatsapp.net", "media.fbdo6-2.fna.whatsapp.net", "media.fcmn2-2.fna.whatsapp.net", "media.fctg1-3.fna.whatsapp.net", "media.ffez1-2.fna.whatsapp.net", "media.fist1-3.fna.whatsapp.net", "media.fist2-2.fna.whatsapp.net", "media.flim2-2.fna.whatsapp.net", "media.fmct2-3.fna.whatsapp.net", "media.fpei3-1.fna.whatsapp.net", "media.frba3-1.fna.whatsapp.net", "media.fsdu8-2.fna.whatsapp.net", "media.fstu2-1.fna.whatsapp.net", "media_type", "receipt_agg", "016", "enable_pli_for_crc_mismatch", "live", "enc_rekey", "frskmsg", "d", "media.fdel11-2.fna.whatsapp.net", "proto", "2250", "audio_piggyback_enable_cache", "skip_nack_if_ltrp_sent", "mark_dtx_jb_frames", "web_service_delay", "7282", "catalog_send_all", "outgoing", "360", "30", "LIMITED", "019", "audio_picker", "bpv2_phase", "media.fada1-7.fna.whatsapp.net", "media.faep7-1.fna.whatsapp.net", "media.fbko1-2.fna.whatsapp.net", "media.fbni1-2.fna.whatsapp.net", "media.fbtz1-1.fna.whatsapp.net", "media.fbtz1-8.fna.whatsapp.net", "media.fcjs3-1.fna.whatsapp.net", "media.fesb3-2.fna.whatsapp.net", "media.fgdl5-4.fna.whatsapp.net", "media.fist2-1.fna.whatsapp.net", "media.flhe2-2.fna.whatsapp.net", "media.flim2-1.fna.whatsapp.net", "media.fmex1-1.fna.whatsapp.net", "media.fpat3-2.fna.whatsapp.net", "media.fpat3-3.fna.whatsapp.net", "media.fros2-1.fna.whatsapp.net", "media.fsdu8-1.fna.whatsapp.net", "media.fsub3-2.fna.whatsapp.net", "payments_chat_plugin", "cond_congestion_no_rtcp_thr", "green_alert", "not-a-biz", "..", "shops_pdp_urls_config", "source", "media-dus1-1.cdn.whatsapp.net", "mute_video", "01b", "currency", "max_keys", "resume_check", "contact_array", "qr_scanning", "23", "b", "media.fbfh15-1.fna.whatsapp.net", "media.flim22-1.fna.whatsapp.net", "media.fsdu11-1.fna.whatsapp.net", "media.fsdu15-1.fna.whatsapp.net", "Chrome", "fts_version", "60", "media.fada1-6.fna.whatsapp.net", "media.faep4-2.fna.whatsapp.net", "media.fbaq5-1.fna.whatsapp.net", "media.fbni1-1.fna.whatsapp.net", "media.fcai3-2.fna.whatsapp.net", "media.fdel3-2.fna.whatsapp.net", "media.fdmm3-2.fna.whatsapp.net", "media.fhex3-1.fna.whatsapp.net", "media.fisb4-2.fna.whatsapp.net", "media.fkhi5-2.fna.whatsapp.net", "media.flos2-1.fna.whatsapp.net", "media.fmct2-1.fna.whatsapp.net", "media.fntr7-1.fna.whatsapp.net", "media.frak3-1.fna.whatsapp.net", "media.fruh5-2.fna.whatsapp.net", "media.fsub6-1.fna.whatsapp.net", "media.fuab1-2.fna.whatsapp.net", "media.fuio1-1.fna.whatsapp.net", "media.fver1-1.fna.whatsapp.net", "media.fymy1-1.fna.whatsapp.net", "product_catalog", "1380", "audio_oob_fec_max_pkts", "22", "254", "media-ort2-2.cdn.whatsapp.net", "media-sjc3-1.cdn.whatsapp.net", "1600", "01a", "01c", "405", "key_frame_interval", "body", "media.fcgh20-1.fna.whatsapp.net", "media.fesb10-2.fna.whatsapp.net", "125", "2000", "media.fbsb1-1.fna.whatsapp.net", "media.fcmn3-2.fna.whatsapp.net", "media.fcpq1-1.fna.whatsapp.net", "media.fdel1-2.fna.whatsapp.net", "media.ffor2-1.fna.whatsapp.net", "media.fgdl1-4.fna.whatsapp.net", "media.fhex2-1.fna.whatsapp.net", "media.fist1-2.fna.whatsapp.net", "media.fjed5-2.fna.whatsapp.net", "media.flim6-4.fna.whatsapp.net", "media.flos2-2.fna.whatsapp.net", "media.fntr6-2.fna.whatsapp.net", "media.fpku3-2.fna.whatsapp.net", "media.fros8-1.fna.whatsapp.net", "media.fymy1-2.fna.whatsapp.net", "ul_bw", "ltrp_qp_offset", "request", "nack", "dtx_delay_state_reset", "timeoffline", "28", "01f", "32", "enable_ltr_pool", "wa_msys_crypto", "01d", "58", "dtx_freeze_hg_update", "nack_if_rpsi_throttled", "253", "840", "media.famd15-1.fna.whatsapp.net", "media.fbog17-2.fna.whatsapp.net", "media.fcai19-2.fna.whatsapp.net", "media.fcai21-4.fna.whatsapp.net", "media.fesb10-4.fna.whatsapp.net", "media.fesb10-5.fna.whatsapp.net", "media.fmaa12-1.fna.whatsapp.net", "media.fmex11-3.fna.whatsapp.net", "media.fpoa33-1.fna.whatsapp.net", "1050", "021", "clean", "cond_range_ema_packet_loss_pct", "media.fadb6-5.fna.whatsapp.net", "media.faqp4-1.fna.whatsapp.net", "media.fbaq3-1.fna.whatsapp.net", "media.fbel2-1.fna.whatsapp.net", "media.fblr4-2.fna.whatsapp.net", "media.fclo8-1.fna.whatsapp.net", "media.fcoo1-2.fna.whatsapp.net", "media.ffjr1-4.fna.whatsapp.net", "media.ffor9-1.fna.whatsapp.net", "media.fisb3-1.fna.whatsapp.net", "media.fkhi2-2.fna.whatsapp.net", "media.fkhi4-1.fna.whatsapp.net", "media.fpbc1-2.fna.whatsapp.net", "media.fruh2-2.fna.whatsapp.net", "media.fruh5-1.fna.whatsapp.net", "media.fsub3-1.fna.whatsapp.net", "payments_transaction_limit", "252", "27", "29", "tintagel", "01e", "237", "780", "callee_updated_payload", "020", "257", "price", "025", "239", "payments_cs_phone_number", "mediaretry", "w:auth:backup:token", "Glass.caf", "max_bitrate", "240", "251", "660", "media.fbog16-1.fna.whatsapp.net", "media.fcgh21-1.fna.whatsapp.net", "media.fkul19-2.fna.whatsapp.net", "media.flim21-2.fna.whatsapp.net", "media.fmex10-4.fna.whatsapp.net", "64", "33", "34", "35", "interruption", "media.fabv3-1.fna.whatsapp.net", "media.fadb6-1.fna.whatsapp.net", "media.fagr1-1.fna.whatsapp.net", "media.famd1-1.fna.whatsapp.net", "media.famm6-1.fna.whatsapp.net", "media.faqp2-3.fna.whatsapp.net"]; +module.exports.DICTIONARIES = [module.exports.DICTIONARY_0_TOKEN, module.exports.DICTIONARY_1_TOKEN, module.exports.DICTIONARY_2_TOKEN, module.exports.DICTIONARY_3_TOKEN]; + +module.exports.SINGLE_BYTE_TOKEN_MAP = buildMap(module.exports.SINGLE_BYTE_TOKEN); +module.exports.DICTIONARIES_MAP = module.exports.DICTIONARIES.map((dict) => buildMap(dict)) \ No newline at end of file diff --git a/WABinary/HexHelper.js b/WABinary/HexHelper.js index 3ecadb8..e274291 100644 --- a/WABinary/HexHelper.js +++ b/WABinary/HexHelper.js @@ -1,4 +1,4 @@ -import * as Crypto from "crypto"; +const { randomBytes } = require('crypto') const r = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70], a = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102]; @@ -36,19 +36,19 @@ const d = (e) => { return o((e >= 0 ? e : 4294967296 + e).toString(16), 8); }; -export const NUM_HEX_IN_LONG = 16; -export const HEX_LOWER = a; +module.exports.NUM_HEX_IN_LONG = 16; +module.exports.HEX_LOWER = a; -export const randomHex = function (e) { +module.exports.randomHex = function (e) { var t = new Uint8Array(e); - var bytes = Crypto.randomBytes(t.length); + var bytes = randomBytes(t.length); t.set(bytes); return i(t); }; -export const toHex = i; +module.exports.toHex = i; -export const toLowerCaseHex = function (e) { +module.exports.toLowerCaseHex = function (e) { for (var t = [], r = 0; r < e.length; r++) { var i = e[r]; t.push(a[i >> 4], a[15 & i]); @@ -56,7 +56,7 @@ export const toLowerCaseHex = function (e) { return String.fromCharCode.apply(String, t); }; -export const parseHex = function (e) { +module.exports.parseHex = function (e) { var t = s(e); if (t.length % 2 != 0) throw new Error( @@ -71,16 +71,16 @@ export const parseHex = function (e) { return r.buffer; }; -export const hexAt = n; -export const hexOrThrow = s; -export const bytesToBuffer = function (e) { +module.exports.hexAt = n; +module.exports.hexOrThrow = s; +module.exports.bytesToBuffer = function (e) { var t = e.buffer; return 0 === e.byteOffset && e.length === t.byteLength ? t : t.slice(e.byteOffset, e.byteOffset + e.length); }; -export const bytesToDebugString = function (e) { +module.exports.bytesToDebugString = function (e) { var t = !0, r = e.length; for (; t && r; ) { @@ -90,7 +90,7 @@ export const bytesToDebugString = function (e) { return t ? JSON.stringify(String.fromCharCode.apply(String, e)) : i(e); }; -export const createHexLong = function (e, t = !1) { +module.exports.createHexLong = function (e, t = !1) { var r = s(e); return ( (function (e, t) { @@ -100,18 +100,18 @@ export const createHexLong = function (e, t = !1) { ); }; -export const createHexLongFrom32Bits = function (e, t, r = !1) { +module.exports.createHexLongFrom32Bits = function (e, t, r = !1) { var a = d(e), i = d(t); return `${r ? "-" : ""}0x${a}${i}`; }; -export const hexLongToHex = function (e) { +module.exports.hexLongToHex = function (e) { return e.substring(e.indexOf("0x") + 2); }; -export const hexLongIsNegative = l; +module.exports.hexLongIsNegative = l; -export const negateHexLong = function (e) { +module.exports.negateHexLong = function (e) { return l(e) ? e.slice(1) : "-" + e; }; diff --git a/package.json b/package.json index 06b5ebd..e5d085b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@adiwajshing/baileys", "version": "4.0.0", - "description": "WhatsApp Web API", + "description": "WhatsApp Multi-Device API", "homepage": "https://github.com/adiwajshing/Baileys", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -13,7 +13,8 @@ "whatsapp", "whatsapp-chat", "whatsapp-group", - "automation" + "automation", + "multi-device" ], "scripts": { "test": "mocha --timeout 240000 -r ts-node/register src/Tests/Tests.*.ts", diff --git a/src/WABinary/LTHash.js b/src/WABinary/LTHash.js index c902c60..bc29567 100644 --- a/src/WABinary/LTHash.js +++ b/src/WABinary/LTHash.js @@ -1,4 +1,4 @@ -import { hkdf } from "../Utils/generics"; +const { hkdf } = require("../Utils/generics"); const o = 128; @@ -45,4 +45,4 @@ class d { return a } } -export const LT_HASH_ANTI_TAMPERING = new d('WhatsApp Patch Integrity') \ No newline at end of file +module.exports.LT_HASH_ANTI_TAMPERING = new d('WhatsApp Patch Integrity') \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 382ac74..34c7507 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ "target": "es2018", "module": "commonjs", "experimentalDecorators": true, - "allowJs": true, + "allowJs": false, "checkJs": false, "outDir": "lib", "strict": false, @@ -14,6 +14,6 @@ "declaration": true, "lib": ["es2020", "esnext.array"] }, - "include": ["src/**/*.ts"], + "include": ["./src/**/*.ts"], "exclude": ["node_modules", "src/Tests/*", "src/Binary/GenerateStatics.ts"] } From 89c819859b1d96fb965e55924bba589c3a820011 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 25 Sep 2021 21:23:40 +0530 Subject: [PATCH 053/311] add waitForConnectionUpdate --- src/Socket/socket.ts | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 309a1f1..bceaf68 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -4,7 +4,7 @@ import { promisify } from "util" import WebSocket from "ws" import { randomBytes } from 'crypto' import { proto } from '../../WAProto' -import { DisconnectReason, SocketConfig, BaileysEventEmitter } from "../Types" +import { DisconnectReason, SocketConfig, BaileysEventEmitter, ConnectionState } from "../Types" import { Curve, initAuthState, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout } from "../Utils" import { DEFAULT_ORIGIN, DEF_TAG_PREFIX, DEF_CALLBACK_PREFIX, KEY_BUNDLE_TYPE } from "../Defaults" import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, S_WHATSAPP_NET } from '../WABinary' @@ -366,6 +366,28 @@ export const makeSocket = ({ }) end(new Boom('Intentional Logout', { statusCode: DisconnectReason.loggedOut })) } + /** Waits for the connection to WA to reach a state */ + const waitForConnectionUpdate = async(check: (u: Partial) => boolean, timeoutMs?: number) => { + let listener: (item: Partial) => void + await ( + promiseTimeout( + timeoutMs, + (resolve, reject) => { + listener = (update) => { + if(check(update)) { + resolve() + } else if(update.connection == 'close') { + reject(update.lastDisconnect?.error || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) + } + } + ev.on('connection.update', listener) + } + ) + .finally(() => ( + ev.off('connection.update', listener) + )) + ) + } ws.on('message', onMessageRecieved) ws.on('open', validateConnection) @@ -463,7 +485,8 @@ export const makeSocket = ({ sendRawMessage, sendNode, logout, - end + end, + waitForConnectionUpdate } } export type Socket = ReturnType \ No newline at end of file From 1f6ef554c23d18d75bad1417dcf957e5aa48e85c Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 25 Sep 2021 23:01:58 +0530 Subject: [PATCH 054/311] fix lthash not being included in lib --- src/WABinary/{LTHash.js => LTHash.ts} | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) rename src/WABinary/{LTHash.js => LTHash.ts} (86%) diff --git a/src/WABinary/LTHash.js b/src/WABinary/LTHash.ts similarity index 86% rename from src/WABinary/LTHash.js rename to src/WABinary/LTHash.ts index bc29567..b11053b 100644 --- a/src/WABinary/LTHash.js +++ b/src/WABinary/LTHash.ts @@ -1,9 +1,12 @@ -const { hkdf } = require("../Utils/generics"); +import { hkdf } from '../Utils' const o = 128; class d { - constructor(e) { + + salt: string + + constructor(e: string) { this.salt = e } add(e, t) { @@ -45,4 +48,4 @@ class d { return a } } -module.exports.LT_HASH_ANTI_TAMPERING = new d('WhatsApp Patch Integrity') \ No newline at end of file +export const LT_HASH_ANTI_TAMPERING = new d('WhatsApp Patch Integrity') \ No newline at end of file From 070d4eebcca64c319eb6e0fb9bca65716213620b Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 25 Sep 2021 23:30:59 +0530 Subject: [PATCH 055/311] respect printQRInTerminal --- src/Socket/socket.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index bceaf68..3bb2472 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -25,7 +25,8 @@ export const makeSocket = ({ keepAliveIntervalMs, version, browser, - auth: initialAuthState + auth: initialAuthState, + printQRInTerminal, }: SocketConfig) => { const ws = new WebSocket(waWebSocketUrl, undefined, { origin: DEFAULT_ORIGIN, @@ -400,10 +401,12 @@ export const makeSocket = ({ // QR gen ws.on('CB:iq,type:set,pair-device', async (stanza: BinaryNode) => { const postQR = async() => { - const QR = await import('qrcode-terminal').catch(err => { - logger.error('add `qrcode-terminal` as a dependency to auto-print QR') - }) - QR?.generate(qr, { small: true }) + if(printQRInTerminal) { + const QR = await import('qrcode-terminal').catch(err => { + logger.error('add `qrcode-terminal` as a dependency to auto-print QR') + }) + QR?.generate(qr, { small: true }) + } } const refs = ((stanza.content[0] as BinaryNode).content as BinaryNode[]).map(n => n.content as string) From a46a07fe45c5fe2c7a2504d4277fc4de3b3ebc93 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 26 Sep 2021 12:35:33 +0530 Subject: [PATCH 056/311] remove keyed-db as dependency --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index e5d085b..a38f513 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ "ws": "^7.3.1" }, "optionalDependencies": { - "@adiwajshing/keyed-db": "^0.2.4", "qrcode-terminal": "^0.12.0" }, "files": [ @@ -53,7 +52,6 @@ "WABinary/*" ], "devDependencies": { - "@adiwajshing/keyed-db": "^0.2.4", "@types/got": "^9.6.11", "@types/jest": "^26.0.24", "@types/node": "^14.6.2", From 23101f87a14bcb4a4389aa38afd20be33dd05395 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 26 Sep 2021 12:35:56 +0530 Subject: [PATCH 057/311] move appstatesynckey to keys --- src/Socket/chats.ts | 16 +++++++------- src/Socket/messages-recv.ts | 15 ++++++------- src/Types/Auth.ts | 6 ++++-- src/Types/Chat.ts | 2 ++ src/Utils/chat-utils.ts | 37 +++++++++++++++++--------------- src/Utils/crypto.ts | 2 +- src/Utils/validate-connection.ts | 15 ++++++++++++- yarn.lock | 5 ----- 8 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index a3c4b25..8052a5b 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1,5 +1,5 @@ import { decodeSyncdPatch, encodeSyncdPatch } from "../Utils/chat-utils"; -import { SocketConfig, WAPresence, PresenceData, Chat, ChatModification, WAMediaUpload } from "../Types"; +import { SocketConfig, WAPresence, PresenceData, Chat, ChatModification, WAMediaUpload, ChatMutation } from "../Types"; import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET } from "../WABinary"; import { makeSocket } from "./socket"; import { proto } from '../../WAProto' @@ -278,7 +278,7 @@ export const makeChatsSocket = (config: SocketConfig) => { } } - const processSyncActions = (actions: { action: proto.ISyncActionValue, index: [string, string] }[]) => { + const processSyncActions = (actions: ChatMutation[]) => { const updates: Partial[] = [] for(const { action, index: [_, id] } of actions) { const update: Partial = { id } @@ -309,7 +309,7 @@ export const makeChatsSocket = (config: SocketConfig) => { jid: string, modification: ChatModification ) => { - const patch = encodeSyncdPatch(modification, { remoteJid: jid }, authState) + const patch = await encodeSyncdPatch(modification, { remoteJid: jid }, authState) const type = 'regular_high' const ver = authState.creds.appStateVersion![type] || 0 const node: BinaryNode = { @@ -373,24 +373,24 @@ export const makeChatsSocket = (config: SocketConfig) => { const patchesNode = getBinaryNodeChild(collectionNode, 'patches') const patches = getBinaryNodeChildren(patchesNode, 'patch') - const successfulMutations = patches.flatMap(({ content }) => { + const successfulMutations: ChatMutation[] = [] + for(const { content } of patches) { if(content) { const syncd = proto.SyncdPatch.decode(content! as Uint8Array) const version = toNumber(syncd.version!.version!) if(version) { authState.creds.appStateVersion[name] = Math.max(version, authState.creds.appStateVersion[name]) } - const { mutations, failures } = decodeSyncdPatch(syncd, authState) + const { mutations, failures } = await decodeSyncdPatch(syncd, authState) if(failures.length) { logger.info( { failures: failures.map(f => ({ trace: f.stack, data: f.data })) }, 'failed to decode' ) } - return mutations + successfulMutations.push(...mutations) } - return [] - }) + } processSyncActions(successfulMutations) ev.emit('auth-state.update', authState) } diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 33c68da..095a098 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -99,16 +99,15 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { }) } - const processMessage = (message: proto.IWebMessageInfo, chatUpdate: Partial) => { + const processMessage = async(message: proto.IWebMessageInfo, chatUpdate: Partial) => { const protocolMsg = message.message?.protocolMessage if(protocolMsg) { switch(protocolMsg.type) { case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_SHARE: - const newKeys = JSON.parse(JSON.stringify(protocolMsg.appStateSyncKeyShare!.keys)) - authState.creds.appStateSyncKeys = [ - ...(authState.creds.appStateSyncKeys || []), - ...newKeys - ] + for(const { keyData, keyId } of protocolMsg.appStateSyncKeyShare!.keys || []) { + const str = Buffer.from(keyId.keyId!).toString('base64') + await authState.keys.setAppStateSyncKey(str, keyData) + } ev.emit('auth-state.update', authState) break case proto.ProtocolMessage.ProtocolMessageType.REVOKE: @@ -417,10 +416,10 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } }) - ev.on('messages.upsert', ({ messages }) => { + ev.on('messages.upsert', async({ messages }) => { const chat: Partial = { id: messages[0].key.remoteJid } for(const msg of messages) { - processMessage(msg, chat) + await processMessage(msg, chat) if(!!msg.message && !msg.message!.protocolMessage) { chat.conversationTimestamp = toNumber(msg.messageTimestamp) if(!msg.key.fromMe) { diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts index 5ff963e..eeb7c97 100644 --- a/src/Types/Auth.ts +++ b/src/Types/Auth.ts @@ -24,11 +24,10 @@ export type AuthenticationCreds = { me?: Contact account?: proto.ADVSignedDeviceIdentity signalIdentities?: SignalIdentity[] - appStateSyncKeys?: proto.IAppStateSyncKey[] appStateVersion?: { [T in CollectionType]: number } - + myAppStateKeyId?: string firstUnuploadedPreKeyId: number serverHasPreKeys: boolean nextPreKeyId: number @@ -43,6 +42,9 @@ export type SignalKeyStore = { getSenderKey: (id: string) => Awaitable setSenderKey: (id: string, item: any | null) => Awaitable + + getAppStateSyncKey: (id: string) => Awaitable + setAppStateSyncKey: (id: string, item: proto.IAppStateSyncKeyData | null) => Awaitable } export type AuthenticationState = { diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 3fbad52..c6cd774 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -8,6 +8,8 @@ export interface PresenceData { lastSeen?: number } +export type ChatMutation = { action: proto.ISyncActionValue, index: [string, string] } + export type Chat = Omit & { /** unix timestamp of date when mute ends, if applicable */ mute?: number | null diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 35c02b6..0ed8a28 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -1,13 +1,13 @@ import { Boom } from '@hapi/boom' import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./crypto" -import { AuthenticationState, ChatModification } from "../Types" +import { AuthenticationState, ChatModification, ChatMutation } from "../Types" import { proto } from '../../WAProto' import { LT_HASH_ANTI_TAMPERING } from '../WABinary/LTHash' type SyncdType = 'regular_high' | 'regular_low' -const mutationKeys = (keydata: string) => { - const expanded = hkdf(Buffer.from(keydata, 'base64'), 160, { info: 'WhatsApp Mutation Keys' }) +const mutationKeys = (keydata: Uint8Array) => { + const expanded = hkdf(keydata, 160, { info: 'WhatsApp Mutation Keys' }) return { indexKey: expanded.slice(0, 32), valueEncryptionKey: expanded.slice(32, 64), @@ -73,7 +73,7 @@ const generatePatchMac = (snapshotMac: Uint8Array, valueMacs: Uint8Array[], vers return hmacSign(total, key) } -export const encodeSyncdPatch = (action: ChatModification, lastMessageKey: proto.IMessageKey, { creds: { appStateSyncKeys: [key], appStateVersion } }: AuthenticationState) => { +export const encodeSyncdPatch = async(action: ChatModification, lastMessageKey: proto.IMessageKey, { creds: { appStateVersion, myAppStateKeyId }, keys }: AuthenticationState) => { let syncAction: proto.ISyncActionValue = { } if('archive' in action) { syncAction.archiveChatAction = { @@ -101,12 +101,18 @@ export const encodeSyncdPatch = (action: ChatModification, lastMessageKey: proto } const encoded = proto.SyncActionValue.encode(syncAction).finish() + const key = !!myAppStateKeyId ? await keys.getAppStateSyncKey(myAppStateKeyId) : undefined + if(!key) { + throw new Boom(`myAppStateKey not present`, { statusCode: 404 }) + } + + const encKeyId = Buffer.from(myAppStateKeyId, 'base64') const index = JSON.stringify([Object.keys(action)[0], lastMessageKey.remoteJid]) - const keyValue = mutationKeys(key.keyData!.keyData! as any) + const keyValue = mutationKeys(key!.keyData!) const encValue = aesEncrypt(encoded, keyValue.valueEncryptionKey) - const macValue = generateMac(1, encValue, key.keyId!.keyId, keyValue.valueMacKey) + const macValue = generateMac(1, encValue, encKeyId, keyValue.valueMacKey) const indexMacValue = hmacSign(Buffer.from(index), keyValue.indexKey) const type = 'regular_high' @@ -117,7 +123,7 @@ export const encodeSyncdPatch = (action: ChatModification, lastMessageKey: proto const patch: proto.ISyncdPatch = { patchMac: generatePatchMac(snapshotMac, [macValue], v, type, keyValue.patchMacKey), snapshotMac: snapshotMac, - keyId: { id: key.keyId.keyId }, + keyId: { id: encKeyId }, mutations: [ { operation: 1, @@ -128,7 +134,7 @@ export const encodeSyncdPatch = (action: ChatModification, lastMessageKey: proto value: { blob: Buffer.concat([ encValue, macValue ]) }, - keyId: { id: key.keyId.keyId } + keyId: { id: encKeyId } } } ] @@ -136,27 +142,24 @@ export const encodeSyncdPatch = (action: ChatModification, lastMessageKey: proto return patch } -export const decodeSyncdPatch = (msg: proto.ISyncdPatch, {creds}: AuthenticationState) => { +export const decodeSyncdPatch = async(msg: proto.ISyncdPatch, {keys}: AuthenticationState) => { const keyCache: { [_: string]: ReturnType } = { } - const getKey = (keyId: Uint8Array) => { + const getKey = async(keyId: Uint8Array) => { const base64Key = Buffer.from(keyId!).toString('base64') - let key = keyCache[base64Key] if(!key) { - const keyEnc = creds.appStateSyncKeys?.find(k => ( - (k.keyId!.keyId as any) === base64Key - )) + const keyEnc = await keys.getAppStateSyncKey(base64Key) if(!keyEnc) { throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500, data: msg }) } - const result = mutationKeys(keyEnc.keyData!.keyData as any) + const result = mutationKeys(keyEnc.keyData!) keyCache[base64Key] = result key = result } return key } - const mutations: { action: proto.ISyncActionValue, index: [string, string] }[] = [] + const mutations: ChatMutation[] = [] const failures: Boom[] = [] /*const mainKey = getKey(msg.keyId!.id) @@ -171,7 +174,7 @@ export const decodeSyncdPatch = (msg: proto.ISyncdPatch, {creds}: Authentication // the remaining record.value.blob[0:-32] is the mac, it the HMAC sign of key.keyId + decoded proto data + length of bytes in keyId for(const { operation, record } of msg.mutations!) { try { - const key = getKey(record.keyId!.id!) + const key = await getKey(record.keyId!.id!) const content = Buffer.from(record.value!.blob!) const encContent = content.slice(0, -32) const contentHmac = generateMac(operation, encContent, record.keyId!.id!, key.valueMacKey) diff --git a/src/Utils/crypto.ts b/src/Utils/crypto.ts index 201ae7e..02e8f08 100644 --- a/src/Utils/crypto.ts +++ b/src/Utils/crypto.ts @@ -70,7 +70,7 @@ export function sha256(buffer: Buffer) { } // HKDF key expansion // from: https://github.com/benadida/node-hkdf -export function hkdf(buffer: Buffer, expandedLength: number, { info, salt }: { salt?: Buffer, info?: string }) { +export function hkdf(buffer: Uint8Array, expandedLength: number, { info, salt }: { salt?: Buffer, info?: string }) { const hashAlg = 'sha256' const hashLength = 32 salt = salt || Buffer.alloc(hashLength) diff --git a/src/Utils/validate-connection.ts b/src/Utils/validate-connection.ts index 02446e1..b327d31 100644 --- a/src/Utils/validate-connection.ts +++ b/src/Utils/validate-connection.ts @@ -83,19 +83,22 @@ export const generateRegistrationNode = ( } export const initInMemoryKeyStore = ( - { preKeys, sessions, senderKeys }: { + { preKeys, sessions, senderKeys, appStateSyncKeys }: { preKeys?: { [k: number]: KeyPair }, sessions?: { [k: string]: any }, senderKeys?: { [k: string]: any } + appStateSyncKeys?: { [k: string]: proto.IAppStateSyncKeyData } } = { }, ) => { preKeys = preKeys || { } sessions = sessions || { } senderKeys = senderKeys || { } + appStateSyncKeys = appStateSyncKeys || { } return { preKeys, sessions, senderKeys, + appStateSyncKeys, getPreKey: keyId => preKeys[keyId], setPreKey: (keyId, pair) => { if(pair) preKeys[keyId] = pair @@ -112,6 +115,16 @@ export const initInMemoryKeyStore = ( setSenderKey: (id, item) => { if(item) senderKeys[id] = item else delete senderKeys[id] + }, + getAppStateSyncKey: id => { + const obj = appStateSyncKeys[id] + if(obj) { + return proto.AppStateSyncKeyData.fromObject(obj) + } + }, + setAppStateSyncKey: (id, item) => { + if(item) appStateSyncKeys[id] = item + else delete appStateSyncKeys[id] } } as SignalKeyStore } diff --git a/yarn.lock b/yarn.lock index e4c9a2a..42d1dd5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,6 @@ # yarn lockfile v1 -"@adiwajshing/keyed-db@^0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@adiwajshing/keyed-db/-/keyed-db-0.2.4.tgz#2a09e88fce20b2672deb60a7750c5fe3ab0dfd99" - integrity sha512-yprSnAtj80/VKuDqRcFFLDYltoNV8tChNwFfIgcf6PGD4sjzWIBgs08pRuTqGH5mk5wgL6PBRSsMCZqtZwzFEw== - "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" From 192f8705a765afd895443189c5e50697f289b518 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 26 Sep 2021 18:04:53 +0530 Subject: [PATCH 058/311] respect message ID --- src/Socket/messages-send.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 509c4f4..1f3f582 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -381,7 +381,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { upload: waUploadToServer } ) - await relayMessage(jid, fullMsg.message) + await relayMessage(jid, fullMsg.message, options.messageId) process.nextTick(() => { ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) }) From a1aa17bc35f0eadd27f6b1afa3d4667cb12a1b6d Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 26 Sep 2021 22:36:07 +0530 Subject: [PATCH 059/311] fix msg id override not being respected --- src/Socket/messages-send.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 1f3f582..cdfda83 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -65,13 +65,13 @@ export const makeMessagesSocket = (config: SocketConfig) => { if(participant) { node.attrs.participant = participant } - messageIds = messageIds.slice(1) - if(messageIds.length) { + const remainingMessageIds = messageIds.slice(1) + if(remainingMessageIds.length) { node.content = [ { tag: 'list', attrs: { }, - content: messageIds.map(id => ({ + content: remainingMessageIds.map(id => ({ tag: 'item', attrs: { id } })) @@ -177,6 +177,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { const { user, server } = jidDecode(jid) const isGroup = server === 'g.us' msgId = msgId || generateMessageID() + const encodedMsg = encodeWAMessage(message) const participants: BinaryNode[] = [] let stanza: BinaryNode @@ -381,7 +382,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { upload: waUploadToServer } ) - await relayMessage(jid, fullMsg.message, options.messageId) + await relayMessage(jid, fullMsg.message, fullMsg.key.id!) process.nextTick(() => { ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) }) From 91bbab54c4af5826041c6a13b6abb31b206f6e2d Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 26 Sep 2021 22:36:15 +0530 Subject: [PATCH 060/311] fix delivery receipt --- src/Socket/messages-recv.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 095a098..75ee003 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -381,7 +381,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } ws.on('CB:receipt,type:read', handleReceipt) - ws.on('CB:ack,class:receipt', handleReceipt) + ws.on('CB:ack,class:message', handleReceipt) ws.on('CB:notification', async(node: BinaryNode) => { const sendAck = async() => { From 7b7fcafb03b3d22a068626c68d9e4d31a401f57a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 26 Sep 2021 22:36:28 +0530 Subject: [PATCH 061/311] privacy setting returns correctly --- src/Socket/chats.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 8052a5b..6991aac 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -155,9 +155,19 @@ export const makeChatsSocket = (config: SocketConfig) => { xmlns: 'privacy', to: S_WHATSAPP_NET, type: 'get' - } + }, + content: [ + { tag: 'privacy', attrs: { } } + ] }) - console.log('privacy', result) + const nodes = getBinaryNodeChildren(result, 'category') + const settings = nodes.reduce( + (dict, { attrs }) => { + dict[attrs.name] = attrs.value + return dict + }, { } as { [_: string]: string } + ) + return settings } const updateAccountSyncTimestamp = async() => { From 2c99a4a8ede674727152d03b4fc4591e2991c09b Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 26 Sep 2021 22:36:36 +0530 Subject: [PATCH 062/311] read message in example --- Example/example.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Example/example.ts b/Example/example.ts index 266f6d6..8f86430 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -38,13 +38,14 @@ import makeWASocket, { WASocket, AuthenticationState, DisconnectReason, AnyMessa logger: P({ level: 'trace' }), auth: loadState() }) - sock.ev.on('messages.upsert', m => { + sock.ev.on('messages.upsert', async m => { console.log(JSON.stringify(m, undefined, 2)) const msg = m.messages[0] if(!msg.key.fromMe && m.type === 'notify') { console.log('replying to', m.messages[0].key.remoteJid) - sendMessageWTyping({ text: 'Hello there!' }, m.messages[0].key.remoteJid!) + await sock!.sendReadReceipt(msg.key.remoteJid, msg.key.participant, [msg.key.id]) + await sendMessageWTyping({ text: 'Hello there!' }, msg.key.remoteJid) } }) From 17e915e273e4a687c99c0271be0145d5773a1812 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 26 Sep 2021 23:00:34 +0530 Subject: [PATCH 063/311] rename package to baileys-md --- README.md | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 4fa4a5f..3a3ff47 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ yarn add github:adiwajshing/baileys#multi-device Then import in your code using: ``` ts -import makeWASocket from '@adiwajshing/baileys' +import makeWASocket from '@adiwajshing/baileys-md' ``` ## Unit Tests @@ -41,7 +41,7 @@ TODO ## Connecting ``` ts -import makeWASocket from '@adiwajshing/baileys' +import makeWASocket from '@adiwajshing/baileys-md' async function connectToWhatsApp () { const conn = makeWASocket({ @@ -119,7 +119,7 @@ You obviously don't want to keep scanning the QR code every time you want to con So, you can save the credentials to log back in via: ``` ts -import makeWASocket, { BufferJSON } from '@adiwajshing/baileys' +import makeWASocket, { BufferJSON } from '@adiwajshing/baileys-md' import * as fs from 'fs' // will initialize a default in-memory auth session @@ -139,7 +139,7 @@ conn.ev.on ('auth-state.update', () => { Then, to restore a session: ``` ts -import makeWASocket, { BufferJSON, initInMemoryKeyStore } from '@adiwajshing/baileys' +import makeWASocket, { BufferJSON, initInMemoryKeyStore } from '@adiwajshing/baileys-md' import * as fs from 'fs' const authJSON = JSON.parse( @@ -248,7 +248,7 @@ sock.ev.on('messages.upsert', ({ messages }) => { ### Non-Media Messages ``` ts -import { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys' +import { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys-md' const id = 'abcd@s.whatsapp.net' // the WhatsApp ID // send a simple text! @@ -283,7 +283,7 @@ Sending media (video, stickers, images) is easier & more efficient than ever. - When specifying a media url, Baileys never loads the entire buffer into memory, it even encrypts the media as a readable stream. ``` ts -import { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys' +import { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys-md' // Sending gifs await conn.sendMessage( id, @@ -338,7 +338,7 @@ await conn.sendMessage( Do not enter this field if you want to automatically generate a thumb */ mimetype: Mimetype.pdf, /* (for media messages) specify the type of media (optional for all media types except documents), - import {Mimetype} from '@adiwajshing/baileys' + import {Mimetype} from '@adiwajshing/baileys-md' */ filename: 'somefile.pdf', // (for media messages) file name for the media /* will send audio messages as voice notes, if set to true */ @@ -391,7 +391,7 @@ The presence expires after about 10 seconds. If you want to save the media you received ``` ts -import { MessageType } from '@adiwajshing/baileys' +import { MessageType } from '@adiwajshing/baileys-md' conn.on ('message-new', async m => { if (!m.message) return // if there is no text or media message const messageType = Object.keys (m.message)[0]// get what type of message it is -- text, image, video diff --git a/package.json b/package.json index a38f513..6c0a9f7 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@adiwajshing/baileys", + "name": "@adiwajshing/baileys-md", "version": "4.0.0", "description": "WhatsApp Multi-Device API", "homepage": "https://github.com/adiwajshing/Baileys", From 8988694d34f90c1e5dffce60f693ca64e904cb4c Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 26 Sep 2021 23:05:01 +0530 Subject: [PATCH 064/311] receipt fix --- src/Socket/messages-recv.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 75ee003..a0c490f 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -373,7 +373,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { key: { remoteJid: attrs.from, id: id, - fromMe: areJidsSameUser(sender, authState.creds.me!.id!), + fromMe: true, participant: attrs.participant }, update: { status } From 4aaf7b6a482c455751f79484063b634877ca052a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 26 Sep 2021 23:15:57 +0530 Subject: [PATCH 065/311] fix group metadata fetch --- src/Socket/groups.ts | 8 ++++---- src/Socket/messages-recv.ts | 4 ++-- src/Types/GroupMetadata.ts | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts index 40eb113..f157684 100644 --- a/src/Socket/groups.ts +++ b/src/Socket/groups.ts @@ -12,16 +12,16 @@ const extractGroupMetadata = (result: BinaryNode) => { desc = getBinaryNodeChild(descChild, 'body')?.content as string descId = descChild.attrs.id } - + const groupId = group.attrs.id.includes('@') ? group.attrs.id : jidEncode(group.attrs.id, 'g.us') const metadata: GroupMetadata = { - id: jidEncode(jidDecode(group.attrs.id).user, 'g.us'), + id: groupId, subject: group.attrs.subject, creation: +group.attrs.creation, owner: group.attrs.creator, desc, descId, - restrict: !!getBinaryNodeChild(result, 'locked') ? 'true' : 'false', - announce: !!getBinaryNodeChild(result, 'announcement') ? 'true' : 'false', + restrict: !!getBinaryNodeChild(result, 'locked'), + announce: !!getBinaryNodeChild(result, 'announcement'), participants: getBinaryNodeChildren(group, 'participant').map( ({ attrs }) => { return { diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index a0c490f..d95e21e 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -155,11 +155,11 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { emitParticipantsUpdate('add') break case WAMessageStubType.GROUP_CHANGE_ANNOUNCE: - const announce = message.messageStubParameters[0] === 'on' ? 'true' : 'false' + const announce = message.messageStubParameters[0] === 'on' emitGroupUpdate({ announce }) break case WAMessageStubType.GROUP_CHANGE_RESTRICT: - const restrict = message.messageStubParameters[0] === 'on' ? 'true' : 'false' + const restrict = message.messageStubParameters[0] === 'on' emitGroupUpdate({ restrict }) break case WAMessageStubType.GROUP_CHANGE_SUBJECT: diff --git a/src/Types/GroupMetadata.ts b/src/Types/GroupMetadata.ts index 13b2442..baa5b96 100644 --- a/src/Types/GroupMetadata.ts +++ b/src/Types/GroupMetadata.ts @@ -13,9 +13,9 @@ export interface GroupMetadata { descOwner?: string descId?: string /** is set when the group only allows admins to change group settings */ - restrict?: 'true' | 'false' + restrict?: boolean /** is set when the group only allows admins to write messages */ - announce?: 'true' | 'false' + announce?: boolean // Baileys modified array participants: GroupParticipant[] ephemeralDuration?: number From 12105a17eee4a9ace47f77f5b4d2a356e7d3b433 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 27 Sep 2021 12:48:57 +0530 Subject: [PATCH 066/311] groups key generation bug fix --- WASignalGroup/group_session_builder.js | 41 +++++++++++--------------- WASignalGroup/keyhelper.js | 21 +++++++++++++ 2 files changed, 39 insertions(+), 23 deletions(-) create mode 100644 WASignalGroup/keyhelper.js diff --git a/WASignalGroup/group_session_builder.js b/WASignalGroup/group_session_builder.js index 60c152f..24c84a2 100644 --- a/WASignalGroup/group_session_builder.js +++ b/WASignalGroup/group_session_builder.js @@ -1,7 +1,7 @@ //const utils = require('../../common/utils'); const SenderKeyDistributionMessage = require('./sender_key_distribution_message'); -const keyhelper = require("libsignal/src/keyhelper"); +const keyhelper = require("./keyhelper"); class GroupSessionBuilder { constructor(senderKeyStore) { this.senderKeyStore = senderKeyStore; @@ -21,31 +21,26 @@ class GroupSessionBuilder { // [{"senderKeyId":1742199468,"senderChainKey":{"iteration":0,"seed":"yxMY9VFQcXEP34olRAcGCtsgx1XoKsHfDIh+1ea4HAQ="},"senderSigningKey":{"public":""}}] async create(senderKeyName) { - try { - const senderKeyRecord = await this.senderKeyStore.loadSenderKey(senderKeyName); - //console.log('GroupSessionBuilder create session', senderKeyName, senderKeyRecord); + const senderKeyRecord = await this.senderKeyStore.loadSenderKey(senderKeyName); + //console.log('GroupSessionBuilder create session', senderKeyName, senderKeyRecord); - if (senderKeyRecord.isEmpty()) { - const keyId = keyhelper.generateSenderKeyId(); - const senderKey = keyhelper.generateSenderKey(); - const signingKey = keyhelper.generateSenderSigningKey(); + if (senderKeyRecord.isEmpty()) { + const keyId = keyhelper.generateSenderKeyId(); + const senderKey = keyhelper.generateSenderKey(); + const signingKey = keyhelper.generateSenderSigningKey(); - senderKeyRecord.setSenderKeyState(keyId, 0, senderKey, signingKey); - await this.senderKeyStore.storeSenderKey(senderKeyName, senderKeyRecord); - } - - const state = senderKeyRecord.getSenderKeyState(); - - return new SenderKeyDistributionMessage( - state.getKeyId(), - state.getSenderChainKey().getIteration(), - state.getSenderChainKey().getSeed(), - state.getSigningKeyPublic() - ); - } catch (e) { - //console.log(e.stack); - throw new Error(e); + senderKeyRecord.setSenderKeyState(keyId, 0, senderKey, signingKey); + await this.senderKeyStore.storeSenderKey(senderKeyName, senderKeyRecord); } + + const state = senderKeyRecord.getSenderKeyState(); + + return new SenderKeyDistributionMessage( + state.getKeyId(), + state.getSenderChainKey().getIteration(), + state.getSenderChainKey().getSeed(), + state.getSigningKeyPublic() + ); } } module.exports = GroupSessionBuilder; \ No newline at end of file diff --git a/WASignalGroup/keyhelper.js b/WASignalGroup/keyhelper.js new file mode 100644 index 0000000..a244581 --- /dev/null +++ b/WASignalGroup/keyhelper.js @@ -0,0 +1,21 @@ +const curve = require('libsignal/src/curve'); +const nodeCrypto = require('crypto'); + +exports.generateSenderKey = function() { + return nodeCrypto.randomBytes(32); +} + +exports.generateSenderKeyId = function() { + return nodeCrypto.randomInt(2147483647); +} + +exports.generateSenderSigningKey = function(key) { + if (!key) { + key = curve.generateKeyPair(); + } + + return { + public: key.pubKey, + private: key.privKey, + }; +} From 9907aedcfa58fe615b91d36893c332e42e67bd5d Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 27 Sep 2021 12:49:12 +0530 Subject: [PATCH 067/311] null expiration for eph messages --- src/Socket/messages-recv.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index d95e21e..3d4f979 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -120,7 +120,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { break case proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING: chatUpdate.ephemeralSettingTimestamp = toNumber(message.messageTimestamp) - chatUpdate.ephemeralExpiration = protocolMsg.ephemeralExpiration + chatUpdate.ephemeralExpiration = protocolMsg.ephemeralExpiration || null break } } else if(message.messageStubType) { From 85d4644ac628a6d0bc404ae1ad14bfe8b070f353 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 27 Sep 2021 12:52:42 +0530 Subject: [PATCH 068/311] fix message not relayed to self --- src/Socket/messages-send.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index cdfda83..fb0fc50 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -2,7 +2,7 @@ import { makeMessagesRecvSocket } from "./messages-recv" import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction } from "../Types" import { encodeWAMessage, generateMessageID, generateWAMessage } from "../Utils" -import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, S_WHATSAPP_NET } from '../WABinary' +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET } from '../WABinary' import { proto } from "../../WAProto" import { encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESession } from "../Utils/signal" import { WA_DEFAULT_EPHEMERAL, DEFAULT_ORIGIN, MEDIA_PATH_MAP } from "../Defaults" @@ -84,7 +84,10 @@ export const makeMessagesSocket = (config: SocketConfig) => { } const getUSyncDevices = async(jids: string[], ignoreZeroDevices: boolean) => { - const users = jids.map(jid => ({ tag: 'user', attrs: { jid } })) + const users = jids.map(jid => ({ + tag: 'user', + attrs: { jid: jidNormalizedUser(jid) } + })) const iq: BinaryNode = { tag: 'iq', attrs: { @@ -123,7 +126,6 @@ export const makeMessagesSocket = (config: SocketConfig) => { if(ignoreZeroDevices) { resultJids = resultJids.filter(item => item.device !== 0) } - return resultJids } From 34ee9647d3abd6c9155dd8e5254c090cdecf967c Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 27 Sep 2021 12:58:03 +0530 Subject: [PATCH 069/311] fix receipt from other device not working --- src/Socket/messages-recv.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 3d4f979..7f35e14 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -360,8 +360,13 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { logger.debug({ attrs: node.attrs }, 'sending receipt for ack') }) - const handleReceipt = ({ attrs, content }: BinaryNode) => { - const sender = attrs.participant || attrs.from + const handleReceipt = ({ tag, attrs, content }: BinaryNode) => { + if(tag === 'receipt') { + // if not read or no type (no type = delivered, but message sent from other device) + if(attrs.type !== 'read' && !!attrs.type) { + return + } + } const status = attrs.type === 'read' ? proto.WebMessageInfo.WebMessageInfoStatus.READ : proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK const ids = [attrs.id] if(Array.isArray(content)) { @@ -380,7 +385,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { }))) } - ws.on('CB:receipt,type:read', handleReceipt) + ws.on('CB:receipt', handleReceipt) ws.on('CB:ack,class:message', handleReceipt) ws.on('CB:notification', async(node: BinaryNode) => { From 07561bec5355914dfa1f8b76f6bb15c20b867398 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 27 Sep 2021 15:58:12 +0530 Subject: [PATCH 070/311] normalize jid before profile picture --- src/Socket/chats.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 6991aac..059d61a 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -215,6 +215,7 @@ export const makeChatsSocket = (config: SocketConfig) => { } const profilePictureUrl = async(jid: string) => { + jid = jidNormalizedUser(jid) const result = await query({ tag: 'iq', attrs: { From 723d1d6712c536e04300fb51efe44390a78ede0a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 27 Sep 2021 16:48:46 +0530 Subject: [PATCH 071/311] fire contact update if pushname provided --- Example/example.ts | 1 + src/Socket/messages-recv.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/Example/example.ts b/Example/example.ts index 8f86430..5a8565d 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -52,6 +52,7 @@ import makeWASocket, { WASocket, AuthenticationState, DisconnectReason, AnyMessa sock.ev.on('messages.update', m => console.log(m)) sock.ev.on('presence.update', m => console.log(m)) sock.ev.on('chats.update', m => console.log(m)) + sock.ev.on('contacts.update', m => console.log(m)) return sock } diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 7f35e14..cde2da9 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -423,7 +423,17 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { ev.on('messages.upsert', async({ messages }) => { const chat: Partial = { id: messages[0].key.remoteJid } + const contactNameUpdates: { [_: string]: string } = { } for(const msg of messages) { + if(!!msg.pushName) { + contactNameUpdates[msg.key.remoteJid!] = msg.pushName + // update our pushname too + if(msg.key.fromMe && authState.creds.me?.name !== msg.pushName) { + authState.creds.me!.name = msg.pushName + ev.emit('auth-state.update', authState) + } + } + await processMessage(msg, chat) if(!!msg.message && !msg.message!.protocolMessage) { chat.conversationTimestamp = toNumber(msg.messageTimestamp) @@ -435,6 +445,11 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { if(Object.keys(chat).length > 1) { ev.emit('chats.update', [ chat ]) } + if(Object.keys(contactNameUpdates).length) { + ev.emit('contacts.update', Object.keys(contactNameUpdates).map( + id => ({ id, notify: contactNameUpdates[id] }) + )) + } }) return sock From 1890b6a021a4118e68c9588399f64c9d4103c9c2 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 27 Sep 2021 16:55:42 +0530 Subject: [PATCH 072/311] fix contact update --- src/Socket/messages-recv.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index cde2da9..e651ae1 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -2,7 +2,7 @@ import { makeGroupsSocket } from "./groups" import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata } from "../Types" import { decodeMessageStanza, encodeBigEndian, toNumber } from "../Utils" -import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren } from '../WABinary' +import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser } from '../WABinary' import { downloadIfHistory } from '../Utils/history' import { proto } from "../../WAProto" import { generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils/signal" @@ -426,7 +426,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const contactNameUpdates: { [_: string]: string } = { } for(const msg of messages) { if(!!msg.pushName) { - contactNameUpdates[msg.key.remoteJid!] = msg.pushName + const jid = msg.key.fromMe ? jidNormalizedUser(authState.creds.me!.id) : (msg.key.participant || msg.key.remoteJid) + contactNameUpdates[jid] = msg.pushName // update our pushname too if(msg.key.fromMe && authState.creds.me?.name !== msg.pushName) { authState.creds.me!.name = msg.pushName From fdfe310fdfab291386e95d4d6ec66009e27df95b Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 28 Sep 2021 19:22:39 +0530 Subject: [PATCH 073/311] implement encrypting app patches --- src/Socket/chats.ts | 154 ++++++++++------- src/Socket/groups.ts | 69 ++++---- src/Socket/index.ts | 2 +- src/Socket/messages-recv.ts | 55 ++++-- src/Socket/messages-send.ts | 21 ++- src/Types/Auth.ts | 9 +- src/Types/Chat.ts | 4 +- src/Types/Message.ts | 8 + src/Utils/chat-utils.ts | 285 ++++++++++++++++++++++--------- src/Utils/history.ts | 6 - src/Utils/validate-connection.ts | 19 ++- src/WABinary/LTHash.ts | 4 +- 12 files changed, 420 insertions(+), 216 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 059d61a..40ae97f 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1,18 +1,20 @@ -import { decodeSyncdPatch, encodeSyncdPatch } from "../Utils/chat-utils"; -import { SocketConfig, WAPresence, PresenceData, Chat, ChatModification, WAMediaUpload, ChatMutation } from "../Types"; +import { encodeSyncdPatch, decodePatches, extractSyncdPatches } from "../Utils/chat-utils"; +import { SocketConfig, WAPresence, PresenceData, Chat, ChatModification, WAMediaUpload, ChatMutation, WAPatchName, LTHashState } from "../Types"; import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET } from "../WABinary"; -import { makeSocket } from "./socket"; import { proto } from '../../WAProto' -import { toNumber } from "../Utils/generics"; -import { generateProfilePicture } from "../Utils"; +import { generateProfilePicture, toNumber } from "../Utils"; +import { randomBytes } from "crypto"; +import { makeMessagesRecvSocket } from "./messages-recv"; export const makeChatsSocket = (config: SocketConfig) => { const { logger } = config - const sock = makeSocket(config) + const sock = makeMessagesRecvSocket(config) const { ev, ws, authState, + processMessage, + relayMessage, generateMessageTag, sendNode, query @@ -25,7 +27,6 @@ export const makeChatsSocket = (config: SocketConfig) => { to: S_WHATSAPP_NET, type: 'get', xmlns: 'usync', - }, content: [ { @@ -188,30 +189,38 @@ export const makeChatsSocket = (config: SocketConfig) => { }) } - const collectionSync = async() => { - const COLLECTIONS = ['critical_block', 'critical_unblock_low', 'regular_low', 'regular_high'] - await sendNode({ + const collectionSync = async(collections: { name: WAPatchName, version: number }[]) => { + const result = await query({ tag: 'iq', attrs: { to: S_WHATSAPP_NET, xmlns: 'w:sync:app:state', - type: 'set', - id: generateMessageTag(), + type: 'set' }, content: [ { tag: 'sync', attrs: { }, - content: COLLECTIONS.map( - name => ({ + content: collections.map( + ({ name, version }) => ({ tag: 'collection', - attrs: { name, version: '0', return_snapshot: 'true' } + attrs: { name, version: version.toString(), return_snapshot: 'true' } }) ) } ] }) - logger.info('synced collection') + const syncNode = getBinaryNodeChild(result, 'sync') + const collectionNodes = getBinaryNodeChildren(syncNode, 'collection') + return collectionNodes.reduce( + (dict, node) => { + const snapshotNode = getBinaryNodeChild(node, 'snapshot') + if(snapshotNode) { + dict[node.attrs.name] = snapshotNode.content as Uint8Array + } + return dict + }, { } as { [P in WAPatchName]: Uint8Array } + ) } const profilePictureUrl = async(jid: string) => { @@ -311,18 +320,31 @@ export const makeChatsSocket = (config: SocketConfig) => { } else { logger.warn({ action, id }, 'unprocessable update') } - updates.push(update) + if(Object.keys(update).length > 1) { + updates.push(update) + } } ev.emit('chats.update', updates) } - const patchChat = async( - jid: string, - modification: ChatModification + const appPatch = async( + syncAction: proto.ISyncActionValue, + index: [string, string], + name: WAPatchName, + operation: proto.SyncdMutation.SyncdMutationSyncdOperation.SET, ) => { - const patch = await encodeSyncdPatch(modification, { remoteJid: jid }, authState) - const type = 'regular_high' - const ver = authState.creds.appStateVersion![type] || 0 + await resyncState(name, false) + const { patch, state } = await encodeSyncdPatch( + syncAction, + index, + name, + operation, + authState, + ) + const initial = await authState.keys.getAppStateSyncVersion(name) + // temp: verify it was encoded correctly + const result = await decodePatches({ syncds: [{ ...patch, version: { version: state.version }, }], name }, initial, authState) + const node: BinaryNode = { tag: 'iq', attrs: { @@ -332,29 +354,35 @@ export const makeChatsSocket = (config: SocketConfig) => { }, content: [ { - tag: 'patch', - attrs: { - name: type, - version: (ver+1).toString(), - return_snapshot: 'false' - }, - content: proto.SyncdPatch.encode(patch).finish() + tag: 'sync', + attrs: { }, + content: [ + { + tag: 'collection', + attrs: { + name, + version: (state.version-1).toString(), + return_snapshot: 'false' + }, + content: [ + { + tag: 'patch', + attrs: { }, + content: proto.SyncdPatch.encode(patch).finish() + } + ] + } + ] } ] } await query(node) - authState.creds.appStateVersion![type] += 1 + await authState.keys.setAppStateSyncVersion(name, state) ev.emit('auth-state.update', authState) } - const resyncState = async(name: 'regular_high' | 'regular_low' = 'regular_high') => { - authState.creds.appStateVersion = authState.creds.appStateVersion || { - regular_high: 0, - regular_low: 0, - critical_unblock_low: 0, - critical_block: 0 - } + const fetchAppState = async(name: WAPatchName, fromVersion: number) => { const result = await query({ tag: 'iq', attrs: { @@ -371,7 +399,7 @@ export const makeChatsSocket = (config: SocketConfig) => { tag: 'collection', attrs: { name, - version: authState.creds.appStateVersion[name].toString(), + version: fromVersion.toString(), return_snapshot: 'false' } } @@ -379,30 +407,24 @@ export const makeChatsSocket = (config: SocketConfig) => { } ] }) - const syncNode = getBinaryNodeChild(result, 'sync') - const collectionNode = getBinaryNodeChild(syncNode, 'collection') - const patchesNode = getBinaryNodeChild(collectionNode, 'patches') + return result + } + + const resyncState = async(name: WAPatchName, fromScratch: boolean) => { + let state: LTHashState = fromScratch ? undefined : await authState.keys.getAppStateSyncVersion(name) + if(!state) state = { version: 0, hash: Buffer.alloc(128), mutations: [] } + + logger.info(`resyncing ${name} from v${state.version}`) + + const result = await fetchAppState(name, state.version) + const decoded = extractSyncdPatches(result) // extract from binary node + const { newMutations, state: newState } = await decodePatches(decoded, state, authState, true) + + await authState.keys.setAppStateSyncVersion(name, newState) + + logger.info(`synced ${name} to v${newState.version}`) + processSyncActions(newMutations) - const patches = getBinaryNodeChildren(patchesNode, 'patch') - const successfulMutations: ChatMutation[] = [] - for(const { content } of patches) { - if(content) { - const syncd = proto.SyncdPatch.decode(content! as Uint8Array) - const version = toNumber(syncd.version!.version!) - if(version) { - authState.creds.appStateVersion[name] = Math.max(version, authState.creds.appStateVersion[name]) - } - const { mutations, failures } = await decodeSyncdPatch(syncd, authState) - if(failures.length) { - logger.info( - { failures: failures.map(f => ({ trace: f.stack, data: f.data })) }, - 'failed to decode' - ) - } - successfulMutations.push(...mutations) - } - } - processSyncActions(successfulMutations) ev.emit('auth-state.update', authState) } @@ -412,7 +434,7 @@ export const makeChatsSocket = (config: SocketConfig) => { ws.on('CB:notification,type:server_sync', (node: BinaryNode) => { const update = getBinaryNodeChild(node, 'collection') if(update) { - resyncState(update.attrs.name as any) + resyncState(update.attrs.name as WAPatchName, false) } }) @@ -421,13 +443,12 @@ export const makeChatsSocket = (config: SocketConfig) => { sendPresenceUpdate('available') fetchBlocklist() fetchPrivacySettings() - //collectionSync() } }) return { ...sock, - patchChat, + appPatch, sendPresenceUpdate, presenceSubscribe, profilePictureUrl, @@ -436,6 +457,7 @@ export const makeChatsSocket = (config: SocketConfig) => { fetchPrivacySettings, fetchStatus, updateProfilePicture, - updateBlockStatus + updateBlockStatus, + resyncState, } } \ No newline at end of file diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts index f157684..39468b6 100644 --- a/src/Socket/groups.ts +++ b/src/Socket/groups.ts @@ -1,41 +1,10 @@ import { generateMessageID } from "../Utils"; import { SocketConfig, GroupMetadata, ParticipantAction } from "../Types"; -import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidDecode, jidEncode } from "../WABinary"; -import { makeChatsSocket } from "./chats"; - -const extractGroupMetadata = (result: BinaryNode) => { - const group = getBinaryNodeChild(result, 'group') - const descChild = getBinaryNodeChild(group, 'description') - let desc: string | undefined - let descId: string | undefined - if(descChild) { - desc = getBinaryNodeChild(descChild, 'body')?.content as string - descId = descChild.attrs.id - } - const groupId = group.attrs.id.includes('@') ? group.attrs.id : jidEncode(group.attrs.id, 'g.us') - const metadata: GroupMetadata = { - id: groupId, - subject: group.attrs.subject, - creation: +group.attrs.creation, - owner: group.attrs.creator, - desc, - descId, - restrict: !!getBinaryNodeChild(result, 'locked'), - announce: !!getBinaryNodeChild(result, 'announcement'), - participants: getBinaryNodeChildren(group, 'participant').map( - ({ attrs }) => { - return { - id: attrs.jid, - admin: attrs.type || null as any, - } - } - ) - } - return metadata -} +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidEncode } from "../WABinary"; +import { makeSocket } from "./socket"; export const makeGroupsSocket = (config: SocketConfig) => { - const sock = makeChatsSocket(config) + const sock = makeSocket(config) const { query } = sock const groupQuery = async(jid: string, type: 'get' | 'set', content: BinaryNode[]) => ( @@ -146,4 +115,36 @@ export const makeGroupsSocket = (config: SocketConfig) => { await groupQuery(jid, 'set', [ { tag: setting, attrs: { } } ]) } } +} + + +const extractGroupMetadata = (result: BinaryNode) => { + const group = getBinaryNodeChild(result, 'group') + const descChild = getBinaryNodeChild(group, 'description') + let desc: string | undefined + let descId: string | undefined + if(descChild) { + desc = getBinaryNodeChild(descChild, 'body')?.content as string + descId = descChild.attrs.id + } + const groupId = group.attrs.id.includes('@') ? group.attrs.id : jidEncode(group.attrs.id, 'g.us') + const metadata: GroupMetadata = { + id: groupId, + subject: group.attrs.subject, + creation: +group.attrs.creation, + owner: group.attrs.creator, + desc, + descId, + restrict: !!getBinaryNodeChild(result, 'locked'), + announce: !!getBinaryNodeChild(result, 'announcement'), + participants: getBinaryNodeChildren(group, 'participant').map( + ({ attrs }) => { + return { + id: attrs.jid, + admin: attrs.type || null as any, + } + } + ) + } + return metadata } \ No newline at end of file diff --git a/src/Socket/index.ts b/src/Socket/index.ts index 0ffddfe..f949186 100644 --- a/src/Socket/index.ts +++ b/src/Socket/index.ts @@ -1,6 +1,6 @@ import { SocketConfig } from '../Types' import { DEFAULT_CONNECTION_CONFIG } from '../Defaults' -import { makeMessagesSocket as _makeSocket } from './messages-send' +import { makeChatsSocket as _makeSocket } from './chats' // export the last socket layer const makeWASocket = (config: Partial) => ( diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index e651ae1..997605f 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -1,22 +1,23 @@ -import { makeGroupsSocket } from "./groups" import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata } from "../Types" import { decodeMessageStanza, encodeBigEndian, toNumber } from "../Utils" import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser } from '../WABinary' -import { downloadIfHistory } from '../Utils/history' +import { downloadHistory } from '../Utils/history' import { proto } from "../../WAProto" import { generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils/signal" import { KEY_BUNDLE_TYPE } from "../Defaults" +import { makeMessagesSocket } from "./messages-send" export const makeMessagesRecvSocket = (config: SocketConfig) => { const { logger } = config - const sock = makeGroupsSocket(config) + const sock = makeMessagesSocket(config) const { ev, authState, ws, assertingPreKeys, sendNode, + relayMessage, } = sock const sendMessageAck = async({ attrs }: BinaryNode) => { @@ -103,11 +104,45 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const protocolMsg = message.message?.protocolMessage if(protocolMsg) { switch(protocolMsg.type) { + case proto.ProtocolMessage.ProtocolMessageType.HISTORY_SYNC_NOTIFICATION: + const history = await downloadHistory(protocolMsg!.historySyncNotification) + processHistoryMessage(history) + break + case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_REQUEST: + const keys = await Promise.all( + protocolMsg.appStateSyncKeyRequest!.keyIds!.map( + async id => { + const keyId = Buffer.from(id.keyId!).toString('base64') + const keyData = await authState.keys.getAppStateSyncKey(keyId) + logger.info({ keyId }, 'received key request') + return { + keyId: id, + keyData + } + } + ) + ) + + const msg: proto.IMessage = { + protocolMessage: { + type: proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_SHARE, + appStateSyncKeyShare: { + keys + } + } + } + await relayMessage(message.key.remoteJid!, msg, { }) + logger.info({ with: message.key.remoteJid! }, 'shared key') + break case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_SHARE: for(const { keyData, keyId } of protocolMsg.appStateSyncKeyShare!.keys || []) { const str = Buffer.from(keyId.keyId!).toString('base64') + logger.info({ str }, 'injecting new app state sync key') await authState.keys.setAppStateSyncKey(str, keyData) + + authState.creds.myAppStateKeyId = str } + ev.emit('auth-state.update', authState) break case proto.ProtocolMessage.ProtocolMessageType.REVOKE: @@ -303,14 +338,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { logger.debug({ msgId: dec.msgId }, 'send message receipt') - const possibleHistory = downloadIfHistory(msg) - if(possibleHistory) { - const history = await possibleHistory - logger.info({ msgId: dec.msgId, type: history.syncType }, 'recv history') - - processHistoryMessage(history) - } else { - const message = msg.deviceSentMessage?.message || msg + const message = msg.deviceSentMessage?.message || msg fullMessages.push({ key: { remoteJid: dec.chatId, @@ -323,7 +351,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { messageTimestamp: dec.timestamp, pushName: dec.pushname }) - } } if(dec.successes.length) { @@ -434,7 +461,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { ev.emit('auth-state.update', authState) } } - + await processMessage(msg, chat) if(!!msg.message && !msg.message!.protocolMessage) { chat.conversationTimestamp = toNumber(msg.messageTimestamp) @@ -453,5 +480,5 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } }) - return sock + return { ...sock, processMessage } } \ No newline at end of file diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index fb0fc50..392db09 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -1,6 +1,5 @@ -import { makeMessagesRecvSocket } from "./messages-recv" -import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction } from "../Types" +import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions } from "../Types" import { encodeWAMessage, generateMessageID, generateWAMessage } from "../Utils" import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET } from '../WABinary' import { proto } from "../../WAProto" @@ -8,10 +7,11 @@ import { encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, import { WA_DEFAULT_EPHEMERAL, DEFAULT_ORIGIN, MEDIA_PATH_MAP } from "../Defaults" import got from "got" import { Boom } from "@hapi/boom" +import { makeGroupsSocket } from "./groups" export const makeMessagesSocket = (config: SocketConfig) => { const { logger } = config - const sock = makeMessagesRecvSocket(config) + const sock = makeGroupsSocket(config) const { ev, authState, @@ -84,10 +84,12 @@ export const makeMessagesSocket = (config: SocketConfig) => { } const getUSyncDevices = async(jids: string[], ignoreZeroDevices: boolean) => { + jids = Array.from(new Set(jids)) const users = jids.map(jid => ({ tag: 'user', attrs: { jid: jidNormalizedUser(jid) } })) + const iq: BinaryNode = { tag: 'iq', attrs: { @@ -175,7 +177,11 @@ export const makeMessagesSocket = (config: SocketConfig) => { return node } - const relayMessage = async(jid: string, message: proto.IMessage, msgId?: string) => { + const relayMessage = async( + jid: string, + message: proto.IMessage, + { messageId: msgId, cachedGroupMetadata }: MessageRelayOptions + ) => { const { user, server } = jidDecode(jid) const isGroup = server === 'g.us' msgId = msgId || generateMessageID() @@ -188,7 +194,10 @@ export const makeMessagesSocket = (config: SocketConfig) => { if(isGroup) { const { ciphertext, senderKeyDistributionMessageKey } = await encryptSenderKeyMsgSignalProto(destinationJid, encodedMsg, authState) - const groupData = await groupMetadata(jid) + + let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined + if(!groupData) groupData = await groupMetadata(jid) + const participantsList = groupData.participants.map(p => p.id) const devices = await getUSyncDevices(participantsList, false) @@ -384,7 +393,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { upload: waUploadToServer } ) - await relayMessage(jid, fullMsg.message, fullMsg.key.id!) + await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id! }) process.nextTick(() => { ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) }) diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts index eeb7c97..273f2fc 100644 --- a/src/Types/Auth.ts +++ b/src/Types/Auth.ts @@ -1,5 +1,6 @@ import type { Contact } from "./Contact" import type { proto } from "../../WAProto" +import type { WAPatchName, ChatMutation } from "./Chat" export type KeyPair = { public: Uint8Array, private: Uint8Array } export type SignedKeyPair = { keyPair: KeyPair, signature: Uint8Array, keyId: number } @@ -13,7 +14,7 @@ export type SignalIdentity = { identifierKey: Uint8Array } -export type CollectionType = 'regular_high' | 'regular_low' | 'critical_unblock_low' | 'critical_block' +export type LTHashState = { version: number, hash: Buffer, mutations: ChatMutation[] } export type AuthenticationCreds = { noiseKey: KeyPair @@ -24,9 +25,6 @@ export type AuthenticationCreds = { me?: Contact account?: proto.ADVSignedDeviceIdentity signalIdentities?: SignalIdentity[] - appStateVersion?: { - [T in CollectionType]: number - } myAppStateKeyId?: string firstUnuploadedPreKeyId: number serverHasPreKeys: boolean @@ -45,6 +43,9 @@ export type SignalKeyStore = { getAppStateSyncKey: (id: string) => Awaitable setAppStateSyncKey: (id: string, item: proto.IAppStateSyncKeyData | null) => Awaitable + + getAppStateSyncVersion: (name: WAPatchName) => Awaitable + setAppStateSyncVersion: (id: WAPatchName, item: LTHashState) => Awaitable } export type AuthenticationState = { diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index c6cd774..8c872ef 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -3,12 +3,14 @@ import type { proto } from "../../WAProto" /** set of statuses visible to other people; see updatePresence() in WhatsAppWeb.Send */ export type WAPresence = 'unavailable' | 'available' | 'composing' | 'recording' | 'paused' +export type WAPatchName = 'critical_block' | 'critical_unblock_low' | 'regular_low' | 'regular_high' | 'regular' + export interface PresenceData { lastKnownPresence: WAPresence lastSeen?: number } -export type ChatMutation = { action: proto.ISyncActionValue, index: [string, string] } +export type ChatMutation = { action: proto.ISyncActionValue, index: [string, string], indexMac: Uint8Array, valueMac: Uint8Array, operation: number } export type Chat = Omit & { /** unix timestamp of date when mute ends, if applicable */ diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 934e4b5..2346d91 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -1,6 +1,7 @@ import type { ReadStream } from "fs" import type { Logger } from "pino" import type { URL } from "url" +import type { GroupMetadata } from "./GroupMetadata" import { proto } from '../../WAProto' // export the WAMessage Prototypes @@ -103,6 +104,13 @@ export type AnyMessageContent = AnyRegularMessageContent | { } | { disappearingMessagesInChat: boolean | number } + +export type MessageRelayOptions = { + messageId?: string + cachedGroupMetadata?: (jid: string) => Promise + //cachedDevices?: (jid: string) => Promise +} + export type MiscMessageGenerationOptions = { /** Force message id */ messageId?: string diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 0ed8a28..bc2c60e 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -1,12 +1,12 @@ import { Boom } from '@hapi/boom' import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./crypto" -import { AuthenticationState, ChatModification, ChatMutation } from "../Types" +import { AuthenticationState, ChatModification, ChatMutation, WAPatchName, LTHashState } from "../Types" import { proto } from '../../WAProto' import { LT_HASH_ANTI_TAMPERING } from '../WABinary/LTHash' +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren } from '../WABinary' +import { toNumber } from './generics' -type SyncdType = 'regular_high' | 'regular_low' - -const mutationKeys = (keydata: Uint8Array) => { +export const mutationKeys = (keydata: Uint8Array) => { const expanded = hkdf(keydata, 160, { info: 'WhatsApp Mutation Keys' }) return { indexKey: expanded.slice(0, 32), @@ -48,22 +48,40 @@ const to64BitNetworkOrder = function(e) { return Buffer.from(t) } -const generateSnapshotMac = (version: number, indexMac: Uint8Array, valueMac: Uint8Array, type: SyncdType, key: Buffer) => { - - const ltHash = () => { - const result = LT_HASH_ANTI_TAMPERING.subtractThenAdd(new Uint8Array(128).buffer, [ new Uint8Array(valueMac).buffer, new Uint8Array(indexMac).buffer ], []) - const buff = Buffer.from(result) - console.log(buff.toString('hex')) - return buff +type Mac = { indexMac: Uint8Array, valueMac: Uint8Array, operation: proto.SyncdMutation.SyncdMutationSyncdOperation } + +const computeLtHash = (initial: Uint8Array, macs: Mac[], getPrevSetValueMac: (index: Uint8Array, internalIndex: number) => Uint8Array) => { + const addBuffs: ArrayBuffer[] = [] + const subBuffs: ArrayBuffer[] = [] + for(let i = 0; i < macs.length;i++) { + const { indexMac, valueMac, operation } = macs[i] + const subBuff = getPrevSetValueMac(indexMac, i) + if(operation === proto.SyncdMutation.SyncdMutationSyncdOperation.REMOVE) { + if(!subBuff) { + throw new Boom('') + } + } else { + addBuffs.push(new Uint8Array(valueMac).buffer) + } + if(subBuff) { + subBuffs.push(new Uint8Array(subBuff).buffer) + } } - const total = Buffer.concat([ - ltHash(), - to64BitNetworkOrder(version), - Buffer.from(type, 'utf-8') - ]) - return hmacSign(total, key) + + const result = LT_HASH_ANTI_TAMPERING.subtractThenAdd(new Uint8Array(initial).buffer, addBuffs, subBuffs) + const buff = Buffer.from(result) + return buff } -const generatePatchMac = (snapshotMac: Uint8Array, valueMacs: Uint8Array[], version: number, type: SyncdType, key: Buffer) => { + +export const generateSnapshotMac = (lthash: Uint8Array, version: number, name: WAPatchName, key: Buffer) => { + const total = Buffer.concat([ + lthash, + to64BitNetworkOrder(version), + Buffer.from(name, 'utf-8') + ]) + return hmacSign(total, key, 'sha256') +} +const generatePatchMac = (snapshotMac: Uint8Array, valueMacs: Uint8Array[], version: number, type: WAPatchName, key: Buffer) => { const total = Buffer.concat([ snapshotMac, ...valueMacs, @@ -73,76 +91,83 @@ const generatePatchMac = (snapshotMac: Uint8Array, valueMacs: Uint8Array[], vers return hmacSign(total, key) } -export const encodeSyncdPatch = async(action: ChatModification, lastMessageKey: proto.IMessageKey, { creds: { appStateVersion, myAppStateKeyId }, keys }: AuthenticationState) => { - let syncAction: proto.ISyncActionValue = { } - if('archive' in action) { - syncAction.archiveChatAction = { - archived: action.archive, - messageRange: { - messages: [ - { key: lastMessageKey } - ] - } - } - } else if('mute' in action) { - const value = typeof action.mute === 'number' ? true : false - syncAction.muteAction = { - muted: value, - muteEndTimestamp: typeof action.mute === 'number' ? action.mute : undefined - } - } else if('delete' in action) { - syncAction.deleteChatAction = { } - } else if('markRead' in action) { - syncAction.markChatAsReadAction = { - read: action.markRead - } - } else if('pin' in action) { - throw new Boom('Pin not supported on multi-device yet', { statusCode: 400 }) - } - - const encoded = proto.SyncActionValue.encode(syncAction).finish() +export const encodeSyncdPatch = async( + syncAction: proto.ISyncActionValue, + index: [string, string], + type: WAPatchName, + operation: proto.SyncdMutation.SyncdMutationSyncdOperation, + { creds: { myAppStateKeyId }, keys }: AuthenticationState +) => { const key = !!myAppStateKeyId ? await keys.getAppStateSyncKey(myAppStateKeyId) : undefined if(!key) { throw new Boom(`myAppStateKey not present`, { statusCode: 404 }) } - const encKeyId = Buffer.from(myAppStateKeyId, 'base64') - const index = JSON.stringify([Object.keys(action)[0], lastMessageKey.remoteJid]) + const state = { ...await keys.getAppStateSyncVersion(type) } + + const indexBuffer = Buffer.from(JSON.stringify(index)) + const encoded = proto.SyncActionData.encode({ + index: indexBuffer, + value: syncAction, + padding: new Uint8Array(0), + version: 2 + }).finish() + const keyValue = mutationKeys(key!.keyData!) const encValue = aesEncrypt(encoded, keyValue.valueEncryptionKey) - const macValue = generateMac(1, encValue, encKeyId, keyValue.valueMacKey) - const indexMacValue = hmacSign(Buffer.from(index), keyValue.indexKey) + const valueMac = generateMac(operation, encValue, encKeyId, keyValue.valueMacKey) + const indexMac = hmacSign(indexBuffer, keyValue.indexKey) - const type = 'regular_high' - const v = appStateVersion[type]+1 + state.hash = computeLtHash( + state.hash, + [ { indexMac, valueMac, operation } ], + (index) => [...state.mutations].reverse().find(m => Buffer.compare(m.indexMac, index) === 0)?.valueMac + ) + state.version += 1 - const snapshotMac = generateSnapshotMac(v, indexMacValue, macValue, type, keyValue.snapshotMacKey) + const snapshotMac = generateSnapshotMac(state.hash, state.version, type, keyValue.snapshotMacKey) const patch: proto.ISyncdPatch = { - patchMac: generatePatchMac(snapshotMac, [macValue], v, type, keyValue.patchMacKey), + patchMac: generatePatchMac(snapshotMac, [valueMac], state.version, type, keyValue.patchMacKey), snapshotMac: snapshotMac, keyId: { id: encKeyId }, mutations: [ { - operation: 1, + operation: operation, record: { index: { - blob: indexMacValue + blob: indexMac }, value: { - blob: Buffer.concat([ encValue, macValue ]) + blob: Buffer.concat([ encValue, valueMac ]) }, keyId: { id: encKeyId } } } ] } - return patch + + state.mutations = [ + ...state.mutations, + { + action: syncAction, + index, + valueMac, + indexMac, + operation + } + ] + return { patch, state } } -export const decodeSyncdPatch = async(msg: proto.ISyncdPatch, {keys}: AuthenticationState) => { +export const decodeSyncdPatch = async( + msg: proto.ISyncdPatch, + name: WAPatchName, + {keys}: AuthenticationState, + validateMacs: boolean = true +) => { const keyCache: { [_: string]: ReturnType } = { } const getKey = async(keyId: Uint8Array) => { const base64Key = Buffer.from(keyId!).toString('base64') @@ -160,42 +185,144 @@ export const decodeSyncdPatch = async(msg: proto.ISyncdPatch, {keys}: Authentica } const mutations: ChatMutation[] = [] - const failures: Boom[] = [] - /*const mainKey = getKey(msg.keyId!.id) - const mutation = msg.mutations![0]!.record - - const patchMac = generatePatchMac(msg.snapshotMac, [ mutation.value!.blob!.slice(-32) ], toNumber(msg.version!.version), 'regular_low', mainKey.patchMacKey) - console.log(patchMac) - console.log(msg.patchMac)*/ + if(validateMacs) { + const mainKey = await getKey(msg.keyId!.id) + const mutationmacs = msg.mutations!.map(mutation => mutation.record!.value!.blob!.slice(-32)) + + const patchMac = generatePatchMac(msg.snapshotMac, mutationmacs, toNumber(msg.version!.version), name, mainKey.patchMacKey) + if(Buffer.compare(patchMac, msg.patchMac) !== 0) { + throw new Boom('Invalid patch mac') + } + } // indexKey used to HMAC sign record.index.blob // valueEncryptionKey used to AES-256-CBC encrypt record.value.blob[0:-32] // the remaining record.value.blob[0:-32] is the mac, it the HMAC sign of key.keyId + decoded proto data + length of bytes in keyId for(const { operation, record } of msg.mutations!) { - try { - const key = await getKey(record.keyId!.id!) - const content = Buffer.from(record.value!.blob!) - const encContent = content.slice(0, -32) + const key = await getKey(record.keyId!.id!) + const content = Buffer.from(record.value!.blob!) + const encContent = content.slice(0, -32) + const ogValueMac = content.slice(-32) + if(validateMacs) { const contentHmac = generateMac(operation, encContent, record.keyId!.id!, key.valueMacKey) - if(Buffer.compare(contentHmac, content.slice(-32)) !== 0) { + if(Buffer.compare(contentHmac, ogValueMac) !== 0) { throw new Boom('HMAC content verification failed') } + } - const result = aesDecrypt(encContent, key.valueEncryptionKey) - const syncAction = proto.SyncActionData.decode(result) + const result = aesDecrypt(encContent, key.valueEncryptionKey) + const syncAction = proto.SyncActionData.decode(result) + if(validateMacs) { const hmac = hmacSign(syncAction.index, key.indexKey) if(Buffer.compare(hmac, record.index!.blob) !== 0) { throw new Boom('HMAC index verification failed') } - - const indexStr = Buffer.from(syncAction.index).toString() - mutations.push({ action: syncAction.value!, index: JSON.parse(indexStr) }) - } catch(error) { - failures.push(new Boom(error, { data: { operation, record } })) } + + const indexStr = Buffer.from(syncAction.index).toString() + mutations.push({ + action: syncAction.value!, + index: JSON.parse(indexStr), + indexMac: record.index!.blob!, + valueMac: ogValueMac, + operation: operation + }) } - return { mutations, failures } + return { mutations } +} + +export const extractSyncdPatches = (result: BinaryNode) => { + const syncNode = getBinaryNodeChild(result, 'sync') + const collectionNode = getBinaryNodeChild(syncNode, 'collection') + const patchesNode = getBinaryNodeChild(collectionNode, 'patches') + + const patches = getBinaryNodeChildren(patchesNode || collectionNode, 'patch') + const syncds: proto.ISyncdPatch[] = [] + const name = collectionNode.attrs.name as WAPatchName + for(let { content } of patches) { + if(content) { + const syncd = proto.SyncdPatch.decode(content! as Uint8Array) + if(!syncd.version) { + syncd.version = { version: +collectionNode.attrs.version+1 } + } + syncds.push(syncd) + } + } + return { syncds, name } +} + +export const decodePatches = async( + { syncds, name }: ReturnType, + initial: LTHashState, + auth: AuthenticationState, + validateMacs: boolean = true +) => { + const successfulMutations: ChatMutation[] = [] + + let current = initial.hash + let currentVersion = initial.version + for(const syncd of syncds) { + const { mutations, version, keyId, snapshotMac } = syncd + const macs = mutations.map( + m => ({ + operation: m.operation!, + indexMac: m.record.index!.blob!, + valueMac: m.record.value!.blob!.slice(-32) + }) + ) + + currentVersion = toNumber(version.version!) + + current = computeLtHash(current, macs, (index, maxIndex) => { + let value: Uint8Array + for(const item of initial.mutations) { + if(Buffer.compare(item.indexMac, index) === 0) { + value = item.valueMac + } + } + for(const { version, mutations } of syncds) { + const versionNum = toNumber(version.version!) + const mutationIdx = mutations.findIndex(m => { + return Buffer.compare(m.record!.index!.blob, index) === 0 + }) + + if(mutationIdx >= 0 && (versionNum < currentVersion || mutationIdx < maxIndex)) { + value = mutations[mutationIdx].record!.value!.blob!.slice(-32) + } + + if(versionNum >= currentVersion) { + break + } + } + return value + }) + + if(validateMacs) { + const base64Key = Buffer.from(keyId!.id!).toString('base64') + const keyEnc = await auth.keys.getAppStateSyncKey(base64Key) + if(!keyEnc) { + throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500 }) + } + const result = mutationKeys(keyEnc.keyData!) + const computedSnapshotMac = generateSnapshotMac(current, currentVersion, name, result.snapshotMacKey) + if(Buffer.compare(snapshotMac, computedSnapshotMac) !== 0) { + throw new Boom(`failed to verify LTHash at ${currentVersion}`, { statusCode: 500 }) + } + } + + const decodeResult = await decodeSyncdPatch(syncd, name, auth!, validateMacs) + console.log(currentVersion, decodeResult.mutations) + successfulMutations.push(...decodeResult.mutations) + } + return { + newMutations: successfulMutations, + state: { + hash: current, + version: currentVersion, + mutations: [...initial.mutations, ...successfulMutations] + } as LTHashState + } } \ No newline at end of file diff --git a/src/Utils/history.ts b/src/Utils/history.ts index b304c0a..b5df9c2 100644 --- a/src/Utils/history.ts +++ b/src/Utils/history.ts @@ -5,12 +5,6 @@ import { inflate } from "zlib"; const inflatePromise = promisify(inflate) -export const downloadIfHistory = (message: proto.IMessage) => { - if(message.protocolMessage?.historySyncNotification) { - return downloadHistory(message.protocolMessage!.historySyncNotification) - } -} - export const downloadHistory = async(msg: proto.IHistorySyncNotification) => { const stream = await downloadContentFromMessage(msg, 'history') let buffer = Buffer.from([]) diff --git a/src/Utils/validate-connection.ts b/src/Utils/validate-connection.ts index b327d31..2709852 100644 --- a/src/Utils/validate-connection.ts +++ b/src/Utils/validate-connection.ts @@ -1,7 +1,7 @@ import { Boom } from '@hapi/boom' import { randomBytes } from 'crypto' import { proto } from '../../WAProto' -import type { AuthenticationState, SocketConfig, SignalKeyStore, AuthenticationCreds, KeyPair } from "../Types" +import type { AuthenticationState, SocketConfig, SignalKeyStore, AuthenticationCreds, KeyPair, LTHashState } from "../Types" import { Curve, hmacSign, signedKeyPair } from './crypto' import { encodeInt, generateRegistrationId } from './generics' import { BinaryNode, S_WHATSAPP_NET, jidDecode, Binary } from '../WABinary' @@ -83,22 +83,25 @@ export const generateRegistrationNode = ( } export const initInMemoryKeyStore = ( - { preKeys, sessions, senderKeys, appStateSyncKeys }: { + { preKeys, sessions, senderKeys, appStateSyncKeys, appStateVersions }: { preKeys?: { [k: number]: KeyPair }, sessions?: { [k: string]: any }, senderKeys?: { [k: string]: any } - appStateSyncKeys?: { [k: string]: proto.IAppStateSyncKeyData } + appStateSyncKeys?: { [k: string]: proto.IAppStateSyncKeyData }, + appStateVersions?: { [k: string]: LTHashState }, } = { }, ) => { preKeys = preKeys || { } sessions = sessions || { } senderKeys = senderKeys || { } appStateSyncKeys = appStateSyncKeys || { } + appStateVersions = appStateVersions || { } return { preKeys, sessions, senderKeys, appStateSyncKeys, + appStateVersions, getPreKey: keyId => preKeys[keyId], setPreKey: (keyId, pair) => { if(pair) preKeys[keyId] = pair @@ -125,6 +128,16 @@ export const initInMemoryKeyStore = ( setAppStateSyncKey: (id, item) => { if(item) appStateSyncKeys[id] = item else delete appStateSyncKeys[id] + }, + getAppStateSyncVersion: id => { + const obj = appStateVersions[id] + if(obj) { + return obj + } + }, + setAppStateSyncVersion: (id, item) => { + if(item) appStateVersions[id] = item + else delete appStateVersions[id] } } as SignalKeyStore } diff --git a/src/WABinary/LTHash.ts b/src/WABinary/LTHash.ts index b11053b..85ea166 100644 --- a/src/WABinary/LTHash.ts +++ b/src/WABinary/LTHash.ts @@ -29,13 +29,13 @@ class d { } _addSingle(e, t) { var r = this; - const n = new Uint8Array(hkdf(t, o, { info: r.salt })).buffer; + const n = new Uint8Array(hkdf(Buffer.from(t), o, { info: r.salt })).buffer; return r.performPointwiseWithOverflow(e, n, ((e,t)=>e + t)) } _subtractSingle(e, t) { var r = this; - const n = new Uint8Array(hkdf(t, o, { info: r.salt })).buffer; + const n = new Uint8Array(hkdf(Buffer.from(t), o, { info: r.salt })).buffer; return r.performPointwiseWithOverflow(e, n, ((e,t)=>e - t)) } performPointwiseWithOverflow(e, t, r) { From 1a83a4c6d4f75adec117422318659decda0815f2 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 28 Sep 2021 19:33:21 +0530 Subject: [PATCH 074/311] nicer patch API --- src/Socket/chats.ts | 17 +++++------------ src/Types/Chat.ts | 7 +++++++ src/Utils/chat-utils.ts | 11 +++++------ 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 40ae97f..fd10bfc 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1,9 +1,8 @@ import { encodeSyncdPatch, decodePatches, extractSyncdPatches } from "../Utils/chat-utils"; -import { SocketConfig, WAPresence, PresenceData, Chat, ChatModification, WAMediaUpload, ChatMutation, WAPatchName, LTHashState } from "../Types"; +import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, LTHashState } from "../Types"; import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET } from "../WABinary"; import { proto } from '../../WAProto' import { generateProfilePicture, toNumber } from "../Utils"; -import { randomBytes } from "crypto"; import { makeMessagesRecvSocket } from "./messages-recv"; export const makeChatsSocket = (config: SocketConfig) => { @@ -327,18 +326,12 @@ export const makeChatsSocket = (config: SocketConfig) => { ev.emit('chats.update', updates) } - const appPatch = async( - syncAction: proto.ISyncActionValue, - index: [string, string], - name: WAPatchName, - operation: proto.SyncdMutation.SyncdMutationSyncdOperation.SET, - ) => { + const appPatch = async(patchCreate: WAPatchCreate) => { + const name = patchCreate.type + await resyncState(name, false) const { patch, state } = await encodeSyncdPatch( - syncAction, - index, - name, - operation, + patchCreate, authState, ) const initial = await authState.keys.getAppStateSyncVersion(name) diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 8c872ef..8d2c320 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -12,6 +12,13 @@ export interface PresenceData { export type ChatMutation = { action: proto.ISyncActionValue, index: [string, string], indexMac: Uint8Array, valueMac: Uint8Array, operation: number } +export type WAPatchCreate = { + syncAction: proto.ISyncActionValue + index: [string, string] + type: WAPatchName + apiVersion: number +} + export type Chat = Omit & { /** unix timestamp of date when mute ends, if applicable */ mute?: number | null diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index bc2c60e..e78dd1e 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -1,6 +1,6 @@ import { Boom } from '@hapi/boom' import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./crypto" -import { AuthenticationState, ChatModification, ChatMutation, WAPatchName, LTHashState } from "../Types" +import { AuthenticationState, WAPatchCreate, ChatMutation, WAPatchName, LTHashState } from "../Types" import { proto } from '../../WAProto' import { LT_HASH_ANTI_TAMPERING } from '../WABinary/LTHash' import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren } from '../WABinary' @@ -92,10 +92,7 @@ const generatePatchMac = (snapshotMac: Uint8Array, valueMacs: Uint8Array[], vers } export const encodeSyncdPatch = async( - syncAction: proto.ISyncActionValue, - index: [string, string], - type: WAPatchName, - operation: proto.SyncdMutation.SyncdMutationSyncdOperation, + { type, index, syncAction, apiVersion }: WAPatchCreate, { creds: { myAppStateKeyId }, keys }: AuthenticationState ) => { const key = !!myAppStateKeyId ? await keys.getAppStateSyncKey(myAppStateKeyId) : undefined @@ -104,6 +101,8 @@ export const encodeSyncdPatch = async( } const encKeyId = Buffer.from(myAppStateKeyId, 'base64') + const operation = proto.SyncdMutation.SyncdMutationSyncdOperation.SET + const state = { ...await keys.getAppStateSyncVersion(type) } const indexBuffer = Buffer.from(JSON.stringify(index)) @@ -111,7 +110,7 @@ export const encodeSyncdPatch = async( index: indexBuffer, value: syncAction, padding: new Uint8Array(0), - version: 2 + version: apiVersion }).finish() const keyValue = mutationKeys(key!.keyData!) From 8b3627742eae3d70441ef5863e71366a755d5cc3 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 29 Sep 2021 12:31:06 +0530 Subject: [PATCH 075/311] update toNumber impl --- src/Utils/generics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/generics.ts b/src/Utils/generics.ts index a107b04..50f5065 100644 --- a/src/Utils/generics.ts +++ b/src/Utils/generics.ts @@ -90,7 +90,7 @@ export const encodeBigEndian = (e: number, t=4) => { return a } -export const toNumber = (t: Long | number) => (typeof t?.['low'] !== 'undefined' ? t['low'] : t) as number +export const toNumber = (t: Long | number) => ((typeof t === 'object' && 'toNumber' in t) ? t.toNumber() : t) export function shallowChanges (old: T, current: T, {lookForDeletedKeys}: {lookForDeletedKeys: boolean}): Partial { let changes: Partial = {} From 173d1ddf8bb8478bf78b832344933fc360614067 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 29 Sep 2021 12:31:22 +0530 Subject: [PATCH 076/311] implement chat modifications --- src/Socket/chats.ts | 48 +++++++++++++++++++++----- src/Types/Chat.ts | 6 ++-- src/Types/index.ts | 4 +-- src/Utils/chat-utils.ts | 76 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 118 insertions(+), 16 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index fd10bfc..fa4a320 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1,5 +1,5 @@ -import { encodeSyncdPatch, decodePatches, extractSyncdPatches } from "../Utils/chat-utils"; -import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, LTHashState } from "../Types"; +import { encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch } from "../Utils/chat-utils"; +import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, LTHashState, ChatModification, Contact } from "../Types"; import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET } from "../WABinary"; import { proto } from '../../WAProto' import { generateProfilePicture, toNumber } from "../Utils"; @@ -298,8 +298,12 @@ export const makeChatsSocket = (config: SocketConfig) => { } const processSyncActions = (actions: ChatMutation[]) => { - const updates: Partial[] = [] - for(const { action, index: [_, id] } of actions) { + + const updates: { [jid: string]: Partial } = {} + const contactUpdates: { [jid: string]: Partial } = {} + const msgDeletes: proto.IMessageKey[] = [] + + for(const { action, index: [_, id, msgId, fromMe] } of actions) { const update: Partial = { id } if(action?.muteAction) { update.mute = action.muteAction?.muted ? @@ -310,9 +314,17 @@ export const makeChatsSocket = (config: SocketConfig) => { } else if(action?.markChatAsReadAction) { update.unreadCount = !!action.markChatAsReadAction?.read ? 0 : -1 } else if(action?.clearChatAction) { - console.log(action.clearChatAction) + msgDeletes.push({ + remoteJid: id, + id: msgId, + fromMe: fromMe === '1' + }) } else if(action?.contactAction) { - ev.emit('contacts.update', [{ id, name: action.contactAction!.fullName }]) + contactUpdates[id] = { + ...(contactUpdates[id] || {}), + id, + name: action.contactAction!.fullName + } } else if(action?.pushNameSetting) { authState.creds.me!.name = action?.pushNameSetting?.name! ev.emit('auth-state.update', authState) @@ -320,10 +332,22 @@ export const makeChatsSocket = (config: SocketConfig) => { logger.warn({ action, id }, 'unprocessable update') } if(Object.keys(update).length > 1) { - updates.push(update) + updates[update.id] = { + ...(updates[update.id] || {}), + ...update + } } } - ev.emit('chats.update', updates) + + if(Object.values(updates).length) { + ev.emit('chats.update', Object.values(updates)) + } + if(Object.values(contactUpdates).length) { + ev.emit('contacts.update', Object.values(contactUpdates)) + } + if(msgDeletes.length) { + ev.emit('messages.delete', { keys: msgDeletes }) + } } const appPatch = async(patchCreate: WAPatchCreate) => { @@ -336,7 +360,7 @@ export const makeChatsSocket = (config: SocketConfig) => { ) const initial = await authState.keys.getAppStateSyncVersion(name) // temp: verify it was encoded correctly - const result = await decodePatches({ syncds: [{ ...patch, version: { version: state.version }, }], name }, initial, authState) + await decodePatches({ syncds: [{ ...patch, version: { version: state.version }, }], name }, initial, authState) const node: BinaryNode = { tag: 'iq', @@ -375,6 +399,11 @@ export const makeChatsSocket = (config: SocketConfig) => { ev.emit('auth-state.update', authState) } + const chatModify = (mod: ChatModification, jid: string, lastMessages: Pick[]) => { + const patch = chatModificationToAppPatch(mod, jid, lastMessages) + return appPatch(patch) + } + const fetchAppState = async(name: WAPatchName, fromVersion: number) => { const result = await query({ tag: 'iq', @@ -452,5 +481,6 @@ export const makeChatsSocket = (config: SocketConfig) => { updateProfilePicture, updateBlockStatus, resyncState, + chatModify, } } \ No newline at end of file diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 8d2c320..9fec2bb 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -10,11 +10,11 @@ export interface PresenceData { lastSeen?: number } -export type ChatMutation = { action: proto.ISyncActionValue, index: [string, string], indexMac: Uint8Array, valueMac: Uint8Array, operation: number } +export type ChatMutation = { action: proto.ISyncActionValue, index: string[], indexMac: Uint8Array, valueMac: Uint8Array, operation: number } export type WAPatchCreate = { syncAction: proto.ISyncActionValue - index: [string, string] + index: string[] type: WAPatchName apiVersion: number } @@ -38,7 +38,7 @@ export type ChatModification = mute: number | null } | { - clear: 'all' | { messages: { id: string, fromMe?: boolean }[] } + clear: 'all' | { message: {id: string, fromMe?: boolean} } } | { star: { diff --git a/src/Types/index.ts b/src/Types/index.ts index 3822933..351bb6a 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -16,7 +16,7 @@ import { Contact } from './Contact' import { ConnectionState } from './State' import { GroupMetadata, ParticipantAction } from './GroupMetadata' -import { MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageUpdate } from './Message' +import { MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageUpdate, WAMessageKey } from './Message' export type WAVersion = [number, number, number] export type WABrowserDescription = [string, string, string] @@ -103,7 +103,7 @@ export type BaileysEventMap = { 'contacts.upsert': Contact[] 'contacts.update': Partial[] - 'messages.delete': { jid: string, ids: string[] } | { jid: string, all: true } + 'messages.delete': { keys: WAMessageKey[] } | { jid: string, all: true } 'messages.update': WAMessageUpdate[] /** * add/update the given messages. If they were received while the connection was online, diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index e78dd1e..95ac3ca 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -1,6 +1,6 @@ import { Boom } from '@hapi/boom' import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./crypto" -import { AuthenticationState, WAPatchCreate, ChatMutation, WAPatchName, LTHashState } from "../Types" +import { AuthenticationState, WAPatchCreate, ChatMutation, WAPatchName, LTHashState, ChatModification } from "../Types" import { proto } from '../../WAProto' import { LT_HASH_ANTI_TAMPERING } from '../WABinary/LTHash' import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren } from '../WABinary' @@ -313,7 +313,6 @@ export const decodePatches = async( } const decodeResult = await decodeSyncdPatch(syncd, name, auth!, validateMacs) - console.log(currentVersion, decodeResult.mutations) successfulMutations.push(...decodeResult.mutations) } return { @@ -324,4 +323,77 @@ export const decodePatches = async( mutations: [...initial.mutations, ...successfulMutations] } as LTHashState } +} + +export const chatModificationToAppPatch = ( + mod: ChatModification, + jid: string, + lastMessages: Pick[] +) => { + const messageRange: proto.ISyncActionMessageRange = { + lastMessageTimestamp: lastMessages[lastMessages.length-1].messageTimestamp, + messages: lastMessages + } + const timestamp = Date.now() + let patch: WAPatchCreate + if('mute' in mod) { + patch = { + syncAction: { + timestamp, + muteAction: { + muted: !!mod.mute, + muteEndTimestamp: mod.mute || undefined + } + }, + index: ['mute', jid], + type: 'regular_high', + apiVersion: 2 + } + } else if('archive' in mod) { + patch = { + syncAction: { + timestamp, + archiveChatAction: { + archived: !!mod.archive, + messageRange + } + }, + index: ['archive', jid], + type: 'regular_low', + apiVersion: 3 + } + } else if('markRead' in mod) { + patch = { + syncAction: { + timestamp, + markChatAsReadAction: { + read: mod.markRead, + messageRange + } + }, + index: ['markChatAsRead', jid], + type: 'regular_low', + apiVersion: 3 + } + } else if('clear' in mod) { + if(mod.clear === 'all') { + throw new Boom('not supported') + } else { + const key = mod.clear.message + patch = { + syncAction: { + timestamp, + deleteMessageForMeAction: { + deleteMedia: false + } + }, + index: ['deleteMessageForMe', jid, key.id, key.fromMe ? '1' : '0', '0'], + type: 'regular_high', + apiVersion: 3, + } + } + } else { + throw new Boom('not supported') + } + return patch } \ No newline at end of file From 15d14836ce4ebd8d8116e9b54a70c0ee2c0ecdb0 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 29 Sep 2021 12:36:40 +0530 Subject: [PATCH 077/311] fix message recv fromMe flag --- src/Socket/messages-recv.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 997605f..a8beb20 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -401,11 +401,13 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { ids.push(...items.map(i => i.attrs.id)) } + const remoteJid = attrs.recipient || attrs.from + const fromMe = attrs.recipient ? false : true ev.emit('messages.update', ids.map(id => ({ key: { - remoteJid: attrs.from, + remoteJid, id: id, - fromMe: true, + fromMe, participant: attrs.participant }, update: { status } From 647c16b46c3aef9c102e819ca56252648b36a51f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 29 Sep 2021 12:44:06 +0530 Subject: [PATCH 078/311] Update README.md --- README.md | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3a3ff47..6631971 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,7 @@ export type BaileysEventMap = { 'auth-state.update': AuthenticationState /** set chats (history sync), messages are reverse chronologically sorted */ 'chats.set': { chats: Chat[], messages: WAMessage[] } - /** update/insert chats */ + /** upsert chats */ 'chats.upsert': Chat[] /** update the given chats */ 'chats.update': Partial[] @@ -212,7 +212,7 @@ export type BaileysEventMap = { 'contacts.upsert': Contact[] 'contacts.update': Partial[] - 'messages.delete': { jid: string, ids: string[] } | { jid: string, all: true } + 'messages.delete': { keys: WAMessageKey[] } | { jid: string, all: true } 'messages.update': WAMessageUpdate[] /** * add/update the given messages. If they were received while the connection was online, @@ -353,9 +353,8 @@ await conn.sendMessage( ## Forwarding Messages ``` ts -const messages = await conn.loadConversation ('1234@s.whatsapp.net', 1) -const message = messages[0] // get the last message from this conversation -await conn.forwardMessage ('455@s.whatsapp.net', message) // WA forward the message! +const msg = getMessageFromStore('455@s.whatsapp.net', 'HSJHJWH7323HSJSJ') // implement this on your end +await conn.sendMessage('1234@s.whatsapp.net', { forward: msg }) // WA forward the message! ``` ## Reading Messages @@ -415,11 +414,42 @@ const response = await conn.sendMessage(jid, { text: 'hello!' }) // send a messa await conn.sendMessage(jid, { delete: response.key }) ``` -Note: deleting for oneself is not supported yet +Note: deleting for oneself is supported via `chatModify` (next section) ## Modifying Chats -TODO: haven't figured this bit out yet. Can receive chat modifications tho. +WA uses an encrypted form of communication to send chat/app updates. This has been implemented mostly and you can send the following updates: + +- Archive a chat + ``` ts + const lastMsgInChat = await getLastMessageInChat('123456@s.whatsapp.net') // implement this on your end + await conn.chatModify({ archive: true }, '123456@s.whatsapp.net', [lastMsgInChat]) + ``` +- Mute/unmute a chat + ``` ts + // mute for 8 hours + await conn.chatModify({ mute: 8*60*60*1000 }, '123456@s.whatsapp.net', []) + // unmute + await conn.chatModify({ mute: null }, '123456@s.whatsapp.net', []) + ``` +- Mark a chat read/unread + ``` ts + const lastMsgInChat = await getLastMessageInChat('123456@s.whatsapp.net') // implement this on your end + // mark it unread + await conn.chatModify({ markRead: false }, '123456@s.whatsapp.net', [lastMsgInChat]) + ``` + +- Delete message for me + ``` ts + // mark it unread + await conn.chatModify( + { clear: { message: { id: 'ATWYHDNNWU81732J', fromMe: true } } }, + '123456@s.whatsapp.net', + [] + ) + ``` + +Note: if you mess up one of your updates, WA can log you out of all your devices and you'll have to login again. ## Disappearing Messages From b3c1063a3f145633f96bbd1c452a980cb90d505a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 29 Sep 2021 13:36:37 +0530 Subject: [PATCH 079/311] update download media example --- README.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6631971..0bbe94f 100644 --- a/README.md +++ b/README.md @@ -390,16 +390,24 @@ The presence expires after about 10 seconds. If you want to save the media you received ``` ts -import { MessageType } from '@adiwajshing/baileys-md' -conn.on ('message-new', async m => { +import { writeFile } from 'fs/promises' +import { downloadContentFromMessage } from '@adiwajshing/baileys-md' + +conn.ev.on('messages.upsert', async ({ messages }) => { + const m = messages[0] + if (!m.message) return // if there is no text or media message const messageType = Object.keys (m.message)[0]// get what type of message it is -- text, image, video - // if the message is not a text message - if (messageType !== MessageType.text && messageType !== MessageType.extendedText) { - const buffer = await conn.downloadMediaMessage(m) // to decrypt & use as a buffer - - const savedFilename = await conn.downloadAndSaveMediaMessage (m) // to decrypt & save to file - console.log(m.key.remoteJid + " sent media, saved at: " + savedFilename) + // if the message is an image + if (messageType === 'imageMessage') { + // download stream + const stream = await downloadContentFromMessage(m.message.imageMessage, 'image') + let buffer = Buffer.from([]) + for await(const chunk of stream) { + buffer = Buffer.concat([buffer, chunk]) + } + // save to file + await writeFile('./my-download.jpeg', buffer) } } ``` From e84002d807bb47e42bc4c1f4a7777abc59976e9e Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 1 Oct 2021 13:46:19 +0530 Subject: [PATCH 080/311] add emitOwnEvents --- src/Defaults/index.ts | 1 + src/Socket/chats.ts | 7 +++++-- src/Socket/messages-send.ts | 8 +++++--- src/Types/index.ts | 2 ++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index ca14a72..b4ae750 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -28,6 +28,7 @@ export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { keepAliveIntervalMs: 25_000, logger: P().child({ class: 'baileys' }), printQRInTerminal: false, + emitOwnEvents: true } export const MEDIA_PATH_MAP: { [T in MediaType]: string } = { diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index fa4a320..28fb5cd 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -298,7 +298,7 @@ export const makeChatsSocket = (config: SocketConfig) => { } const processSyncActions = (actions: ChatMutation[]) => { - + const updates: { [jid: string]: Partial } = {} const contactUpdates: { [jid: string]: Partial } = {} const msgDeletes: proto.IMessageKey[] = [] @@ -360,7 +360,7 @@ export const makeChatsSocket = (config: SocketConfig) => { ) const initial = await authState.keys.getAppStateSyncVersion(name) // temp: verify it was encoded correctly - await decodePatches({ syncds: [{ ...patch, version: { version: state.version }, }], name }, initial, authState) + const result = await decodePatches({ syncds: [{ ...patch, version: { version: state.version }, }], name }, initial, authState) const node: BinaryNode = { tag: 'iq', @@ -397,6 +397,9 @@ export const makeChatsSocket = (config: SocketConfig) => { await authState.keys.setAppStateSyncVersion(name, state) ev.emit('auth-state.update', authState) + if(config.emitOwnEvents) { + processSyncActions(result.newMutations) + } } const chatModify = (mod: ChatModification, jid: string, lastMessages: Pick[]) => { diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 392db09..1ce0cc5 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -394,9 +394,11 @@ export const makeMessagesSocket = (config: SocketConfig) => { } ) await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id! }) - process.nextTick(() => { - ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) - }) + if(config.emitOwnEvents) { + process.nextTick(() => { + ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) + }) + } return fullMsg } } diff --git a/src/Types/index.ts b/src/Types/index.ts index 351bb6a..470dcc7 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -43,6 +43,8 @@ export type SocketConfig = { fetchAgent?: Agent /** should the QR be printed in the terminal */ printQRInTerminal: boolean + /** should events be emitted for actions done by this socket connection */ + emitOwnEvents: boolean } export enum DisconnectReason { From de8e2811035ccbd4307c92b493e3caa2db066946 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 1 Oct 2021 13:47:02 +0530 Subject: [PATCH 081/311] export WABinay in default export --- src/Defaults/index.ts | 2 -- src/index.ts | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index b4ae750..ae37702 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -4,8 +4,6 @@ import { Browsers } from "../Utils" export const UNAUTHORIZED_CODES = [401, 403, 419] -export const STORIES_JID = 'status@broadcast' - export const DEFAULT_ORIGIN = 'https://web.whatsapp.com' export const DEF_CALLBACK_PREFIX = 'CB:' export const DEF_TAG_PREFIX = 'TAG:' diff --git a/src/index.ts b/src/index.ts index 5f0c293..fe1c58f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,7 @@ export * from './Utils' export * from './Types' //export * from './Store' export * from './Defaults' +export * from './WABinary' export type WASocket = ReturnType From 019e04fb742b066a3d6742d7c2e22504e30099ee Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 1 Oct 2021 14:03:46 +0530 Subject: [PATCH 082/311] add participating groups query --- src/Socket/groups.ts | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts index 39468b6..ff43fd1 100644 --- a/src/Socket/groups.ts +++ b/src/Socket/groups.ts @@ -113,6 +113,40 @@ export const makeGroupsSocket = (config: SocketConfig) => { }, groupSettingUpdate: async(jid: string, setting: 'announcement' | 'not_announcement' | 'locked' | 'unlocked') => { await groupQuery(jid, 'set', [ { tag: setting, attrs: { } } ]) + }, + groupFetchAllParticipating: async() => { + const result = await query({ + tag: 'iq', + attrs: { + to: '@g.us', + xmlns: 'w:g2', + type: 'get', + }, + content: [ + { + tag: 'participating', + attrs: { }, + content: [ + { tag: 'participants', attrs: { } }, + { tag: 'description', attrs: { } } + ] + } + ] + }) + const data: { [_: string]: GroupMetadata } = { } + const groupsChild = getBinaryNodeChild(result, 'groups') + if(groupsChild) { + const groups = getBinaryNodeChildren(groupsChild, 'group') + for(const groupNode of groups) { + const meta = extractGroupMetadata({ + tag: 'result', + attrs: { }, + content: [groupNode] + }) + data[meta.id] = meta + } + } + return data } } } @@ -128,6 +162,7 @@ const extractGroupMetadata = (result: BinaryNode) => { descId = descChild.attrs.id } const groupId = group.attrs.id.includes('@') ? group.attrs.id : jidEncode(group.attrs.id, 'g.us') + const eph = getBinaryNodeChild(group, 'ephemeral')?.attrs.expiration const metadata: GroupMetadata = { id: groupId, subject: group.attrs.subject, @@ -144,7 +179,8 @@ const extractGroupMetadata = (result: BinaryNode) => { admin: attrs.type || null as any, } } - ) + ), + ephemeralDuration: eph ? +eph : undefined } return metadata } \ No newline at end of file From 0c1045b55b6de740f2b7239e3fa9094330581690 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 2 Oct 2021 08:36:09 +0530 Subject: [PATCH 083/311] emit undefined QR at start --- src/Socket/socket.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 3bb2472..80488b8 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -470,7 +470,7 @@ export const makeSocket = ({ end(new Boom('Logged Out', { statusCode: DisconnectReason.loggedOut })) }) process.nextTick(() => { - ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false }) + ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false, qr: undefined }) }) return { From 919781488b666b6b3eabceaccc1ec403368b378f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 4 Oct 2021 09:48:33 +0530 Subject: [PATCH 084/311] upsert contact on app sync patch + add message.participant to full message --- src/Socket/chats.ts | 4 ++-- src/Socket/messages-recv.ts | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 28fb5cd..467ecb7 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -300,7 +300,7 @@ export const makeChatsSocket = (config: SocketConfig) => { const processSyncActions = (actions: ChatMutation[]) => { const updates: { [jid: string]: Partial } = {} - const contactUpdates: { [jid: string]: Partial } = {} + const contactUpdates: { [jid: string]: Contact } = {} const msgDeletes: proto.IMessageKey[] = [] for(const { action, index: [_, id, msgId, fromMe] } of actions) { @@ -343,7 +343,7 @@ export const makeChatsSocket = (config: SocketConfig) => { ev.emit('chats.update', Object.values(updates)) } if(Object.values(contactUpdates).length) { - ev.emit('contacts.update', Object.values(contactUpdates)) + ev.emit('contacts.upsert', Object.values(contactUpdates)) } if(msgDeletes.length) { ev.emit('messages.delete', { keys: msgDeletes }) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index a8beb20..7ee5f8e 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -349,7 +349,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { message, status: isMe ? proto.WebMessageInfo.WebMessageInfoStatus.SERVER_ACK : null, messageTimestamp: dec.timestamp, - pushName: dec.pushname + pushName: dec.pushname, + participant: dec.participant }) } From 3202bae225954ecbf590e6cc47ccdf6fa7e274f4 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 5 Oct 2021 09:47:35 +0530 Subject: [PATCH 085/311] buttons msg fix --- src/Utils/messages.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 2f845d9..7d1a3a3 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -235,12 +235,11 @@ export const generateWAMessageContent = async( } if('buttons' in message && !!message.buttons) { const buttonsMessage: proto.IButtonsMessage = { - buttons: message.buttons!, - text: '' + buttons: message.buttons!.map(b => ({ ...b, type: proto.Button.ButtonType.RESPONSE })) } if('text' in message) { buttonsMessage.contentText = message.text - buttonsMessage.headerType = ButtonType.TEXT + buttonsMessage.headerType = ButtonType.EMPTY } else { if('caption' in message) { buttonsMessage.contentText = message.caption From 063803ae1bd131d0f85029092c8f971428d51661 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 5 Oct 2021 15:51:14 +0530 Subject: [PATCH 086/311] delete message fix --- src/Socket/messages-recv.ts | 1 + src/Socket/messages-send.ts | 15 +++++++++++---- src/Types/Message.ts | 1 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 7ee5f8e..dadeda0 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -222,6 +222,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } ) ev.emit('chats.set', { chats, messages }) + ev.emit('connection.update', { receivedPendingNotifications: true }) break case proto.HistorySync.HistorySyncHistorySyncType.PUSH_NAME: const contacts = item.pushnames.map( diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 1ce0cc5..f3c072e 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -1,7 +1,7 @@ import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions } from "../Types" import { encodeWAMessage, generateMessageID, generateWAMessage } from "../Utils" -import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET } from '../WABinary' +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes } from '../WABinary' import { proto } from "../../WAProto" import { encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESession } from "../Utils/signal" import { WA_DEFAULT_EPHEMERAL, DEFAULT_ORIGIN, MEDIA_PATH_MAP } from "../Defaults" @@ -180,7 +180,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { const relayMessage = async( jid: string, message: proto.IMessage, - { messageId: msgId, cachedGroupMetadata }: MessageRelayOptions + { messageId: msgId, additionalAttributes, cachedGroupMetadata }: MessageRelayOptions ) => { const { user, server } = jidDecode(jid) const isGroup = server === 'g.us' @@ -281,7 +281,8 @@ export const makeMessagesSocket = (config: SocketConfig) => { attrs: { id: msgId, type: 'text', - to: destinationJid + to: destinationJid, + ...(additionalAttributes || {}) }, content: [ { @@ -393,7 +394,13 @@ export const makeMessagesSocket = (config: SocketConfig) => { upload: waUploadToServer } ) - await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id! }) + const additionalAttributes: BinaryNodeAttributes = { } + // required for delete + if('delete' in content) { + additionalAttributes.edit = '7' + } + + await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id!, additionalAttributes }) if(config.emitOwnEvents) { process.nextTick(() => { ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 2346d91..120c895 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -107,6 +107,7 @@ export type AnyMessageContent = AnyRegularMessageContent | { export type MessageRelayOptions = { messageId?: string + additionalAttributes?: { [_: string]: string } cachedGroupMetadata?: (jid: string) => Promise //cachedDevices?: (jid: string) => Promise } From 601c793fcdba7d82237c4f0e42aef54eb8934107 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 5 Oct 2021 17:56:57 +0530 Subject: [PATCH 087/311] dont emit delete msg events --- src/Socket/messages-recv.ts | 2 +- src/Socket/messages-send.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index dadeda0..f9ebf10 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -149,7 +149,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { ev.emit('messages.update', [ { key: protocolMsg.key, - update: { message: null, messageStubType: 1, key: message.key } + update: { message: null, messageStubType: WAMessageStubType.REVOKE, key: message.key } } ]) break diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index f3c072e..c982757 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -394,14 +394,15 @@ export const makeMessagesSocket = (config: SocketConfig) => { upload: waUploadToServer } ) + const isDeleteMsg = 'delete' in content && !!content.delete const additionalAttributes: BinaryNodeAttributes = { } // required for delete - if('delete' in content) { + if(isDeleteMsg) { additionalAttributes.edit = '7' } await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id!, additionalAttributes }) - if(config.emitOwnEvents) { + if(config.emitOwnEvents && !isDeleteMsg) { process.nextTick(() => { ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) }) From 0406f4a9ba08f344d50b42ce8b224078b3a465c5 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 5 Oct 2021 18:42:39 +0530 Subject: [PATCH 088/311] delete msg key fix --- src/Socket/messages-recv.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index f9ebf10..ac4bd95 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -148,8 +148,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { case proto.ProtocolMessage.ProtocolMessageType.REVOKE: ev.emit('messages.update', [ { - key: protocolMsg.key, - update: { message: null, messageStubType: WAMessageStubType.REVOKE, key: message.key } + key: message.key, + update: { message: null, messageStubType: WAMessageStubType.REVOKE, key: protocolMsg.key } } ]) break From e6bc1916c2eef4d5c4b56853471bbcb0e77f9d22 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 5 Oct 2021 19:09:23 +0530 Subject: [PATCH 089/311] Update messages-send.ts --- src/Socket/messages-send.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index c982757..46d7bb3 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -402,7 +402,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { } await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id!, additionalAttributes }) - if(config.emitOwnEvents && !isDeleteMsg) { + if(config.emitOwnEvents) { process.nextTick(() => { ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) }) From c5d8389754a22c3e4ba79a93adda0163dfb7307f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 7 Oct 2021 12:57:02 +0530 Subject: [PATCH 090/311] receipt ack fix --- src/Socket/messages-recv.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index ac4bd95..cebe683 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -148,8 +148,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { case proto.ProtocolMessage.ProtocolMessageType.REVOKE: ev.emit('messages.update', [ { - key: message.key, - update: { message: null, messageStubType: WAMessageStubType.REVOKE, key: protocolMsg.key } + key: protocolMsg.key, + update: { message: null, messageStubType: WAMessageStubType.REVOKE, key: message.key } } ]) break @@ -306,10 +306,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const isGroup = !!stanza.attrs.participant const sender = (attrs.participant || attrs.from)?.toString() const isMe = areJidsSameUser(sender, authState.creds.me!.id) - - await sendMessageAck(stanza) - - logger.debug({ msgId: dec.msgId, sender }, 'send message ack') // send delivery receipt let recpAttrs: { [_: string]: any } @@ -327,17 +323,22 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } else { const isStatus = isJidStatusBroadcast(stanza.attrs.from) recpAttrs = { - //type: 'inactive', + type: 'inactive', id: stanza.attrs.id, - to: dec.chatId, } if(isGroup || isStatus) { recpAttrs.participant = stanza.attrs.participant + recpAttrs.to = dec.chatId + } else { + recpAttrs.to = jidEncode(jidDecode(dec.chatId).user, 'c.us') } } + await sendNode({ tag: 'receipt', attrs: recpAttrs }) + logger.debug({ msgId: dec.msgId }, 'sent message receipt') - logger.debug({ msgId: dec.msgId }, 'send message receipt') + await sendMessageAck(stanza) + logger.debug({ msgId: dec.msgId, sender }, 'sent message ack') const message = msg.deviceSentMessage?.message || msg fullMessages.push({ From edc10d0923138a9bcd973c2b3639041fac3732c0 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 8 Oct 2021 10:48:22 +0530 Subject: [PATCH 091/311] resync from scratch if current sync fails --- src/Socket/chats.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 467ecb7..25ab73d 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -352,8 +352,13 @@ export const makeChatsSocket = (config: SocketConfig) => { const appPatch = async(patchCreate: WAPatchCreate) => { const name = patchCreate.type - - await resyncState(name, false) + try { + await resyncState(name, false) + } catch(error) { + logger.info({ name, error: error.stack }, 'failed to sync state from version, trying from scratch') + await resyncState(name, true) + } + const { patch, state } = await encodeSyncdPatch( patchCreate, authState, From 91bbf575ece5a5759a096e0f7bd0ba2bde9325d3 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 8 Oct 2021 10:50:55 +0530 Subject: [PATCH 092/311] implement recent history sync --- .gitignore | 3 ++- src/Socket/messages-recv.ts | 33 +++++++++++++++++++++++++++------ src/Types/Message.ts | 2 +- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index ad1c15d..ee4cfa5 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ docs browser-token.json Proxy messages*.json -test.ts \ No newline at end of file +test.ts +TestData \ No newline at end of file diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index cebe683..1165119 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -99,14 +99,27 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { ev.emit('auth-state.update', authState) }) } - const processMessage = async(message: proto.IWebMessageInfo, chatUpdate: Partial) => { const protocolMsg = message.message?.protocolMessage if(protocolMsg) { switch(protocolMsg.type) { case proto.ProtocolMessage.ProtocolMessageType.HISTORY_SYNC_NOTIFICATION: - const history = await downloadHistory(protocolMsg!.historySyncNotification) + const histNotification = protocolMsg!.historySyncNotification + + logger.info({ type: histNotification.syncType!, id: message.key.id }, 'got history notification') + const history = await downloadHistory(histNotification) + processHistoryMessage(history) + + const meJid = authState.creds.me!.id + await sendNode({ + tag: 'receipt', + attrs: { + id: message.key.id, + type: 'hist_sync', + to: jidEncode(jidDecode(meJid).user, 'c.us') + } + }) break case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_REQUEST: const keys = await Promise.all( @@ -207,22 +220,30 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } const processHistoryMessage = (item: proto.HistorySync) => { + const messages: proto.IWebMessageInfo[] = [] switch(item.syncType) { case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_BOOTSTRAP: - const messages: proto.IWebMessageInfo[] = [] const chats = item.conversations!.map( c => { const chat: Chat = { ...c } //@ts-expect-error delete chat.messages - for(const item of c.messages || []) { - messages.push(item.message) + if(c.messages?.[0]) { + messages.push(c.messages![0].message!) } return chat } ) ev.emit('chats.set', { chats, messages }) - ev.emit('connection.update', { receivedPendingNotifications: true }) + break + case proto.HistorySync.HistorySyncHistorySyncType.RECENT: + // push remaining messages + for(const conv of item.conversations) { + for(const m of (conv.messages || []).slice(1)) { + messages.push(m.message!) + } + } + ev.emit('messages.upsert', { messages, type: 'prepend' }) break case proto.HistorySync.HistorySyncHistorySyncType.PUSH_NAME: const contacts = item.pushnames.map( diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 120c895..c890a82 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -139,7 +139,7 @@ export type MessageContentGenerationOptions = MediaGenerationOptions & { } export type MessageGenerationOptions = MessageContentGenerationOptions & MessageGenerationOptionsFromContent -export type MessageUpdateType = 'append' | 'notify' +export type MessageUpdateType = 'append' | 'notify' | 'prepend' export type MessageInfoEventMap = { [jid: string]: Date } export interface MessageInfo { From 183a1c6ad04f0d8031ccf295d08de986583d7bca Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 8 Oct 2021 12:07:25 +0530 Subject: [PATCH 093/311] fix message prepend event --- src/Socket/messages-recv.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 1165119..3cb0173 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -239,7 +239,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { case proto.HistorySync.HistorySyncHistorySyncType.RECENT: // push remaining messages for(const conv of item.conversations) { - for(const m of (conv.messages || []).slice(1)) { + for(const m of (conv.messages || [])) { messages.push(m.message!) } } From cacbaa37f2d094c60fbb32c86ebaf8ff18909ac1 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 9 Oct 2021 19:29:10 +0530 Subject: [PATCH 094/311] exclude my device from message send --- src/Socket/messages-send.ts | 7 ++----- src/Utils/signal.ts | 7 ++++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 46d7bb3..642407a 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -124,11 +124,8 @@ export const makeMessagesSocket = (config: SocketConfig) => { ], } const result = await query(iq) - let resultJids = extractDeviceJids(result) - if(ignoreZeroDevices) { - resultJids = resultJids.filter(item => item.device !== 0) - } - return resultJids + const { device } = jidDecode(authState.creds.me!.id) + return extractDeviceJids(result, device, ignoreZeroDevices) } const assertSession = async(jid: string, force: boolean) => { diff --git a/src/Utils/signal.ts b/src/Utils/signal.ts index 3eab1fc..d479491 100644 --- a/src/Utils/signal.ts +++ b/src/Utils/signal.ts @@ -231,7 +231,7 @@ export const parseAndInjectE2ESession = async(node: BinaryNode, auth: Authentica await cipher.initOutgoing(device) } -export const extractDeviceJids = (result: BinaryNode) => { +export const extractDeviceJids = (result: BinaryNode, myDeviceId: number, excludeZeroDevices: boolean) => { const extracted: { user: string, device?: number, agent?: number }[] = [] for(const node of result.content as BinaryNode[]) { const list = getBinaryNodeChild(node, 'list')?.content @@ -242,8 +242,9 @@ export const extractDeviceJids = (result: BinaryNode) => { const deviceListNode = getBinaryNodeChild(devicesNode, 'device-list') if(Array.isArray(deviceListNode?.content)) { for(const { tag, attrs } of deviceListNode!.content) { - if(tag === 'device') { - extracted.push({ user, device: +attrs.id }) + const device = +attrs.id + if(tag === 'device' && myDeviceId !== device && (!excludeZeroDevices || device !== 0)) { + extracted.push({ user, device }) } } } From c75364ada8000b30924c8c01d7fe8b9ab1cdc319 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 9 Oct 2021 20:28:59 +0530 Subject: [PATCH 095/311] include all messages in initial bootstrap --- src/Socket/messages-recv.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 3cb0173..323778a 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -228,8 +228,10 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const chat: Chat = { ...c } //@ts-expect-error delete chat.messages - if(c.messages?.[0]) { - messages.push(c.messages![0].message!) + for(const msg of c.messages || []) { + if(msg.message) { + messages.push(msg.message) + } } return chat } From d3b7ffecf24e17f57ae5539b0f893f71d41973a2 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 11 Oct 2021 09:36:17 +0530 Subject: [PATCH 096/311] code cleanup --- src/Socket/chats.ts | 3 +-- src/Socket/messages-recv.ts | 4 +--- src/Socket/messages-send.ts | 11 +++++------ src/Socket/socket.ts | 7 ++----- src/Utils/chat-utils.ts | 2 +- src/Utils/index.ts | 7 ++++++- src/{WABinary/LTHash.ts => Utils/lt-hash.ts} | 8 +++++++- src/Utils/noise-handler.ts | 2 +- src/WABinary/index.ts | 4 ++-- src/WABinary/{JidUtils.ts => jid-utils.ts} | 0 10 files changed, 26 insertions(+), 22 deletions(-) rename src/{WABinary/LTHash.ts => Utils/lt-hash.ts} (79%) rename src/WABinary/{JidUtils.ts => jid-utils.ts} (100%) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 25ab73d..e6a7e26 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1,8 +1,7 @@ -import { encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch } from "../Utils/chat-utils"; import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, LTHashState, ChatModification, Contact } from "../Types"; import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET } from "../WABinary"; import { proto } from '../../WAProto' -import { generateProfilePicture, toNumber } from "../Utils"; +import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch } from "../Utils"; import { makeMessagesRecvSocket } from "./messages-recv"; export const makeChatsSocket = (config: SocketConfig) => { diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 323778a..7cdd863 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -1,10 +1,8 @@ import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata } from "../Types" -import { decodeMessageStanza, encodeBigEndian, toNumber } from "../Utils" +import { decodeMessageStanza, encodeBigEndian, toNumber, downloadHistory, generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils" import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser } from '../WABinary' -import { downloadHistory } from '../Utils/history' import { proto } from "../../WAProto" -import { generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils/signal" import { KEY_BUNDLE_TYPE } from "../Defaults" import { makeMessagesSocket } from "./messages-send" diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 642407a..76454a5 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -1,12 +1,11 @@ -import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions } from "../Types" -import { encodeWAMessage, generateMessageID, generateWAMessage } from "../Utils" -import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes } from '../WABinary' -import { proto } from "../../WAProto" -import { encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESession } from "../Utils/signal" -import { WA_DEFAULT_EPHEMERAL, DEFAULT_ORIGIN, MEDIA_PATH_MAP } from "../Defaults" import got from "got" import { Boom } from "@hapi/boom" +import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions } from "../Types" +import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESession } from "../Utils" +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes } from '../WABinary' +import { proto } from "../../WAProto" +import { WA_DEFAULT_EPHEMERAL, DEFAULT_ORIGIN, MEDIA_PATH_MAP } from "../Defaults" import { makeGroupsSocket } from "./groups" export const makeMessagesSocket = (config: SocketConfig) => { diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 80488b8..02ef48e 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -5,12 +5,9 @@ import WebSocket from "ws" import { randomBytes } from 'crypto' import { proto } from '../../WAProto' import { DisconnectReason, SocketConfig, BaileysEventEmitter, ConnectionState } from "../Types" -import { Curve, initAuthState, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout } from "../Utils" +import { Curve, initAuthState, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout, generateOrGetPreKeys, xmppSignedPreKey, xmppPreKey, getPreKeys, makeNoiseHandler } from "../Utils" import { DEFAULT_ORIGIN, DEF_TAG_PREFIX, DEF_CALLBACK_PREFIX, KEY_BUNDLE_TYPE } from "../Defaults" import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, S_WHATSAPP_NET } from '../WABinary' -import noiseHandler from '../Utils/noise-handler' -import { generateOrGetPreKeys, xmppSignedPreKey, xmppPreKey, getPreKeys } from '../Utils/signal' - /** * Connects to WA servers and performs: * - simple queries (no retry mechanism, wait for connection establishment) @@ -45,7 +42,7 @@ export const makeSocket = ({ /** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */ const ephemeralKeyPair = Curve.generateKeyPair() /** WA noise protocol wrapper */ - const noise = noiseHandler(ephemeralKeyPair) + const noise = makeNoiseHandler(ephemeralKeyPair) const authState = initialAuthState || initAuthState() const { creds } = authState const ev = new EventEmitter() as BaileysEventEmitter diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 95ac3ca..71ddbc1 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -2,7 +2,7 @@ import { Boom } from '@hapi/boom' import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./crypto" import { AuthenticationState, WAPatchCreate, ChatMutation, WAPatchName, LTHashState, ChatModification } from "../Types" import { proto } from '../../WAProto' -import { LT_HASH_ANTI_TAMPERING } from '../WABinary/LTHash' +import { LT_HASH_ANTI_TAMPERING } from './lt-hash' import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren } from '../WABinary' import { toNumber } from './generics' diff --git a/src/Utils/index.ts b/src/Utils/index.ts index 8ea6ea7..640c9f2 100644 --- a/src/Utils/index.ts +++ b/src/Utils/index.ts @@ -3,4 +3,9 @@ export * from './generics' export * from './messages' export * from './messages-media' export * from './validate-connection' -export * from './crypto' \ No newline at end of file +export * from './crypto' +export * from './signal' +export * from './noise-handler' +export * from './history' +export * from './chat-utils' +export * from './lt-hash' \ No newline at end of file diff --git a/src/WABinary/LTHash.ts b/src/Utils/lt-hash.ts similarity index 79% rename from src/WABinary/LTHash.ts rename to src/Utils/lt-hash.ts index 85ea166..0eeaaa4 100644 --- a/src/WABinary/LTHash.ts +++ b/src/Utils/lt-hash.ts @@ -1,4 +1,10 @@ -import { hkdf } from '../Utils' +import { hkdf } from './crypto' + +/** + * LT Hash is a summation based hash algorithm that maintains the integrity of a piece of data + * over a series of mutations. You can add/remove mutations and it'll return a hash equal to + * if the same series of mutations was made sequentially. + */ const o = 128; diff --git a/src/Utils/noise-handler.ts b/src/Utils/noise-handler.ts index 4f60c03..28039cf 100644 --- a/src/Utils/noise-handler.ts +++ b/src/Utils/noise-handler.ts @@ -14,7 +14,7 @@ const generateIV = (counter: number) => { return new Uint8Array(iv) } -export default ({ public: publicKey, private: privateKey }: KeyPair) => { +export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: KeyPair) => { const authenticate = (data: Uint8Array) => { if(!isFinished) { diff --git a/src/WABinary/index.ts b/src/WABinary/index.ts index bcb8016..74bc259 100644 --- a/src/WABinary/index.ts +++ b/src/WABinary/index.ts @@ -1,5 +1,5 @@ import { DICTIONARIES_MAP, SINGLE_BYTE_TOKEN, SINGLE_BYTE_TOKEN_MAP, DICTIONARIES } from '../../WABinary/Constants'; -import { jidDecode, jidEncode } from './JidUtils'; +import { jidDecode, jidEncode } from './jid-utils'; import { Binary, numUtf8Bytes } from '../../WABinary/Binary'; import { Boom } from '@hapi/boom'; @@ -301,5 +301,5 @@ export const assertNodeErrorFree = (node: BinaryNode) => { } } -export * from './JidUtils' +export * from './jid-utils' export { Binary } from '../../WABinary/Binary' \ No newline at end of file diff --git a/src/WABinary/JidUtils.ts b/src/WABinary/jid-utils.ts similarity index 100% rename from src/WABinary/JidUtils.ts rename to src/WABinary/jid-utils.ts From 3f6bd2ad84c1687e04cf74118753748761d9c629 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 13 Oct 2021 17:42:48 +0530 Subject: [PATCH 097/311] update libsignal + no dependency on proto files + no native deps --- WASignalGroup/GroupProtocol.js | 1697 +++++++++++++++++++++++++++++++ WASignalGroup/generate-proto.sh | 1 + WASignalGroup/group.proto | 29 +- WASignalGroup/protobufs.js | 14 +- package.json | 9 +- src/Utils/crypto.ts | 18 +- yarn.lock | 11 +- 7 files changed, 1733 insertions(+), 46 deletions(-) create mode 100644 WASignalGroup/GroupProtocol.js create mode 100644 WASignalGroup/generate-proto.sh diff --git a/WASignalGroup/GroupProtocol.js b/WASignalGroup/GroupProtocol.js new file mode 100644 index 0000000..efa722a --- /dev/null +++ b/WASignalGroup/GroupProtocol.js @@ -0,0 +1,1697 @@ +/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/ +"use strict"; + +var $protobuf = require("protobufjs/minimal"); + +// Common aliases +var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util; + +// Exported root namespace +var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {}); + +$root.groupproto = (function() { + + /** + * Namespace groupproto. + * @exports groupproto + * @namespace + */ + var groupproto = {}; + + groupproto.SenderKeyMessage = (function() { + + /** + * Properties of a SenderKeyMessage. + * @memberof groupproto + * @interface ISenderKeyMessage + * @property {number|null} [id] SenderKeyMessage id + * @property {number|null} [iteration] SenderKeyMessage iteration + * @property {Uint8Array|null} [ciphertext] SenderKeyMessage ciphertext + */ + + /** + * Constructs a new SenderKeyMessage. + * @memberof groupproto + * @classdesc Represents a SenderKeyMessage. + * @implements ISenderKeyMessage + * @constructor + * @param {groupproto.ISenderKeyMessage=} [properties] Properties to set + */ + function SenderKeyMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SenderKeyMessage id. + * @member {number} id + * @memberof groupproto.SenderKeyMessage + * @instance + */ + SenderKeyMessage.prototype.id = 0; + + /** + * SenderKeyMessage iteration. + * @member {number} iteration + * @memberof groupproto.SenderKeyMessage + * @instance + */ + SenderKeyMessage.prototype.iteration = 0; + + /** + * SenderKeyMessage ciphertext. + * @member {Uint8Array} ciphertext + * @memberof groupproto.SenderKeyMessage + * @instance + */ + SenderKeyMessage.prototype.ciphertext = $util.newBuffer([]); + + /** + * Creates a new SenderKeyMessage instance using the specified properties. + * @function create + * @memberof groupproto.SenderKeyMessage + * @static + * @param {groupproto.ISenderKeyMessage=} [properties] Properties to set + * @returns {groupproto.SenderKeyMessage} SenderKeyMessage instance + */ + SenderKeyMessage.create = function create(properties) { + return new SenderKeyMessage(properties); + }; + + /** + * Encodes the specified SenderKeyMessage message. Does not implicitly {@link groupproto.SenderKeyMessage.verify|verify} messages. + * @function encode + * @memberof groupproto.SenderKeyMessage + * @static + * @param {groupproto.ISenderKeyMessage} message SenderKeyMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderKeyMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.id); + if (message.iteration != null && Object.hasOwnProperty.call(message, "iteration")) + writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.iteration); + if (message.ciphertext != null && Object.hasOwnProperty.call(message, "ciphertext")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.ciphertext); + return writer; + }; + + /** + * Encodes the specified SenderKeyMessage message, length delimited. Does not implicitly {@link groupproto.SenderKeyMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof groupproto.SenderKeyMessage + * @static + * @param {groupproto.ISenderKeyMessage} message SenderKeyMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderKeyMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SenderKeyMessage message from the specified reader or buffer. + * @function decode + * @memberof groupproto.SenderKeyMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {groupproto.SenderKeyMessage} SenderKeyMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderKeyMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.groupproto.SenderKeyMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.uint32(); + break; + case 2: + message.iteration = reader.uint32(); + break; + case 3: + message.ciphertext = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SenderKeyMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof groupproto.SenderKeyMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {groupproto.SenderKeyMessage} SenderKeyMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderKeyMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SenderKeyMessage message. + * @function verify + * @memberof groupproto.SenderKeyMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SenderKeyMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isInteger(message.id)) + return "id: integer expected"; + if (message.iteration != null && message.hasOwnProperty("iteration")) + if (!$util.isInteger(message.iteration)) + return "iteration: integer expected"; + if (message.ciphertext != null && message.hasOwnProperty("ciphertext")) + if (!(message.ciphertext && typeof message.ciphertext.length === "number" || $util.isString(message.ciphertext))) + return "ciphertext: buffer expected"; + return null; + }; + + /** + * Creates a SenderKeyMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof groupproto.SenderKeyMessage + * @static + * @param {Object.} object Plain object + * @returns {groupproto.SenderKeyMessage} SenderKeyMessage + */ + SenderKeyMessage.fromObject = function fromObject(object) { + if (object instanceof $root.groupproto.SenderKeyMessage) + return object; + var message = new $root.groupproto.SenderKeyMessage(); + if (object.id != null) + message.id = object.id >>> 0; + if (object.iteration != null) + message.iteration = object.iteration >>> 0; + if (object.ciphertext != null) + if (typeof object.ciphertext === "string") + $util.base64.decode(object.ciphertext, message.ciphertext = $util.newBuffer($util.base64.length(object.ciphertext)), 0); + else if (object.ciphertext.length) + message.ciphertext = object.ciphertext; + return message; + }; + + /** + * Creates a plain object from a SenderKeyMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof groupproto.SenderKeyMessage + * @static + * @param {groupproto.SenderKeyMessage} message SenderKeyMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SenderKeyMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.id = 0; + object.iteration = 0; + if (options.bytes === String) + object.ciphertext = ""; + else { + object.ciphertext = []; + if (options.bytes !== Array) + object.ciphertext = $util.newBuffer(object.ciphertext); + } + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.iteration != null && message.hasOwnProperty("iteration")) + object.iteration = message.iteration; + if (message.ciphertext != null && message.hasOwnProperty("ciphertext")) + object.ciphertext = options.bytes === String ? $util.base64.encode(message.ciphertext, 0, message.ciphertext.length) : options.bytes === Array ? Array.prototype.slice.call(message.ciphertext) : message.ciphertext; + return object; + }; + + /** + * Converts this SenderKeyMessage to JSON. + * @function toJSON + * @memberof groupproto.SenderKeyMessage + * @instance + * @returns {Object.} JSON object + */ + SenderKeyMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SenderKeyMessage; + })(); + + groupproto.SenderKeyDistributionMessage = (function() { + + /** + * Properties of a SenderKeyDistributionMessage. + * @memberof groupproto + * @interface ISenderKeyDistributionMessage + * @property {number|null} [id] SenderKeyDistributionMessage id + * @property {number|null} [iteration] SenderKeyDistributionMessage iteration + * @property {Uint8Array|null} [chainKey] SenderKeyDistributionMessage chainKey + * @property {Uint8Array|null} [signingKey] SenderKeyDistributionMessage signingKey + */ + + /** + * Constructs a new SenderKeyDistributionMessage. + * @memberof groupproto + * @classdesc Represents a SenderKeyDistributionMessage. + * @implements ISenderKeyDistributionMessage + * @constructor + * @param {groupproto.ISenderKeyDistributionMessage=} [properties] Properties to set + */ + function SenderKeyDistributionMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SenderKeyDistributionMessage id. + * @member {number} id + * @memberof groupproto.SenderKeyDistributionMessage + * @instance + */ + SenderKeyDistributionMessage.prototype.id = 0; + + /** + * SenderKeyDistributionMessage iteration. + * @member {number} iteration + * @memberof groupproto.SenderKeyDistributionMessage + * @instance + */ + SenderKeyDistributionMessage.prototype.iteration = 0; + + /** + * SenderKeyDistributionMessage chainKey. + * @member {Uint8Array} chainKey + * @memberof groupproto.SenderKeyDistributionMessage + * @instance + */ + SenderKeyDistributionMessage.prototype.chainKey = $util.newBuffer([]); + + /** + * SenderKeyDistributionMessage signingKey. + * @member {Uint8Array} signingKey + * @memberof groupproto.SenderKeyDistributionMessage + * @instance + */ + SenderKeyDistributionMessage.prototype.signingKey = $util.newBuffer([]); + + /** + * Creates a new SenderKeyDistributionMessage instance using the specified properties. + * @function create + * @memberof groupproto.SenderKeyDistributionMessage + * @static + * @param {groupproto.ISenderKeyDistributionMessage=} [properties] Properties to set + * @returns {groupproto.SenderKeyDistributionMessage} SenderKeyDistributionMessage instance + */ + SenderKeyDistributionMessage.create = function create(properties) { + return new SenderKeyDistributionMessage(properties); + }; + + /** + * Encodes the specified SenderKeyDistributionMessage message. Does not implicitly {@link groupproto.SenderKeyDistributionMessage.verify|verify} messages. + * @function encode + * @memberof groupproto.SenderKeyDistributionMessage + * @static + * @param {groupproto.ISenderKeyDistributionMessage} message SenderKeyDistributionMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderKeyDistributionMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.id); + if (message.iteration != null && Object.hasOwnProperty.call(message, "iteration")) + writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.iteration); + if (message.chainKey != null && Object.hasOwnProperty.call(message, "chainKey")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.chainKey); + if (message.signingKey != null && Object.hasOwnProperty.call(message, "signingKey")) + writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.signingKey); + return writer; + }; + + /** + * Encodes the specified SenderKeyDistributionMessage message, length delimited. Does not implicitly {@link groupproto.SenderKeyDistributionMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof groupproto.SenderKeyDistributionMessage + * @static + * @param {groupproto.ISenderKeyDistributionMessage} message SenderKeyDistributionMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderKeyDistributionMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SenderKeyDistributionMessage message from the specified reader or buffer. + * @function decode + * @memberof groupproto.SenderKeyDistributionMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {groupproto.SenderKeyDistributionMessage} SenderKeyDistributionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderKeyDistributionMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.groupproto.SenderKeyDistributionMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.uint32(); + break; + case 2: + message.iteration = reader.uint32(); + break; + case 3: + message.chainKey = reader.bytes(); + break; + case 4: + message.signingKey = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SenderKeyDistributionMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof groupproto.SenderKeyDistributionMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {groupproto.SenderKeyDistributionMessage} SenderKeyDistributionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderKeyDistributionMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SenderKeyDistributionMessage message. + * @function verify + * @memberof groupproto.SenderKeyDistributionMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SenderKeyDistributionMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isInteger(message.id)) + return "id: integer expected"; + if (message.iteration != null && message.hasOwnProperty("iteration")) + if (!$util.isInteger(message.iteration)) + return "iteration: integer expected"; + if (message.chainKey != null && message.hasOwnProperty("chainKey")) + if (!(message.chainKey && typeof message.chainKey.length === "number" || $util.isString(message.chainKey))) + return "chainKey: buffer expected"; + if (message.signingKey != null && message.hasOwnProperty("signingKey")) + if (!(message.signingKey && typeof message.signingKey.length === "number" || $util.isString(message.signingKey))) + return "signingKey: buffer expected"; + return null; + }; + + /** + * Creates a SenderKeyDistributionMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof groupproto.SenderKeyDistributionMessage + * @static + * @param {Object.} object Plain object + * @returns {groupproto.SenderKeyDistributionMessage} SenderKeyDistributionMessage + */ + SenderKeyDistributionMessage.fromObject = function fromObject(object) { + if (object instanceof $root.groupproto.SenderKeyDistributionMessage) + return object; + var message = new $root.groupproto.SenderKeyDistributionMessage(); + if (object.id != null) + message.id = object.id >>> 0; + if (object.iteration != null) + message.iteration = object.iteration >>> 0; + if (object.chainKey != null) + if (typeof object.chainKey === "string") + $util.base64.decode(object.chainKey, message.chainKey = $util.newBuffer($util.base64.length(object.chainKey)), 0); + else if (object.chainKey.length) + message.chainKey = object.chainKey; + if (object.signingKey != null) + if (typeof object.signingKey === "string") + $util.base64.decode(object.signingKey, message.signingKey = $util.newBuffer($util.base64.length(object.signingKey)), 0); + else if (object.signingKey.length) + message.signingKey = object.signingKey; + return message; + }; + + /** + * Creates a plain object from a SenderKeyDistributionMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof groupproto.SenderKeyDistributionMessage + * @static + * @param {groupproto.SenderKeyDistributionMessage} message SenderKeyDistributionMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SenderKeyDistributionMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.id = 0; + object.iteration = 0; + if (options.bytes === String) + object.chainKey = ""; + else { + object.chainKey = []; + if (options.bytes !== Array) + object.chainKey = $util.newBuffer(object.chainKey); + } + if (options.bytes === String) + object.signingKey = ""; + else { + object.signingKey = []; + if (options.bytes !== Array) + object.signingKey = $util.newBuffer(object.signingKey); + } + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.iteration != null && message.hasOwnProperty("iteration")) + object.iteration = message.iteration; + if (message.chainKey != null && message.hasOwnProperty("chainKey")) + object.chainKey = options.bytes === String ? $util.base64.encode(message.chainKey, 0, message.chainKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.chainKey) : message.chainKey; + if (message.signingKey != null && message.hasOwnProperty("signingKey")) + object.signingKey = options.bytes === String ? $util.base64.encode(message.signingKey, 0, message.signingKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.signingKey) : message.signingKey; + return object; + }; + + /** + * Converts this SenderKeyDistributionMessage to JSON. + * @function toJSON + * @memberof groupproto.SenderKeyDistributionMessage + * @instance + * @returns {Object.} JSON object + */ + SenderKeyDistributionMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SenderKeyDistributionMessage; + })(); + + groupproto.SenderChainKey = (function() { + + /** + * Properties of a SenderChainKey. + * @memberof groupproto + * @interface ISenderChainKey + * @property {number|null} [iteration] SenderChainKey iteration + * @property {Uint8Array|null} [seed] SenderChainKey seed + */ + + /** + * Constructs a new SenderChainKey. + * @memberof groupproto + * @classdesc Represents a SenderChainKey. + * @implements ISenderChainKey + * @constructor + * @param {groupproto.ISenderChainKey=} [properties] Properties to set + */ + function SenderChainKey(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SenderChainKey iteration. + * @member {number} iteration + * @memberof groupproto.SenderChainKey + * @instance + */ + SenderChainKey.prototype.iteration = 0; + + /** + * SenderChainKey seed. + * @member {Uint8Array} seed + * @memberof groupproto.SenderChainKey + * @instance + */ + SenderChainKey.prototype.seed = $util.newBuffer([]); + + /** + * Creates a new SenderChainKey instance using the specified properties. + * @function create + * @memberof groupproto.SenderChainKey + * @static + * @param {groupproto.ISenderChainKey=} [properties] Properties to set + * @returns {groupproto.SenderChainKey} SenderChainKey instance + */ + SenderChainKey.create = function create(properties) { + return new SenderChainKey(properties); + }; + + /** + * Encodes the specified SenderChainKey message. Does not implicitly {@link groupproto.SenderChainKey.verify|verify} messages. + * @function encode + * @memberof groupproto.SenderChainKey + * @static + * @param {groupproto.ISenderChainKey} message SenderChainKey message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderChainKey.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.iteration != null && Object.hasOwnProperty.call(message, "iteration")) + writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.iteration); + if (message.seed != null && Object.hasOwnProperty.call(message, "seed")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.seed); + return writer; + }; + + /** + * Encodes the specified SenderChainKey message, length delimited. Does not implicitly {@link groupproto.SenderChainKey.verify|verify} messages. + * @function encodeDelimited + * @memberof groupproto.SenderChainKey + * @static + * @param {groupproto.ISenderChainKey} message SenderChainKey message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderChainKey.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SenderChainKey message from the specified reader or buffer. + * @function decode + * @memberof groupproto.SenderChainKey + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {groupproto.SenderChainKey} SenderChainKey + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderChainKey.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.groupproto.SenderChainKey(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.iteration = reader.uint32(); + break; + case 2: + message.seed = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SenderChainKey message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof groupproto.SenderChainKey + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {groupproto.SenderChainKey} SenderChainKey + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderChainKey.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SenderChainKey message. + * @function verify + * @memberof groupproto.SenderChainKey + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SenderChainKey.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.iteration != null && message.hasOwnProperty("iteration")) + if (!$util.isInteger(message.iteration)) + return "iteration: integer expected"; + if (message.seed != null && message.hasOwnProperty("seed")) + if (!(message.seed && typeof message.seed.length === "number" || $util.isString(message.seed))) + return "seed: buffer expected"; + return null; + }; + + /** + * Creates a SenderChainKey message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof groupproto.SenderChainKey + * @static + * @param {Object.} object Plain object + * @returns {groupproto.SenderChainKey} SenderChainKey + */ + SenderChainKey.fromObject = function fromObject(object) { + if (object instanceof $root.groupproto.SenderChainKey) + return object; + var message = new $root.groupproto.SenderChainKey(); + if (object.iteration != null) + message.iteration = object.iteration >>> 0; + if (object.seed != null) + if (typeof object.seed === "string") + $util.base64.decode(object.seed, message.seed = $util.newBuffer($util.base64.length(object.seed)), 0); + else if (object.seed.length) + message.seed = object.seed; + return message; + }; + + /** + * Creates a plain object from a SenderChainKey message. Also converts values to other types if specified. + * @function toObject + * @memberof groupproto.SenderChainKey + * @static + * @param {groupproto.SenderChainKey} message SenderChainKey + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SenderChainKey.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.iteration = 0; + if (options.bytes === String) + object.seed = ""; + else { + object.seed = []; + if (options.bytes !== Array) + object.seed = $util.newBuffer(object.seed); + } + } + if (message.iteration != null && message.hasOwnProperty("iteration")) + object.iteration = message.iteration; + if (message.seed != null && message.hasOwnProperty("seed")) + object.seed = options.bytes === String ? $util.base64.encode(message.seed, 0, message.seed.length) : options.bytes === Array ? Array.prototype.slice.call(message.seed) : message.seed; + return object; + }; + + /** + * Converts this SenderChainKey to JSON. + * @function toJSON + * @memberof groupproto.SenderChainKey + * @instance + * @returns {Object.} JSON object + */ + SenderChainKey.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SenderChainKey; + })(); + + groupproto.SenderMessageKey = (function() { + + /** + * Properties of a SenderMessageKey. + * @memberof groupproto + * @interface ISenderMessageKey + * @property {number|null} [iteration] SenderMessageKey iteration + * @property {Uint8Array|null} [seed] SenderMessageKey seed + */ + + /** + * Constructs a new SenderMessageKey. + * @memberof groupproto + * @classdesc Represents a SenderMessageKey. + * @implements ISenderMessageKey + * @constructor + * @param {groupproto.ISenderMessageKey=} [properties] Properties to set + */ + function SenderMessageKey(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SenderMessageKey iteration. + * @member {number} iteration + * @memberof groupproto.SenderMessageKey + * @instance + */ + SenderMessageKey.prototype.iteration = 0; + + /** + * SenderMessageKey seed. + * @member {Uint8Array} seed + * @memberof groupproto.SenderMessageKey + * @instance + */ + SenderMessageKey.prototype.seed = $util.newBuffer([]); + + /** + * Creates a new SenderMessageKey instance using the specified properties. + * @function create + * @memberof groupproto.SenderMessageKey + * @static + * @param {groupproto.ISenderMessageKey=} [properties] Properties to set + * @returns {groupproto.SenderMessageKey} SenderMessageKey instance + */ + SenderMessageKey.create = function create(properties) { + return new SenderMessageKey(properties); + }; + + /** + * Encodes the specified SenderMessageKey message. Does not implicitly {@link groupproto.SenderMessageKey.verify|verify} messages. + * @function encode + * @memberof groupproto.SenderMessageKey + * @static + * @param {groupproto.ISenderMessageKey} message SenderMessageKey message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderMessageKey.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.iteration != null && Object.hasOwnProperty.call(message, "iteration")) + writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.iteration); + if (message.seed != null && Object.hasOwnProperty.call(message, "seed")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.seed); + return writer; + }; + + /** + * Encodes the specified SenderMessageKey message, length delimited. Does not implicitly {@link groupproto.SenderMessageKey.verify|verify} messages. + * @function encodeDelimited + * @memberof groupproto.SenderMessageKey + * @static + * @param {groupproto.ISenderMessageKey} message SenderMessageKey message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderMessageKey.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SenderMessageKey message from the specified reader or buffer. + * @function decode + * @memberof groupproto.SenderMessageKey + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {groupproto.SenderMessageKey} SenderMessageKey + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderMessageKey.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.groupproto.SenderMessageKey(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.iteration = reader.uint32(); + break; + case 2: + message.seed = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SenderMessageKey message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof groupproto.SenderMessageKey + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {groupproto.SenderMessageKey} SenderMessageKey + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderMessageKey.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SenderMessageKey message. + * @function verify + * @memberof groupproto.SenderMessageKey + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SenderMessageKey.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.iteration != null && message.hasOwnProperty("iteration")) + if (!$util.isInteger(message.iteration)) + return "iteration: integer expected"; + if (message.seed != null && message.hasOwnProperty("seed")) + if (!(message.seed && typeof message.seed.length === "number" || $util.isString(message.seed))) + return "seed: buffer expected"; + return null; + }; + + /** + * Creates a SenderMessageKey message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof groupproto.SenderMessageKey + * @static + * @param {Object.} object Plain object + * @returns {groupproto.SenderMessageKey} SenderMessageKey + */ + SenderMessageKey.fromObject = function fromObject(object) { + if (object instanceof $root.groupproto.SenderMessageKey) + return object; + var message = new $root.groupproto.SenderMessageKey(); + if (object.iteration != null) + message.iteration = object.iteration >>> 0; + if (object.seed != null) + if (typeof object.seed === "string") + $util.base64.decode(object.seed, message.seed = $util.newBuffer($util.base64.length(object.seed)), 0); + else if (object.seed.length) + message.seed = object.seed; + return message; + }; + + /** + * Creates a plain object from a SenderMessageKey message. Also converts values to other types if specified. + * @function toObject + * @memberof groupproto.SenderMessageKey + * @static + * @param {groupproto.SenderMessageKey} message SenderMessageKey + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SenderMessageKey.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.iteration = 0; + if (options.bytes === String) + object.seed = ""; + else { + object.seed = []; + if (options.bytes !== Array) + object.seed = $util.newBuffer(object.seed); + } + } + if (message.iteration != null && message.hasOwnProperty("iteration")) + object.iteration = message.iteration; + if (message.seed != null && message.hasOwnProperty("seed")) + object.seed = options.bytes === String ? $util.base64.encode(message.seed, 0, message.seed.length) : options.bytes === Array ? Array.prototype.slice.call(message.seed) : message.seed; + return object; + }; + + /** + * Converts this SenderMessageKey to JSON. + * @function toJSON + * @memberof groupproto.SenderMessageKey + * @instance + * @returns {Object.} JSON object + */ + SenderMessageKey.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SenderMessageKey; + })(); + + groupproto.SenderSigningKey = (function() { + + /** + * Properties of a SenderSigningKey. + * @memberof groupproto + * @interface ISenderSigningKey + * @property {Uint8Array|null} ["public"] SenderSigningKey public + * @property {Uint8Array|null} ["private"] SenderSigningKey private + */ + + /** + * Constructs a new SenderSigningKey. + * @memberof groupproto + * @classdesc Represents a SenderSigningKey. + * @implements ISenderSigningKey + * @constructor + * @param {groupproto.ISenderSigningKey=} [properties] Properties to set + */ + function SenderSigningKey(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SenderSigningKey public. + * @member {Uint8Array} public + * @memberof groupproto.SenderSigningKey + * @instance + */ + SenderSigningKey.prototype["public"] = $util.newBuffer([]); + + /** + * SenderSigningKey private. + * @member {Uint8Array} private + * @memberof groupproto.SenderSigningKey + * @instance + */ + SenderSigningKey.prototype["private"] = $util.newBuffer([]); + + /** + * Creates a new SenderSigningKey instance using the specified properties. + * @function create + * @memberof groupproto.SenderSigningKey + * @static + * @param {groupproto.ISenderSigningKey=} [properties] Properties to set + * @returns {groupproto.SenderSigningKey} SenderSigningKey instance + */ + SenderSigningKey.create = function create(properties) { + return new SenderSigningKey(properties); + }; + + /** + * Encodes the specified SenderSigningKey message. Does not implicitly {@link groupproto.SenderSigningKey.verify|verify} messages. + * @function encode + * @memberof groupproto.SenderSigningKey + * @static + * @param {groupproto.ISenderSigningKey} message SenderSigningKey message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderSigningKey.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message["public"] != null && Object.hasOwnProperty.call(message, "public")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message["public"]); + if (message["private"] != null && Object.hasOwnProperty.call(message, "private")) + writer.uint32(/* id 2, wireType 2 =*/18).bytes(message["private"]); + return writer; + }; + + /** + * Encodes the specified SenderSigningKey message, length delimited. Does not implicitly {@link groupproto.SenderSigningKey.verify|verify} messages. + * @function encodeDelimited + * @memberof groupproto.SenderSigningKey + * @static + * @param {groupproto.ISenderSigningKey} message SenderSigningKey message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderSigningKey.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SenderSigningKey message from the specified reader or buffer. + * @function decode + * @memberof groupproto.SenderSigningKey + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {groupproto.SenderSigningKey} SenderSigningKey + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderSigningKey.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.groupproto.SenderSigningKey(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message["public"] = reader.bytes(); + break; + case 2: + message["private"] = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SenderSigningKey message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof groupproto.SenderSigningKey + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {groupproto.SenderSigningKey} SenderSigningKey + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderSigningKey.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SenderSigningKey message. + * @function verify + * @memberof groupproto.SenderSigningKey + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SenderSigningKey.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message["public"] != null && message.hasOwnProperty("public")) + if (!(message["public"] && typeof message["public"].length === "number" || $util.isString(message["public"]))) + return "public: buffer expected"; + if (message["private"] != null && message.hasOwnProperty("private")) + if (!(message["private"] && typeof message["private"].length === "number" || $util.isString(message["private"]))) + return "private: buffer expected"; + return null; + }; + + /** + * Creates a SenderSigningKey message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof groupproto.SenderSigningKey + * @static + * @param {Object.} object Plain object + * @returns {groupproto.SenderSigningKey} SenderSigningKey + */ + SenderSigningKey.fromObject = function fromObject(object) { + if (object instanceof $root.groupproto.SenderSigningKey) + return object; + var message = new $root.groupproto.SenderSigningKey(); + if (object["public"] != null) + if (typeof object["public"] === "string") + $util.base64.decode(object["public"], message["public"] = $util.newBuffer($util.base64.length(object["public"])), 0); + else if (object["public"].length) + message["public"] = object["public"]; + if (object["private"] != null) + if (typeof object["private"] === "string") + $util.base64.decode(object["private"], message["private"] = $util.newBuffer($util.base64.length(object["private"])), 0); + else if (object["private"].length) + message["private"] = object["private"]; + return message; + }; + + /** + * Creates a plain object from a SenderSigningKey message. Also converts values to other types if specified. + * @function toObject + * @memberof groupproto.SenderSigningKey + * @static + * @param {groupproto.SenderSigningKey} message SenderSigningKey + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SenderSigningKey.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object["public"] = ""; + else { + object["public"] = []; + if (options.bytes !== Array) + object["public"] = $util.newBuffer(object["public"]); + } + if (options.bytes === String) + object["private"] = ""; + else { + object["private"] = []; + if (options.bytes !== Array) + object["private"] = $util.newBuffer(object["private"]); + } + } + if (message["public"] != null && message.hasOwnProperty("public")) + object["public"] = options.bytes === String ? $util.base64.encode(message["public"], 0, message["public"].length) : options.bytes === Array ? Array.prototype.slice.call(message["public"]) : message["public"]; + if (message["private"] != null && message.hasOwnProperty("private")) + object["private"] = options.bytes === String ? $util.base64.encode(message["private"], 0, message["private"].length) : options.bytes === Array ? Array.prototype.slice.call(message["private"]) : message["private"]; + return object; + }; + + /** + * Converts this SenderSigningKey to JSON. + * @function toJSON + * @memberof groupproto.SenderSigningKey + * @instance + * @returns {Object.} JSON object + */ + SenderSigningKey.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SenderSigningKey; + })(); + + groupproto.SenderKeyStateStructure = (function() { + + /** + * Properties of a SenderKeyStateStructure. + * @memberof groupproto + * @interface ISenderKeyStateStructure + * @property {number|null} [senderKeyId] SenderKeyStateStructure senderKeyId + * @property {groupproto.ISenderChainKey|null} [senderChainKey] SenderKeyStateStructure senderChainKey + * @property {groupproto.ISenderSigningKey|null} [senderSigningKey] SenderKeyStateStructure senderSigningKey + * @property {Array.|null} [senderMessageKeys] SenderKeyStateStructure senderMessageKeys + */ + + /** + * Constructs a new SenderKeyStateStructure. + * @memberof groupproto + * @classdesc Represents a SenderKeyStateStructure. + * @implements ISenderKeyStateStructure + * @constructor + * @param {groupproto.ISenderKeyStateStructure=} [properties] Properties to set + */ + function SenderKeyStateStructure(properties) { + this.senderMessageKeys = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SenderKeyStateStructure senderKeyId. + * @member {number} senderKeyId + * @memberof groupproto.SenderKeyStateStructure + * @instance + */ + SenderKeyStateStructure.prototype.senderKeyId = 0; + + /** + * SenderKeyStateStructure senderChainKey. + * @member {groupproto.ISenderChainKey|null|undefined} senderChainKey + * @memberof groupproto.SenderKeyStateStructure + * @instance + */ + SenderKeyStateStructure.prototype.senderChainKey = null; + + /** + * SenderKeyStateStructure senderSigningKey. + * @member {groupproto.ISenderSigningKey|null|undefined} senderSigningKey + * @memberof groupproto.SenderKeyStateStructure + * @instance + */ + SenderKeyStateStructure.prototype.senderSigningKey = null; + + /** + * SenderKeyStateStructure senderMessageKeys. + * @member {Array.} senderMessageKeys + * @memberof groupproto.SenderKeyStateStructure + * @instance + */ + SenderKeyStateStructure.prototype.senderMessageKeys = $util.emptyArray; + + /** + * Creates a new SenderKeyStateStructure instance using the specified properties. + * @function create + * @memberof groupproto.SenderKeyStateStructure + * @static + * @param {groupproto.ISenderKeyStateStructure=} [properties] Properties to set + * @returns {groupproto.SenderKeyStateStructure} SenderKeyStateStructure instance + */ + SenderKeyStateStructure.create = function create(properties) { + return new SenderKeyStateStructure(properties); + }; + + /** + * Encodes the specified SenderKeyStateStructure message. Does not implicitly {@link groupproto.SenderKeyStateStructure.verify|verify} messages. + * @function encode + * @memberof groupproto.SenderKeyStateStructure + * @static + * @param {groupproto.ISenderKeyStateStructure} message SenderKeyStateStructure message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderKeyStateStructure.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.senderKeyId != null && Object.hasOwnProperty.call(message, "senderKeyId")) + writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.senderKeyId); + if (message.senderChainKey != null && Object.hasOwnProperty.call(message, "senderChainKey")) + $root.groupproto.SenderChainKey.encode(message.senderChainKey, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.senderSigningKey != null && Object.hasOwnProperty.call(message, "senderSigningKey")) + $root.groupproto.SenderSigningKey.encode(message.senderSigningKey, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.senderMessageKeys != null && message.senderMessageKeys.length) + for (var i = 0; i < message.senderMessageKeys.length; ++i) + $root.groupproto.SenderMessageKey.encode(message.senderMessageKeys[i], writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SenderKeyStateStructure message, length delimited. Does not implicitly {@link groupproto.SenderKeyStateStructure.verify|verify} messages. + * @function encodeDelimited + * @memberof groupproto.SenderKeyStateStructure + * @static + * @param {groupproto.ISenderKeyStateStructure} message SenderKeyStateStructure message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderKeyStateStructure.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SenderKeyStateStructure message from the specified reader or buffer. + * @function decode + * @memberof groupproto.SenderKeyStateStructure + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {groupproto.SenderKeyStateStructure} SenderKeyStateStructure + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderKeyStateStructure.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.groupproto.SenderKeyStateStructure(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.senderKeyId = reader.uint32(); + break; + case 2: + message.senderChainKey = $root.groupproto.SenderChainKey.decode(reader, reader.uint32()); + break; + case 3: + message.senderSigningKey = $root.groupproto.SenderSigningKey.decode(reader, reader.uint32()); + break; + case 4: + if (!(message.senderMessageKeys && message.senderMessageKeys.length)) + message.senderMessageKeys = []; + message.senderMessageKeys.push($root.groupproto.SenderMessageKey.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SenderKeyStateStructure message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof groupproto.SenderKeyStateStructure + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {groupproto.SenderKeyStateStructure} SenderKeyStateStructure + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderKeyStateStructure.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SenderKeyStateStructure message. + * @function verify + * @memberof groupproto.SenderKeyStateStructure + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SenderKeyStateStructure.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.senderKeyId != null && message.hasOwnProperty("senderKeyId")) + if (!$util.isInteger(message.senderKeyId)) + return "senderKeyId: integer expected"; + if (message.senderChainKey != null && message.hasOwnProperty("senderChainKey")) { + var error = $root.groupproto.SenderChainKey.verify(message.senderChainKey); + if (error) + return "senderChainKey." + error; + } + if (message.senderSigningKey != null && message.hasOwnProperty("senderSigningKey")) { + var error = $root.groupproto.SenderSigningKey.verify(message.senderSigningKey); + if (error) + return "senderSigningKey." + error; + } + if (message.senderMessageKeys != null && message.hasOwnProperty("senderMessageKeys")) { + if (!Array.isArray(message.senderMessageKeys)) + return "senderMessageKeys: array expected"; + for (var i = 0; i < message.senderMessageKeys.length; ++i) { + var error = $root.groupproto.SenderMessageKey.verify(message.senderMessageKeys[i]); + if (error) + return "senderMessageKeys." + error; + } + } + return null; + }; + + /** + * Creates a SenderKeyStateStructure message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof groupproto.SenderKeyStateStructure + * @static + * @param {Object.} object Plain object + * @returns {groupproto.SenderKeyStateStructure} SenderKeyStateStructure + */ + SenderKeyStateStructure.fromObject = function fromObject(object) { + if (object instanceof $root.groupproto.SenderKeyStateStructure) + return object; + var message = new $root.groupproto.SenderKeyStateStructure(); + if (object.senderKeyId != null) + message.senderKeyId = object.senderKeyId >>> 0; + if (object.senderChainKey != null) { + if (typeof object.senderChainKey !== "object") + throw TypeError(".groupproto.SenderKeyStateStructure.senderChainKey: object expected"); + message.senderChainKey = $root.groupproto.SenderChainKey.fromObject(object.senderChainKey); + } + if (object.senderSigningKey != null) { + if (typeof object.senderSigningKey !== "object") + throw TypeError(".groupproto.SenderKeyStateStructure.senderSigningKey: object expected"); + message.senderSigningKey = $root.groupproto.SenderSigningKey.fromObject(object.senderSigningKey); + } + if (object.senderMessageKeys) { + if (!Array.isArray(object.senderMessageKeys)) + throw TypeError(".groupproto.SenderKeyStateStructure.senderMessageKeys: array expected"); + message.senderMessageKeys = []; + for (var i = 0; i < object.senderMessageKeys.length; ++i) { + if (typeof object.senderMessageKeys[i] !== "object") + throw TypeError(".groupproto.SenderKeyStateStructure.senderMessageKeys: object expected"); + message.senderMessageKeys[i] = $root.groupproto.SenderMessageKey.fromObject(object.senderMessageKeys[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a SenderKeyStateStructure message. Also converts values to other types if specified. + * @function toObject + * @memberof groupproto.SenderKeyStateStructure + * @static + * @param {groupproto.SenderKeyStateStructure} message SenderKeyStateStructure + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SenderKeyStateStructure.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.senderMessageKeys = []; + if (options.defaults) { + object.senderKeyId = 0; + object.senderChainKey = null; + object.senderSigningKey = null; + } + if (message.senderKeyId != null && message.hasOwnProperty("senderKeyId")) + object.senderKeyId = message.senderKeyId; + if (message.senderChainKey != null && message.hasOwnProperty("senderChainKey")) + object.senderChainKey = $root.groupproto.SenderChainKey.toObject(message.senderChainKey, options); + if (message.senderSigningKey != null && message.hasOwnProperty("senderSigningKey")) + object.senderSigningKey = $root.groupproto.SenderSigningKey.toObject(message.senderSigningKey, options); + if (message.senderMessageKeys && message.senderMessageKeys.length) { + object.senderMessageKeys = []; + for (var j = 0; j < message.senderMessageKeys.length; ++j) + object.senderMessageKeys[j] = $root.groupproto.SenderMessageKey.toObject(message.senderMessageKeys[j], options); + } + return object; + }; + + /** + * Converts this SenderKeyStateStructure to JSON. + * @function toJSON + * @memberof groupproto.SenderKeyStateStructure + * @instance + * @returns {Object.} JSON object + */ + SenderKeyStateStructure.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SenderKeyStateStructure; + })(); + + groupproto.SenderKeyRecordStructure = (function() { + + /** + * Properties of a SenderKeyRecordStructure. + * @memberof groupproto + * @interface ISenderKeyRecordStructure + * @property {Array.|null} [senderKeyStates] SenderKeyRecordStructure senderKeyStates + */ + + /** + * Constructs a new SenderKeyRecordStructure. + * @memberof groupproto + * @classdesc Represents a SenderKeyRecordStructure. + * @implements ISenderKeyRecordStructure + * @constructor + * @param {groupproto.ISenderKeyRecordStructure=} [properties] Properties to set + */ + function SenderKeyRecordStructure(properties) { + this.senderKeyStates = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SenderKeyRecordStructure senderKeyStates. + * @member {Array.} senderKeyStates + * @memberof groupproto.SenderKeyRecordStructure + * @instance + */ + SenderKeyRecordStructure.prototype.senderKeyStates = $util.emptyArray; + + /** + * Creates a new SenderKeyRecordStructure instance using the specified properties. + * @function create + * @memberof groupproto.SenderKeyRecordStructure + * @static + * @param {groupproto.ISenderKeyRecordStructure=} [properties] Properties to set + * @returns {groupproto.SenderKeyRecordStructure} SenderKeyRecordStructure instance + */ + SenderKeyRecordStructure.create = function create(properties) { + return new SenderKeyRecordStructure(properties); + }; + + /** + * Encodes the specified SenderKeyRecordStructure message. Does not implicitly {@link groupproto.SenderKeyRecordStructure.verify|verify} messages. + * @function encode + * @memberof groupproto.SenderKeyRecordStructure + * @static + * @param {groupproto.ISenderKeyRecordStructure} message SenderKeyRecordStructure message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderKeyRecordStructure.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.senderKeyStates != null && message.senderKeyStates.length) + for (var i = 0; i < message.senderKeyStates.length; ++i) + $root.groupproto.SenderKeyStateStructure.encode(message.senderKeyStates[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified SenderKeyRecordStructure message, length delimited. Does not implicitly {@link groupproto.SenderKeyRecordStructure.verify|verify} messages. + * @function encodeDelimited + * @memberof groupproto.SenderKeyRecordStructure + * @static + * @param {groupproto.ISenderKeyRecordStructure} message SenderKeyRecordStructure message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SenderKeyRecordStructure.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SenderKeyRecordStructure message from the specified reader or buffer. + * @function decode + * @memberof groupproto.SenderKeyRecordStructure + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {groupproto.SenderKeyRecordStructure} SenderKeyRecordStructure + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderKeyRecordStructure.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.groupproto.SenderKeyRecordStructure(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.senderKeyStates && message.senderKeyStates.length)) + message.senderKeyStates = []; + message.senderKeyStates.push($root.groupproto.SenderKeyStateStructure.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SenderKeyRecordStructure message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof groupproto.SenderKeyRecordStructure + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {groupproto.SenderKeyRecordStructure} SenderKeyRecordStructure + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SenderKeyRecordStructure.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SenderKeyRecordStructure message. + * @function verify + * @memberof groupproto.SenderKeyRecordStructure + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SenderKeyRecordStructure.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.senderKeyStates != null && message.hasOwnProperty("senderKeyStates")) { + if (!Array.isArray(message.senderKeyStates)) + return "senderKeyStates: array expected"; + for (var i = 0; i < message.senderKeyStates.length; ++i) { + var error = $root.groupproto.SenderKeyStateStructure.verify(message.senderKeyStates[i]); + if (error) + return "senderKeyStates." + error; + } + } + return null; + }; + + /** + * Creates a SenderKeyRecordStructure message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof groupproto.SenderKeyRecordStructure + * @static + * @param {Object.} object Plain object + * @returns {groupproto.SenderKeyRecordStructure} SenderKeyRecordStructure + */ + SenderKeyRecordStructure.fromObject = function fromObject(object) { + if (object instanceof $root.groupproto.SenderKeyRecordStructure) + return object; + var message = new $root.groupproto.SenderKeyRecordStructure(); + if (object.senderKeyStates) { + if (!Array.isArray(object.senderKeyStates)) + throw TypeError(".groupproto.SenderKeyRecordStructure.senderKeyStates: array expected"); + message.senderKeyStates = []; + for (var i = 0; i < object.senderKeyStates.length; ++i) { + if (typeof object.senderKeyStates[i] !== "object") + throw TypeError(".groupproto.SenderKeyRecordStructure.senderKeyStates: object expected"); + message.senderKeyStates[i] = $root.groupproto.SenderKeyStateStructure.fromObject(object.senderKeyStates[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a SenderKeyRecordStructure message. Also converts values to other types if specified. + * @function toObject + * @memberof groupproto.SenderKeyRecordStructure + * @static + * @param {groupproto.SenderKeyRecordStructure} message SenderKeyRecordStructure + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SenderKeyRecordStructure.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.senderKeyStates = []; + if (message.senderKeyStates && message.senderKeyStates.length) { + object.senderKeyStates = []; + for (var j = 0; j < message.senderKeyStates.length; ++j) + object.senderKeyStates[j] = $root.groupproto.SenderKeyStateStructure.toObject(message.senderKeyStates[j], options); + } + return object; + }; + + /** + * Converts this SenderKeyRecordStructure to JSON. + * @function toJSON + * @memberof groupproto.SenderKeyRecordStructure + * @instance + * @returns {Object.} JSON object + */ + SenderKeyRecordStructure.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return SenderKeyRecordStructure; + })(); + + return groupproto; +})(); + +module.exports = $root; diff --git a/WASignalGroup/generate-proto.sh b/WASignalGroup/generate-proto.sh new file mode 100644 index 0000000..051876d --- /dev/null +++ b/WASignalGroup/generate-proto.sh @@ -0,0 +1 @@ +yarn pbjs -t static-module -w commonjs -o ./WASignalGroup/GroupProtocol.js ./WASignalGroup/group.proto \ No newline at end of file diff --git a/WASignalGroup/group.proto b/WASignalGroup/group.proto index a83c11e..e6f549b 100644 --- a/WASignalGroup/group.proto +++ b/WASignalGroup/group.proto @@ -13,22 +13,23 @@ message SenderKeyMessage { optional bytes signingKey = 4; } + message SenderChainKey { + optional uint32 iteration = 1; + optional bytes seed = 2; +} + +message SenderMessageKey { + optional uint32 iteration = 1; + optional bytes seed = 2; +} + +message SenderSigningKey { + optional bytes public = 1; + optional bytes private = 2; +} message SenderKeyStateStructure { - message SenderChainKey { - optional uint32 iteration = 1; - optional bytes seed = 2; - } - - message SenderMessageKey { - optional uint32 iteration = 1; - optional bytes seed = 2; - } - - message SenderSigningKey { - optional bytes public = 1; - optional bytes private = 2; - } + optional uint32 senderKeyId = 1; optional SenderChainKey senderChainKey = 2; diff --git a/WASignalGroup/protobufs.js b/WASignalGroup/protobufs.js index 797bd73..76daa5c 100644 --- a/WASignalGroup/protobufs.js +++ b/WASignalGroup/protobufs.js @@ -1,13 +1,3 @@ -const path = require('path'); -const protobuf = require('protobufjs'); +const { groupproto } = require('./GroupProtocol') -const protodir = path.resolve(__dirname); -const group = protobuf.loadSync(path.join(protodir, 'group.proto')).lookup('groupproto'); - -module.exports = { - SenderKeyDistributionMessage: group.lookup('SenderKeyDistributionMessage'), - SenderKeyMessage: group.lookup('SenderKeyMessage'), - SenderKeyStateStructure: group.lookup('SenderKeyStateStructure'), - SenderChainKey: group.lookup('SenderChainKey'), - SenderSigningKey: group.lookup('SenderSigningKey'), -}; +module.exports = groupproto \ No newline at end of file diff --git a/package.json b/package.json index 6c0a9f7..5832a0e 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "multi-device" ], "scripts": { - "test": "mocha --timeout 240000 -r ts-node/register src/Tests/Tests.*.ts", + "test": "jest", "prepare": "tsc", "lint": "eslint '*/*.ts' --quiet --fix", "build:all": "tsc && typedoc", @@ -34,9 +34,10 @@ }, "dependencies": { "@hapi/boom": "^9.1.3", + "curve25519-js": "^0.0.4", "got": "^11.8.1", "jimp": "^0.16.1", - "libsignal": "^2.0.1", + "libsignal": "git+https://github.com/adiwajshing/libsignal-node", "music-metadata": "^7.4.1", "pino": "^6.7.0", "protobufjs": "^6.10.1", @@ -48,8 +49,8 @@ "files": [ "lib/*", "WAProto/*", - "WASignalGroup/*", - "WABinary/*" + "WASignalGroup/*.js", + "WABinary/*.js" ], "devDependencies": { "@types/got": "^9.6.11", diff --git a/src/Utils/crypto.ts b/src/Utils/crypto.ts index 02e8f08..babffd0 100644 --- a/src/Utils/crypto.ts +++ b/src/Utils/crypto.ts @@ -1,32 +1,24 @@ -import CurveCrypto from 'libsignal/src/curve25519_wrapper' +import * as curveJs from 'curve25519-js' import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes } from 'crypto' import { KeyPair } from '../Types' export const Curve = { generateKeyPair: (): KeyPair => { - const { pubKey, privKey } = CurveCrypto.keyPair(randomBytes(32)) + const { public: pubKey, private: privKey } = curveJs.generateKeyPair(randomBytes(32)) return { private: Buffer.from(privKey), public: Buffer.from(pubKey) } }, sharedKey: (privateKey: Uint8Array, publicKey: Uint8Array) => { - const shared = CurveCrypto.sharedSecret(publicKey, privateKey) + const shared = curveJs.sharedKey(privateKey, publicKey) return Buffer.from(shared) }, sign: (privateKey: Uint8Array, buf: Uint8Array) => ( - Buffer.from(CurveCrypto.sign(privateKey, buf)) + Buffer.from(curveJs.sign(privateKey, buf, null)) ), verify: (pubKey: Uint8Array, message: Uint8Array, signature: Uint8Array) => { - try { - CurveCrypto.verify(pubKey, message, signature) - return true - } catch(error) { - if(error.message.includes('Invalid')) { - return false - } - throw error - } + return curveJs.verify(pubKey, message, signature) } } diff --git a/yarn.lock b/yarn.lock index 42d1dd5..48b2201 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1570,6 +1570,11 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" +curve25519-js@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/curve25519-js/-/curve25519-js-0.0.4.tgz#e6ad967e8cd284590d657bbfc90d8b50e49ba060" + integrity sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w== + data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -2698,11 +2703,11 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -libsignal@^2.0.1: +"libsignal@git+https://github.com/adiwajshing/libsignal-node": version "2.0.1" - resolved "https://registry.yarnpkg.com/libsignal/-/libsignal-2.0.1.tgz#c276025c184ae4ebbd7d75c12c0be9f3b50cc19e" - integrity sha512-kqdl/BK5i0WCa4NxhtiBsjSzztB/FtUp3mVVLKBFicWH8rDsq95tEIqNcCaVlflLxOm6T/HRb/zv8IsCe7aopA== + resolved "git+https://github.com/adiwajshing/libsignal-node#11de21293c352a57d0c25d29c66963029873d953" dependencies: + curve25519-js "^0.0.4" protobufjs "6.8.8" load-bmfont@^1.3.1, load-bmfont@^1.4.0: From 466cb614e66065a464988b0204903ca16fb246dc Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 15 Oct 2021 23:59:51 +0530 Subject: [PATCH 098/311] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0bbe94f..2bf610e 100644 --- a/README.md +++ b/README.md @@ -562,7 +562,7 @@ Of course, replace ``` xyz ``` with an actual ID. const metadata = await conn.groupMetadata("abcd-xyz@g.us") console.log(json.id + ", title: " + json.subject + ", description: " + json.desc) ``` -- To join the group using the invitation code +- To join the group using the invitation code (not supported yet) ``` ts const response = await conn.acceptInvite("xxx") console.log("joined to: " + response.gid) @@ -571,6 +571,8 @@ Of course, replace ``` xyz ``` with an actual ID. ## Broadcast Lists & Stories +**Note:** messages cannot be sent to broadcast lists from the MD version right now + - You can send messages to broadcast lists the same way you send messages to groups & individual chats. - Unfortunately, WA Web does not support creating broadcast lists right now but you can still delete them. - Broadcast IDs are in the format `12345678@broadcast` From d0b11dadbfc2e773c4d3fead3ead45368d3cb570 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 23 Oct 2021 10:07:55 +0530 Subject: [PATCH 099/311] add high res picture fetch --- README.md | 3 +++ src/Socket/chats.ts | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2bf610e..ac59e10 100644 --- a/README.md +++ b/README.md @@ -496,8 +496,11 @@ await conn.sendMessage( ``` - To get the display picture of some person/group ``` ts + // for low res picture const ppUrl = await conn.profilePictureUrl("xyz@g.us") console.log("download profile picture from: " + ppUrl) + // for high res picture + const ppUrl = await conn.profilePictureUrl("xyz@g.us", 'image') ``` - To change your display picture or a group's ``` ts diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index e6a7e26..66fe476 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -11,8 +11,6 @@ export const makeChatsSocket = (config: SocketConfig) => { ev, ws, authState, - processMessage, - relayMessage, generateMessageTag, sendNode, query @@ -221,7 +219,12 @@ export const makeChatsSocket = (config: SocketConfig) => { ) } - const profilePictureUrl = async(jid: string) => { + /** + * fetch the profile picture of a user/group + * type = "preview" for a low res picture + * type = "image for the high res picture" + */ + const profilePictureUrl = async(jid: string, type: 'preview' | 'image' = 'preview') => { jid = jidNormalizedUser(jid) const result = await query({ tag: 'iq', @@ -231,7 +234,7 @@ export const makeChatsSocket = (config: SocketConfig) => { xmlns: 'w:profile:picture' }, content: [ - { tag: 'picture', attrs: { type: 'preview', query: 'url' } } + { tag: 'picture', attrs: { type, query: 'url' } } ] }) const child = getBinaryNodeChild(result, 'picture') From 8a23d8ecd6545958f94316db4341fc5f2620690e Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 28 Oct 2021 13:24:30 +0530 Subject: [PATCH 100/311] update signal lib --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 48b2201..c81de94 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2705,7 +2705,7 @@ levn@~0.3.0: "libsignal@git+https://github.com/adiwajshing/libsignal-node": version "2.0.1" - resolved "git+https://github.com/adiwajshing/libsignal-node#11de21293c352a57d0c25d29c66963029873d953" + resolved "git+https://github.com/adiwajshing/libsignal-node#4ffc1f3d6147ffdec88f62e70f41e7de2e08cd42" dependencies: curve25519-js "^0.0.4" protobufjs "6.8.8" From 18c6b44b9ab3c826eb0fe7c6cede504cc78e2cd5 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 28 Oct 2021 13:24:35 +0530 Subject: [PATCH 101/311] Update example.ts --- Example/example.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/Example/example.ts b/Example/example.ts index 5a8565d..f863d5a 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -36,6 +36,7 @@ import makeWASocket, { WASocket, AuthenticationState, DisconnectReason, AnyMessa const startSock = () => { const sock = makeWASocket({ logger: P({ level: 'trace' }), + printQRInTerminal: true, auth: loadState() }) sock.ev.on('messages.upsert', async m => { From 5d8b00489da91c855d54eb1b2e771d45611fe124 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 6 Nov 2021 09:25:26 +0530 Subject: [PATCH 102/311] chore: update version --- src/Defaults/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index ae37702..15c7180 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -18,7 +18,7 @@ export const NOISE_WA_HEADER = new Uint8Array([87, 65, 5, 2]) // last is "DICT_V export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { - version: [2, 2136, 9], + version: [2, 2142, 12], browser: Browsers.baileys('Chrome'), waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', From 12eb181e37a1eeb1f930aaf19cc838da358bb5d8 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 6 Nov 2021 09:25:37 +0530 Subject: [PATCH 103/311] chore: add open connection log --- src/Socket/socket.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 02ef48e..67db00c 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -460,6 +460,9 @@ export const makeSocket = ({ await uploadPreKeys() } await sendPassiveIq('active') + + logger.info('opened connection to WA') + ev.emit('connection.update', { connection: 'open' }) }) // logged out From 5a33fd85a4396ada752ef9b6b3d15015500e4638 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 6 Nov 2021 15:41:49 +0530 Subject: [PATCH 104/311] fix: read receipts --- src/Socket/chats.ts | 26 ++------------------------ src/Socket/messages-recv.ts | 7 +++++-- src/Socket/messages-send.ts | 32 +++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 66fe476..bd412c7 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -13,7 +13,8 @@ export const makeChatsSocket = (config: SocketConfig) => { authState, generateMessageTag, sendNode, - query + query, + fetchPrivacySettings, } = sock const interactiveQuery = async(userNodes: BinaryNode[], queryNode: BinaryNode) => { @@ -145,28 +146,6 @@ export const makeChatsSocket = (config: SocketConfig) => { }) } - const fetchPrivacySettings = async() => { - const result = await query({ - tag: 'iq', - attrs: { - xmlns: 'privacy', - to: S_WHATSAPP_NET, - type: 'get' - }, - content: [ - { tag: 'privacy', attrs: { } } - ] - }) - const nodes = getBinaryNodeChildren(result, 'category') - const settings = nodes.reduce( - (dict, { attrs }) => { - dict[attrs.name] = attrs.value - return dict - }, { } as { [_: string]: string } - ) - return settings - } - const updateAccountSyncTimestamp = async() => { await sendNode({ tag: 'iq', @@ -486,7 +465,6 @@ export const makeChatsSocket = (config: SocketConfig) => { profilePictureUrl, onWhatsApp, fetchBlocklist, - fetchPrivacySettings, fetchStatus, updateProfilePicture, updateBlockStatus, diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 7cdd863..ab86f0e 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -6,6 +6,8 @@ import { proto } from "../../WAProto" import { KEY_BUNDLE_TYPE } from "../Defaults" import { makeMessagesSocket } from "./messages-send" +const isReadReceipt = (type: string) => type === 'read' || type === 'read-self' + export const makeMessagesRecvSocket = (config: SocketConfig) => { const { logger } = config const sock = makeMessagesSocket(config) @@ -412,13 +414,14 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { }) const handleReceipt = ({ tag, attrs, content }: BinaryNode) => { + const isRead = isReadReceipt(attrs.type) if(tag === 'receipt') { // if not read or no type (no type = delivered, but message sent from other device) - if(attrs.type !== 'read' && !!attrs.type) { + if(!isRead && !!attrs.type) { return } } - const status = attrs.type === 'read' ? proto.WebMessageInfo.WebMessageInfoStatus.READ : proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK + const status = isRead ? proto.WebMessageInfo.WebMessageInfoStatus.READ : proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK const ids = [attrs.id] if(Array.isArray(content)) { const items = getBinaryNodeChildren(content[0], 'item') diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 76454a5..0ed975c 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -21,6 +21,32 @@ export const makeMessagesSocket = (config: SocketConfig) => { groupToggleEphemeral } = sock + let privacySettings: { [_: string]: string } | undefined + + const fetchPrivacySettings = async(force: boolean = false) => { + if(!privacySettings || force) { + const result = await query({ + tag: 'iq', + attrs: { + xmlns: 'privacy', + to: S_WHATSAPP_NET, + type: 'get' + }, + content: [ + { tag: 'privacy', attrs: { } } + ] + }) + const nodes = getBinaryNodeChildren(result, 'category') + privacySettings = nodes.reduce( + (dict, { attrs }) => { + dict[attrs.name] = attrs.value + return dict + }, { } as { [_: string]: string } + ) + } + return privacySettings + } + let mediaConn: Promise const refreshMediaConn = async(forceGet = false) => { let media = await mediaConn @@ -52,13 +78,16 @@ export const makeMessagesSocket = (config: SocketConfig) => { } const sendReadReceipt = async(jid: string, participant: string | undefined, messageIds: string[]) => { + const privacySettings = await fetchPrivacySettings() + // based on privacy settings, we have to change the read type + const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self' const node: BinaryNode = { tag: 'receipt', attrs: { id: messageIds[0], t: Date.now().toString(), to: jid, - type: 'read' + type: readType }, } if(participant) { @@ -360,6 +389,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { relayMessage, sendReadReceipt, refreshMediaConn, + fetchPrivacySettings, sendMessage: async( jid: string, content: AnyMessageContent, From 609c925225843220e3a47deeba6607300a825a3f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 6 Nov 2021 16:58:46 +0530 Subject: [PATCH 105/311] fix: delivery receipts --- src/Socket/messages-recv.ts | 19 ++++++++----------- src/Socket/messages-send.ts | 23 +++++++++++++++++------ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index ab86f0e..6d4278d 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -18,6 +18,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { assertingPreKeys, sendNode, relayMessage, + sendDeliveryReceipt, } = sock const sendMessageAck = async({ attrs }: BinaryNode) => { @@ -28,7 +29,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { attrs: { class: 'receipt', id: attrs.id, - to: isGroup ? attrs.from : authState.creds.me!.id, + to: isGroup ? attrs.from : jidEncode(jidDecode(authState.creds.me!.id).user, 'c.us'), } } if(isGroup) { @@ -353,16 +354,19 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { recpAttrs.participant = stanza.attrs.participant recpAttrs.to = dec.chatId } else { - recpAttrs.to = jidEncode(jidDecode(dec.chatId).user, 'c.us') + recpAttrs.to = jidNormalizedUser(dec.chatId) } } - + await sendNode({ tag: 'receipt', attrs: recpAttrs }) logger.debug({ msgId: dec.msgId }, 'sent message receipt') await sendMessageAck(stanza) logger.debug({ msgId: dec.msgId, sender }, 'sent message ack') + await sendDeliveryReceipt(dec.chatId, dec.participant, [dec.msgId]) + logger.debug({ msgId: dec.msgId }, 'sent delivery receipt') + const message = msg.deviceSentMessage?.message || msg fullMessages.push({ key: { @@ -413,14 +417,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { logger.debug({ attrs: node.attrs }, 'sending receipt for ack') }) - const handleReceipt = ({ tag, attrs, content }: BinaryNode) => { + const handleReceipt = ({ attrs, content }: BinaryNode) => { const isRead = isReadReceipt(attrs.type) - if(tag === 'receipt') { - // if not read or no type (no type = delivered, but message sent from other device) - if(!isRead && !!attrs.type) { - return - } - } const status = isRead ? proto.WebMessageInfo.WebMessageInfoStatus.READ : proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK const ids = [attrs.id] if(Array.isArray(content)) { @@ -442,7 +440,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } ws.on('CB:receipt', handleReceipt) - ws.on('CB:ack,class:message', handleReceipt) ws.on('CB:notification', async(node: BinaryNode) => { const sendAck = async() => { diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 0ed975c..bb933d4 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -1,7 +1,7 @@ import got from "got" import { Boom } from "@hapi/boom" -import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions } from "../Types" +import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions, WAMessageKey } from "../Types" import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESession } from "../Utils" import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes } from '../WABinary' import { proto } from "../../WAProto" @@ -77,19 +77,18 @@ export const makeMessagesSocket = (config: SocketConfig) => { return mediaConn } - const sendReadReceipt = async(jid: string, participant: string | undefined, messageIds: string[]) => { - const privacySettings = await fetchPrivacySettings() - // based on privacy settings, we have to change the read type - const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self' + const sendReceipt = async(jid: string, participant: string | undefined, messageIds: string[], type: 'read' | 'read-self' | undefined) => { const node: BinaryNode = { tag: 'receipt', attrs: { id: messageIds[0], t: Date.now().toString(), to: jid, - type: readType }, } + if(type) { + node.attrs.type = type + } if(participant) { node.attrs.participant = participant } @@ -111,6 +110,17 @@ export const makeMessagesSocket = (config: SocketConfig) => { await sendNode(node) } + const sendDeliveryReceipt = (jid: string, participant: string | undefined, messageIds: string[]) => { + return sendReceipt(jid, participant, messageIds, undefined) + } + + const sendReadReceipt = async(jid: string, participant: string | undefined, messageIds: string[]) => { + const privacySettings = await fetchPrivacySettings() + // based on privacy settings, we have to change the read type + const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self' + return sendReceipt(jid, participant, messageIds, readType) + } + const getUSyncDevices = async(jids: string[], ignoreZeroDevices: boolean) => { jids = Array.from(new Set(jids)) const users = jids.map(jid => ({ @@ -387,6 +397,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { ...sock, assertSession, relayMessage, + sendDeliveryReceipt, sendReadReceipt, refreshMediaConn, fetchPrivacySettings, From e547d85f980fba405cae0a4d75457bc63a152245 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 7 Nov 2021 19:05:21 +0530 Subject: [PATCH 106/311] fix: remove redundant collectionSync --- src/Socket/chats.ts | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index bd412c7..a6309e0 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -164,40 +164,6 @@ export const makeChatsSocket = (config: SocketConfig) => { }) } - const collectionSync = async(collections: { name: WAPatchName, version: number }[]) => { - const result = await query({ - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - xmlns: 'w:sync:app:state', - type: 'set' - }, - content: [ - { - tag: 'sync', - attrs: { }, - content: collections.map( - ({ name, version }) => ({ - tag: 'collection', - attrs: { name, version: version.toString(), return_snapshot: 'true' } - }) - ) - } - ] - }) - const syncNode = getBinaryNodeChild(result, 'sync') - const collectionNodes = getBinaryNodeChildren(syncNode, 'collection') - return collectionNodes.reduce( - (dict, node) => { - const snapshotNode = getBinaryNodeChild(node, 'snapshot') - if(snapshotNode) { - dict[node.attrs.name] = snapshotNode.content as Uint8Array - } - return dict - }, { } as { [P in WAPatchName]: Uint8Array } - ) - } - /** * fetch the profile picture of a user/group * type = "preview" for a low res picture From 60d3be460bf668bdfe0a8cad3393660d674ec593 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 7 Nov 2021 19:05:58 +0530 Subject: [PATCH 107/311] chore: log when state sync fails --- src/Socket/chats.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index a6309e0..f27f450 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -412,6 +412,7 @@ export const makeChatsSocket = (config: SocketConfig) => { const update = getBinaryNodeChild(node, 'collection') if(update) { resyncState(update.attrs.name as WAPatchName, false) + .catch(err => logger.error({ trace: err.stack, node }, `failed to sync state`)) } }) From ba502f0436ac74fc3843594c4982aff0e5c29ba6 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 7 Nov 2021 19:07:36 +0530 Subject: [PATCH 108/311] chore: more descriptive LTHash error --- src/Utils/chat-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 71ddbc1..8deb9aa 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -58,7 +58,7 @@ const computeLtHash = (initial: Uint8Array, macs: Mac[], getPrevSetValueMac: (in const subBuff = getPrevSetValueMac(indexMac, i) if(operation === proto.SyncdMutation.SyncdMutationSyncdOperation.REMOVE) { if(!subBuff) { - throw new Boom('') + throw new Boom('tried remove, but no buffer', { statusCode: 500 }) } } else { addBuffs.push(new Uint8Array(valueMac).buffer) From dee815448b4d7fc9ec946b06533186fa487eb02b Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 7 Nov 2021 19:51:14 +0530 Subject: [PATCH 109/311] feat: cache user devices --- package.json | 1 + src/Socket/messages-send.ts | 51 +++++++++++++++++++++++++++++-------- src/Types/index.ts | 3 +++ src/Utils/signal.ts | 4 +-- src/WABinary/jid-utils.ts | 5 ++++ yarn.lock | 12 +++++++++ 6 files changed, 64 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 5832a0e..2ed692d 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "jimp": "^0.16.1", "libsignal": "git+https://github.com/adiwajshing/libsignal-node", "music-metadata": "^7.4.1", + "node-cache": "^5.1.2", "pino": "^6.7.0", "protobufjs": "^6.10.1", "ws": "^7.3.1" diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index bb933d4..cd97fcc 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -3,10 +3,11 @@ import got from "got" import { Boom } from "@hapi/boom" import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions, WAMessageKey } from "../Types" import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESession } from "../Utils" -import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes } from '../WABinary' +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes, JidWithDevice } from '../WABinary' import { proto } from "../../WAProto" import { WA_DEFAULT_EPHEMERAL, DEFAULT_ORIGIN, MEDIA_PATH_MAP } from "../Defaults" import { makeGroupsSocket } from "./groups" +import NodeCache from "node-cache" export const makeMessagesSocket = (config: SocketConfig) => { const { logger } = config @@ -21,6 +22,10 @@ export const makeMessagesSocket = (config: SocketConfig) => { groupToggleEphemeral } = sock + const userDevicesCache = config.userDevicesCache || new NodeCache({ + stdTTL: 300, // 5 minutes + useClones: false + }) let privacySettings: { [_: string]: string } | undefined const fetchPrivacySettings = async(force: boolean = false) => { @@ -122,11 +127,22 @@ export const makeMessagesSocket = (config: SocketConfig) => { } const getUSyncDevices = async(jids: string[], ignoreZeroDevices: boolean) => { + const deviceResults: JidWithDevice[] = [] + + const users: BinaryNode[] = [] jids = Array.from(new Set(jids)) - const users = jids.map(jid => ({ - tag: 'user', - attrs: { jid: jidNormalizedUser(jid) } - })) + for(let jid of jids) { + const user = jidDecode(jid).user + jid = jidNormalizedUser(jid) + if(userDevicesCache.has(user)) { + const devices: JidWithDevice[] = userDevicesCache.get(user) + deviceResults.push(...devices) + + logger.trace({ user }, 'using cache for devices') + } else { + users.push({ tag: 'user', attrs: { jid } }) + } + } const iq: BinaryNode = { tag: 'iq', @@ -163,7 +179,22 @@ export const makeMessagesSocket = (config: SocketConfig) => { } const result = await query(iq) const { device } = jidDecode(authState.creds.me!.id) - return extractDeviceJids(result, device, ignoreZeroDevices) + + const extracted = extractDeviceJids(result, device, ignoreZeroDevices) + const deviceMap: { [_: string]: JidWithDevice[] } = {} + + for(const item of extracted) { + deviceMap[item.user] = deviceMap[item.user] || [] + deviceMap[item.user].push(item) + + deviceResults.push(item) + } + + for(const key in deviceMap) { + userDevicesCache.set(key, deviceMap[key]) + } + + return deviceResults } const assertSession = async(jid: string, force: boolean) => { @@ -245,8 +276,8 @@ export const makeMessagesSocket = (config: SocketConfig) => { } }) - for(const {user, device, agent} of devices) { - const jid = jidEncode(user, 's.whatsapp.net', device, agent) + for(const {user, device} of devices) { + const jid = jidEncode(user, 's.whatsapp.net', device) const participant = await createParticipantNode(jid, encSenderKeyMsg) participants.push(participant) } @@ -301,11 +332,11 @@ export const makeMessagesSocket = (config: SocketConfig) => { logger.debug(`got ${devices.length} additional devices`) - for(const { user, device, agent } of devices) { + for(const { user, device } of devices) { const isMe = user === meUser participants.push( await createParticipantNode( - jidEncode(user, 's.whatsapp.net', device, agent), + jidEncode(user, 's.whatsapp.net', device), isMe ? encodedMeMsg : encodedMsg ) ) diff --git a/src/Types/index.ts b/src/Types/index.ts index 470dcc7..bcc7b1f 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -9,6 +9,7 @@ import type EventEmitter from "events" import type { Agent } from "https" import type { Logger } from "pino" import type { URL } from "url" +import type NodeCache from 'node-cache' import { AuthenticationState } from './Auth' import { Chat, PresenceData } from './Chat' @@ -45,6 +46,8 @@ export type SocketConfig = { printQRInTerminal: boolean /** should events be emitted for actions done by this socket connection */ emitOwnEvents: boolean + /** provide a cache to store a user's device list */ + userDevicesCache?: NodeCache } export enum DisconnectReason { diff --git a/src/Utils/signal.ts b/src/Utils/signal.ts index d479491..c7c90c8 100644 --- a/src/Utils/signal.ts +++ b/src/Utils/signal.ts @@ -3,7 +3,7 @@ import { encodeBigEndian } from "./generics" import { Curve } from "./crypto" import { SenderKeyDistributionMessage, GroupSessionBuilder, SenderKeyRecord, SenderKeyName, GroupCipher } from '../../WASignalGroup' import { SignalIdentity, SignalKeyStore, SignedKeyPair, KeyPair, AuthenticationState } from "../Types/Auth" -import { assertNodeErrorFree, BinaryNode, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildUInt, jidDecode } from "../WABinary" +import { assertNodeErrorFree, BinaryNode, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildUInt, jidDecode, JidWithDevice } from "../WABinary" import { proto } from "../../WAProto" export const generateSignalPubKey = (pubKey: Uint8Array | Buffer) => { @@ -232,7 +232,7 @@ export const parseAndInjectE2ESession = async(node: BinaryNode, auth: Authentica } export const extractDeviceJids = (result: BinaryNode, myDeviceId: number, excludeZeroDevices: boolean) => { - const extracted: { user: string, device?: number, agent?: number }[] = [] + const extracted: JidWithDevice[] = [] for(const node of result.content as BinaryNode[]) { const list = getBinaryNodeChild(node, 'list')?.content if(list && Array.isArray(list)) { diff --git a/src/WABinary/jid-utils.ts b/src/WABinary/jid-utils.ts index 492e050..5b09c00 100644 --- a/src/WABinary/jid-utils.ts +++ b/src/WABinary/jid-utils.ts @@ -6,6 +6,11 @@ export const STORIES_JID = 'status@broadcast' export type JidServer = 'c.us' | 'g.us' | 'broadcast' | 's.whatsapp.net' | 'call' +export type JidWithDevice = { + user: string + device?: number +} + export const jidEncode = (user: string | number | null, server: JidServer, device?: number, agent?: number) => { return `${user || ''}${!!agent ? `_${agent}` : ''}${!!device ? `:${device}` : ''}@${server}` } diff --git a/yarn.lock b/yarn.lock index c81de94..902a756 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1471,6 +1471,11 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" +clone@2.x: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -2897,6 +2902,13 @@ neo-async@^2.6.0: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +node-cache@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-5.1.2.tgz#f264dc2ccad0a780e76253a694e9fd0ed19c398d" + integrity sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg== + dependencies: + clone "2.x" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" From 9b8684701a8f022989a20d691cfff2c24ddc10ce Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 7 Nov 2021 20:27:57 +0530 Subject: [PATCH 110/311] fix: use normalized jid for messages --- src/Socket/messages-recv.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 6d4278d..a75ef25 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -367,10 +367,12 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { await sendDeliveryReceipt(dec.chatId, dec.participant, [dec.msgId]) logger.debug({ msgId: dec.msgId }, 'sent delivery receipt') + const remoteJid = jidNormalizedUser(dec.chatId) + const message = msg.deviceSentMessage?.message || msg fullMessages.push({ key: { - remoteJid: dec.chatId, + remoteJid, fromMe: isMe, id: dec.msgId, participant: dec.participant From 56c17ce0d142c5393955eb8fa22fe3f603691e48 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 8 Nov 2021 00:18:12 +0530 Subject: [PATCH 111/311] feat: implement stream:error events --- src/Socket/socket.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 67db00c..ff2bc3a 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -465,6 +465,12 @@ export const makeSocket = ({ ev.emit('connection.update', { connection: 'open' }) }) + ws.on('CB:stream:error', (node: BinaryNode) => { + logger.error({ error: node }, `stream errored out`) + + const statusCode = +(node.attrs.code || DisconnectReason.restartRequired) + end(new Boom('Stream Errored', { statusCode, data: node })) + }) // logged out ws.on('CB:failure,reason:401', () => { end(new Boom('Logged Out', { statusCode: DisconnectReason.loggedOut })) From d796b286a616b62ae6a104730292043d4bae7866 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 8 Nov 2021 00:18:29 +0530 Subject: [PATCH 112/311] feat: implement account sync --- src/Socket/chats.ts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index f27f450..0b1778d 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -146,7 +146,8 @@ export const makeChatsSocket = (config: SocketConfig) => { }) } - const updateAccountSyncTimestamp = async() => { + const updateAccountSyncTimestamp = async(fromTimestamp: number | string) => { + logger.info({ fromTimestamp }, 'requesting account sync') await sendNode({ tag: 'iq', attrs: { @@ -158,7 +159,10 @@ export const makeChatsSocket = (config: SocketConfig) => { content: [ { tag: 'clean', - attrs: { } + attrs: { + type: 'account_sync', + timestamp: fromTimestamp.toString(), + } } ] }) @@ -408,6 +412,19 @@ export const makeChatsSocket = (config: SocketConfig) => { ws.on('CB:presence', handlePresenceUpdate) ws.on('CB:chatstate', handlePresenceUpdate) + ws.on('CB:ib,,dirty', async(node: BinaryNode) => { + const { attrs } = getBinaryNodeChild(node, 'dirty') + const type = attrs.type + switch(type) { + case 'account_sync': + await updateAccountSyncTimestamp(attrs.timestamp) + break + default: + logger.info({ node }, `received unknown sync`) + break + } + }) + ws.on('CB:notification,type:server_sync', (node: BinaryNode) => { const update = getBinaryNodeChild(node, 'collection') if(update) { From 6eaed6947032ca822b66fa3a8298352f938d9efa Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 8 Nov 2021 00:18:40 +0530 Subject: [PATCH 113/311] fix: remove blocklist console log --- src/Socket/chats.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 0b1778d..f88b71a 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -124,7 +124,6 @@ export const makeChatsSocket = (config: SocketConfig) => { type: 'get' } }) - console.log('blocklist', result) } const updateBlockStatus = async(jid: string, action: 'block' | 'unblock') => { From 85574d1d795f32f75f98dfd9ef52242960c68f2b Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 8 Nov 2021 00:18:59 +0530 Subject: [PATCH 114/311] Revert "fix: remove redundant collectionSync" This reverts commit e547d85f980fba405cae0a4d75457bc63a152245. --- src/Socket/chats.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index f88b71a..c2cbf42 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -167,6 +167,40 @@ export const makeChatsSocket = (config: SocketConfig) => { }) } + const collectionSync = async(collections: { name: WAPatchName, version: number }[]) => { + const result = await query({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + xmlns: 'w:sync:app:state', + type: 'set' + }, + content: [ + { + tag: 'sync', + attrs: { }, + content: collections.map( + ({ name, version }) => ({ + tag: 'collection', + attrs: { name, version: version.toString(), return_snapshot: 'true' } + }) + ) + } + ] + }) + const syncNode = getBinaryNodeChild(result, 'sync') + const collectionNodes = getBinaryNodeChildren(syncNode, 'collection') + return collectionNodes.reduce( + (dict, node) => { + const snapshotNode = getBinaryNodeChild(node, 'snapshot') + if(snapshotNode) { + dict[node.attrs.name] = snapshotNode.content as Uint8Array + } + return dict + }, { } as { [P in WAPatchName]: Uint8Array } + ) + } + /** * fetch the profile picture of a user/group * type = "preview" for a low res picture From 3c6edde1d61af6619dd0eedefd8e286de4ab0d4d Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 8 Nov 2021 13:22:25 +0530 Subject: [PATCH 115/311] fix: listen to all failure messages --- src/Socket/socket.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index ff2bc3a..ddedd35 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -471,9 +471,10 @@ export const makeSocket = ({ const statusCode = +(node.attrs.code || DisconnectReason.restartRequired) end(new Boom('Stream Errored', { statusCode, data: node })) }) - // logged out - ws.on('CB:failure,reason:401', () => { - end(new Boom('Logged Out', { statusCode: DisconnectReason.loggedOut })) + // stream fail, possible logout + ws.on('CB:failure', (node: BinaryNode) => { + const reason = +(node.attrs.reason || 500) + end(new Boom('Connection Failure', { statusCode: reason, data: node.attrs })) }) process.nextTick(() => { ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false, qr: undefined }) From ba453a588be05825b76d90632e8876ad43d7c8c9 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 8 Nov 2021 15:07:25 +0530 Subject: [PATCH 116/311] feat: implement external patch parsing + app state sync on login --- src/Defaults/index.ts | 3 +- src/Socket/chats.ts | 106 ++++++++++++++---------------------- src/Types/Message.ts | 2 +- src/Utils/chat-utils.ts | 54 +++++++++++++----- src/Utils/messages-media.ts | 6 +- src/Utils/messages.ts | 3 +- 6 files changed, 88 insertions(+), 86 deletions(-) diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 15c7180..0d937f2 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -35,7 +35,8 @@ export const MEDIA_PATH_MAP: { [T in MediaType]: string } = { document: '/mms/document', audio: '/mms/audio', sticker: '/mms/image', - history: '' + history: '', + 'md-app-state': '' } export const MEDIA_KEYS = Object.keys(MEDIA_PATH_MAP) as MediaType[] diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index c2cbf42..6513390 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -167,7 +167,16 @@ export const makeChatsSocket = (config: SocketConfig) => { }) } - const collectionSync = async(collections: { name: WAPatchName, version: number }[]) => { + const resyncAppState = async(collections: WAPatchName[], fromScratch: boolean = false, returnSnapshot: boolean = false) => { + const states = { } as { [T in WAPatchName]: LTHashState } + for(const name of collections) { + let state: LTHashState = fromScratch ? undefined : await authState.keys.getAppStateSyncVersion(name) + if(!state) state = { version: 0, hash: Buffer.alloc(128), mutations: [] } + + states[name] = state + + logger.info(`resyncing ${name} from v${state.version}`) + } const result = await query({ tag: 'iq', attrs: { @@ -180,25 +189,35 @@ export const makeChatsSocket = (config: SocketConfig) => { tag: 'sync', attrs: { }, content: collections.map( - ({ name, version }) => ({ + (name) => ({ tag: 'collection', - attrs: { name, version: version.toString(), return_snapshot: 'true' } + attrs: { + name, + version: states[name].version.toString(), + return_snapshot: returnSnapshot ? 'true' : 'false' + } }) ) } ] }) - const syncNode = getBinaryNodeChild(result, 'sync') - const collectionNodes = getBinaryNodeChildren(syncNode, 'collection') - return collectionNodes.reduce( - (dict, node) => { - const snapshotNode = getBinaryNodeChild(node, 'snapshot') - if(snapshotNode) { - dict[node.attrs.name] = snapshotNode.content as Uint8Array - } - return dict - }, { } as { [P in WAPatchName]: Uint8Array } - ) + + const decoded = extractSyncdPatches(result) // extract from binary node + + for(const key in decoded) { + const name = key as WAPatchName + // only process if there are syncd patches + if(decoded[name].length) { + const { newMutations, state: newState } = await decodePatches(name, decoded[name], states[name], authState, true) + + await authState.keys.setAppStateSyncVersion(name, newState) + + logger.info(`synced ${name} to v${newState.version}`) + processSyncActions(newMutations) + } + } + + ev.emit('auth-state.update', authState) } /** @@ -282,7 +301,6 @@ export const makeChatsSocket = (config: SocketConfig) => { } const processSyncActions = (actions: ChatMutation[]) => { - const updates: { [jid: string]: Partial } = {} const contactUpdates: { [jid: string]: Contact } = {} const msgDeletes: proto.IMessageKey[] = [] @@ -337,10 +355,10 @@ export const makeChatsSocket = (config: SocketConfig) => { const appPatch = async(patchCreate: WAPatchCreate) => { const name = patchCreate.type try { - await resyncState(name, false) + await resyncAppState([name]) } catch(error) { logger.info({ name, error: error.stack }, 'failed to sync state from version, trying from scratch') - await resyncState(name, true) + await resyncAppState([name], true) } const { patch, state } = await encodeSyncdPatch( @@ -349,7 +367,7 @@ export const makeChatsSocket = (config: SocketConfig) => { ) const initial = await authState.keys.getAppStateSyncVersion(name) // temp: verify it was encoded correctly - const result = await decodePatches({ syncds: [{ ...patch, version: { version: state.version }, }], name }, initial, authState) + const result = await decodePatches(name, [{ ...patch, version: { version: state.version }, }], initial, authState) const node: BinaryNode = { tag: 'iq', @@ -396,52 +414,6 @@ export const makeChatsSocket = (config: SocketConfig) => { return appPatch(patch) } - const fetchAppState = async(name: WAPatchName, fromVersion: number) => { - const result = await query({ - tag: 'iq', - attrs: { - type: 'set', - xmlns: 'w:sync:app:state', - to: S_WHATSAPP_NET - }, - content: [ - { - tag: 'sync', - attrs: { }, - content: [ - { - tag: 'collection', - attrs: { - name, - version: fromVersion.toString(), - return_snapshot: 'false' - } - } - ] - } - ] - }) - return result - } - - const resyncState = async(name: WAPatchName, fromScratch: boolean) => { - let state: LTHashState = fromScratch ? undefined : await authState.keys.getAppStateSyncVersion(name) - if(!state) state = { version: 0, hash: Buffer.alloc(128), mutations: [] } - - logger.info(`resyncing ${name} from v${state.version}`) - - const result = await fetchAppState(name, state.version) - const decoded = extractSyncdPatches(result) // extract from binary node - const { newMutations, state: newState } = await decodePatches(decoded, state, authState, true) - - await authState.keys.setAppStateSyncVersion(name, newState) - - logger.info(`synced ${name} to v${newState.version}`) - processSyncActions(newMutations) - - ev.emit('auth-state.update', authState) - } - ws.on('CB:presence', handlePresenceUpdate) ws.on('CB:chatstate', handlePresenceUpdate) @@ -461,7 +433,8 @@ export const makeChatsSocket = (config: SocketConfig) => { ws.on('CB:notification,type:server_sync', (node: BinaryNode) => { const update = getBinaryNodeChild(node, 'collection') if(update) { - resyncState(update.attrs.name as WAPatchName, false) + const name = update.attrs.name as WAPatchName + resyncAppState([name], false) .catch(err => logger.error({ trace: err.stack, node }, `failed to sync state`)) } }) @@ -471,6 +444,7 @@ export const makeChatsSocket = (config: SocketConfig) => { sendPresenceUpdate('available') fetchBlocklist() fetchPrivacySettings() + resyncAppState([ 'critical_block', 'critical_unblock_low' ]) } }) @@ -485,7 +459,7 @@ export const makeChatsSocket = (config: SocketConfig) => { fetchStatus, updateProfilePicture, updateBlockStatus, - resyncState, + resyncAppState, chatModify, } } \ No newline at end of file diff --git a/src/Types/Message.ts b/src/Types/Message.ts index c890a82..335c9f0 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -52,7 +52,7 @@ type WithDimensions = { width?: number height?: number } -export type MediaType = 'image' | 'video' | 'sticker' | 'audio' | 'document' | 'history' +export type MediaType = 'image' | 'video' | 'sticker' | 'audio' | 'document' | 'history' | 'md-app-state' export type AnyMediaMessageContent = ( ({ image: WAMediaUpload diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 8deb9aa..e06393b 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -5,6 +5,7 @@ import { proto } from '../../WAProto' import { LT_HASH_ANTI_TAMPERING } from './lt-hash' import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren } from '../WABinary' import { toNumber } from './generics' +import { downloadContentFromMessage, } from './messages-media' export const mutationKeys = (keydata: Uint8Array) => { const expanded = hkdf(keydata, 160, { info: 'WhatsApp Mutation Keys' }) @@ -235,26 +236,44 @@ export const decodeSyncdPatch = async( export const extractSyncdPatches = (result: BinaryNode) => { const syncNode = getBinaryNodeChild(result, 'sync') - const collectionNode = getBinaryNodeChild(syncNode, 'collection') - const patchesNode = getBinaryNodeChild(collectionNode, 'patches') + const collectionNodes = getBinaryNodeChildren(syncNode, 'collection') + + const final = { } as { [T in WAPatchName]: proto.ISyncdPatch[] } + for(const collectionNode of collectionNodes) { + const patchesNode = getBinaryNodeChild(collectionNode, 'patches') - const patches = getBinaryNodeChildren(patchesNode || collectionNode, 'patch') - const syncds: proto.ISyncdPatch[] = [] - const name = collectionNode.attrs.name as WAPatchName - for(let { content } of patches) { - if(content) { - const syncd = proto.SyncdPatch.decode(content! as Uint8Array) - if(!syncd.version) { - syncd.version = { version: +collectionNode.attrs.version+1 } + const patches = getBinaryNodeChildren(patchesNode || collectionNode, 'patch') + const syncds: proto.ISyncdPatch[] = [] + const name = collectionNode.attrs.name as WAPatchName + for(let { content } of patches) { + if(content) { + const syncd = proto.SyncdPatch.decode(content! as Uint8Array) + if(!syncd.version) { + syncd.version = { version: +collectionNode.attrs.version+1 } + } + syncds.push(syncd) } - syncds.push(syncd) } + + final[name] = syncds } - return { syncds, name } + + return final +} + +export const downloadExternalPatch = async(blob: proto.IExternalBlobReference) => { + const stream = await downloadContentFromMessage(blob, 'md-app-state') + let buffer = Buffer.from([]) + for await(const chunk of stream) { + buffer = Buffer.concat([buffer, chunk]) + } + const syncData = proto.SyncdMutations.decode(buffer) + return syncData } export const decodePatches = async( - { syncds, name }: ReturnType, + name: WAPatchName, + syncds: proto.ISyncdPatch[], initial: LTHashState, auth: AuthenticationState, validateMacs: boolean = true @@ -263,8 +282,13 @@ export const decodePatches = async( let current = initial.hash let currentVersion = initial.version + for(const syncd of syncds) { - const { mutations, version, keyId, snapshotMac } = syncd + const { mutations, version, keyId, snapshotMac, externalMutations } = syncd + if(externalMutations) { + const ref = await downloadExternalPatch(externalMutations) + mutations.push(...ref.mutations) + } const macs = mutations.map( m => ({ operation: m.operation!, @@ -308,7 +332,7 @@ export const decodePatches = async( const result = mutationKeys(keyEnc.keyData!) const computedSnapshotMac = generateSnapshotMac(current, currentVersion, name, result.snapshotMacKey) if(Buffer.compare(snapshotMac, computedSnapshotMac) !== 0) { - throw new Boom(`failed to verify LTHash at ${currentVersion}`, { statusCode: 500 }) + throw new Boom(`failed to verify LTHash at ${currentVersion} of ${name}`, { statusCode: 500 }) } } diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 3df3a76..05f3253 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -16,9 +16,11 @@ import { hkdf } from './crypto' import { DEFAULT_ORIGIN } from '../Defaults' export const hkdfInfoKey = (type: MediaType) => { - if(type === 'sticker') type = 'image' + let str: string = type + if(type === 'sticker') str = 'image' + if(type === 'md-app-state') str = 'App State' - let hkdfInfo = type[0].toUpperCase() + type.slice(1) + let hkdfInfo = str[0].toUpperCase() + str.slice(1) return `WhatsApp ${hkdfInfo} Keys` } /** generates all the keys required to encrypt/decrypt & sign a media message */ diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 7d1a3a3..491cc0c 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -38,7 +38,8 @@ const MIMETYPE_MAP: { [T in MediaType]: string } = { document: 'application/pdf', audio: 'audio/ogg; codecs=opus', sticker: 'image/webp', - history: 'application/x-protobuf' + history: 'application/x-protobuf', + "md-app-state": 'application/x-protobuf', } const MessageTypeProto = { From 070722fcac6c84b713fccd83a22afc68fe5078da Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 8 Nov 2021 21:47:49 +0530 Subject: [PATCH 117/311] fix: log failed app syncs --- src/Socket/chats.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 6513390..a8324c2 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -445,6 +445,7 @@ export const makeChatsSocket = (config: SocketConfig) => { fetchBlocklist() fetchPrivacySettings() resyncAppState([ 'critical_block', 'critical_unblock_low' ]) + .catch(err => logger.info({ trace: err.stack }, 'failed to sync app state')) } }) From 4edfc7531b7a9c0c64d6d21193dcc2dcd6a1def7 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 8 Nov 2021 21:51:06 +0530 Subject: [PATCH 118/311] fix: possibly more accurate receipts --- src/Socket/messages-recv.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index a75ef25..8265a42 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -29,7 +29,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { attrs: { class: 'receipt', id: attrs.id, - to: isGroup ? attrs.from : jidEncode(jidDecode(authState.creds.me!.id).user, 'c.us'), + to: isGroup ? attrs.from : authState.creds.me!.id, } } if(isGroup) { @@ -347,7 +347,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } else { const isStatus = isJidStatusBroadcast(stanza.attrs.from) recpAttrs = { - type: 'inactive', id: stanza.attrs.id, } if(isGroup || isStatus) { @@ -419,7 +418,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { logger.debug({ attrs: node.attrs }, 'sending receipt for ack') }) - const handleReceipt = ({ attrs, content }: BinaryNode) => { + const handleReceipt = async(node: BinaryNode) => { + const { attrs, content } = node const isRead = isReadReceipt(attrs.type) const status = isRead ? proto.WebMessageInfo.WebMessageInfoStatus.READ : proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK const ids = [attrs.id] @@ -439,6 +439,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { }, update: { status } }))) + + await sendMessageAck(node) } ws.on('CB:receipt', handleReceipt) From 5120f1d1e419c7fadef7b35a04974dbd7c3bb4d8 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 8 Nov 2021 22:58:03 +0530 Subject: [PATCH 119/311] fix: ack receipts --- src/Socket/messages-recv.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 8265a42..b00d92e 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -21,7 +21,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { sendDeliveryReceipt, } = sock - const sendMessageAck = async({ attrs }: BinaryNode) => { + const sendMessageAck = async({ attrs }: BinaryNode, includeType: boolean) => { const isGroup = !!attrs.participant const { user: meUser } = jidDecode(authState.creds.me!.id!) const stanza: BinaryNode = { @@ -32,9 +32,13 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { to: isGroup ? attrs.from : authState.creds.me!.id, } } + if(includeType) { + stanza.attrs.type = attrs.type + } if(isGroup) { stanza.attrs.participant = jidEncode(meUser, 's.whatsapp.net') } + logger.debug({ attrs: stanza.attrs }, 'sent message ack') await sendNode(stanza) } @@ -360,8 +364,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { await sendNode({ tag: 'receipt', attrs: recpAttrs }) logger.debug({ msgId: dec.msgId }, 'sent message receipt') - await sendMessageAck(stanza) - logger.debug({ msgId: dec.msgId, sender }, 'sent message ack') + await sendMessageAck(stanza, false) await sendDeliveryReceipt(dec.chatId, dec.participant, [dec.msgId]) logger.debug({ msgId: dec.msgId }, 'sent delivery receipt') @@ -440,7 +443,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { update: { status } }))) - await sendMessageAck(node) + await sendMessageAck(node, true) } ws.on('CB:receipt', handleReceipt) From cd59b8fc9724fbc80f3ef175596ef0a895bbcb08 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 9 Nov 2021 00:09:50 +0530 Subject: [PATCH 120/311] fix: extract msg content correctly --- src/Utils/messages.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 491cc0c..0ceab16 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -342,6 +342,11 @@ export const generateWAMessage = async( * Eg. extracts the inner message from a disappearing message/view once message */ export const extractMessageContent = (content: WAMessageContent | undefined | null): WAMessageContent | undefined => { + content = content?.ephemeralMessage?.message || + content?.viewOnceMessage?.message || + content || + undefined + if(content?.buttonsMessage) { const { buttonsMessage } = content if(buttonsMessage.imageMessage) { @@ -355,10 +360,6 @@ export const extractMessageContent = (content: WAMessageContent | undefined | nu } else { return { conversation: buttonsMessage.contentText } } - } else { - return content?.ephemeralMessage?.message || - content?.viewOnceMessage?.message || - content || - undefined } - } \ No newline at end of file + return content +} \ No newline at end of file From cfa7e8ec66aab05baa30aeb1e167d149528f9f52 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 9 Nov 2021 13:40:59 +0530 Subject: [PATCH 121/311] fix: possible ack fix --- src/Socket/messages-recv.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index b00d92e..ae2e22b 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -23,20 +23,20 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const sendMessageAck = async({ attrs }: BinaryNode, includeType: boolean) => { const isGroup = !!attrs.participant - const { user: meUser } = jidDecode(authState.creds.me!.id!) + const meJid = authState.creds.me!.id! const stanza: BinaryNode = { tag: 'ack', attrs: { class: 'receipt', id: attrs.id, - to: isGroup ? attrs.from : authState.creds.me!.id, + to: attrs.from, } } if(includeType) { stanza.attrs.type = attrs.type } if(isGroup) { - stanza.attrs.participant = jidEncode(meUser, 's.whatsapp.net') + stanza.attrs.participant = jidNormalizedUser(meJid) } logger.debug({ attrs: stanza.attrs }, 'sent message ack') await sendNode(stanza) @@ -513,5 +513,5 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } }) - return { ...sock, processMessage } + return { ...sock, processMessage, sendMessageAck } } \ No newline at end of file From 3e5474104213ba6e37a6951cbf2cb21b325e11e1 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 10 Nov 2021 19:22:00 +0530 Subject: [PATCH 122/311] feat: cache media uploads --- src/Socket/messages-send.ts | 10 ++++++---- src/Types/Message.ts | 9 +++++++-- src/Types/index.ts | 2 ++ src/Utils/messages.ts | 27 +++++++++++++++++++-------- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index cd97fcc..5a547ba 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -379,7 +379,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { return msgId } - const waUploadToServer: WAMediaUploadFunction = async(stream, { mediaType, fileEncSha256B64 }) => { + const waUploadToServer: WAMediaUploadFunction = async(stream, { mediaType, fileEncSha256B64, timeoutMs }) => { // send a query JSON to obtain the url & auth token to upload our media let uploadInfo = await refreshMediaConn(false) @@ -399,7 +399,8 @@ export const makeMessagesSocket = (config: SocketConfig) => { agent: { https: config.agent }, - body: stream + body: stream, + timeout: timeoutMs } ) const result = JSON.parse(responseText) @@ -456,10 +457,11 @@ export const makeMessagesSocket = (config: SocketConfig) => { { ...options, logger, - userJid: userJid, + userJid, // multi-device does not have this yet //getUrlInfo: generateUrlInfo, - upload: waUploadToServer + upload: waUploadToServer, + mediaCache: config.mediaCache, } ) const isDeleteMsg = 'delete' in content && !!content.delete diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 335c9f0..fb768f2 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -1,6 +1,7 @@ import type { ReadStream } from "fs" import type { Logger } from "pino" import type { URL } from "url" +import type NodeCache from "node-cache" import type { GroupMetadata } from "./GroupMetadata" import { proto } from '../../WAProto' @@ -121,18 +122,22 @@ export type MiscMessageGenerationOptions = { quoted?: WAMessage /** disappearing messages settings */ ephemeralExpiration?: number | string + + mediaUploadTimeoutMs?: number } export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & { userJid: string } -export type WAMediaUploadFunction = (readStream: ReadStream, opts: { fileEncSha256B64: string, mediaType: MediaType }) => Promise<{ mediaUrl: string }> +export type WAMediaUploadFunction = (readStream: ReadStream, opts: { fileEncSha256B64: string, mediaType: MediaType, timeoutMs?: number }) => Promise<{ mediaUrl: string }> export type MediaGenerationOptions = { logger?: Logger upload: WAMediaUploadFunction /** cache media so it does not have to be uploaded again */ - mediaCache?: (url: string) => Promise | WAGenericMediaMessage + mediaCache?: NodeCache + + mediaUploadTimeoutMs?: number } export type MessageContentGenerationOptions = MediaGenerationOptions & { getUrlInfo?: (text: string) => Promise diff --git a/src/Types/index.ts b/src/Types/index.ts index bcc7b1f..6816d21 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -48,6 +48,8 @@ export type SocketConfig = { emitOwnEvents: boolean /** provide a cache to store a user's device list */ userDevicesCache?: NodeCache + /** provide a cache to store media, so does not have to be re-uploaded */ + mediaCache?: NodeCache } export enum DisconnectReason { diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 0ceab16..3550bc4 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -67,13 +67,19 @@ export const prepareWAMessageMedia = async( [mediaType]: undefined, media: message[mediaType] } + // check if cacheable + generate cache key + const cacheableKey = typeof uploadData.media === 'object' && + ('url' in uploadData.media) && + !!uploadData.media.url && + !!options.mediaCache && ( + // generate the key + mediaType + ':' + uploadData.media.url!.toString() + ) // check for cache hit - if(typeof uploadData.media === 'object' && 'url' in uploadData.media) { - const result = !!options.mediaCache && await options.mediaCache!(uploadData.media.url?.toString()) - if(result) { - return WAProto.Message.fromObject({ - [`${mediaType}Message`]: result - }) + if(cacheableKey) { + const mediaBuff: Buffer = options.mediaCache!.get(cacheableKey) + if(mediaBuff) { + return WAProto.Message.decode(mediaBuff) } } if(mediaType === 'document' && !uploadData.fileName) { @@ -114,7 +120,7 @@ export const prepareWAMessageMedia = async( } const {mediaUrl} = await options.upload( createReadStream(encBodyPath), - { fileEncSha256B64, mediaType } + { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs } ) // remove tmp files await Promise.all( @@ -138,7 +144,12 @@ export const prepareWAMessageMedia = async( } ) } - return WAProto.Message.fromObject(content) + const obj = WAProto.Message.fromObject(content) + if(cacheableKey) { + options.mediaCache!.set(cacheableKey, WAProto.Message.encode(obj)) + } + + return obj } export const prepareDisappearingMessageSettingContent = (ephemeralExpiration?: number) => { ephemeralExpiration = ephemeralExpiration || 0 From 469f3451d266464c85c2ff025a57c64dc6d5998e Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 10 Nov 2021 19:46:25 +0530 Subject: [PATCH 123/311] feat: catch groups create notification --- src/Socket/groups.ts | 2 +- src/Socket/messages-recv.ts | 26 +++++++++++++++++++++----- src/Types/index.ts | 1 + 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts index ff43fd1..caec21f 100644 --- a/src/Socket/groups.ts +++ b/src/Socket/groups.ts @@ -152,7 +152,7 @@ export const makeGroupsSocket = (config: SocketConfig) => { } -const extractGroupMetadata = (result: BinaryNode) => { +export const extractGroupMetadata = (result: BinaryNode) => { const group = getBinaryNodeChild(result, 'group') const descChild = getBinaryNodeChild(group, 'description') let desc: string | undefined diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index ae2e22b..bfb195d 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -1,10 +1,11 @@ import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata } from "../Types" import { decodeMessageStanza, encodeBigEndian, toNumber, downloadHistory, generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils" -import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser } from '../WABinary' +import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser, getBinaryNodeChild } from '../WABinary' import { proto } from "../../WAProto" import { KEY_BUNDLE_TYPE } from "../Defaults" import { makeMessagesSocket } from "./messages-send" +import { extractGroupMetadata } from "./groups" const isReadReceipt = (type: string) => type === 'read' || type === 'read-self' @@ -216,7 +217,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { emitGroupUpdate({ restrict }) break case WAMessageStubType.GROUP_CHANGE_SUBJECT: - case WAMessageStubType.GROUP_CREATE: chatUpdate.name = message.messageStubParameters[0] emitGroupUpdate({ subject: chatUpdate.name }) break @@ -270,6 +270,18 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { if(node.attrs.type === 'w:gp2') { switch(child?.tag) { + case 'create': + const metadata = extractGroupMetadata(child) + result.messageStubType = WAMessageStubType.GROUP_CREATE + result.messageStubParameters = [metadata.subject] + + ev.emit('chats.upsert', [{ + id: metadata.id, + name: metadata.subject, + conversationTimestamp: metadata.creation, + }]) + ev.emit('groups.upsert', [metadata]) + break case 'ephemeral': case 'not_ephemeral': result.message = { @@ -450,7 +462,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { ws.on('CB:notification', async(node: BinaryNode) => { const sendAck = async() => { - await sendNode({ + const stanza: BinaryNode = { tag: 'ack', attrs: { class: 'notification', @@ -458,9 +470,13 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { type: node.attrs.type, to: node.attrs.from } - }) + } + if(node.attrs.participant) { + stanza.attrs.participant = node.attrs.participant + } + await sendNode(stanza) - logger.debug({ msgId: node.attrs.id }, 'ack notification') + logger.debug({ attrs: stanza.attrs }, 'ack notification') } await sendAck() diff --git a/src/Types/index.ts b/src/Types/index.ts index 6816d21..a860819 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -120,6 +120,7 @@ export type BaileysEventMap = { 'message-info.update': MessageInfoUpdate[] + 'groups.upsert': GroupMetadata[] 'groups.update': Partial[] /** apply an action to participants in a group */ 'group-participants.update': { id: string, participants: string[], action: ParticipantAction } From 05b3095bfdf9b24beb5816a25820177d1716b37a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 11 Nov 2021 09:43:10 +0530 Subject: [PATCH 124/311] fix: message ack on group messages --- src/Socket/messages-recv.ts | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index bfb195d..7080ff7 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -1,7 +1,7 @@ import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata } from "../Types" import { decodeMessageStanza, encodeBigEndian, toNumber, downloadHistory, generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils" -import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser, getBinaryNodeChild } from '../WABinary' +import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser, getAllBinaryNodeChildren, BinaryNodeAttributes } from '../WABinary' import { proto } from "../../WAProto" import { KEY_BUNDLE_TYPE } from "../Defaults" import { makeMessagesSocket } from "./messages-send" @@ -22,24 +22,19 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { sendDeliveryReceipt, } = sock - const sendMessageAck = async({ attrs }: BinaryNode, includeType: boolean) => { - const isGroup = !!attrs.participant - const meJid = authState.creds.me!.id! + const sendMessageAck = async({ tag, attrs }: BinaryNode, extraAttrs: BinaryNodeAttributes) => { const stanza: BinaryNode = { tag: 'ack', attrs: { - class: 'receipt', id: attrs.id, to: attrs.from, + ...extraAttrs, } } - if(includeType) { - stanza.attrs.type = attrs.type + if(!!attrs.participant) { + stanza.attrs.participant = jidNormalizedUser(attrs.participant) } - if(isGroup) { - stanza.attrs.participant = jidNormalizedUser(meJid) - } - logger.debug({ attrs: stanza.attrs }, 'sent message ack') + logger.debug({ recv: attrs, sent: stanza.attrs }, `sent "${tag}" ack`) await sendNode(stanza) } @@ -376,7 +371,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { await sendNode({ tag: 'receipt', attrs: recpAttrs }) logger.debug({ msgId: dec.msgId }, 'sent message receipt') - await sendMessageAck(stanza, false) + await sendMessageAck(stanza, { class: 'receipt' }) await sendDeliveryReceipt(dec.chatId, dec.participant, [dec.msgId]) logger.debug({ msgId: dec.msgId }, 'sent delivery receipt') @@ -455,7 +450,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { update: { status } }))) - await sendMessageAck(node, true) + await sendMessageAck(node, { class: 'receipt', type: attrs.type }) } ws.on('CB:receipt', handleReceipt) From d8c8d46adb6fc4ffd67aa9e477d25994cb789d78 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 11 Nov 2021 11:24:10 +0530 Subject: [PATCH 125/311] feat: implement call ack --- src/Socket/messages-recv.ts | 9 +++++++++ src/WABinary/index.ts | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 7080ff7..0a8f959 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -428,6 +428,15 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { logger.debug({ attrs: node.attrs }, 'sending receipt for ack') }) + ws.on('CB:call', async(node: BinaryNode) => { + logger.info({ node }, 'recv call') + + const [child] = getAllBinaryNodeChildren(node) + if(child.tag === 'terminate' || child.tag === 'relaylatency') { + await sendMessageAck(node, { class: 'call', type: child.tag }) + } + }) + const handleReceipt = async(node: BinaryNode) => { const { attrs, content } = node const isRead = isReadReceipt(attrs.type) diff --git a/src/WABinary/index.ts b/src/WABinary/index.ts index 74bc259..e9d677c 100644 --- a/src/WABinary/index.ts +++ b/src/WABinary/index.ts @@ -276,6 +276,13 @@ export const getBinaryNodeChildren = ({ content }: BinaryNode, childTag: string) return [] } +export const getAllBinaryNodeChildren = ({ content }: BinaryNode) => { + if(Array.isArray(content)) { + return content + } + return [] +} + export const getBinaryNodeChild = ({ content }: BinaryNode, childTag: string) => { if(Array.isArray(content)) { return content.find(item => item.tag == childTag) From 71664756dd34babbeaf6a1822997652ff68c6afe Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 11 Nov 2021 11:29:12 +0530 Subject: [PATCH 126/311] style: use getAllBinaryNodeChildren --- src/Socket/messages-recv.ts | 4 ++-- src/Utils/validate-connection.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 0a8f959..12156b5 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -190,7 +190,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { participants = message.messageStubParameters emitParticipantsUpdate('remove') // mark the chat read only if you left the group - if (participants.includes(meJid)) { + if(participants.includes(meJid)) { chatUpdate.readOnly = true } break @@ -261,7 +261,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const processNotification = (node: BinaryNode): Partial => { const result: Partial = { } - const child = (node.content as BinaryNode[])?.[0] + const [child] = getAllBinaryNodeChildren(node) if(node.attrs.type === 'w:gp2') { switch(child?.tag) { diff --git a/src/Utils/validate-connection.ts b/src/Utils/validate-connection.ts index 2709852..f09c304 100644 --- a/src/Utils/validate-connection.ts +++ b/src/Utils/validate-connection.ts @@ -4,7 +4,7 @@ import { proto } from '../../WAProto' import type { AuthenticationState, SocketConfig, SignalKeyStore, AuthenticationCreds, KeyPair, LTHashState } from "../Types" import { Curve, hmacSign, signedKeyPair } from './crypto' import { encodeInt, generateRegistrationId } from './generics' -import { BinaryNode, S_WHATSAPP_NET, jidDecode, Binary } from '../WABinary' +import { BinaryNode, S_WHATSAPP_NET, jidDecode, Binary, getAllBinaryNodeChildren } from '../WABinary' import { createSignalIdentity } from './signal' const ENCODED_VERSION = 'S9Kdc4pc4EJryo21snc5cg==' @@ -164,7 +164,7 @@ export const configureSuccessfulPairing = ( stanza: BinaryNode, { advSecretKey, signedIdentityKey, signalIdentities }: Pick ) => { - const pair = stanza.content[0] as BinaryNode + const [pair] = getAllBinaryNodeChildren(stanza) const pairContent = Array.isArray(pair.content) ? pair.content : [] const msgId = stanza.attrs.id From 7b5bb1f428169632c85ede75b231f9ec2ddd0c43 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 11 Nov 2021 15:14:42 +0530 Subject: [PATCH 127/311] style: use sendMessageAck in recv notification --- src/Socket/messages-recv.ts | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 12156b5..46b7279 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -465,25 +465,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { ws.on('CB:receipt', handleReceipt) ws.on('CB:notification', async(node: BinaryNode) => { - const sendAck = async() => { - const stanza: BinaryNode = { - tag: 'ack', - attrs: { - class: 'notification', - id: node.attrs.id, - type: node.attrs.type, - to: node.attrs.from - } - } - if(node.attrs.participant) { - stanza.attrs.participant = node.attrs.participant - } - await sendNode(stanza) - - logger.debug({ attrs: stanza.attrs }, 'ack notification') - } - - await sendAck() + await sendMessageAck(node, { class: 'notification', type: node.attrs.type }) const msg = processNotification(node) if(msg) { From b1eab17409b36c9513de1902ee8ad2f5b197ecbb Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 11 Nov 2021 15:21:51 +0530 Subject: [PATCH 128/311] temp: comment out account sync Not sure if this is correctly implemented --- src/Socket/chats.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index a8324c2..f1ee63f 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -417,7 +417,7 @@ export const makeChatsSocket = (config: SocketConfig) => { ws.on('CB:presence', handlePresenceUpdate) ws.on('CB:chatstate', handlePresenceUpdate) - ws.on('CB:ib,,dirty', async(node: BinaryNode) => { + /*ws.on('CB:ib,,dirty', async(node: BinaryNode) => { const { attrs } = getBinaryNodeChild(node, 'dirty') const type = attrs.type switch(type) { @@ -428,7 +428,7 @@ export const makeChatsSocket = (config: SocketConfig) => { logger.info({ node }, `received unknown sync`) break } - }) + })*/ ws.on('CB:notification,type:server_sync', (node: BinaryNode) => { const update = getBinaryNodeChild(node, 'collection') From ae80566c0e4f905e874e0973f5891ceaee1773ed Mon Sep 17 00:00:00 2001 From: Ilya Borodin <48887908+ilyaborodin@users.noreply.github.com> Date: Mon, 15 Nov 2021 05:39:10 +0300 Subject: [PATCH 129/311] Group update description (#859) * Added groupUpdateDescription * Updated README Co-authored-by: Ilya Borodin --- README.md | 4 ++++ src/Socket/groups.ts | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/README.md b/README.md index ac59e10..9a8270d 100644 --- a/README.md +++ b/README.md @@ -542,6 +542,10 @@ Of course, replace ``` xyz ``` with an actual ID. ``` ts await conn.groupUpdateSubject("abcd-xyz@g.us", "New Subject!") ``` +- To change the group's description + ``` ts + await conn.groupUpdateDescription("abcd-xyz@g.us", "New Description!") + ``` - To change group settings ``` ts // only allow admins to send messages diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts index caec21f..508760e 100644 --- a/src/Socket/groups.ts +++ b/src/Socket/groups.ts @@ -100,6 +100,25 @@ export const makeGroupsSocket = (config: SocketConfig) => { const participantsAffected = getBinaryNodeChildren(node!, 'participant') return participantsAffected.map(p => p.attrs.jid) }, + groupUpdateDescription: async(jid: string, description?: string) => { + const metadata = await groupMetadata(jid); + const prev = metadata.descId ?? null; + + await groupQuery( + jid, + 'set', + [ + { + tag: 'description', + attrs: { + ...( description ? { id: generateMessageID() } : { delete: 'true' } ), + ...(prev ? { prev } : {}) + }, + content: description ? [{tag: 'body', attrs: {}, content: Buffer.from(description, 'utf-8')}] : null + } + ] + ) + }, groupInviteCode: async(jid: string) => { const result = await groupQuery(jid, 'get', [{ tag: 'invite', attrs: {} }]) const inviteNode = getBinaryNodeChild(result, 'invite') From bbf5bc96cca79bc31f8dd1aac4a5d54f49225e07 Mon Sep 17 00:00:00 2001 From: Diego Araujo Date: Sun, 14 Nov 2021 23:41:39 -0300 Subject: [PATCH 130/311] Fix retry receipt, fix assertingPreKeys, uploadPreKeys to 30, generate QR timeout and update example (#833) * update example * fix assertingPreKeys, uploadPreKeys to 30, generate QR timeout, sendRetryReceipt fix * update example, change clear qr to event connection.update * update example * firstQR flag * change checkConnection qr * update example * remove semis * update example --- Example/example.ts | 37 ++++++++++++++------------- src/Socket/messages-recv.ts | 13 +++++++--- src/Socket/socket.ts | 51 ++++++++++++++++++++++++++++--------- 3 files changed, 69 insertions(+), 32 deletions(-) diff --git a/Example/example.ts b/Example/example.ts index f863d5a..c0aadeb 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -32,9 +32,10 @@ import makeWASocket, { WASocket, AuthenticationState, DisconnectReason, AnyMessa JSON.stringify(state, BufferJSON.replacer, 2) ) } + // start a connection const startSock = () => { - const sock = makeWASocket({ + let sock = makeWASocket({ logger: P({ level: 'trace' }), printQRInTerminal: true, auth: loadState() @@ -50,15 +51,32 @@ import makeWASocket, { WASocket, AuthenticationState, DisconnectReason, AnyMessa } }) + sock.ev.on('messages.update', m => console.log(m)) sock.ev.on('presence.update', m => console.log(m)) sock.ev.on('chats.update', m => console.log(m)) sock.ev.on('contacts.update', m => console.log(m)) + + sock.ev.on('connection.update', (update) => { + const { connection, lastDisconnect } = update + if(connection === 'close') { + // reconnect if not logged out + if((lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut) { + sock = startSock() + } else { + console.log('connection closed') + } + } + console.log('connection update', update) + }) + // listen for when the auth state is updated + // it is imperative you save this data, it affects the signing keys you need to have conversations + sock.ev.on('auth-state.update', () => saveState()) + return sock } const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { - await sock.presenceSubscribe(jid) await delay(500) @@ -71,19 +89,4 @@ import makeWASocket, { WASocket, AuthenticationState, DisconnectReason, AnyMessa } sock = startSock() - sock.ev.on('connection.update', (update) => { - const { connection, lastDisconnect } = update - if(connection === 'close') { - // reconnect if not logged out - if((lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut) { - sock = startSock() - } else { - console.log('connection closed') - } - } - console.log('connection update', update) - }) - // listen for when the auth state is updated - // it is imperative you save this data, it affects the signing keys you need to have conversations - sock.ev.on('auth-state.update', () => saveState()) })() \ No newline at end of file diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 46b7279..1112caa 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -38,8 +38,15 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { await sendNode(stanza) } + const retries = new Map() const sendRetryRequest = async(node: BinaryNode) => { - const retryCount = +(node.attrs.retryCount || 0) + 1 + if (retries.has(node.attrs.id) && retries.get(node.attrs.id)! >= 5) { + retries.delete(node.attrs.id) + return + } + const retryCount = retries.get(node.attrs.id) || 1 + retries.set(node.attrs.id, retryCount + 1) + const isGroup = !!node.attrs.participant const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds @@ -81,7 +88,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { if(retryCount > 1) { const exec = generateSignalPubKey(Buffer.from(KEY_BUNDLE_TYPE)).slice(0, 1); - (node.content! as BinaryNode[]).push({ + (receipt.content! as BinaryNode[]).push({ tag: 'keys', attrs: { }, content: [ @@ -93,7 +100,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { ] }) } - await sendNode(node) + await sendNode(receipt) logger.info({ msgId: node.attrs.id, retryCount }, 'sent retry receipt') diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index ddedd35..2a1443c 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -50,6 +50,7 @@ export const makeSocket = ({ let lastDateRecv: Date let epoch = 0 let keepAliveReq: NodeJS.Timeout + let qrTimer: NodeJS.Timeout const uqTagId = `${randomBytes(1).toString('hex')[0]}.${randomBytes(1).toString('hex')[0]}-` const generateMessageTag = () => `${uqTagId}${epoch++}` @@ -174,10 +175,7 @@ export const makeSocket = ({ /** get some pre-keys and do something with them */ const assertingPreKeys = async(range: number, execute: (keys: { [_: number]: any }) => Promise) => { const { newPreKeys, lastPreKeyId, preKeysRange } = generateOrGetPreKeys(authState, range) - const preKeys = await getPreKeys(authState.keys, preKeysRange[0], preKeysRange[1]) - await execute(preKeys) - creds.serverHasPreKeys = true creds.nextPreKeyId = Math.max(lastPreKeyId+1, creds.nextPreKeyId) creds.firstUnuploadedPreKeyId = Math.max(creds.firstUnuploadedPreKeyId, lastPreKeyId+1) @@ -185,11 +183,14 @@ export const makeSocket = ({ Object.keys(newPreKeys).map(k => authState.keys.setPreKey(+k, newPreKeys[+k])) ) + const preKeys = await getPreKeys(authState.keys, preKeysRange[0], preKeysRange[0] + preKeysRange[1]) + await execute(preKeys) + ev.emit('auth-state.update', authState) } /** generates and uploads a set of pre-keys */ const uploadPreKeys = async() => { - await assertingPreKeys(50, async preKeys => { + await assertingPreKeys(30, async preKeys => { const node: BinaryNode = { tag: 'iq', attrs: { @@ -397,7 +398,7 @@ export const makeSocket = ({ }) // QR gen ws.on('CB:iq,type:set,pair-device', async (stanza: BinaryNode) => { - const postQR = async() => { + const postQR = async(qr: string) => { if(printQRInTerminal) { const QR = await import('qrcode-terminal').catch(err => { logger.error('add `qrcode-terminal` as a dependency to auto-print QR') @@ -405,8 +406,7 @@ export const makeSocket = ({ QR?.generate(qr, { small: true }) } } - - const refs = ((stanza.content[0] as BinaryNode).content as BinaryNode[]).map(n => n.content as string) + const iq: BinaryNode = { tag: 'iq', attrs: { @@ -415,14 +415,41 @@ export const makeSocket = ({ id: stanza.attrs.id, } } - const noiseKeyB64 = Buffer.from(creds.noiseKey.public).toString('base64'); + await sendNode(iq) + const refs = ((stanza.content[0] as BinaryNode).content as BinaryNode[]).map(n => n.content as string) + const noiseKeyB64 = Buffer.from(creds.noiseKey.public).toString('base64') const identityKeyB64 = Buffer.from(creds.signedIdentityKey.public).toString('base64') const advB64 = creds.advSecretKey - const qr = [refs[0], noiseKeyB64, identityKeyB64, advB64].join(','); - ev.emit('connection.update', { qr }) - await postQR() - await sendNode(iq) + let firstQR = true + const genPairQR = () => { + const ms = firstQR ? 60000 : 20000 + firstQR = false + + const ref = refs.shift() + if(!ref) { + end(new Boom('QR refs attempts ended', { statusCode: DisconnectReason.restartRequired })) + return + } + + const qr = [ref, noiseKeyB64, identityKeyB64, advB64].join(',') + + ev.emit('connection.update', { qr }) + postQR(qr) + + qrTimer = setTimeout(genPairQR, ms) + } + + genPairQR() + + const checkConnection = ({ connection }: ConnectionState) => { + if(connection === 'open' || connection === 'close') { + clearTimeout(qrTimer) + ev.off('connection.update', checkConnection) + } + } + + ev.on('connection.update', checkConnection) }) // device paired for the first time // if device pairs successfully, the server asks to restart the connection From e250560088f6fea5b9630ac32f5def2e1400878f Mon Sep 17 00:00:00 2001 From: azudin Date: Mon, 15 Nov 2021 10:44:55 +0800 Subject: [PATCH 131/311] Update README.md (#816) --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/README.md b/README.md index 9a8270d..fc8feea 100644 --- a/README.md +++ b/README.md @@ -274,6 +274,22 @@ const sentMsg = await conn.sendMessage( } } ) + +// send a buttons message! +const buttons = [ + {buttonId: 'id1', buttonText: {displayText: 'Button 1'}, type: 1}, + {buttonId: 'id2', buttonText: {displayText: 'Button 2'}, type: 1}, + {buttonId: 'id3', buttonText: {displayText: 'Button 3'}, type: 1} +] + +const buttonMessage = { + text: "Hi it's button message", + footerText: 'Hello World', + buttons: buttons, + headerType: 1 +} + +const sendMsg = await conn.sendMessage(id, buttonMessage) ``` ### Media Messages @@ -317,6 +333,23 @@ await conn.sendMessage( { audio: { url: "./Media/audio.mp3" }, mimetype: 'audio/mp4' } { url: "Media/audio.mp3" }, // can send mp3, mp4, & ogg ) + +// send a buttons message with image header! +const buttons = [ + {buttonId: 'id1', buttonText: {displayText: 'Button 1'}, type: 1}, + {buttonId: 'id2', buttonText: {displayText: 'Button 2'}, type: 1}, + {buttonId: 'id3', buttonText: {displayText: 'Button 3'}, type: 1} +] + +const buttonMessage = { + image: {url: url}, + caption: "Hi it's button message", + footerText: 'Hello World', + buttons: buttons, + headerType: 4 +} + +const sendMsg = await conn.sendMessage(id, buttonMessage) ``` ### Notes From 8ae1cae5b293dc8c6a3448b9c1ad24ca7da6ab21 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 15 Nov 2021 08:22:58 +0530 Subject: [PATCH 132/311] chore: cleaner example file --- Example/example.ts | 144 ++++++++++++++++++++++----------------------- 1 file changed, 71 insertions(+), 73 deletions(-) diff --git a/Example/example.ts b/Example/example.ts index c0aadeb..2f9832f 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -1,80 +1,42 @@ import { readFileSync, writeFileSync } from "fs" import P from "pino" import { Boom } from "@hapi/boom" -import makeWASocket, { WASocket, AuthenticationState, DisconnectReason, AnyMessageContent, BufferJSON, initInMemoryKeyStore, delay } from '../src' +import makeWASocket, { AuthenticationState, DisconnectReason, AnyMessageContent, BufferJSON, initInMemoryKeyStore, delay } from '../src' -(async() => { - let sock: WASocket | undefined = undefined - // load authentication state from a file - const loadState = () => { - let state: AuthenticationState | undefined = undefined - try { - const value = JSON.parse( - readFileSync('./auth_info_multi.json', { encoding: 'utf-8' }), - BufferJSON.reviver - ) - state = { - creds: value.creds, - // stores pre-keys, session & other keys in a JSON object - // we deserialize it here - keys: initInMemoryKeyStore(value.keys) - } - } catch{ } - return state - } - // save the authentication state to a file - const saveState = (state?: any) => { - console.log('saving pre-keys') - state = state || sock?.authState - writeFileSync( - './auth_info_multi.json', - // BufferJSON replacer utility saves buffers nicely - JSON.stringify(state, BufferJSON.replacer, 2) +// load authentication state from a file +const loadState = () => { + let state: AuthenticationState | undefined = undefined + try { + const value = JSON.parse( + readFileSync('./auth_info_multi.json', { encoding: 'utf-8' }), + BufferJSON.reviver ) - } + state = { + creds: value.creds, + // stores pre-keys, session & other keys in a JSON object + // we deserialize it here + keys: initInMemoryKeyStore(value.keys) + } + } catch{ } + return state +} +// save the authentication state to a file +const saveState = (state: any | undefined) => { + console.log('saving auth state') + writeFileSync( + './auth_info_multi.json', + // BufferJSON replacer utility saves buffers nicely + JSON.stringify(state, BufferJSON.replacer, 2) + ) +} - // start a connection - const startSock = () => { - let sock = makeWASocket({ - logger: P({ level: 'trace' }), - printQRInTerminal: true, - auth: loadState() - }) - sock.ev.on('messages.upsert', async m => { - console.log(JSON.stringify(m, undefined, 2)) - - const msg = m.messages[0] - if(!msg.key.fromMe && m.type === 'notify') { - console.log('replying to', m.messages[0].key.remoteJid) - await sock!.sendReadReceipt(msg.key.remoteJid, msg.key.participant, [msg.key.id]) - await sendMessageWTyping({ text: 'Hello there!' }, msg.key.remoteJid) - } - - }) - - sock.ev.on('messages.update', m => console.log(m)) - sock.ev.on('presence.update', m => console.log(m)) - sock.ev.on('chats.update', m => console.log(m)) - sock.ev.on('contacts.update', m => console.log(m)) - - sock.ev.on('connection.update', (update) => { - const { connection, lastDisconnect } = update - if(connection === 'close') { - // reconnect if not logged out - if((lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut) { - sock = startSock() - } else { - console.log('connection closed') - } - } - console.log('connection update', update) - }) - // listen for when the auth state is updated - // it is imperative you save this data, it affects the signing keys you need to have conversations - sock.ev.on('auth-state.update', () => saveState()) - - return sock - } +// start a connection +const startSock = () => { + const sock = makeWASocket({ + logger: P({ level: 'trace' }), + printQRInTerminal: true, + auth: loadState() + }) const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { await sock.presenceSubscribe(jid) @@ -87,6 +49,42 @@ import makeWASocket, { WASocket, AuthenticationState, DisconnectReason, AnyMessa await sock.sendMessage(jid, msg) } + + sock.ev.on('messages.upsert', async m => { + console.log(JSON.stringify(m, undefined, 2)) + + const msg = m.messages[0] + if(!msg.key.fromMe && m.type === 'notify') { + console.log('replying to', m.messages[0].key.remoteJid) + await sock!.sendReadReceipt(msg.key.remoteJid, msg.key.participant, [msg.key.id]) + await sendMessageWTyping({ text: 'Hello there!' }, msg.key.remoteJid) + } + + }) - sock = startSock() -})() \ No newline at end of file + sock.ev.on('messages.update', m => console.log(m)) + sock.ev.on('presence.update', m => console.log(m)) + sock.ev.on('chats.update', m => console.log(m)) + sock.ev.on('contacts.update', m => console.log(m)) + + sock.ev.on('connection.update', (update) => { + const { connection, lastDisconnect } = update + if(connection === 'close') { + // reconnect if not logged out + if((lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut) { + startSock() + } else { + console.log('connection closed') + } + } + + console.log('connection update', update) + }) + // listen for when the auth state is updated + // it is imperative you save this data, it affects the signing keys you need to have conversations + sock.ev.on('auth-state.update', () => saveState(sock.authState)) + + return sock +} + +startSock() \ No newline at end of file From 44059059d98305c99d326f9635db5d1e1448faa8 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 15 Nov 2021 09:07:39 +0530 Subject: [PATCH 133/311] fix: remove need for firstQR in socket --- src/Socket/socket.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 2a1443c..6cfe4b3 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -416,16 +416,14 @@ export const makeSocket = ({ } } await sendNode(iq) + const refs = ((stanza.content[0] as BinaryNode).content as BinaryNode[]).map(n => n.content as string) const noiseKeyB64 = Buffer.from(creds.noiseKey.public).toString('base64') const identityKeyB64 = Buffer.from(creds.signedIdentityKey.public).toString('base64') const advB64 = creds.advSecretKey - let firstQR = true + let qrMs = 60_000 // time to let a QR live const genPairQR = () => { - const ms = firstQR ? 60000 : 20000 - firstQR = false - const ref = refs.shift() if(!ref) { end(new Boom('QR refs attempts ended', { statusCode: DisconnectReason.restartRequired })) @@ -437,7 +435,8 @@ export const makeSocket = ({ ev.emit('connection.update', { qr }) postQR(qr) - qrTimer = setTimeout(genPairQR, ms) + qrTimer = setTimeout(genPairQR, qrMs) + qrMs = 20_000 // shorter subsequent qrs } genPairQR() From 2dfe5adbe11997e4ea1813c673a413d65515b350 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 15 Nov 2021 09:08:24 +0530 Subject: [PATCH 134/311] feat: push failed decryption messages as "CIPHERTEXT" --- src/Socket/messages-recv.ts | 66 +++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 1112caa..49dcfe5 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -342,14 +342,28 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { // recv a message ws.on('CB:message', async(stanza: BinaryNode) => { const dec = await decodeMessageStanza(stanza, authState) - const fullMessages: proto.IWebMessageInfo[] = [] - for(const msg of dec.successes) { - const { attrs } = stanza - const isGroup = !!stanza.attrs.participant - const sender = (attrs.participant || attrs.from)?.toString() - const isMe = areJidsSameUser(sender, authState.creds.me!.id) + if(dec.successes.length) { + ev.emit('auth-state.update', authState) + } - // send delivery receipt + const fullMessages: proto.IWebMessageInfo[] = [] + + const { attrs } = stanza + const isGroup = !!stanza.attrs.participant + const sender = (attrs.participant || attrs.from)?.toString() + const isMe = areJidsSameUser(sender, authState.creds.me!.id) + + const remoteJid = jidNormalizedUser(dec.chatId) + + const key: WAMessageKey = { + remoteJid, + fromMe: isMe, + id: dec.msgId, + participant: dec.participant + } + + for(const msg of dec.successes) { + // send message receipt let recpAttrs: { [_: string]: any } if(isMe) { recpAttrs = { @@ -383,16 +397,9 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { await sendDeliveryReceipt(dec.chatId, dec.participant, [dec.msgId]) logger.debug({ msgId: dec.msgId }, 'sent delivery receipt') - const remoteJid = jidNormalizedUser(dec.chatId) - const message = msg.deviceSentMessage?.message || msg fullMessages.push({ - key: { - remoteJid, - fromMe: isMe, - id: dec.msgId, - participant: dec.participant - }, + key, message, status: isMe ? proto.WebMessageInfo.WebMessageInfoStatus.SERVER_ACK : null, messageTimestamp: dec.timestamp, @@ -400,19 +407,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { participant: dec.participant }) } - - if(dec.successes.length) { - ev.emit('auth-state.update', authState) - if(fullMessages.length) { - ev.emit( - 'messages.upsert', - { - messages: fullMessages.map(m => proto.WebMessageInfo.fromObject(m)), - type: stanza.attrs.offline ? 'append' : 'notify' - } - ) - } - } for(const { error } of dec.failures) { logger.error( @@ -420,6 +414,22 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { 'failure in decrypting message' ) await sendRetryRequest(stanza) + + fullMessages.push({ + key, + messageStubType: WAMessageStubType.CIPHERTEXT, + messageStubParameters: [error.message] + }) + } + + if(fullMessages.length) { + ev.emit( + 'messages.upsert', + { + messages: fullMessages.map(m => proto.WebMessageInfo.fromObject(m)), + type: stanza.attrs.offline ? 'append' : 'notify' + } + ) } }) From 9ed4c28b8ebd4651541fc084ce052318efef76ed Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 15 Nov 2021 09:09:55 +0530 Subject: [PATCH 135/311] fix: minor retry logic cleanup --- src/Socket/messages-recv.ts | 21 +++++++++++---------- src/Types/index.ts | 2 ++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 49dcfe5..3040fcf 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -1,5 +1,5 @@ -import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata } from "../Types" +import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata, WAMessageKey } from "../Types" import { decodeMessageStanza, encodeBigEndian, toNumber, downloadHistory, generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils" import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser, getAllBinaryNodeChildren, BinaryNodeAttributes } from '../WABinary' import { proto } from "../../WAProto" @@ -22,6 +22,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { sendDeliveryReceipt, } = sock + const msgRetryMap = config.msgRetryCounterMap || { } + const sendMessageAck = async({ tag, attrs }: BinaryNode, extraAttrs: BinaryNodeAttributes) => { const stanza: BinaryNode = { tag: 'ack', @@ -38,14 +40,15 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { await sendNode(stanza) } - const retries = new Map() const sendRetryRequest = async(node: BinaryNode) => { - if (retries.has(node.attrs.id) && retries.get(node.attrs.id)! >= 5) { - retries.delete(node.attrs.id) + const msgId = node.attrs.id + const retryCount = msgRetryMap[msgId] || 1 + if(retryCount >= 5) { + logger.debug({ retryCount, msgId }, 'reached retry limit, clearing') + delete msgRetryMap[msgId] return } - const retryCount = retries.get(node.attrs.id) || 1 - retries.set(node.attrs.id, retryCount + 1) + msgRetryMap[msgId] = retryCount+1 const isGroup = !!node.attrs.participant const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds @@ -59,7 +62,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const receipt: BinaryNode = { tag: 'receipt', attrs: { - id: node.attrs.id, + id: msgId, type: 'retry', to: isGroup ? node.attrs.from : jidEncode(decFrom!.user, 's.whatsapp.net', decFrom!.device, 0) }, @@ -102,9 +105,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } await sendNode(receipt) - logger.info({ msgId: node.attrs.id, retryCount }, 'sent retry receipt') - - ev.emit('auth-state.update', authState) + logger.info({ msgAttrs: node.attrs, retryCount }, 'sent retry receipt') }) } const processMessage = async(message: proto.IWebMessageInfo, chatUpdate: Partial) => { diff --git a/src/Types/index.ts b/src/Types/index.ts index a860819..a8e3f77 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -50,6 +50,8 @@ export type SocketConfig = { userDevicesCache?: NodeCache /** provide a cache to store media, so does not have to be re-uploaded */ mediaCache?: NodeCache + /** map to store the retry counts for failed messages */ + msgRetryCounterMap?: { [msgId: string]: number } } export enum DisconnectReason { From 823701a9c7eb9e734868524e8a2afa79448a34bb Mon Sep 17 00:00:00 2001 From: BochilGaming <79433517+BochilGaming@users.noreply.github.com> Date: Mon, 15 Nov 2021 14:14:43 +0700 Subject: [PATCH 136/311] Add groupRevokeInvite, groupAcceptInvite and fix groupLeave (#860) * Update groups.ts * Fix: error TS2448: Block-scoped variable 'result' used before its declaration. --- src/Socket/groups.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts index 508760e..b002534 100644 --- a/src/Socket/groups.ts +++ b/src/Socket/groups.ts @@ -52,7 +52,7 @@ export const makeGroupsSocket = (config: SocketConfig) => { ) return extractGroupMetadata(result) }, - groupLeave: async(jid: string) => { + groupLeave: async(id: string) => { await groupQuery( '@g.us', 'set', @@ -61,7 +61,7 @@ export const makeGroupsSocket = (config: SocketConfig) => { tag: 'leave', attrs: { }, content: [ - { tag: 'group', attrs: { jid } } + { tag: 'group', attrs: { id } } ] } ] @@ -124,6 +124,16 @@ export const makeGroupsSocket = (config: SocketConfig) => { const inviteNode = getBinaryNodeChild(result, 'invite') return inviteNode.attrs.code }, + groupRevokeInvite: async (jid: string) => { + const result = await groupQuery(jid, 'set', [{ tag: 'invite', attrs: {} }]) + const inviteNode = getBinaryNodeChild(result, 'invite') + return inviteNode.attrs.code + }, + groupAcceptInvite: async (code: string) => { + const results = await groupQuery('@g.us', 'set', [{ tag: 'invite', attrs: { code } }]) + const result = getBinaryNodeChild(results, 'group') + return result.attrs.jid + }, groupToggleEphemeral: async(jid: string, ephemeralExpiration: number) => { const content: BinaryNode = ephemeralExpiration ? { tag: 'ephemeral', attrs: { ephemeral: ephemeralExpiration.toString() } } : @@ -202,4 +212,4 @@ export const extractGroupMetadata = (result: BinaryNode) => { ephemeralDuration: eph ? +eph : undefined } return metadata -} \ No newline at end of file +} From e142f0b76ec46eb62d74cde8d7bc1de19b289111 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 16 Nov 2021 10:08:22 +0530 Subject: [PATCH 137/311] fix: empty messages upsert event on history sync --- src/Socket/messages-recv.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 3040fcf..7e88fb1 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -253,7 +253,9 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { messages.push(m.message!) } } - ev.emit('messages.upsert', { messages, type: 'prepend' }) + if(messages.length) { + ev.emit('messages.upsert', { messages, type: 'prepend' }) + } break case proto.HistorySync.HistorySyncHistorySyncType.PUSH_NAME: const contacts = item.pushnames.map( From cff2b1427abd010f7fae1ae20b4b18a34b7f5d94 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 16 Nov 2021 10:09:03 +0530 Subject: [PATCH 138/311] fix: prevent duplicate receipts on multiple messages recv in stanza --- src/Socket/messages-recv.ts | 43 +++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 7e88fb1..1b9cbaf 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -345,10 +345,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { // recv a message ws.on('CB:message', async(stanza: BinaryNode) => { const dec = await decodeMessageStanza(stanza, authState) - if(dec.successes.length) { - ev.emit('auth-state.update', authState) - } - const fullMessages: proto.IWebMessageInfo[] = [] const { attrs } = stanza @@ -364,8 +360,9 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { id: dec.msgId, participant: dec.participant } - - for(const msg of dec.successes) { + // if there were some successful decryptions + if(dec.successes.length) { + ev.emit('auth-state.update', authState) // send message receipt let recpAttrs: { [_: string]: any } if(isMe) { @@ -399,16 +396,18 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { await sendDeliveryReceipt(dec.chatId, dec.participant, [dec.msgId]) logger.debug({ msgId: dec.msgId }, 'sent delivery receipt') + } + for(const msg of dec.successes) { const message = msg.deviceSentMessage?.message || msg - fullMessages.push({ - key, - message, - status: isMe ? proto.WebMessageInfo.WebMessageInfoStatus.SERVER_ACK : null, - messageTimestamp: dec.timestamp, - pushName: dec.pushname, - participant: dec.participant - }) + fullMessages.push({ + key, + message, + status: isMe ? proto.WebMessageInfo.WebMessageInfoStatus.SERVER_ACK : null, + messageTimestamp: dec.timestamp, + pushName: dec.pushname, + participant: dec.participant + }) } for(const { error } of dec.failures) { @@ -425,15 +424,13 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { }) } - if(fullMessages.length) { - ev.emit( - 'messages.upsert', - { - messages: fullMessages.map(m => proto.WebMessageInfo.fromObject(m)), - type: stanza.attrs.offline ? 'append' : 'notify' - } - ) - } + ev.emit( + 'messages.upsert', + { + messages: fullMessages.map(m => proto.WebMessageInfo.fromObject(m)), + type: stanza.attrs.offline ? 'append' : 'notify' + } + ) }) ws.on('CB:ack,class:message', async(node: BinaryNode) => { From dac5a63ff98fa41d4cb287779f485970a880e645 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 16 Nov 2021 16:21:56 +0530 Subject: [PATCH 139/311] fix: ack for participants on MD --- src/Socket/messages-recv.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 1b9cbaf..27a42b8 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -34,7 +34,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } } if(!!attrs.participant) { - stanza.attrs.participant = jidNormalizedUser(attrs.participant) + stanza.attrs.participant = attrs.participant } logger.debug({ recv: attrs, sent: stanza.attrs }, `sent "${tag}" ack`) await sendNode(stanza) From 40280d777def79a4c8d68988210b9031c8db4d1f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 17 Nov 2021 15:44:22 +0530 Subject: [PATCH 140/311] chore: update WA version --- src/Defaults/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 0d937f2..464369d 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -18,7 +18,7 @@ export const NOISE_WA_HEADER = new Uint8Array([87, 65, 5, 2]) // last is "DICT_V export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { - version: [2, 2142, 12], + version: [2, 2144, 11], browser: Browsers.baileys('Chrome'), waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', From bb5f13d188e1dc044e6e091bfac87b40f677038f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 18 Nov 2021 11:30:35 +0530 Subject: [PATCH 141/311] fix: mutex app state sync to prevent race conditions that log connection out --- src/Socket/chats.ts | 114 +++++++++++++++++++++++----------------- src/Utils/make-mutex.ts | 19 +++++++ 2 files changed, 84 insertions(+), 49 deletions(-) create mode 100644 src/Utils/make-mutex.ts diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index f1ee63f..6fe85c8 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -3,6 +3,7 @@ import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUse import { proto } from '../../WAProto' import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch } from "../Utils"; import { makeMessagesRecvSocket } from "./messages-recv"; +import makeMutex from "../Utils/make-mutex"; export const makeChatsSocket = (config: SocketConfig) => { const { logger } = config @@ -17,6 +18,8 @@ export const makeChatsSocket = (config: SocketConfig) => { fetchPrivacySettings, } = sock + const mutationMutex = makeMutex() + const interactiveQuery = async(userNodes: BinaryNode[], queryNode: BinaryNode) => { const result = await query({ tag: 'iq', @@ -216,7 +219,6 @@ export const makeChatsSocket = (config: SocketConfig) => { processSyncActions(newMutations) } } - ev.emit('auth-state.update', authState) } @@ -354,59 +356,63 @@ export const makeChatsSocket = (config: SocketConfig) => { const appPatch = async(patchCreate: WAPatchCreate) => { const name = patchCreate.type - try { - await resyncAppState([name]) - } catch(error) { - logger.info({ name, error: error.stack }, 'failed to sync state from version, trying from scratch') - await resyncAppState([name], true) - } - - const { patch, state } = await encodeSyncdPatch( - patchCreate, - authState, - ) - const initial = await authState.keys.getAppStateSyncVersion(name) - // temp: verify it was encoded correctly - const result = await decodePatches(name, [{ ...patch, version: { version: state.version }, }], initial, authState) - - const node: BinaryNode = { - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - type: 'set', - xmlns: 'w:sync:app:state' - }, - content: [ - { - tag: 'sync', - attrs: { }, + await mutationMutex.mutex( + async() => { + try { + await resyncAppState([name]) + } catch(error) { + logger.info({ name, error: error.stack }, 'failed to sync state from version, trying from scratch') + await resyncAppState([name], true) + } + const { patch, state } = await encodeSyncdPatch( + patchCreate, + authState, + ) + const initial = await authState.keys.getAppStateSyncVersion(name) + // temp: verify it was encoded correctly + const result = await decodePatches(name, [{ ...patch, version: { version: state.version }, }], initial, authState) + + const node: BinaryNode = { + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'set', + xmlns: 'w:sync:app:state' + }, content: [ { - tag: 'collection', - attrs: { - name, - version: (state.version-1).toString(), - return_snapshot: 'false' - }, + tag: 'sync', + attrs: { }, content: [ { - tag: 'patch', - attrs: { }, - content: proto.SyncdPatch.encode(patch).finish() + tag: 'collection', + attrs: { + name, + version: (state.version-1).toString(), + return_snapshot: 'false' + }, + content: [ + { + tag: 'patch', + attrs: { }, + content: proto.SyncdPatch.encode(patch).finish() + } + ] } ] } ] } - ] - } - await query(node) - - await authState.keys.setAppStateSyncVersion(name, state) - ev.emit('auth-state.update', authState) - if(config.emitOwnEvents) { - processSyncActions(result.newMutations) - } + await query(node) + + await authState.keys.setAppStateSyncVersion(name, state) + ev.emit('auth-state.update', authState) + + if(config.emitOwnEvents) { + processSyncActions(result.newMutations) + } + } + ) } const chatModify = (mod: ChatModification, jid: string, lastMessages: Pick[]) => { @@ -434,8 +440,12 @@ export const makeChatsSocket = (config: SocketConfig) => { const update = getBinaryNodeChild(node, 'collection') if(update) { const name = update.attrs.name as WAPatchName - resyncAppState([name], false) - .catch(err => logger.error({ trace: err.stack, node }, `failed to sync state`)) + mutationMutex.mutex( + async() => { + await resyncAppState([name], false) + .catch(err => logger.error({ trace: err.stack, node }, `failed to sync state`)) + } + ) } }) @@ -444,8 +454,14 @@ export const makeChatsSocket = (config: SocketConfig) => { sendPresenceUpdate('available') fetchBlocklist() fetchPrivacySettings() - resyncAppState([ 'critical_block', 'critical_unblock_low' ]) - .catch(err => logger.info({ trace: err.stack }, 'failed to sync app state')) + mutationMutex.mutex( + async() => { + await ( + resyncAppState([ 'critical_block', 'critical_unblock_low' ]) + .catch(err => logger.info({ trace: err.stack }, 'failed to sync app state')) + ) + } + ) } }) diff --git a/src/Utils/make-mutex.ts b/src/Utils/make-mutex.ts new file mode 100644 index 0000000..76f4148 --- /dev/null +++ b/src/Utils/make-mutex.ts @@ -0,0 +1,19 @@ + +export default () => { + let task = Promise.resolve() as Promise + return { + mutex(code: () => Promise):Promise { + task = (async () => { + // wait for the previous task to complete + // if there is an error, we swallow so as to not block the queue + try { await task } catch { } + // execute the current task + return code() + })() + // we replace the existing task, appending the new piece of execution to it + // so the next task will have to wait for this one to finish + return task + }, + } + } + \ No newline at end of file From 9f196663e8aec704de7d89b587172d3b3293d063 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 19 Nov 2021 16:25:17 +0530 Subject: [PATCH 142/311] fix: logout error when not logged in --- src/Socket/socket.ts | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 6cfe4b3..9d464a2 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -345,24 +345,28 @@ export const makeSocket = ({ ) /** logout & invalidate connection */ const logout = async() => { - await sendNode({ - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - type: 'set', - id: generateMessageTag(), - xmlns: 'md' - }, - content: [ - { - tag: 'remove-companion-device', - attrs: { - jid: authState.creds.me!.id, - reason: 'user_initiated' + const jid = authState.creds.me?.id + if(jid) { + await sendNode({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'set', + id: generateMessageTag(), + xmlns: 'md' + }, + content: [ + { + tag: 'remove-companion-device', + attrs: { + jid: jid, + reason: 'user_initiated' + } } - } - ] - }) + ] + }) + } + end(new Boom('Intentional Logout', { statusCode: DisconnectReason.loggedOut })) } /** Waits for the connection to WA to reach a state */ From 79100a3164cf444c228b2ff4ffd2206d6797a1bc Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 19 Nov 2021 17:41:57 +0530 Subject: [PATCH 143/311] feat: export resyncmainappstate --- src/Socket/chats.ts | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 6fe85c8..1759e7c 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -302,6 +302,20 @@ export const makeChatsSocket = (config: SocketConfig) => { } } + const resyncMainAppState = async() => { + + logger.debug('resyncing main app state') + + await ( + mutationMutex.mutex( + () => resyncAppState([ 'critical_block', 'critical_unblock_low' ]) + ) + .catch(err => ( + logger.warn({ trace: err.stack }, 'failed to sync app state') + )) + ) + } + const processSyncActions = (actions: ChatMutation[]) => { const updates: { [jid: string]: Partial } = {} const contactUpdates: { [jid: string]: Contact } = {} @@ -454,14 +468,7 @@ export const makeChatsSocket = (config: SocketConfig) => { sendPresenceUpdate('available') fetchBlocklist() fetchPrivacySettings() - mutationMutex.mutex( - async() => { - await ( - resyncAppState([ 'critical_block', 'critical_unblock_low' ]) - .catch(err => logger.info({ trace: err.stack }, 'failed to sync app state')) - ) - } - ) + resyncMainAppState() } }) @@ -478,5 +485,6 @@ export const makeChatsSocket = (config: SocketConfig) => { updateBlockStatus, resyncAppState, chatModify, + resyncMainAppState, } } \ No newline at end of file From 72889551b9fd6d484c6507553a7cc92c490b5818 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 19 Nov 2021 17:43:14 +0530 Subject: [PATCH 144/311] feat: resync main app state on new key --- src/Socket/chats.ts | 4 ++-- src/Socket/index.ts | 2 +- src/Socket/messages-recv.ts | 7 +++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 1759e7c..2329ad1 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -2,12 +2,12 @@ import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpl import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET } from "../WABinary"; import { proto } from '../../WAProto' import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch } from "../Utils"; -import { makeMessagesRecvSocket } from "./messages-recv"; +import { makeMessagesSocket } from "./messages-send"; import makeMutex from "../Utils/make-mutex"; export const makeChatsSocket = (config: SocketConfig) => { const { logger } = config - const sock = makeMessagesRecvSocket(config) + const sock = makeMessagesSocket(config) const { ev, ws, diff --git a/src/Socket/index.ts b/src/Socket/index.ts index f949186..e2f7f1e 100644 --- a/src/Socket/index.ts +++ b/src/Socket/index.ts @@ -1,6 +1,6 @@ import { SocketConfig } from '../Types' import { DEFAULT_CONNECTION_CONFIG } from '../Defaults' -import { makeChatsSocket as _makeSocket } from './chats' +import { makeMessagesRecvSocket as _makeSocket } from './messages-recv' // export the last socket layer const makeWASocket = (config: Partial) => ( diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 27a42b8..7a67cc3 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -4,14 +4,14 @@ import { decodeMessageStanza, encodeBigEndian, toNumber, downloadHistory, genera import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser, getAllBinaryNodeChildren, BinaryNodeAttributes } from '../WABinary' import { proto } from "../../WAProto" import { KEY_BUNDLE_TYPE } from "../Defaults" -import { makeMessagesSocket } from "./messages-send" +import { makeChatsSocket } from "./chats" import { extractGroupMetadata } from "./groups" const isReadReceipt = (type: string) => type === 'read' || type === 'read-self' export const makeMessagesRecvSocket = (config: SocketConfig) => { const { logger } = config - const sock = makeMessagesSocket(config) + const sock = makeChatsSocket(config) const { ev, authState, @@ -20,6 +20,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { sendNode, relayMessage, sendDeliveryReceipt, + resyncMainAppState, } = sock const msgRetryMap = config.msgRetryCounterMap || { } @@ -166,6 +167,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } ev.emit('auth-state.update', authState) + + resyncMainAppState() break case proto.ProtocolMessage.ProtocolMessageType.REVOKE: ev.emit('messages.update', [ From 2641474c5aed49beb5ec3693fafa061bcb0e62ef Mon Sep 17 00:00:00 2001 From: lyfe00011 <76509367+lyfe00011@users.noreply.github.com> Date: Fri, 19 Nov 2021 18:39:31 +0530 Subject: [PATCH 145/311] prepareWAMessageMedia option (#880) --- src/Socket/messages-send.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 5a547ba..7046e0f 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -432,6 +432,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { sendDeliveryReceipt, sendReadReceipt, refreshMediaConn, + waUploadToServer, fetchPrivacySettings, sendMessage: async( jid: string, @@ -481,4 +482,4 @@ export const makeMessagesSocket = (config: SocketConfig) => { } } } -} \ No newline at end of file +} From 3590c1f569f4a76e38f8aa0ee5fac80f6055d048 Mon Sep 17 00:00:00 2001 From: yanun Date: Fri, 19 Nov 2021 20:10:34 +0700 Subject: [PATCH 146/311] Update README.md (#879) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc8feea..09ad0d2 100644 --- a/README.md +++ b/README.md @@ -600,7 +600,7 @@ Of course, replace ``` xyz ``` with an actual ID. - To query the metadata of a group ``` ts const metadata = await conn.groupMetadata("abcd-xyz@g.us") - console.log(json.id + ", title: " + json.subject + ", description: " + json.desc) + console.log(metadata.id + ", title: " + metadata.subject + ", description: " + metadata.desc) ``` - To join the group using the invitation code (not supported yet) ``` ts From 3adeb2ed6b48e862d64ec218942884a97889eeeb Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 19 Nov 2021 21:46:48 +0530 Subject: [PATCH 147/311] chore: use interface instead of full type in auth --- src/Types/Auth.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts index 273f2fc..0e47fd8 100644 --- a/src/Types/Auth.ts +++ b/src/Types/Auth.ts @@ -23,13 +23,14 @@ export type AuthenticationCreds = { registrationId: number advSecretKey: string me?: Contact - account?: proto.ADVSignedDeviceIdentity + account?: proto.IADVSignedDeviceIdentity signalIdentities?: SignalIdentity[] myAppStateKeyId?: string firstUnuploadedPreKeyId: number serverHasPreKeys: boolean nextPreKeyId: number } + type Awaitable = T | Promise export type SignalKeyStore = { getPreKey: (keyId: number) => Awaitable From 49da0e4e71255a69bb7426cda1c5c367395472f8 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 19 Nov 2021 21:47:51 +0530 Subject: [PATCH 148/311] fix: remove "connection.update" listener from ev instead of ws --- src/Socket/socket.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 9d464a2..ab2c695 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -252,6 +252,7 @@ export const makeSocket = ({ logger.info({ error }, 'connection closed') clearInterval(keepAliveReq) + clearInterval(qrTimer) ws.removeAllListeners('close') ws.removeAllListeners('error') @@ -269,7 +270,7 @@ export const makeSocket = ({ date: new Date() } }) - ws.removeAllListeners('connection.update') + ev.removeAllListeners('connection.update') } const waitForSocketOpen = async() => { @@ -444,15 +445,6 @@ export const makeSocket = ({ } genPairQR() - - const checkConnection = ({ connection }: ConnectionState) => { - if(connection === 'open' || connection === 'close') { - clearTimeout(qrTimer) - ev.off('connection.update', checkConnection) - } - } - - ev.on('connection.update', checkConnection) }) // device paired for the first time // if device pairs successfully, the server asks to restart the connection @@ -492,6 +484,7 @@ export const makeSocket = ({ await sendPassiveIq('active') logger.info('opened connection to WA') + clearTimeout(qrTimer) // will never happen in all likelyhood -- but just in case WA sends success on first try ev.emit('connection.update', { connection: 'open' }) }) From 7d174ca77b3993b0f17c6215b934a35d026b4377 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 19 Nov 2021 22:00:37 +0530 Subject: [PATCH 149/311] fix: "receivedPendingNotifications" not firing on zero offline notifications --- src/Socket/socket.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index ab2c695..0005c7a 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -7,7 +7,7 @@ import { proto } from '../../WAProto' import { DisconnectReason, SocketConfig, BaileysEventEmitter, ConnectionState } from "../Types" import { Curve, initAuthState, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout, generateOrGetPreKeys, xmppSignedPreKey, xmppPreKey, getPreKeys, makeNoiseHandler } from "../Utils" import { DEFAULT_ORIGIN, DEF_TAG_PREFIX, DEF_CALLBACK_PREFIX, KEY_BUNDLE_TYPE } from "../Defaults" -import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, S_WHATSAPP_NET } from '../WABinary' +import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, S_WHATSAPP_NET, getBinaryNodeChild } from '../WABinary' /** * Connects to WA servers and performs: * - simple queries (no retry mechanism, wait for connection establishment) @@ -488,6 +488,18 @@ export const makeSocket = ({ ev.emit('connection.update', { connection: 'open' }) }) + + ws.on('CB:ib,,offline', (node: BinaryNode) => { + const child = getBinaryNodeChild(node, 'offline') + const offlineCount = +child.attrs.count + + logger.info(`got ${offlineCount} offline messages/notifications`) + + if(!offlineCount) { + ev.emit('connection.update', { receivedPendingNotifications: true }) + } + }) + ws.on('CB:stream:error', (node: BinaryNode) => { logger.error({ error: node }, `stream errored out`) From c2c27a5dea8a5bdd14e518ff94cf8b6d45ccc904 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 20 Nov 2021 13:39:56 +0530 Subject: [PATCH 150/311] fix: experimental patch to correctly identify end of offline notifications --- src/Socket/messages-recv.ts | 6 ------ src/Socket/socket.ts | 4 +--- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 7a67cc3..6db257d 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -326,12 +326,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } } else { switch(child.tag) { - case 'count': - if(child.attrs.value === '0') { - logger.info('recv all pending notifications') - ev.emit('connection.update', { receivedPendingNotifications: true }) - } - break case 'devices': const devices = getBinaryNodeChildren(child, 'device') if(areJidsSameUser(child.attrs.jid, authState.creds!.me!.id)) { diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 0005c7a..06dd674 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -495,9 +495,7 @@ export const makeSocket = ({ logger.info(`got ${offlineCount} offline messages/notifications`) - if(!offlineCount) { - ev.emit('connection.update', { receivedPendingNotifications: true }) - } + ev.emit('connection.update', { receivedPendingNotifications: true }) }) ws.on('CB:stream:error', (node: BinaryNode) => { From 3d0704a317c1441789f0c995fc5748791167048f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 20 Nov 2021 16:21:56 +0530 Subject: [PATCH 151/311] feat: cleaner auth state management 1. removes the "auth-state.update" event since it was bloated and fairly unnecessary 2. adds "creds.update" event that only sends the updated properties of the auth credentials 3. ensure the auth creds are not mutated anywhere, but only with the "creds.update" event 4. Separates the signal credentials from the auth credentials (kinda in progress) 5. in memory key store requires a save function to let one know when to save the keys !BREAKING_CHANGE --- Example/example.ts | 38 ++------- README.md | 51 +++--------- src/Defaults/index.ts | 2 +- src/Socket/chats.ts | 14 ++-- src/Socket/messages-recv.ts | 9 +-- src/Socket/messages-send.ts | 3 +- src/Socket/socket.ts | 43 +++++++--- src/Types/Auth.ts | 21 +++-- src/Types/index.ts | 6 +- src/Utils/auth-utils.ts | 133 +++++++++++++++++++++++++++++++ src/Utils/index.ts | 3 +- src/Utils/signal.ts | 20 ++--- src/Utils/validate-connection.ts | 87 +------------------- 13 files changed, 229 insertions(+), 201 deletions(-) create mode 100644 src/Utils/auth-utils.ts diff --git a/Example/example.ts b/Example/example.ts index 2f9832f..d3e48d8 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -1,41 +1,16 @@ -import { readFileSync, writeFileSync } from "fs" import P from "pino" import { Boom } from "@hapi/boom" -import makeWASocket, { AuthenticationState, DisconnectReason, AnyMessageContent, BufferJSON, initInMemoryKeyStore, delay } from '../src' +import makeWASocket, { DisconnectReason, AnyMessageContent, delay, useSingleFileAuthState } from '../src' -// load authentication state from a file -const loadState = () => { - let state: AuthenticationState | undefined = undefined - try { - const value = JSON.parse( - readFileSync('./auth_info_multi.json', { encoding: 'utf-8' }), - BufferJSON.reviver - ) - state = { - creds: value.creds, - // stores pre-keys, session & other keys in a JSON object - // we deserialize it here - keys: initInMemoryKeyStore(value.keys) - } - } catch{ } - return state -} -// save the authentication state to a file -const saveState = (state: any | undefined) => { - console.log('saving auth state') - writeFileSync( - './auth_info_multi.json', - // BufferJSON replacer utility saves buffers nicely - JSON.stringify(state, BufferJSON.replacer, 2) - ) -} +const { state, saveState } = useSingleFileAuthState('./auth_info_multi.json') // start a connection const startSock = () => { + const sock = makeWASocket({ logger: P({ level: 'trace' }), printQRInTerminal: true, - auth: loadState() + auth: state }) const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { @@ -80,9 +55,8 @@ const startSock = () => { console.log('connection update', update) }) - // listen for when the auth state is updated - // it is imperative you save this data, it affects the signing keys you need to have conversations - sock.ev.on('auth-state.update', () => saveState(sock.authState)) + // listen for when the auth credentials is updated + sock.ev.on('creds.update', saveState) return sock } diff --git a/README.md b/README.md index 09ad0d2..b97fd3e 100644 --- a/README.md +++ b/README.md @@ -117,49 +117,22 @@ type SocketConfig = { You obviously don't want to keep scanning the QR code every time you want to connect. -So, you can save the credentials to log back in via: +So, you can load the credentials to log back in: ``` ts -import makeWASocket, { BufferJSON } from '@adiwajshing/baileys-md' +import makeWASocket, { BufferJSON, useSingleFileAuthState } from '@adiwajshing/baileys-md' import * as fs from 'fs' -// will initialize a default in-memory auth session -const conn = makeSocket() +// utility function to help save the auth state in a single file +// it's utility ends at demos -- as re-writing a large file over and over again is very inefficient +const { state, saveState } = useSingleFileAuthState('./auth_info_multi.json') +// will use the given state to connect +// so if valid credentials are available -- it'll connect without QR +const conn = makeSocket({ auth: state }) // this will be called as soon as the credentials are updated -conn.ev.on ('auth-state.update', () => { - // save credentials whenever updated - console.log (`credentials updated!`) - const authInfo = conn.authState // get all the auth info we need to restore this session - // save this info to a file - fs.writeFileSync( - './auth_info.json', - JSON.stringify(authInfo, BufferJSON.replacer, 2) - ) -}) +conn.ev.on ('creds.update', saveState) ``` -Then, to restore a session: -``` ts -import makeWASocket, { BufferJSON, initInMemoryKeyStore } from '@adiwajshing/baileys-md' -import * as fs from 'fs' - -const authJSON = JSON.parse( - fs.readFileSync( - './auth_info.json', - { encoding: 'utf-8' } - ), - BufferJSON.reviver -) -const auth = { - creds: authJSON.creds, - // stores pre-keys, session & other keys in a JSON object - // we deserialize it here - keys: initInMemoryKeyStore(authJSON.keys) -} -const conn = makeWASocket(auth) -// yay will connect without scanning QR -``` - -**Note**: Upon every successive connection, the auth state can update part of the stored credentials. It will also update when a message is received/sent due to signal sessions needing updating. Whenever that happens, the `auth-state.update` event is fired uploaded, and you must update your saved credentials upon receiving the event. Not doing so will prevent your messages from reaching the recipient & other unexpected consequences. +**Note**: When a message is received/sent, due to signal sessions needing updating, the auth keys (`authState.keys`) will update. Whenever that happens, you must save the updated keys. Not doing so will prevent your messages from reaching the recipient & other unexpected consequences. The `useSingleFileAuthState` function automatically takes care of that, but for any other serious implementation -- you will need to be very careful with the key state management. ## Listening to Connection Updates @@ -196,8 +169,8 @@ The events are typed up in a type map, as mentioned here: export type BaileysEventMap = { /** connection state has been updated -- WS closed, opened, connecting etc. */ 'connection.update': Partial - /** auth state updated -- some pre keys, or identity keys etc. */ - 'auth-state.update': AuthenticationState + /** auth credentials updated -- some pre key state, device ID etc. */ + 'creds.update': Partial /** set chats (history sync), messages are reverse chronologically sorted */ 'chats.set': { chats: Chat[], messages: WAMessage[] } /** upsert chats */ diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 464369d..298d0aa 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -26,7 +26,7 @@ export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { keepAliveIntervalMs: 25_000, logger: P().child({ class: 'baileys' }), printQRInTerminal: false, - emitOwnEvents: true + emitOwnEvents: true, } export const MEDIA_PATH_MAP: { [T in MediaType]: string } = { diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 2329ad1..e4f63ff 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -219,7 +219,6 @@ export const makeChatsSocket = (config: SocketConfig) => { processSyncActions(newMutations) } } - ev.emit('auth-state.update', authState) } /** @@ -245,11 +244,12 @@ export const makeChatsSocket = (config: SocketConfig) => { } const sendPresenceUpdate = async(type: WAPresence, toJid?: string) => { + const me = authState.creds.me! if(type === 'available' || type === 'unavailable') { await sendNode({ tag: 'presence', attrs: { - name: authState.creds.me!.name, + name: me!.name, type } }) @@ -257,7 +257,7 @@ export const makeChatsSocket = (config: SocketConfig) => { await sendNode({ tag: 'chatstate', attrs: { - from: authState.creds.me!.id!, + from: me!.id!, to: toJid, }, content: [ @@ -344,8 +344,11 @@ export const makeChatsSocket = (config: SocketConfig) => { name: action.contactAction!.fullName } } else if(action?.pushNameSetting) { - authState.creds.me!.name = action?.pushNameSetting?.name! - ev.emit('auth-state.update', authState) + const me = { + ...authState.creds.me!, + name: action?.pushNameSetting?.name! + } + ev.emit('creds.update', { me }) } else { logger.warn({ action, id }, 'unprocessable update') } @@ -420,7 +423,6 @@ export const makeChatsSocket = (config: SocketConfig) => { await query(node) await authState.keys.setAppStateSyncVersion(name, state) - ev.emit('auth-state.update', authState) if(config.emitOwnEvents) { processSyncActions(result.newMutations) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 6db257d..9ad9aee 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -158,15 +158,16 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { logger.info({ with: message.key.remoteJid! }, 'shared key') break case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_SHARE: + let newAppStateSyncKeyId = '' for(const { keyData, keyId } of protocolMsg.appStateSyncKeyShare!.keys || []) { const str = Buffer.from(keyId.keyId!).toString('base64') logger.info({ str }, 'injecting new app state sync key') await authState.keys.setAppStateSyncKey(str, keyData) - authState.creds.myAppStateKeyId = str + newAppStateSyncKeyId = str } - ev.emit('auth-state.update', authState) + ev.emit('creds.update', { myAppStateKeyId: newAppStateSyncKeyId }) resyncMainAppState() break @@ -359,7 +360,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } // if there were some successful decryptions if(dec.successes.length) { - ev.emit('auth-state.update', authState) // send message receipt let recpAttrs: { [_: string]: any } if(isMe) { @@ -506,8 +506,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { contactNameUpdates[jid] = msg.pushName // update our pushname too if(msg.key.fromMe && authState.creds.me?.name !== msg.pushName) { - authState.creds.me!.name = msg.pushName - ev.emit('auth-state.update', authState) + ev.emit('creds.update', { me: { ...authState.creds.me!, name: msg.pushName! } }) } } diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 7046e0f..56eb181 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -259,7 +259,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { const destinationJid = jidEncode(user, isGroup ? 'g.us' : 's.whatsapp.net') if(isGroup) { - const { ciphertext, senderKeyDistributionMessageKey } = await encryptSenderKeyMsgSignalProto(destinationJid, encodedMsg, authState) + const { ciphertext, senderKeyDistributionMessageKey } = await encryptSenderKeyMsgSignalProto(destinationJid, encodedMsg, authState.creds.me!.id, authState) let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined if(!groupData) groupData = await groupMetadata(jid) @@ -375,7 +375,6 @@ export const makeMessagesSocket = (config: SocketConfig) => { await sendNode(stanza) - ev.emit('auth-state.update', authState) return msgId } diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 06dd674..a3b4f1d 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -4,10 +4,11 @@ import { promisify } from "util" import WebSocket from "ws" import { randomBytes } from 'crypto' import { proto } from '../../WAProto' -import { DisconnectReason, SocketConfig, BaileysEventEmitter, ConnectionState } from "../Types" -import { Curve, initAuthState, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout, generateOrGetPreKeys, xmppSignedPreKey, xmppPreKey, getPreKeys, makeNoiseHandler } from "../Utils" +import { DisconnectReason, SocketConfig, BaileysEventEmitter, ConnectionState, AuthenticationCreds } from "../Types" +import { Curve, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout, generateOrGetPreKeys, xmppSignedPreKey, xmppPreKey, getPreKeys, makeNoiseHandler, useSingleFileAuthState } from "../Utils" import { DEFAULT_ORIGIN, DEF_TAG_PREFIX, DEF_CALLBACK_PREFIX, KEY_BUNDLE_TYPE } from "../Defaults" import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, S_WHATSAPP_NET, getBinaryNodeChild } from '../WABinary' + /** * Connects to WA servers and performs: * - simple queries (no retry mechanism, wait for connection establishment) @@ -39,13 +40,22 @@ export const makeSocket = ({ } }) ws.setMaxListeners(0) + const ev = new EventEmitter() as BaileysEventEmitter /** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */ const ephemeralKeyPair = Curve.generateKeyPair() /** WA noise protocol wrapper */ const noise = makeNoiseHandler(ephemeralKeyPair) - const authState = initialAuthState || initAuthState() + let authState = initialAuthState + if(!authState) { + authState = useSingleFileAuthState('./auth-info-multi.json').state + + logger.warn(` + Baileys just created a single file state for your credentials. + This will not be supported soon. + Please pass the credentials in the config itself + `) + } const { creds } = authState - const ev = new EventEmitter() as BaileysEventEmitter let lastDateRecv: Date let epoch = 0 @@ -174,11 +184,16 @@ export const makeSocket = ({ } /** get some pre-keys and do something with them */ const assertingPreKeys = async(range: number, execute: (keys: { [_: number]: any }) => Promise) => { - const { newPreKeys, lastPreKeyId, preKeysRange } = generateOrGetPreKeys(authState, range) - - creds.serverHasPreKeys = true - creds.nextPreKeyId = Math.max(lastPreKeyId+1, creds.nextPreKeyId) - creds.firstUnuploadedPreKeyId = Math.max(creds.firstUnuploadedPreKeyId, lastPreKeyId+1) + const { newPreKeys, lastPreKeyId, preKeysRange } = generateOrGetPreKeys(authState.creds, range) + + const update: Partial = { + nextPreKeyId: Math.max(lastPreKeyId+1, creds.nextPreKeyId), + firstUnuploadedPreKeyId: Math.max(creds.firstUnuploadedPreKeyId, lastPreKeyId+1) + } + if(!creds.serverHasPreKeys) { + update.serverHasPreKeys = true + } + await Promise.all( Object.keys(newPreKeys).map(k => authState.keys.setPreKey(+k, newPreKeys[+k])) ) @@ -186,7 +201,7 @@ export const makeSocket = ({ const preKeys = await getPreKeys(authState.keys, preKeysRange[0], preKeysRange[0] + preKeysRange[1]) await execute(preKeys) - ev.emit('auth-state.update', authState) + ev.emit('creds.update', update) } /** generates and uploads a set of pre-keys */ const uploadPreKeys = async() => { @@ -464,10 +479,10 @@ export const makeSocket = ({ throw new Boom('Authentication failed', { statusCode: +(value.attrs.code || 500) }) } } - Object.assign(creds, updatedCreds) - logger.info({ jid: creds.me!.id }, 'registered connection, restart server') - ev.emit('auth-state.update', authState) + logger.info({ jid: updatedCreds.me!.id }, 'registered connection, restart server') + + ev.emit('creds.update', updatedCreds) ev.emit('connection.update', { isNewLogin: true, qr: undefined }) end(new Boom('Restart Required', { statusCode: DisconnectReason.restartRequired })) @@ -512,6 +527,8 @@ export const makeSocket = ({ process.nextTick(() => { ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false, qr: undefined }) }) + // update credentials when required + ev.on('creds.update', update => Object.assign(creds, update)) return { ws, diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts index 0e47fd8..5ff95fe 100644 --- a/src/Types/Auth.ts +++ b/src/Types/Auth.ts @@ -16,12 +16,16 @@ export type SignalIdentity = { export type LTHashState = { version: number, hash: Buffer, mutations: ChatMutation[] } -export type AuthenticationCreds = { - noiseKey: KeyPair - signedIdentityKey: KeyPair - signedPreKey: SignedKeyPair - registrationId: number - advSecretKey: string +export type SignalCreds = { + readonly signedIdentityKey: KeyPair + readonly signedPreKey: SignedKeyPair + readonly registrationId: number +} + +export type AuthenticationCreds = SignalCreds & { + readonly noiseKey: KeyPair + readonly advSecretKey: string + me?: Contact account?: proto.IADVSignedDeviceIdentity signalIdentities?: SignalIdentity[] @@ -49,6 +53,11 @@ export type SignalKeyStore = { setAppStateSyncVersion: (id: WAPatchName, item: LTHashState) => Awaitable } +export type SignalAuthState = { + creds: SignalCreds + keys: SignalKeyStore +} + export type AuthenticationState = { creds: AuthenticationCreds keys: SignalKeyStore diff --git a/src/Types/index.ts b/src/Types/index.ts index a8e3f77..1c69c2d 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -11,7 +11,7 @@ import type { Logger } from "pino" import type { URL } from "url" import type NodeCache from 'node-cache' -import { AuthenticationState } from './Auth' +import { AuthenticationState, AuthenticationCreds } from './Auth' import { Chat, PresenceData } from './Chat' import { Contact } from './Contact' import { ConnectionState } from './State' @@ -96,8 +96,8 @@ export type CurveKeyPair = { private: Uint8Array; public: Uint8Array } export type BaileysEventMap = { /** connection state has been updated -- WS closed, opened, connecting etc. */ 'connection.update': Partial - /** auth state updated -- some pre keys, or identity keys etc. */ - 'auth-state.update': AuthenticationState + /** credentials updated -- some metadata, keys or something */ + 'creds.update': Partial /** set chats (history sync), messages are reverse chronologically sorted */ 'chats.set': { chats: Chat[], messages: WAMessage[] } /** upsert chats */ diff --git a/src/Utils/auth-utils.ts b/src/Utils/auth-utils.ts new file mode 100644 index 0000000..16e6b4a --- /dev/null +++ b/src/Utils/auth-utils.ts @@ -0,0 +1,133 @@ +import { randomBytes } from 'crypto' +import { proto } from '../../WAProto' +import type { SignalKeyStore, AuthenticationCreds, KeyPair, LTHashState, AuthenticationState } from "../Types" +import { Curve, signedKeyPair } from './crypto' +import { generateRegistrationId, BufferJSON } from './generics' + +export const initInMemoryKeyStore = ( + { preKeys, sessions, senderKeys, appStateSyncKeys, appStateVersions }: { + preKeys?: { [k: number]: KeyPair }, + sessions?: { [k: string]: any }, + senderKeys?: { [k: string]: any } + appStateSyncKeys?: { [k: string]: proto.IAppStateSyncKeyData }, + appStateVersions?: { [k: string]: LTHashState }, + } = { }, + save: (data: any) => void +) => { + + preKeys = preKeys || { } + sessions = sessions || { } + senderKeys = senderKeys || { } + appStateSyncKeys = appStateSyncKeys || { } + appStateVersions = appStateVersions || { } + + const keyData = { + preKeys, + sessions, + senderKeys, + appStateSyncKeys, + appStateVersions, + } + + return { + ...keyData, + getPreKey: keyId => preKeys[keyId], + setPreKey: (keyId, pair) => { + if(pair) preKeys[keyId] = pair + else delete preKeys[keyId] + + save(keyData) + }, + getSession: id => sessions[id], + setSession: (id, item) => { + if(item) sessions[id] = item + else delete sessions[id] + + save(keyData) + }, + getSenderKey: id => { + return senderKeys[id] + }, + setSenderKey: (id, item) => { + if(item) senderKeys[id] = item + else delete senderKeys[id] + + save(keyData) + }, + getAppStateSyncKey: id => { + const obj = appStateSyncKeys[id] + if(obj) { + return proto.AppStateSyncKeyData.fromObject(obj) + } + }, + setAppStateSyncKey: (id, item) => { + if(item) appStateSyncKeys[id] = item + else delete appStateSyncKeys[id] + + save(keyData) + }, + getAppStateSyncVersion: id => { + const obj = appStateVersions[id] + if(obj) { + return obj + } + }, + setAppStateSyncVersion: (id, item) => { + if(item) appStateVersions[id] = item + else delete appStateVersions[id] + + save(keyData) + } + } as SignalKeyStore +} + +export const initAuthCreds = (): AuthenticationCreds => { + const identityKey = Curve.generateKeyPair() + return { + noiseKey: Curve.generateKeyPair(), + signedIdentityKey: identityKey, + signedPreKey: signedKeyPair(identityKey, 1), + registrationId: generateRegistrationId(), + advSecretKey: randomBytes(32).toString('base64'), + + nextPreKeyId: 1, + firstUnuploadedPreKeyId: 1, + serverHasPreKeys: false + } +} +/** stores the full authentication state in a single JSON file */ +export const useSingleFileAuthState = (filename: string) => { + // require fs here so that in case "fs" is not available -- the app does not crash + const { readFileSync, writeFileSync, existsSync } = require('fs') + + let state: AuthenticationState = undefined + + // save the authentication state to a file + const saveState = () => { + console.log('saving auth state') + writeFileSync( + filename, + // BufferJSON replacer utility saves buffers nicely + JSON.stringify(state, BufferJSON.replacer, 2) + ) + } + + if(existsSync(filename)) { + const { creds, keys } = JSON.parse( + readFileSync(filename, { encoding: 'utf-8' }), + BufferJSON.reviver + ) + state = { + creds: creds, + // stores pre-keys, session & other keys in a JSON object + // we deserialize it here + keys: initInMemoryKeyStore(keys, saveState) + } + } else { + const creds = initAuthCreds() + const keys = initInMemoryKeyStore({ }, saveState) + state = { creds: creds, keys: keys } + } + + return { state, saveState } +} \ No newline at end of file diff --git a/src/Utils/index.ts b/src/Utils/index.ts index 640c9f2..a4c41fe 100644 --- a/src/Utils/index.ts +++ b/src/Utils/index.ts @@ -8,4 +8,5 @@ export * from './signal' export * from './noise-handler' export * from './history' export * from './chat-utils' -export * from './lt-hash' \ No newline at end of file +export * from './lt-hash' +export * from './auth-utils' \ No newline at end of file diff --git a/src/Utils/signal.ts b/src/Utils/signal.ts index c7c90c8..7caa4d7 100644 --- a/src/Utils/signal.ts +++ b/src/Utils/signal.ts @@ -2,7 +2,7 @@ import * as libsignal from 'libsignal' import { encodeBigEndian } from "./generics" import { Curve } from "./crypto" import { SenderKeyDistributionMessage, GroupSessionBuilder, SenderKeyRecord, SenderKeyName, GroupCipher } from '../../WASignalGroup' -import { SignalIdentity, SignalKeyStore, SignedKeyPair, KeyPair, AuthenticationState } from "../Types/Auth" +import { SignalIdentity, SignalKeyStore, SignedKeyPair, KeyPair, SignalAuthState, AuthenticationCreds } from "../Types/Auth" import { assertNodeErrorFree, BinaryNode, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildUInt, jidDecode, JidWithDevice } from "../WABinary" import { proto } from "../../WAProto" @@ -42,7 +42,7 @@ export const getPreKeys = async({ getPreKey }: SignalKeyStore, min: number, limi return dict } -export const generateOrGetPreKeys = ({ creds }: AuthenticationState, range: number) => { +export const generateOrGetPreKeys = (creds: AuthenticationCreds, range: number) => { const avaliable = creds.nextPreKeyId - creds.firstUnuploadedPreKeyId const remaining = range - avaliable const lastPreKeyId = creds.nextPreKeyId + remaining - 1 @@ -83,7 +83,7 @@ export const xmppPreKey = (pair: KeyPair, id: number): BinaryNode => ( } ) -export const signalStorage = ({ creds, keys }: AuthenticationState) => ({ +export const signalStorage = ({ creds, keys }: SignalAuthState) => ({ loadSession: async id => { const sess = await keys.getSession(id) if(sess) { @@ -132,7 +132,7 @@ export const signalStorage = ({ creds, keys }: AuthenticationState) => ({ } }) -export const decryptGroupSignalProto = (group: string, user: string, msg: Buffer | Uint8Array, auth: AuthenticationState) => { +export const decryptGroupSignalProto = (group: string, user: string, msg: Buffer | Uint8Array, auth: SignalAuthState) => { const senderName = jidToSignalSenderKeyName(group, user) const cipher = new GroupCipher(signalStorage(auth), senderName) @@ -142,7 +142,7 @@ export const decryptGroupSignalProto = (group: string, user: string, msg: Buffer export const processSenderKeyMessage = async( authorJid: string, item: proto.ISenderKeyDistributionMessage, - auth: AuthenticationState + auth: SignalAuthState ) => { const builder = new GroupSessionBuilder(signalStorage(auth)) const senderName = jidToSignalSenderKeyName(item.groupId, authorJid) @@ -156,7 +156,7 @@ export const processSenderKeyMessage = async( await builder.process(senderName, senderMsg) } -export const decryptSignalProto = async(user: string, type: 'pkmsg' | 'msg', msg: Buffer | Uint8Array, auth: AuthenticationState) => { +export const decryptSignalProto = async(user: string, type: 'pkmsg' | 'msg', msg: Buffer | Uint8Array, auth: SignalAuthState) => { const addr = jidToSignalProtocolAddress(user) const session = new libsignal.SessionCipher(signalStorage(auth), addr) let result: Buffer @@ -172,7 +172,7 @@ export const decryptSignalProto = async(user: string, type: 'pkmsg' | 'msg', msg } -export const encryptSignalProto = async(user: string, buffer: Buffer, auth: AuthenticationState) => { +export const encryptSignalProto = async(user: string, buffer: Buffer, auth: SignalAuthState) => { const addr = jidToSignalProtocolAddress(user) const cipher = new libsignal.SessionCipher(signalStorage(auth), addr) @@ -183,9 +183,9 @@ export const encryptSignalProto = async(user: string, buffer: Buffer, auth: Auth } } -export const encryptSenderKeyMsgSignalProto = async(group: string, data: Uint8Array | Buffer, auth: AuthenticationState) => { +export const encryptSenderKeyMsgSignalProto = async(group: string, data: Uint8Array | Buffer, meId: string, auth: SignalAuthState) => { const storage = signalStorage(auth) - const senderName = jidToSignalSenderKeyName(group, auth.creds.me!.id) + const senderName = jidToSignalSenderKeyName(group, meId) const builder = new GroupSessionBuilder(storage) const senderKey = await auth.keys.getSenderKey(senderName) @@ -202,7 +202,7 @@ export const encryptSenderKeyMsgSignalProto = async(group: string, data: Uint8Ar } } -export const parseAndInjectE2ESession = async(node: BinaryNode, auth: AuthenticationState) => { +export const parseAndInjectE2ESession = async(node: BinaryNode, auth: SignalAuthState) => { const extractKey = (key: BinaryNode) => ( key ? ({ keyId: getBinaryNodeChildUInt(key, 'id', 3), diff --git a/src/Utils/validate-connection.ts b/src/Utils/validate-connection.ts index f09c304..88468b8 100644 --- a/src/Utils/validate-connection.ts +++ b/src/Utils/validate-connection.ts @@ -1,9 +1,8 @@ import { Boom } from '@hapi/boom' -import { randomBytes } from 'crypto' import { proto } from '../../WAProto' -import type { AuthenticationState, SocketConfig, SignalKeyStore, AuthenticationCreds, KeyPair, LTHashState } from "../Types" -import { Curve, hmacSign, signedKeyPair } from './crypto' -import { encodeInt, generateRegistrationId } from './generics' +import type { SocketConfig, AuthenticationCreds, SignalCreds } from "../Types" +import { Curve, hmacSign } from './crypto' +import { encodeInt } from './generics' import { BinaryNode, S_WHATSAPP_NET, jidDecode, Binary, getAllBinaryNodeChildren } from '../WABinary' import { createSignalIdentity } from './signal' @@ -41,7 +40,7 @@ export const generateLoginNode = (userJid: string, config: Pick, + { registrationId, signedPreKey, signedIdentityKey }: SignalCreds, config: Pick ) => { const appVersionBuf = new Uint8Array(Buffer.from(ENCODED_VERSION, "base64")); @@ -82,84 +81,6 @@ export const generateRegistrationNode = ( return proto.ClientPayload.encode(registerPayload).finish() } -export const initInMemoryKeyStore = ( - { preKeys, sessions, senderKeys, appStateSyncKeys, appStateVersions }: { - preKeys?: { [k: number]: KeyPair }, - sessions?: { [k: string]: any }, - senderKeys?: { [k: string]: any } - appStateSyncKeys?: { [k: string]: proto.IAppStateSyncKeyData }, - appStateVersions?: { [k: string]: LTHashState }, - } = { }, -) => { - preKeys = preKeys || { } - sessions = sessions || { } - senderKeys = senderKeys || { } - appStateSyncKeys = appStateSyncKeys || { } - appStateVersions = appStateVersions || { } - return { - preKeys, - sessions, - senderKeys, - appStateSyncKeys, - appStateVersions, - getPreKey: keyId => preKeys[keyId], - setPreKey: (keyId, pair) => { - if(pair) preKeys[keyId] = pair - else delete preKeys[keyId] - }, - getSession: id => sessions[id], - setSession: (id, item) => { - if(item) sessions[id] = item - else delete sessions[id] - }, - getSenderKey: id => { - return senderKeys[id] - }, - setSenderKey: (id, item) => { - if(item) senderKeys[id] = item - else delete senderKeys[id] - }, - getAppStateSyncKey: id => { - const obj = appStateSyncKeys[id] - if(obj) { - return proto.AppStateSyncKeyData.fromObject(obj) - } - }, - setAppStateSyncKey: (id, item) => { - if(item) appStateSyncKeys[id] = item - else delete appStateSyncKeys[id] - }, - getAppStateSyncVersion: id => { - const obj = appStateVersions[id] - if(obj) { - return obj - } - }, - setAppStateSyncVersion: (id, item) => { - if(item) appStateVersions[id] = item - else delete appStateVersions[id] - } - } as SignalKeyStore -} - -export const initAuthState = (): AuthenticationState => { - const identityKey = Curve.generateKeyPair() - return { - creds: { - noiseKey: Curve.generateKeyPair(), - signedIdentityKey: identityKey, - signedPreKey: signedKeyPair(identityKey, 1), - registrationId: generateRegistrationId(), - advSecretKey: randomBytes(32).toString('base64'), - - nextPreKeyId: 1, - firstUnuploadedPreKeyId: 1, - serverHasPreKeys: false - }, - keys: initInMemoryKeyStore() - } -} - export const configureSuccessfulPairing = ( stanza: BinaryNode, { advSecretKey, signedIdentityKey, signalIdentities }: Pick From d523bf8981324634e18f19667f09c923766515b8 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 20 Nov 2021 17:20:06 +0530 Subject: [PATCH 152/311] feat: detect when multi-device beta not joined --- src/Socket/socket.ts | 5 +++++ src/Types/index.ts | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index a3b4f1d..45323d7 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -524,6 +524,11 @@ export const makeSocket = ({ const reason = +(node.attrs.reason || 500) end(new Boom('Connection Failure', { statusCode: reason, data: node.attrs })) }) + + ws.on('CB:ib,,downgrade_webclient', () => { + end(new Boom('Multi-device beta not joined', { statusCode: DisconnectReason.notJoinedBeta })) + }) + process.nextTick(() => { ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false, qr: undefined }) }) diff --git a/src/Types/index.ts b/src/Types/index.ts index 1c69c2d..6eca814 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -60,7 +60,8 @@ export enum DisconnectReason { timedOut = 408, loggedOut = 401, badSession = 500, - restartRequired = 410 + restartRequired = 410, + notJoinedBeta = 403 } export type WAInitResponse = { From 1cd96ad0390897fe0bc2652e16f87db388446ac3 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 21 Nov 2021 16:10:38 +0530 Subject: [PATCH 153/311] fix: incorrect group owner --- src/Socket/messages-recv.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 9ad9aee..cf4098f 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -281,8 +281,12 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { switch(child?.tag) { case 'create': const metadata = extractGroupMetadata(child) + result.messageStubType = WAMessageStubType.GROUP_CREATE result.messageStubParameters = [metadata.subject] + result.key = { + participant: jidNormalizedUser(metadata.owner) + } ev.emit('chats.upsert', [{ id: metadata.id, @@ -488,7 +492,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { remoteJid: node.attrs.from, fromMe, participant: node.attrs.participant, - id: node.attrs.id + id: node.attrs.id, + ...(msg.key || {}) } msg.messageTimestamp = +node.attrs.t From 27cf3954e8926313153d5be87b057770f6408842 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 21 Nov 2021 16:52:59 +0530 Subject: [PATCH 154/311] fix: account for 0 messages in stanza --- src/Socket/messages-recv.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index cf4098f..0bb090c 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -425,13 +425,17 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { }) } - ev.emit( - 'messages.upsert', - { - messages: fullMessages.map(m => proto.WebMessageInfo.fromObject(m)), - type: stanza.attrs.offline ? 'append' : 'notify' - } - ) + if(fullMessages.length) { + ev.emit( + 'messages.upsert', + { + messages: fullMessages.map(m => proto.WebMessageInfo.fromObject(m)), + type: stanza.attrs.offline ? 'append' : 'notify' + } + ) + } else { + logger.warn({ stanza }, `received node with 0 messages`) + } }) ws.on('CB:ack,class:message', async(node: BinaryNode) => { From 088bae44e801d72b29ebade263880a6e2e63ac3a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 21 Nov 2021 21:39:31 +0530 Subject: [PATCH 155/311] fix: correctly map left group notification --- src/Socket/messages-recv.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 0bb090c..97d7b12 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -311,7 +311,18 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { case 'leave': const stubType = `GROUP_PARTICIPANT_${child.tag!.toUpperCase()}` result.messageStubType = WAMessageStubType[stubType] - result.messageStubParameters = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid) + + const participants = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid) + if( + participants.length === 1 && + // if recv. "remove" message and sender removed themselves + // mark as left + areJidsSameUser(participants[0], node.attrs.participant) && + child.tag === 'remove' + ) { + result.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_LEAVE + } + result.messageStubParameters = participants break case 'subject': result.messageStubType = WAMessageStubType.GROUP_CHANGE_SUBJECT From d5e3d049c4d53cbad71c636106fac4e4c60ca5b0 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 22 Nov 2021 00:16:22 +0530 Subject: [PATCH 156/311] fix: add "offer" call ack --- src/Socket/messages-recv.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 97d7b12..3fc67e6 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -7,6 +7,8 @@ import { KEY_BUNDLE_TYPE } from "../Defaults" import { makeChatsSocket } from "./chats" import { extractGroupMetadata } from "./groups" +const CALL_TAGS_TO_ACK = ['terminate', 'relaylatency', 'offer'] + const isReadReceipt = (type: string) => type === 'read' || type === 'read-self' export const makeMessagesRecvSocket = (config: SocketConfig) => { @@ -465,7 +467,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { logger.info({ node }, 'recv call') const [child] = getAllBinaryNodeChildren(node) - if(child.tag === 'terminate' || child.tag === 'relaylatency') { + if(CALL_TAGS_TO_ACK.includes(child.tag)) { await sendMessageAck(node, { class: 'call', type: child.tag }) } }) From d2e3abfe49088777dcd20256be7f282868957638 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 22 Nov 2021 16:01:58 +0530 Subject: [PATCH 157/311] fix: timestamp & other details not appearing + remove participant property from root message --- src/Socket/messages-recv.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 3fc67e6..e2d4c8b 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -375,6 +375,10 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { id: dec.msgId, participant: dec.participant } + const partialMsg: Partial = { + messageTimestamp: dec.timestamp, + pushName: dec.pushname + } // if there were some successful decryptions if(dec.successes.length) { // send message receipt @@ -418,9 +422,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { key, message, status: isMe ? proto.WebMessageInfo.WebMessageInfoStatus.SERVER_ACK : null, - messageTimestamp: dec.timestamp, - pushName: dec.pushname, - participant: dec.participant + ...partialMsg }) } @@ -434,7 +436,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { fullMessages.push({ key, messageStubType: WAMessageStubType.CIPHERTEXT, - messageStubParameters: [error.message] + messageStubParameters: [error.message], + ...partialMsg }) } From e222ec4151575ebb33f402a1a5563455bbaa83f4 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 23 Nov 2021 12:17:57 +0530 Subject: [PATCH 158/311] refactor: use only "getAppStateSyncKey" in syncd patch --- src/Socket/chats.ts | 4 ++-- src/Utils/chat-utils.ts | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index e4f63ff..78981e3 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -211,7 +211,7 @@ export const makeChatsSocket = (config: SocketConfig) => { const name = key as WAPatchName // only process if there are syncd patches if(decoded[name].length) { - const { newMutations, state: newState } = await decodePatches(name, decoded[name], states[name], authState, true) + const { newMutations, state: newState } = await decodePatches(name, decoded[name], states[name], authState.keys.getAppStateSyncKey, true) await authState.keys.setAppStateSyncVersion(name, newState) @@ -387,7 +387,7 @@ export const makeChatsSocket = (config: SocketConfig) => { ) const initial = await authState.keys.getAppStateSyncVersion(name) // temp: verify it was encoded correctly - const result = await decodePatches(name, [{ ...patch, version: { version: state.version }, }], initial, authState) + const result = await decodePatches(name, [{ ...patch, version: { version: state.version }, }], initial, authState.keys.getAppStateSyncKey) const node: BinaryNode = { tag: 'iq', diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index e06393b..ab8cd76 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -1,6 +1,6 @@ import { Boom } from '@hapi/boom' import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./crypto" -import { AuthenticationState, WAPatchCreate, ChatMutation, WAPatchName, LTHashState, ChatModification } from "../Types" +import { AuthenticationState, WAPatchCreate, ChatMutation, WAPatchName, LTHashState, ChatModification, SignalKeyStore } from "../Types" import { proto } from '../../WAProto' import { LT_HASH_ANTI_TAMPERING } from './lt-hash' import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren } from '../WABinary' @@ -165,7 +165,7 @@ export const encodeSyncdPatch = async( export const decodeSyncdPatch = async( msg: proto.ISyncdPatch, name: WAPatchName, - {keys}: AuthenticationState, + getAppStateSyncKey: SignalKeyStore['getAppStateSyncKey'], validateMacs: boolean = true ) => { const keyCache: { [_: string]: ReturnType } = { } @@ -173,7 +173,7 @@ export const decodeSyncdPatch = async( const base64Key = Buffer.from(keyId!).toString('base64') let key = keyCache[base64Key] if(!key) { - const keyEnc = await keys.getAppStateSyncKey(base64Key) + const keyEnc = await getAppStateSyncKey(base64Key) if(!keyEnc) { throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500, data: msg }) } @@ -275,7 +275,7 @@ export const decodePatches = async( name: WAPatchName, syncds: proto.ISyncdPatch[], initial: LTHashState, - auth: AuthenticationState, + getAppStateSyncKey: SignalKeyStore['getAppStateSyncKey'], validateMacs: boolean = true ) => { const successfulMutations: ChatMutation[] = [] @@ -325,7 +325,7 @@ export const decodePatches = async( if(validateMacs) { const base64Key = Buffer.from(keyId!.id!).toString('base64') - const keyEnc = await auth.keys.getAppStateSyncKey(base64Key) + const keyEnc = await getAppStateSyncKey(base64Key) if(!keyEnc) { throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500 }) } @@ -336,7 +336,7 @@ export const decodePatches = async( } } - const decodeResult = await decodeSyncdPatch(syncd, name, auth!, validateMacs) + const decodeResult = await decodeSyncdPatch(syncd, name, getAppStateSyncKey, validateMacs) successfulMutations.push(...decodeResult.mutations) } return { From b4332488b833f1a079d89636eb1a09293050dee7 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 23 Nov 2021 12:23:25 +0530 Subject: [PATCH 159/311] fix: LT hash computation failing Was trying to remove a patch that was already removed, adding a check to ensure to only remove patches that are of the SET type --- src/Utils/chat-utils.ts | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index ab8cd76..f3cdf6f 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -51,21 +51,23 @@ const to64BitNetworkOrder = function(e) { type Mac = { indexMac: Uint8Array, valueMac: Uint8Array, operation: proto.SyncdMutation.SyncdMutationSyncdOperation } -const computeLtHash = (initial: Uint8Array, macs: Mac[], getPrevSetValueMac: (index: Uint8Array, internalIndex: number) => Uint8Array) => { +const computeLtHash = (initial: Uint8Array, macs: Mac[], getPrevSetValueMac: (index: Uint8Array, internalIndex: number) => { valueMac: Uint8Array, operation: number }) => { const addBuffs: ArrayBuffer[] = [] const subBuffs: ArrayBuffer[] = [] for(let i = 0; i < macs.length;i++) { const { indexMac, valueMac, operation } = macs[i] - const subBuff = getPrevSetValueMac(indexMac, i) + const subOp = getPrevSetValueMac(indexMac, i) if(operation === proto.SyncdMutation.SyncdMutationSyncdOperation.REMOVE) { - if(!subBuff) { + if(!subOp) { throw new Boom('tried remove, but no buffer', { statusCode: 500 }) } } else { addBuffs.push(new Uint8Array(valueMac).buffer) } - if(subBuff) { - subBuffs.push(new Uint8Array(subBuff).buffer) + if(subOp) { + if(subOp.operation === proto.SyncdMutation.SyncdMutationSyncdOperation.SET) { + subBuffs.push(new Uint8Array(subOp.valueMac).buffer) + } } } @@ -123,7 +125,7 @@ export const encodeSyncdPatch = async( state.hash = computeLtHash( state.hash, [ { indexMac, valueMac, operation } ], - (index) => [...state.mutations].reverse().find(m => Buffer.compare(m.indexMac, index) === 0)?.valueMac + (index) => [...state.mutations].reverse().find(m => Buffer.compare(m.indexMac, index) === 0) ) state.version += 1 @@ -300,10 +302,10 @@ export const decodePatches = async( currentVersion = toNumber(version.version!) current = computeLtHash(current, macs, (index, maxIndex) => { - let value: Uint8Array + let result: { valueMac: Uint8Array, operation: number } for(const item of initial.mutations) { if(Buffer.compare(item.indexMac, index) === 0) { - value = item.valueMac + result = item } } for(const { version, mutations } of syncds) { @@ -313,14 +315,18 @@ export const decodePatches = async( }) if(mutationIdx >= 0 && (versionNum < currentVersion || mutationIdx < maxIndex)) { - value = mutations[mutationIdx].record!.value!.blob!.slice(-32) + const mut = mutations[mutationIdx] + result = { + valueMac: mut.record!.value!.blob!.slice(-32), + operation: mut.operation + } } if(versionNum >= currentVersion) { break } } - return value + return result }) if(validateMacs) { From 3173e0d034cd446be131d6cab71008bfc45f1c19 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 24 Nov 2021 15:35:43 +0530 Subject: [PATCH 160/311] fix: media cache throwing error --- src/Utils/messages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 3550bc4..f478e2c 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -146,7 +146,7 @@ export const prepareWAMessageMedia = async( } const obj = WAProto.Message.fromObject(content) if(cacheableKey) { - options.mediaCache!.set(cacheableKey, WAProto.Message.encode(obj)) + options.mediaCache!.set(cacheableKey, WAProto.Message.encode(obj).finish()) } return obj From 13ef870f3e32f45a5123a7dc9065a3539df7da68 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 24 Nov 2021 15:36:25 +0530 Subject: [PATCH 161/311] style: remove useless variable in messages --- src/Utils/messages.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index f478e2c..6900c2a 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -131,7 +131,8 @@ export const prepareWAMessageMedia = async( .filter(Boolean) ) delete uploadData.media - const content = { + + const obj = WAProto.Message.fromObject({ [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject( { url: mediaUrl, @@ -143,8 +144,8 @@ export const prepareWAMessageMedia = async( ...uploadData } ) - } - const obj = WAProto.Message.fromObject(content) + }) + if(cacheableKey) { options.mediaCache!.set(cacheableKey, WAProto.Message.encode(obj).finish()) } From aa3309db3c20aa3965291a3c8c8f98237a8f53dd Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 24 Nov 2021 18:46:38 +0530 Subject: [PATCH 162/311] perf: do not resync on every reconnect --- src/Socket/chats.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 78981e3..6ce3496 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -470,7 +470,6 @@ export const makeChatsSocket = (config: SocketConfig) => { sendPresenceUpdate('available') fetchBlocklist() fetchPrivacySettings() - resyncMainAppState() } }) From aae2b7a55972f6018c55b8be327e6c922157539b Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 24 Nov 2021 18:47:08 +0530 Subject: [PATCH 163/311] fix: resync all collections on mainappresync --- src/Socket/chats.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 6ce3496..5e983d6 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -308,7 +308,13 @@ export const makeChatsSocket = (config: SocketConfig) => { await ( mutationMutex.mutex( - () => resyncAppState([ 'critical_block', 'critical_unblock_low' ]) + () => resyncAppState([ + 'critical_block', + 'critical_unblock_low', + 'regular_high', + 'regular_low', + 'regular' + ]) ) .catch(err => ( logger.warn({ trace: err.stack }, 'failed to sync app state') From 983b28ba0e40b1d1be8978311fc98e6d94f622ea Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 24 Nov 2021 18:48:00 +0530 Subject: [PATCH 164/311] feat: implement "snapshot" resyncing --- src/Socket/chats.ts | 35 ++++++--- src/Utils/chat-utils.ts | 166 +++++++++++++++++++++++++++++----------- 2 files changed, 146 insertions(+), 55 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 5e983d6..9928742 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1,7 +1,7 @@ import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, LTHashState, ChatModification, Contact } from "../Types"; import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET } from "../WABinary"; import { proto } from '../../WAProto' -import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch } from "../Utils"; +import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch, decodeSyncdSnapshot } from "../Utils"; import { makeMessagesSocket } from "./messages-send"; import makeMutex from "../Utils/make-mutex"; @@ -170,7 +170,9 @@ export const makeChatsSocket = (config: SocketConfig) => { }) } - const resyncAppState = async(collections: WAPatchName[], fromScratch: boolean = false, returnSnapshot: boolean = false) => { + const resyncAppStateInternal = async(collections: WAPatchName[], fromScratch: boolean = false, returnSnapshot: boolean = false) => { + if(fromScratch) returnSnapshot = true + const states = { } as { [T in WAPatchName]: LTHashState } for(const name of collections) { let state: LTHashState = fromScratch ? undefined : await authState.keys.getAppStateSyncVersion(name) @@ -205,13 +207,20 @@ export const makeChatsSocket = (config: SocketConfig) => { ] }) - const decoded = extractSyncdPatches(result) // extract from binary node + const decoded = await extractSyncdPatches(result) // extract from binary node for(const key in decoded) { const name = key as WAPatchName + const { patches, snapshot } = decoded[name] + if(snapshot) { + const newState = await decodeSyncdSnapshot(name, snapshot, authState.keys.getAppStateSyncKey) + states[name] = newState + + logger.info(`restored state of ${name} from snapshot to v${newState.version}`) + } // only process if there are syncd patches - if(decoded[name].length) { - const { newMutations, state: newState } = await decodePatches(name, decoded[name], states[name], authState.keys.getAppStateSyncKey, true) + if(patches.length) { + const { newMutations, state: newState } = await decodePatches(name, patches, states[name], authState.keys.getAppStateSyncKey, true) await authState.keys.setAppStateSyncVersion(name, newState) @@ -221,6 +230,15 @@ export const makeChatsSocket = (config: SocketConfig) => { } } + const resyncAppState = async(collections: WAPatchName[], returnSnapshot: boolean = false) => { + try { + await resyncAppStateInternal(collections, returnSnapshot) + } catch(error) { + logger.info({ collections, error: error.stack }, 'failed to sync state from version, trying from scratch') + await resyncAppStateInternal(collections, true, true) + } + } + /** * fetch the profile picture of a user/group * type = "preview" for a low res picture @@ -381,12 +399,7 @@ export const makeChatsSocket = (config: SocketConfig) => { const name = patchCreate.type await mutationMutex.mutex( async() => { - try { - await resyncAppState([name]) - } catch(error) { - logger.info({ name, error: error.stack }, 'failed to sync state from version, trying from scratch') - await resyncAppState([name], true) - } + await resyncAppState([name]) const { patch, state } = await encodeSyncdPatch( patchCreate, authState, diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index f3cdf6f..a55bd4e 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -7,7 +7,7 @@ import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren } from '../WABina import { toNumber } from './generics' import { downloadContentFromMessage, } from './messages-media' -export const mutationKeys = (keydata: Uint8Array) => { +const mutationKeys = (keydata: Uint8Array) => { const expanded = hkdf(keydata, 160, { info: 'WhatsApp Mutation Keys' }) return { indexKey: expanded.slice(0, 32), @@ -59,7 +59,7 @@ const computeLtHash = (initial: Uint8Array, macs: Mac[], getPrevSetValueMac: (in const subOp = getPrevSetValueMac(indexMac, i) if(operation === proto.SyncdMutation.SyncdMutationSyncdOperation.REMOVE) { if(!subOp) { - throw new Boom('tried remove, but no buffer', { statusCode: 500 }) + throw new Boom('tried remove, but no buffer', { data: { indexMac, valueMac } }) } } else { addBuffs.push(new Uint8Array(valueMac).buffer) @@ -76,7 +76,7 @@ const computeLtHash = (initial: Uint8Array, macs: Mac[], getPrevSetValueMac: (in return buff } -export const generateSnapshotMac = (lthash: Uint8Array, version: number, name: WAPatchName, key: Buffer) => { +const generateSnapshotMac = (lthash: Uint8Array, version: number, name: WAPatchName, key: Buffer) => { const total = Buffer.concat([ lthash, to64BitNetworkOrder(version), @@ -84,6 +84,7 @@ export const generateSnapshotMac = (lthash: Uint8Array, version: number, name: W ]) return hmacSign(total, key, 'sha256') } + const generatePatchMac = (snapshotMac: Uint8Array, valueMacs: Uint8Array[], version: number, type: WAPatchName, key: Buffer) => { const total = Buffer.concat([ snapshotMac, @@ -164,11 +165,10 @@ export const encodeSyncdPatch = async( return { patch, state } } -export const decodeSyncdPatch = async( - msg: proto.ISyncdPatch, - name: WAPatchName, +export const decodeSyncdMutations = async( + msgMutations: proto.ISyncdMutation[], getAppStateSyncKey: SignalKeyStore['getAppStateSyncKey'], - validateMacs: boolean = true + validateMacs: boolean ) => { const keyCache: { [_: string]: ReturnType } = { } const getKey = async(keyId: Uint8Array) => { @@ -177,7 +177,7 @@ export const decodeSyncdPatch = async( if(!key) { const keyEnc = await getAppStateSyncKey(base64Key) if(!keyEnc) { - throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500, data: msg }) + throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500, data: { msgMutations } }) } const result = mutationKeys(keyEnc.keyData!) keyCache[base64Key] = result @@ -187,21 +187,10 @@ export const decodeSyncdPatch = async( } const mutations: ChatMutation[] = [] - - if(validateMacs) { - const mainKey = await getKey(msg.keyId!.id) - const mutationmacs = msg.mutations!.map(mutation => mutation.record!.value!.blob!.slice(-32)) - - const patchMac = generatePatchMac(msg.snapshotMac, mutationmacs, toNumber(msg.version!.version), name, mainKey.patchMacKey) - if(Buffer.compare(patchMac, msg.patchMac) !== 0) { - throw new Boom('Invalid patch mac') - } - } - // indexKey used to HMAC sign record.index.blob // valueEncryptionKey used to AES-256-CBC encrypt record.value.blob[0:-32] // the remaining record.value.blob[0:-32] is the mac, it the HMAC sign of key.keyId + decoded proto data + length of bytes in keyId - for(const { operation, record } of msg.mutations!) { + for(const { operation, record } of msgMutations!) { const key = await getKey(record.keyId!.id!) const content = Buffer.from(record.value!.blob!) const encContent = content.slice(0, -32) @@ -236,43 +225,136 @@ export const decodeSyncdPatch = async( return { mutations } } -export const extractSyncdPatches = (result: BinaryNode) => { +export const decodeSyncdPatch = async( + msg: proto.ISyncdPatch, + name: WAPatchName, + getAppStateSyncKey: SignalKeyStore['getAppStateSyncKey'], + validateMacs: boolean +) => { + if(validateMacs) { + const base64Key = Buffer.from(msg.keyId!.id).toString('base64') + const mainKeyObj = await getAppStateSyncKey(base64Key) + const mainKey = mutationKeys(mainKeyObj.keyData!) + const mutationmacs = msg.mutations!.map(mutation => mutation.record!.value!.blob!.slice(-32)) + + const patchMac = generatePatchMac(msg.snapshotMac, mutationmacs, toNumber(msg.version!.version), name, mainKey.patchMacKey) + if(Buffer.compare(patchMac, msg.patchMac) !== 0) { + throw new Boom('Invalid patch mac') + } + } + + const result = await decodeSyncdMutations(msg!.mutations!, getAppStateSyncKey, validateMacs) + return result +} + +export const extractSyncdPatches = async(result: BinaryNode) => { const syncNode = getBinaryNodeChild(result, 'sync') const collectionNodes = getBinaryNodeChildren(syncNode, 'collection') - const final = { } as { [T in WAPatchName]: proto.ISyncdPatch[] } - for(const collectionNode of collectionNodes) { - const patchesNode = getBinaryNodeChild(collectionNode, 'patches') + const final = { } as { [T in WAPatchName]: { patches: proto.ISyncdPatch[], snapshot?: proto.ISyncdSnapshot } } + await Promise.all( + collectionNodes.map( + async collectionNode => { + const patchesNode = getBinaryNodeChild(collectionNode, 'patches') - const patches = getBinaryNodeChildren(patchesNode || collectionNode, 'patch') - const syncds: proto.ISyncdPatch[] = [] - const name = collectionNode.attrs.name as WAPatchName - for(let { content } of patches) { - if(content) { - const syncd = proto.SyncdPatch.decode(content! as Uint8Array) - if(!syncd.version) { - syncd.version = { version: +collectionNode.attrs.version+1 } + const patches = getBinaryNodeChildren(patchesNode || collectionNode, 'patch') + const snapshotNode = getBinaryNodeChild(collectionNode, 'snapshot') + + const syncds: proto.ISyncdPatch[] = [] + const name = collectionNode.attrs.name as WAPatchName + + let snapshot: proto.ISyncdSnapshot | undefined = undefined + if(snapshotNode && !!snapshotNode.content) { + if(!Buffer.isBuffer(snapshotNode)) { + snapshotNode.content = Buffer.from(Object.values(snapshotNode.content)) + } + const blobRef = proto.ExternalBlobReference.decode( + snapshotNode.content! as Buffer + ) + const data = await downloadExternalBlob(blobRef) + snapshot = proto.SyncdSnapshot.decode(data) } - syncds.push(syncd) - } - } - final[name] = syncds - } - + for(let { content } of patches) { + if(content) { + if(!Buffer.isBuffer(content)) { + content = Buffer.from(Object.values(content)) + } + const syncd = proto.SyncdPatch.decode(content! as Uint8Array) + if(!syncd.version) { + syncd.version = { version: +collectionNode.attrs.version+1 } + } + if(syncd.externalMutations) { + const ref = await downloadExternalPatch(syncd.externalMutations) + syncd.mutations.push(...ref.mutations) + } + syncds.push(syncd) + } + } + + final[name] = { patches: syncds, snapshot } + } + ) + ) + return final } -export const downloadExternalPatch = async(blob: proto.IExternalBlobReference) => { + +export const downloadExternalBlob = async(blob: proto.IExternalBlobReference) => { const stream = await downloadContentFromMessage(blob, 'md-app-state') let buffer = Buffer.from([]) for await(const chunk of stream) { buffer = Buffer.concat([buffer, chunk]) } + return buffer +} + +export const downloadExternalPatch = async(blob: proto.IExternalBlobReference) => { + const buffer = await downloadExternalBlob(blob) const syncData = proto.SyncdMutations.decode(buffer) return syncData } +export const decodeSyncdSnapshot = async( + name: WAPatchName, + snapshot: proto.ISyncdSnapshot, + getAppStateSyncKey: SignalKeyStore['getAppStateSyncKey'], + validateMacs: boolean = true +) => { + + const version = toNumber(snapshot.version!.version!) + + const mappedRecords = snapshot.records!.map( + record => ({ record, operation: proto.SyncdMutation.SyncdMutationSyncdOperation.SET }) + ) + const macs = mappedRecords.map(m => ({ + operation: m.operation!, + indexMac: m.record.index!.blob!, + valueMac: m.record.value!.blob!.slice(-32) + })) + const { mutations } = await decodeSyncdMutations(mappedRecords, getAppStateSyncKey, validateMacs) + + let hash = Buffer.alloc(128) + hash = computeLtHash(hash, macs, () => undefined) + + if(validateMacs) { + const base64Key = Buffer.from(snapshot.keyId!.id!).toString('base64') + const keyEnc = await getAppStateSyncKey(base64Key) + if(!keyEnc) { + throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500 }) + } + const result = mutationKeys(keyEnc.keyData!) + const computedSnapshotMac = generateSnapshotMac(hash, version, name, result.snapshotMacKey) + if(Buffer.compare(snapshot.mac!, computedSnapshotMac) !== 0) { + throw new Boom(`failed to verify LTHash at ${version} of ${name} from snapshot`, { statusCode: 500 }) + } + } + + const state: LTHashState = { version, mutations, hash } + return state +} + export const decodePatches = async( name: WAPatchName, syncds: proto.ISyncdPatch[], @@ -286,11 +368,7 @@ export const decodePatches = async( let currentVersion = initial.version for(const syncd of syncds) { - const { mutations, version, keyId, snapshotMac, externalMutations } = syncd - if(externalMutations) { - const ref = await downloadExternalPatch(externalMutations) - mutations.push(...ref.mutations) - } + const { mutations, version, keyId, snapshotMac } = syncd const macs = mutations.map( m => ({ operation: m.operation!, From 920e60815b1087f2a4d4032c4abca017e07c3032 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 24 Nov 2021 20:02:36 +0530 Subject: [PATCH 165/311] feat: add newLTHashState util --- src/Socket/chats.ts | 4 ++-- src/Utils/chat-utils.ts | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 9928742..c70b5f3 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1,7 +1,7 @@ import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, LTHashState, ChatModification, Contact } from "../Types"; import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET } from "../WABinary"; import { proto } from '../../WAProto' -import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch, decodeSyncdSnapshot } from "../Utils"; +import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch, decodeSyncdSnapshot, newLTHashState } from "../Utils"; import { makeMessagesSocket } from "./messages-send"; import makeMutex from "../Utils/make-mutex"; @@ -176,7 +176,7 @@ export const makeChatsSocket = (config: SocketConfig) => { const states = { } as { [T in WAPatchName]: LTHashState } for(const name of collections) { let state: LTHashState = fromScratch ? undefined : await authState.keys.getAppStateSyncVersion(name) - if(!state) state = { version: 0, hash: Buffer.alloc(128), mutations: [] } + if(!state) state = newLTHashState() states[name] = state diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index a55bd4e..0ed6d81 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -95,6 +95,8 @@ const generatePatchMac = (snapshotMac: Uint8Array, valueMacs: Uint8Array[], vers return hmacSign(total, key) } +export const newLTHashState = (): LTHashState => ({ version: 0, hash: Buffer.alloc(128), indexValueMap: {} }) + export const encodeSyncdPatch = async( { type, index, syncAction, apiVersion }: WAPatchCreate, { creds: { myAppStateKeyId }, keys }: AuthenticationState From efc7dffbebcfaa6b2eef2e1fa9035715c2f53f48 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 24 Nov 2021 20:04:36 +0530 Subject: [PATCH 166/311] refactor: cleaner & faster app state sync management 1. Is orders of magnitude faster than the previous edition 2. Stores lesser data, so more memory efficient 3. This breaks the current app state in baileys, but baileys will auto-resync & update the state --- src/Types/Auth.ts | 10 ++- src/Utils/chat-utils.ts | 194 ++++++++++++++++++---------------------- 2 files changed, 94 insertions(+), 110 deletions(-) diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts index 5ff95fe..80fd367 100644 --- a/src/Types/Auth.ts +++ b/src/Types/Auth.ts @@ -1,6 +1,6 @@ import type { Contact } from "./Contact" import type { proto } from "../../WAProto" -import type { WAPatchName, ChatMutation } from "./Chat" +import type { WAPatchName } from "./Chat" export type KeyPair = { public: Uint8Array, private: Uint8Array } export type SignedKeyPair = { keyPair: KeyPair, signature: Uint8Array, keyId: number } @@ -14,7 +14,13 @@ export type SignalIdentity = { identifierKey: Uint8Array } -export type LTHashState = { version: number, hash: Buffer, mutations: ChatMutation[] } +export type LTHashState = { + version: number + hash: Buffer + indexValueMap: { + [indexMacBase64: string]: { valueMac: Uint8Array | Buffer } + } +} export type SignalCreds = { readonly signedIdentityKey: KeyPair diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 0ed6d81..9fa22de 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -51,29 +51,40 @@ const to64BitNetworkOrder = function(e) { type Mac = { indexMac: Uint8Array, valueMac: Uint8Array, operation: proto.SyncdMutation.SyncdMutationSyncdOperation } -const computeLtHash = (initial: Uint8Array, macs: Mac[], getPrevSetValueMac: (index: Uint8Array, internalIndex: number) => { valueMac: Uint8Array, operation: number }) => { +const makeLtHashGenerator = ({ indexValueMap, hash }: Pick) => { + indexValueMap = { ...indexValueMap } const addBuffs: ArrayBuffer[] = [] const subBuffs: ArrayBuffer[] = [] - for(let i = 0; i < macs.length;i++) { - const { indexMac, valueMac, operation } = macs[i] - const subOp = getPrevSetValueMac(indexMac, i) - if(operation === proto.SyncdMutation.SyncdMutationSyncdOperation.REMOVE) { - if(!subOp) { - throw new Boom('tried remove, but no buffer', { data: { indexMac, valueMac } }) + + return { + mix: ({ indexMac, valueMac, operation }: Mac) => { + const indexMacBase64 = Buffer.from(indexMac).toString('base64') + const prevOp = indexValueMap[indexMacBase64] + if(operation === proto.SyncdMutation.SyncdMutationSyncdOperation.REMOVE) { + if(!prevOp) { + throw new Boom('tried remove, but no previous op', { data: { indexMac, valueMac } }) + } + // remove from index value mac, since this mutation is erased + delete indexValueMap[indexMacBase64] + } else { + addBuffs.push(new Uint8Array(valueMac).buffer) + // add this index into the history map + indexValueMap[indexMacBase64] = { valueMac } } - } else { - addBuffs.push(new Uint8Array(valueMac).buffer) - } - if(subOp) { - if(subOp.operation === proto.SyncdMutation.SyncdMutationSyncdOperation.SET) { - subBuffs.push(new Uint8Array(subOp.valueMac).buffer) + if(prevOp) { + subBuffs.push(new Uint8Array(prevOp.valueMac).buffer) + } + }, + finish: () => { + const result = LT_HASH_ANTI_TAMPERING.subtractThenAdd(new Uint8Array(hash).buffer, addBuffs, subBuffs) + const buffer = Buffer.from(result) + + return { + hash: buffer, + indexValueMap } } } - - const result = LT_HASH_ANTI_TAMPERING.subtractThenAdd(new Uint8Array(initial).buffer, addBuffs, subBuffs) - const buff = Buffer.from(result) - return buff } const generateSnapshotMac = (lthash: Uint8Array, version: number, name: WAPatchName, key: Buffer) => { @@ -125,11 +136,11 @@ export const encodeSyncdPatch = async( const valueMac = generateMac(operation, encValue, encKeyId, keyValue.valueMacKey) const indexMac = hmacSign(indexBuffer, keyValue.indexKey) - state.hash = computeLtHash( - state.hash, - [ { indexMac, valueMac, operation } ], - (index) => [...state.mutations].reverse().find(m => Buffer.compare(m.indexMac, index) === 0) - ) + // update LT hash + const generator = makeLtHashGenerator(state) + generator.mix({ indexMac, valueMac, operation }) + Object.assign(state, generator.finish()) + state.version += 1 const snapshotMac = generateSnapshotMac(state.hash, state.version, type, keyValue.snapshotMacKey) @@ -154,21 +165,15 @@ export const encodeSyncdPatch = async( ] } - state.mutations = [ - ...state.mutations, - { - action: syncAction, - index, - valueMac, - indexMac, - operation - } - ] + const base64Index = indexMac.toString('base64') + state.indexValueMap[base64Index] = { valueMac } + return { patch, state } } export const decodeSyncdMutations = async( - msgMutations: proto.ISyncdMutation[], + msgMutations: (proto.ISyncdMutation | proto.ISyncdRecord)[], + initialState: LTHashState, getAppStateSyncKey: SignalKeyStore['getAppStateSyncKey'], validateMacs: boolean ) => { @@ -188,11 +193,18 @@ export const decodeSyncdMutations = async( return key } + const ltGenerator = makeLtHashGenerator(initialState) + const mutations: ChatMutation[] = [] // indexKey used to HMAC sign record.index.blob // valueEncryptionKey used to AES-256-CBC encrypt record.value.blob[0:-32] // the remaining record.value.blob[0:-32] is the mac, it the HMAC sign of key.keyId + decoded proto data + length of bytes in keyId - for(const { operation, record } of msgMutations!) { + for(const msgMutation of msgMutations!) { + // if it's a syncdmutation, get the operation property + // otherwise, if it's only a record -- it'll be a SET mutation + const operation = 'operation' in msgMutation ? msgMutation.operation : proto.SyncdMutation.SyncdMutationSyncdOperation.SET + const record = ('record' in msgMutation && !!msgMutation.record) ? msgMutation.record : msgMutation as proto.ISyncdRecord + const key = await getKey(record.keyId!.id!) const content = Buffer.from(record.value!.blob!) const encContent = content.slice(0, -32) @@ -215,21 +227,25 @@ export const decodeSyncdMutations = async( } const indexStr = Buffer.from(syncAction.index).toString() - mutations.push({ + const mutation: ChatMutation = { action: syncAction.value!, index: JSON.parse(indexStr), indexMac: record.index!.blob!, valueMac: ogValueMac, operation: operation - }) + } + mutations.push(mutation) + + ltGenerator.mix(mutation) } - return { mutations } + return { mutations, ...ltGenerator.finish() } } export const decodeSyncdPatch = async( msg: proto.ISyncdPatch, name: WAPatchName, + initialState: LTHashState, getAppStateSyncKey: SignalKeyStore['getAppStateSyncKey'], validateMacs: boolean ) => { @@ -245,7 +261,7 @@ export const decodeSyncdPatch = async( } } - const result = await decodeSyncdMutations(msg!.mutations!, getAppStateSyncKey, validateMacs) + const result = await decodeSyncdMutations(msg!.mutations!, initialState, getAppStateSyncKey, validateMacs) return result } @@ -286,10 +302,6 @@ export const extractSyncdPatches = async(result: BinaryNode) => { if(!syncd.version) { syncd.version = { version: +collectionNode.attrs.version+1 } } - if(syncd.externalMutations) { - const ref = await downloadExternalPatch(syncd.externalMutations) - syncd.mutations.push(...ref.mutations) - } syncds.push(syncd) } } @@ -324,21 +336,18 @@ export const decodeSyncdSnapshot = async( getAppStateSyncKey: SignalKeyStore['getAppStateSyncKey'], validateMacs: boolean = true ) => { + const newState = newLTHashState() + newState.version = toNumber(snapshot.version!.version!) + + const records = snapshot.records! - const version = toNumber(snapshot.version!.version!) + const ltGenerator = makeLtHashGenerator(newState) + for(const { index, value } of records) { + const valueMac = value.blob!.slice(-32)! + ltGenerator.mix({ indexMac: index.blob!, valueMac, operation: 0 }) + } - const mappedRecords = snapshot.records!.map( - record => ({ record, operation: proto.SyncdMutation.SyncdMutationSyncdOperation.SET }) - ) - const macs = mappedRecords.map(m => ({ - operation: m.operation!, - indexMac: m.record.index!.blob!, - valueMac: m.record.value!.blob!.slice(-32) - })) - const { mutations } = await decodeSyncdMutations(mappedRecords, getAppStateSyncKey, validateMacs) - - let hash = Buffer.alloc(128) - hash = computeLtHash(hash, macs, () => undefined) + Object.assign(newState, ltGenerator.finish()) if(validateMacs) { const base64Key = Buffer.from(snapshot.keyId!.id!).toString('base64') @@ -347,14 +356,13 @@ export const decodeSyncdSnapshot = async( throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500 }) } const result = mutationKeys(keyEnc.keyData!) - const computedSnapshotMac = generateSnapshotMac(hash, version, name, result.snapshotMacKey) + const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey) if(Buffer.compare(snapshot.mac!, computedSnapshotMac) !== 0) { - throw new Boom(`failed to verify LTHash at ${version} of ${name} from snapshot`, { statusCode: 500 }) + throw new Boom(`failed to verify LTHash at ${newState.version} of ${name} from snapshot`, { statusCode: 500 }) } } - - const state: LTHashState = { version, mutations, hash } - return state + + return newState } export const decodePatches = async( @@ -366,72 +374,42 @@ export const decodePatches = async( ) => { const successfulMutations: ChatMutation[] = [] - let current = initial.hash - let currentVersion = initial.version + const newState: LTHashState = { + ...initial, + indexValueMap: { ...initial.indexValueMap } + } for(const syncd of syncds) { - const { mutations, version, keyId, snapshotMac } = syncd - const macs = mutations.map( - m => ({ - operation: m.operation!, - indexMac: m.record.index!.blob!, - valueMac: m.record.value!.blob!.slice(-32) - }) - ) + const { version, keyId, snapshotMac } = syncd + if(syncd.externalMutations) { + const ref = await downloadExternalPatch(syncd.externalMutations) + syncd.mutations.push(...ref.mutations) + } - currentVersion = toNumber(version.version!) + newState.version = toNumber(version.version!) - current = computeLtHash(current, macs, (index, maxIndex) => { - let result: { valueMac: Uint8Array, operation: number } - for(const item of initial.mutations) { - if(Buffer.compare(item.indexMac, index) === 0) { - result = item - } - } - for(const { version, mutations } of syncds) { - const versionNum = toNumber(version.version!) - const mutationIdx = mutations.findIndex(m => { - return Buffer.compare(m.record!.index!.blob, index) === 0 - }) + const decodeResult = await decodeSyncdPatch(syncd, name, newState, getAppStateSyncKey, validateMacs) - if(mutationIdx >= 0 && (versionNum < currentVersion || mutationIdx < maxIndex)) { - const mut = mutations[mutationIdx] - result = { - valueMac: mut.record!.value!.blob!.slice(-32), - operation: mut.operation - } - } - - if(versionNum >= currentVersion) { - break - } - } - return result - }) + newState.hash = decodeResult.hash + newState.indexValueMap = decodeResult.indexValueMap + successfulMutations.push(...decodeResult.mutations) if(validateMacs) { const base64Key = Buffer.from(keyId!.id!).toString('base64') const keyEnc = await getAppStateSyncKey(base64Key) if(!keyEnc) { - throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500 }) + throw new Boom(`failed to find key "${base64Key}" to decode mutation`) } const result = mutationKeys(keyEnc.keyData!) - const computedSnapshotMac = generateSnapshotMac(current, currentVersion, name, result.snapshotMacKey) + const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey) if(Buffer.compare(snapshotMac, computedSnapshotMac) !== 0) { - throw new Boom(`failed to verify LTHash at ${currentVersion} of ${name}`, { statusCode: 500 }) + throw new Boom(`failed to verify LTHash at ${newState.version} of ${name}`) } } - - const decodeResult = await decodeSyncdPatch(syncd, name, getAppStateSyncKey, validateMacs) - successfulMutations.push(...decodeResult.mutations) } return { newMutations: successfulMutations, - state: { - hash: current, - version: currentVersion, - mutations: [...initial.mutations, ...successfulMutations] - } as LTHashState + state: newState } } From 7b42fa5a54ed71c28e4992db4adc38779e6d909d Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 00:37:44 +0530 Subject: [PATCH 167/311] fix: correct operation type on chat patch --- src/Types/Chat.ts | 1 + src/Utils/chat-utils.ts | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 9fec2bb..2214381 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -17,6 +17,7 @@ export type WAPatchCreate = { index: string[] type: WAPatchName apiVersion: number + operation: proto.SyncdMutation.SyncdMutationSyncdOperation } export type Chat = Omit & { diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 9fa22de..11238d1 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -109,7 +109,7 @@ const generatePatchMac = (snapshotMac: Uint8Array, valueMacs: Uint8Array[], vers export const newLTHashState = (): LTHashState => ({ version: 0, hash: Buffer.alloc(128), indexValueMap: {} }) export const encodeSyncdPatch = async( - { type, index, syncAction, apiVersion }: WAPatchCreate, + { type, index, syncAction, apiVersion, operation }: WAPatchCreate, { creds: { myAppStateKeyId }, keys }: AuthenticationState ) => { const key = !!myAppStateKeyId ? await keys.getAppStateSyncKey(myAppStateKeyId) : undefined @@ -118,8 +118,6 @@ export const encodeSyncdPatch = async( } const encKeyId = Buffer.from(myAppStateKeyId, 'base64') - const operation = proto.SyncdMutation.SyncdMutationSyncdOperation.SET - const state = { ...await keys.getAppStateSyncVersion(type) } const indexBuffer = Buffer.from(JSON.stringify(index)) @@ -418,6 +416,7 @@ export const chatModificationToAppPatch = ( jid: string, lastMessages: Pick[] ) => { + const OP = proto.SyncdMutation.SyncdMutationSyncdOperation const messageRange: proto.ISyncActionMessageRange = { lastMessageTimestamp: lastMessages[lastMessages.length-1].messageTimestamp, messages: lastMessages @@ -435,7 +434,8 @@ export const chatModificationToAppPatch = ( }, index: ['mute', jid], type: 'regular_high', - apiVersion: 2 + apiVersion: 2, + operation: mod.mute ? OP.SET : OP.REMOVE } } else if('archive' in mod) { patch = { @@ -448,7 +448,8 @@ export const chatModificationToAppPatch = ( }, index: ['archive', jid], type: 'regular_low', - apiVersion: 3 + apiVersion: 3, + operation: mod.archive ? OP.SET : OP.REMOVE } } else if('markRead' in mod) { patch = { @@ -461,7 +462,8 @@ export const chatModificationToAppPatch = ( }, index: ['markChatAsRead', jid], type: 'regular_low', - apiVersion: 3 + apiVersion: 3, + operation: !mod.markRead ? OP.SET : OP.REMOVE } } else if('clear' in mod) { if(mod.clear === 'all') { @@ -478,6 +480,7 @@ export const chatModificationToAppPatch = ( index: ['deleteMessageForMe', jid, key.id, key.fromMe ? '1' : '0', '0'], type: 'regular_high', apiVersion: 3, + operation: OP.SET } } } else { From a417d6dc5abadbe5d74ee7c0375099ca1ae7744a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 00:38:13 +0530 Subject: [PATCH 168/311] fix: return mutations on patch --- src/Socket/chats.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index c70b5f3..9881dfc 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -208,7 +208,7 @@ export const makeChatsSocket = (config: SocketConfig) => { }) const decoded = await extractSyncdPatches(result) // extract from binary node - + const totalMutations: ChatMutation[] = [] for(const key in decoded) { const name = key as WAPatchName const { patches, snapshot } = decoded[name] @@ -226,17 +226,23 @@ export const makeChatsSocket = (config: SocketConfig) => { logger.info(`synced ${name} to v${newState.version}`) processSyncActions(newMutations) + + totalMutations.push(...newMutations) } } + + return totalMutations } const resyncAppState = async(collections: WAPatchName[], returnSnapshot: boolean = false) => { + let result: ChatMutation[] try { - await resyncAppStateInternal(collections, returnSnapshot) + result = await resyncAppStateInternal(collections, false, returnSnapshot) } catch(error) { logger.info({ collections, error: error.stack }, 'failed to sync state from version, trying from scratch') - await resyncAppStateInternal(collections, true, true) + result = await resyncAppStateInternal(collections, true, true) } + return result } /** From 669fcaa43864522d38503f18e45563271101ccbf Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 12:23:12 +0530 Subject: [PATCH 169/311] fix: ack all calls --- src/Socket/messages-recv.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index e2d4c8b..3eb0ba1 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -7,8 +7,6 @@ import { KEY_BUNDLE_TYPE } from "../Defaults" import { makeChatsSocket } from "./chats" import { extractGroupMetadata } from "./groups" -const CALL_TAGS_TO_ACK = ['terminate', 'relaylatency', 'offer'] - const isReadReceipt = (type: string) => type === 'read' || type === 'read-self' export const makeMessagesRecvSocket = (config: SocketConfig) => { @@ -470,7 +468,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { logger.info({ node }, 'recv call') const [child] = getAllBinaryNodeChildren(node) - if(CALL_TAGS_TO_ACK.includes(child.tag)) { + if(!!child?.tag) { await sendMessageAck(node, { class: 'call', type: child.tag }) } }) From 25f76b2f6607db3032e575ef3c71ec77229e2cb9 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 13:33:56 +0530 Subject: [PATCH 170/311] refactor: more specific arguments for encode patch --- src/Socket/chats.ts | 6 ++++-- src/Utils/chat-utils.ts | 19 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 9881dfc..da1c9a2 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -406,11 +406,13 @@ export const makeChatsSocket = (config: SocketConfig) => { await mutationMutex.mutex( async() => { await resyncAppState([name]) + const initial = await authState.keys.getAppStateSyncVersion(name) const { patch, state } = await encodeSyncdPatch( patchCreate, - authState, + authState.creds.myAppStateKeyId!, + initial, + authState.keys, ) - const initial = await authState.keys.getAppStateSyncVersion(name) // temp: verify it was encoded correctly const result = await decodePatches(name, [{ ...patch, version: { version: state.version }, }], initial, authState.keys.getAppStateSyncKey) diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 11238d1..a496a97 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -110,23 +110,26 @@ export const newLTHashState = (): LTHashState => ({ version: 0, hash: Buffer.all export const encodeSyncdPatch = async( { type, index, syncAction, apiVersion, operation }: WAPatchCreate, - { creds: { myAppStateKeyId }, keys }: AuthenticationState + myAppStateKeyId: string, + state: LTHashState, + keys: SignalKeyStore ) => { const key = !!myAppStateKeyId ? await keys.getAppStateSyncKey(myAppStateKeyId) : undefined if(!key) { - throw new Boom(`myAppStateKey not present`, { statusCode: 404 }) + throw new Boom(`myAppStateKey ("${myAppStateKeyId}") not present`, { statusCode: 404 }) } const encKeyId = Buffer.from(myAppStateKeyId, 'base64') - const state = { ...await keys.getAppStateSyncVersion(type) } + state = { ...state, indexValueMap: { ...state.indexValueMap } } const indexBuffer = Buffer.from(JSON.stringify(index)) - const encoded = proto.SyncActionData.encode({ + const dataProto = proto.SyncActionData.fromObject({ index: indexBuffer, value: syncAction, padding: new Uint8Array(0), version: apiVersion - }).finish() + }) + const encoded = proto.SyncActionData.encode(dataProto).finish() const keyValue = mutationKeys(key!.keyData!) @@ -225,12 +228,12 @@ export const decodeSyncdMutations = async( } const indexStr = Buffer.from(syncAction.index).toString() - const mutation: ChatMutation = { - action: syncAction.value!, + const mutation: ChatMutation = { + syncAction, index: JSON.parse(indexStr), indexMac: record.index!.blob!, valueMac: ogValueMac, - operation: operation + operation: operation, } mutations.push(mutation) From 49f0f4080cb12d5ce560440a4e5e56d8fa0ac5f7 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 13:34:21 +0530 Subject: [PATCH 171/311] docs: log new mutations in trace mode --- src/Socket/chats.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index da1c9a2..a025f9b 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -225,6 +225,9 @@ export const makeChatsSocket = (config: SocketConfig) => { await authState.keys.setAppStateSyncVersion(name, newState) logger.info(`synced ${name} to v${newState.version}`) + if(newMutations.length) { + logger.trace({ newMutations, name }, 'recv new mutations') + } processSyncActions(newMutations) totalMutations.push(...newMutations) From 99619c4c42aa3bfdf39e2b038c1ee71883c3da66 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 13:35:03 +0530 Subject: [PATCH 172/311] refactor: less code duplication for timestamp --- src/Utils/chat-utils.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index a496a97..b61521a 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -424,12 +424,10 @@ export const chatModificationToAppPatch = ( lastMessageTimestamp: lastMessages[lastMessages.length-1].messageTimestamp, messages: lastMessages } - const timestamp = Date.now() let patch: WAPatchCreate if('mute' in mod) { patch = { syncAction: { - timestamp, muteAction: { muted: !!mod.mute, muteEndTimestamp: mod.mute || undefined @@ -443,7 +441,6 @@ export const chatModificationToAppPatch = ( } else if('archive' in mod) { patch = { syncAction: { - timestamp, archiveChatAction: { archived: !!mod.archive, messageRange @@ -457,7 +454,6 @@ export const chatModificationToAppPatch = ( } else if('markRead' in mod) { patch = { syncAction: { - timestamp, markChatAsReadAction: { read: mod.markRead, messageRange @@ -475,7 +471,6 @@ export const chatModificationToAppPatch = ( const key = mod.clear.message patch = { syncAction: { - timestamp, deleteMessageForMeAction: { deleteMedia: false } @@ -489,5 +484,8 @@ export const chatModificationToAppPatch = ( } else { throw new Boom('not supported') } + + patch.syncAction.timestamp = Date.now() + return patch } \ No newline at end of file From b3e0f26ec025a0b5eaf1c79b1ca8a3560b446268 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 13:35:26 +0530 Subject: [PATCH 173/311] fix: typeerror on no messages provided --- src/Utils/chat-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index b61521a..5974782 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -421,7 +421,7 @@ export const chatModificationToAppPatch = ( ) => { const OP = proto.SyncdMutation.SyncdMutationSyncdOperation const messageRange: proto.ISyncActionMessageRange = { - lastMessageTimestamp: lastMessages[lastMessages.length-1].messageTimestamp, + lastMessageTimestamp: lastMessages[lastMessages.length-1]?.messageTimestamp, messages: lastMessages } let patch: WAPatchCreate From 032b2a314b3fdbc4d7e407594df113200bcec46f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 13:35:57 +0530 Subject: [PATCH 174/311] refactor: include full sync action in chatmutation --- src/Socket/chats.ts | 2 +- src/Types/Chat.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index a025f9b..31cc424 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -354,7 +354,7 @@ export const makeChatsSocket = (config: SocketConfig) => { const contactUpdates: { [jid: string]: Contact } = {} const msgDeletes: proto.IMessageKey[] = [] - for(const { action, index: [_, id, msgId, fromMe] } of actions) { + for(const { syncAction: { value: action }, index: [_, id, msgId, fromMe] } of actions) { const update: Partial = { id } if(action?.muteAction) { update.mute = action.muteAction?.muted ? diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 2214381..86e86ad 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -10,7 +10,7 @@ export interface PresenceData { lastSeen?: number } -export type ChatMutation = { action: proto.ISyncActionValue, index: string[], indexMac: Uint8Array, valueMac: Uint8Array, operation: number } +export type ChatMutation = { syncAction: proto.ISyncActionData, index: string[], indexMac: Uint8Array, valueMac: Uint8Array, operation: number } export type WAPatchCreate = { syncAction: proto.ISyncActionValue From ddf6daba657f108df8644a7d29437dca6d389db4 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 13:36:29 +0530 Subject: [PATCH 175/311] feat: implement pin chat modification --- src/Socket/chats.ts | 3 +++ src/Utils/chat-utils.ts | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 31cc424..684c631 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -382,9 +382,12 @@ export const makeChatsSocket = (config: SocketConfig) => { name: action?.pushNameSetting?.name! } ev.emit('creds.update', { me }) + } else if(action?.pinAction) { + update.pin = action.pinAction?.pinned ? toNumber(action.timestamp) : undefined } else { logger.warn({ action, id }, 'unprocessable update') } + if(Object.keys(update).length > 1) { updates[update.id] = { ...(updates[update.id] || {}), diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 5974782..0b8baf5 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -481,6 +481,18 @@ export const chatModificationToAppPatch = ( operation: OP.SET } } + } else if('pin' in mod) { + patch = { + syncAction: { + pinAction: { + pinned: !!mod.pin + } + }, + index: ['pin_v1', '919646328797@s.whatsapp.net'], + type: 'regular_low', + apiVersion: 5, + operation: mod.pin ? OP.SET : OP.REMOVE + } } else { throw new Boom('not supported') } From 396e1d2e950d5b88753911c98cec833baad5017b Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 13:42:44 +0530 Subject: [PATCH 176/311] cleanup: remove redundant sync key request handler --- src/Socket/messages-recv.ts | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 3eb0ba1..bf0a512 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -131,32 +131,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } }) break - case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_REQUEST: - const keys = await Promise.all( - protocolMsg.appStateSyncKeyRequest!.keyIds!.map( - async id => { - const keyId = Buffer.from(id.keyId!).toString('base64') - const keyData = await authState.keys.getAppStateSyncKey(keyId) - logger.info({ keyId }, 'received key request') - return { - keyId: id, - keyData - } - } - ) - ) - - const msg: proto.IMessage = { - protocolMessage: { - type: proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_SHARE, - appStateSyncKeyShare: { - keys - } - } - } - await relayMessage(message.key.remoteJid!, msg, { }) - logger.info({ with: message.key.remoteJid! }, 'shared key') - break case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_SHARE: let newAppStateSyncKeyId = '' for(const { keyData, keyId } of protocolMsg.appStateSyncKeyShare!.keys || []) { From 09b3815d89fd44a7404da628deb28af99fb33c68 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 13:42:58 +0530 Subject: [PATCH 177/311] fix: handle case with 0 app state sync keys --- src/Socket/messages-recv.ts | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index bf0a512..f7cbd88 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -132,18 +132,24 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { }) break case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_SHARE: - let newAppStateSyncKeyId = '' - for(const { keyData, keyId } of protocolMsg.appStateSyncKeyShare!.keys || []) { - const str = Buffer.from(keyId.keyId!).toString('base64') - logger.info({ str }, 'injecting new app state sync key') - await authState.keys.setAppStateSyncKey(str, keyData) - - newAppStateSyncKeyId = str - } - - ev.emit('creds.update', { myAppStateKeyId: newAppStateSyncKeyId }) - - resyncMainAppState() + const keys = protocolMsg.appStateSyncKeyShare!.keys + if(keys?.length) { + let newAppStateSyncKeyId = '' + for(const { keyData, keyId } of keys) { + const str = Buffer.from(keyId.keyId!).toString('base64') + + logger.info({ str }, 'injecting new app state sync key') + await authState.keys.setAppStateSyncKey(str, keyData) + + newAppStateSyncKeyId = str + } + + ev.emit('creds.update', { myAppStateKeyId: newAppStateSyncKeyId }) + + resyncMainAppState() + } else [ + logger.info({ protocolMsg }, 'recv app state sync with 0 keys') + ] break case proto.ProtocolMessage.ProtocolMessageType.REVOKE: ev.emit('messages.update', [ From c07c013a903300c6f1531f718b98b9ac7b0f0ab9 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 13:51:43 +0530 Subject: [PATCH 178/311] refactor: specify pin mutation with boolean --- src/Types/Chat.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 86e86ad..e5656cb 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -30,9 +30,8 @@ export type Chat = Omit & { export type ChatModification = { archive: boolean } | - { - /** pin at current timestamp, or provide timestamp of pin to remove */ - pin: number | null + { + pin: boolean } | { /** mute for duration, or provide timestamp of mute to remove*/ From f5fcaa36f3c4898dcc0f7f8c6e1f66e7005576ab Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 13:52:18 +0530 Subject: [PATCH 179/311] feat: (hopefully) correctly implement account timestamp sync --- src/Socket/chats.ts | 11 ++++++++--- src/Types/Auth.ts | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 684c631..2608efd 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -472,18 +472,23 @@ export const makeChatsSocket = (config: SocketConfig) => { ws.on('CB:presence', handlePresenceUpdate) ws.on('CB:chatstate', handlePresenceUpdate) - /*ws.on('CB:ib,,dirty', async(node: BinaryNode) => { + ws.on('CB:ib,,dirty', async(node: BinaryNode) => { const { attrs } = getBinaryNodeChild(node, 'dirty') const type = attrs.type switch(type) { case 'account_sync': - await updateAccountSyncTimestamp(attrs.timestamp) + let { lastAccountSyncTimestamp } = authState.creds + if(lastAccountSyncTimestamp) { + await updateAccountSyncTimestamp(lastAccountSyncTimestamp) + } + lastAccountSyncTimestamp = +attrs.timestamp + ev.emit('creds.update', { lastAccountSyncTimestamp }) break default: logger.info({ node }, `received unknown sync`) break } - })*/ + }) ws.on('CB:notification,type:server_sync', (node: BinaryNode) => { const update = getBinaryNodeChild(node, 'collection') diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts index 80fd367..7a3e749 100644 --- a/src/Types/Auth.ts +++ b/src/Types/Auth.ts @@ -39,6 +39,8 @@ export type AuthenticationCreds = SignalCreds & { firstUnuploadedPreKeyId: number serverHasPreKeys: boolean nextPreKeyId: number + + lastAccountSyncTimestamp?: number } type Awaitable = T | Promise From a07a63fa2858bfd86dc1df48fa366a76a09057b7 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 15:20:47 +0530 Subject: [PATCH 180/311] perf: single process event for processSyncActions --- src/Socket/chats.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 2608efd..7ed3e5e 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -228,12 +228,13 @@ export const makeChatsSocket = (config: SocketConfig) => { if(newMutations.length) { logger.trace({ newMutations, name }, 'recv new mutations') } - processSyncActions(newMutations) totalMutations.push(...newMutations) } } + processSyncActions(totalMutations) + return totalMutations } @@ -419,9 +420,7 @@ export const makeChatsSocket = (config: SocketConfig) => { initial, authState.keys, ) - // temp: verify it was encoded correctly - const result = await decodePatches(name, [{ ...patch, version: { version: state.version }, }], initial, authState.keys.getAppStateSyncKey) - + const node: BinaryNode = { tag: 'iq', attrs: { @@ -458,6 +457,7 @@ export const makeChatsSocket = (config: SocketConfig) => { await authState.keys.setAppStateSyncVersion(name, state) if(config.emitOwnEvents) { + const result = await decodePatches(name, [{ ...patch, version: { version: state.version }, }], initial, authState.keys.getAppStateSyncKey) processSyncActions(result.newMutations) } } From eac75afbe21d8304563548424250054264fa30d0 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 15:21:33 +0530 Subject: [PATCH 181/311] fix: do not call REMOVE op for mutations --- src/Utils/chat-utils.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 0b8baf5..342be90 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -436,7 +436,7 @@ export const chatModificationToAppPatch = ( index: ['mute', jid], type: 'regular_high', apiVersion: 2, - operation: mod.mute ? OP.SET : OP.REMOVE + operation: OP.SET } } else if('archive' in mod) { patch = { @@ -449,7 +449,7 @@ export const chatModificationToAppPatch = ( index: ['archive', jid], type: 'regular_low', apiVersion: 3, - operation: mod.archive ? OP.SET : OP.REMOVE + operation: OP.SET } } else if('markRead' in mod) { patch = { @@ -462,7 +462,7 @@ export const chatModificationToAppPatch = ( index: ['markChatAsRead', jid], type: 'regular_low', apiVersion: 3, - operation: !mod.markRead ? OP.SET : OP.REMOVE + operation: OP.SET } } else if('clear' in mod) { if(mod.clear === 'all') { @@ -491,7 +491,7 @@ export const chatModificationToAppPatch = ( index: ['pin_v1', '919646328797@s.whatsapp.net'], type: 'regular_low', apiVersion: 5, - operation: mod.pin ? OP.SET : OP.REMOVE + operation: OP.SET } } else { throw new Boom('not supported') From 841a129019e2002e4d5ffb26ec51d7fb77a995eb Mon Sep 17 00:00:00 2001 From: azudin Date: Thu, 25 Nov 2021 18:07:34 +0800 Subject: [PATCH 182/311] Multi device - Clean up typos and replace conn to sock (#916) * Update README.md * Update README.md Change updatePresence to sendPresenceUpdate * Update README.md clean up typos and replace conn to sock * Update README.md clean up typos and replace conn to sock to standardize with existing example --- README.md | 104 +++++++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index b97fd3e..2ab53bb 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ TODO import makeWASocket from '@adiwajshing/baileys-md' async function connectToWhatsApp () { - const conn = makeWASocket({ + const sock = makeWASocket({ // can provide additional config here printQRInTerminal: true }) @@ -65,7 +65,7 @@ async function connectToWhatsApp () { console.log(JSON.stringify(m, undefined, 2)) console.log('replying to', m.messages[0].key.remoteJid) - sendMessageWTyping({ text: 'Hello there!' }, m.messages[0].key.remoteJid!) + await sock.sendMessage(m.messages[0].key.remoteJid!, { text: 'Hello there!' }) }) } // run in main file @@ -129,7 +129,7 @@ const { state, saveState } = useSingleFileAuthState('./auth_info_multi.json') // so if valid credentials are available -- it'll connect without QR const conn = makeSocket({ auth: state }) // this will be called as soon as the credentials are updated -conn.ev.on ('creds.update', saveState) +sock.ev.on ('creds.update', saveState) ``` **Note**: When a message is received/sent, due to signal sessions needing updating, the auth keys (`authState.keys`) will update. Whenever that happens, you must save the updated keys. Not doing so will prevent your messages from reaching the recipient & other unexpected consequences. The `useSingleFileAuthState` function automatically takes care of that, but for any other serious implementation -- you will need to be very careful with the key state management. @@ -225,9 +225,9 @@ import { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys-md' const id = 'abcd@s.whatsapp.net' // the WhatsApp ID // send a simple text! -const sentMsg = await conn.sendMessage(id, { text: 'oh hello there' }) +const sentMsg = await sock.sendMessage(id, { text: 'oh hello there' }) // send a location! -const sentMsg = await conn.sendMessage( +const sentMsg = await sock.sendMessage( id, { location: { degreesLatitude: 24.121231, degreesLongitude: 55.1121221 } } ) @@ -238,7 +238,7 @@ const vcard = 'BEGIN:VCARD\n' // metadata of the contact card + 'ORG:Ashoka Uni;\n' // the organization of the contact + 'TEL;type=CELL;type=VOICE;waid=911234567890:+91 12345 67890\n' // WhatsApp ID + phone number + 'END:VCARD' -const sentMsg = await conn.sendMessage( +const sentMsg = await sock.sendMessage( id, { contacts: { @@ -262,7 +262,7 @@ const buttonMessage = { headerType: 1 } -const sendMsg = await conn.sendMessage(id, buttonMessage) +const sendMsg = await sock.sendMessage(id, buttonMessage) ``` ### Media Messages @@ -274,7 +274,7 @@ Sending media (video, stickers, images) is easier & more efficient than ever. ``` ts import { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys-md' // Sending gifs -await conn.sendMessage( +await sock.sendMessage( id, { video: fs.readFileSync("Media/ma_gif.mp4"), @@ -282,7 +282,7 @@ await conn.sendMessage( gifPlayback: true } ) -await conn.sendMessage( +await sock.sendMessage( id, { video: "./Media/ma_gif.mp4", @@ -291,7 +291,7 @@ await conn.sendMessage( } ) -await conn.sendMessage( +await sock.sendMessage( id, { video: "./Media/ma_gif.mp4", @@ -301,7 +301,7 @@ await conn.sendMessage( ) // send an audio file -await conn.sendMessage( +await sock.sendMessage( id, { audio: { url: "./Media/audio.mp3" }, mimetype: 'audio/mp4' } { url: "Media/audio.mp3" }, // can send mp3, mp4, & ogg @@ -315,14 +315,14 @@ const buttons = [ ] const buttonMessage = { - image: {url: url}, + image: {url: 'https://example.com/image.jpeg'}, caption: "Hi it's button message", footerText: 'Hello World', buttons: buttons, headerType: 4 } -const sendMsg = await conn.sendMessage(id, buttonMessage) +const sendMsg = await sock.sendMessage(id, buttonMessage) ``` ### Notes @@ -360,7 +360,7 @@ const sendMsg = await conn.sendMessage(id, buttonMessage) ``` ts const msg = getMessageFromStore('455@s.whatsapp.net', 'HSJHJWH7323HSJSJ') // implement this on your end -await conn.sendMessage('1234@s.whatsapp.net', { forward: msg }) // WA forward the message! +await sock.sendMessage('1234@s.whatsapp.net', { forward: msg }) // WA forward the message! ``` ## Reading Messages @@ -374,7 +374,7 @@ const id = '1234-123@g.us' const messageID = 'AHASHH123123AHGA' // id of the message you want to read const participant = '912121232@s.whatsapp.net' // the ID of the user that sent the message (undefined for individual chats) -await conn.sendReadReceipt(id, participant, [messageID]) +await sock.sendReadReceipt(id, participant, [messageID]) ``` The message ID is the unique identifier of the message that you are marking as read. On a `WAMessage`, the `messageID` can be accessed using ```messageID = message.key.id```. @@ -382,7 +382,7 @@ The message ID is the unique identifier of the message that you are marking as r ## Update Presence ``` ts -await conn.updatePresence(id, 'available') +await sock.sendPresenceUpdate('available', id) ``` This lets the person/group with ``` id ``` know whether you're online, offline, typing etc. where ``` presence ``` can be one of the following: @@ -399,7 +399,7 @@ If you want to save the media you received import { writeFile } from 'fs/promises' import { downloadContentFromMessage } from '@adiwajshing/baileys-md' -conn.ev.on('messages.upsert', async ({ messages }) => { +sock.ev.on('messages.upsert', async ({ messages }) => { const m = messages[0] if (!m.message) return // if there is no text or media message @@ -422,10 +422,10 @@ conn.ev.on('messages.upsert', async ({ messages }) => { ``` ts const jid = '1234@s.whatsapp.net' // can also be a group -const response = await conn.sendMessage(jid, { text: 'hello!' }) // send a message +const response = await sock.sendMessage(jid, { text: 'hello!' }) // send a message // sends a message to delete the given message // this deletes the message for everyone -await conn.sendMessage(jid, { delete: response.key }) +await sock.sendMessage(jid, { delete: response.key }) ``` Note: deleting for oneself is supported via `chatModify` (next section) @@ -437,26 +437,26 @@ WA uses an encrypted form of communication to send chat/app updates. This has be - Archive a chat ``` ts const lastMsgInChat = await getLastMessageInChat('123456@s.whatsapp.net') // implement this on your end - await conn.chatModify({ archive: true }, '123456@s.whatsapp.net', [lastMsgInChat]) + await sock.chatModify({ archive: true }, '123456@s.whatsapp.net', [lastMsgInChat]) ``` - Mute/unmute a chat ``` ts // mute for 8 hours - await conn.chatModify({ mute: 8*60*60*1000 }, '123456@s.whatsapp.net', []) + await sock.chatModify({ mute: 8*60*60*1000 }, '123456@s.whatsapp.net', []) // unmute - await conn.chatModify({ mute: null }, '123456@s.whatsapp.net', []) + await sock.chatModify({ mute: null }, '123456@s.whatsapp.net', []) ``` - Mark a chat read/unread ``` ts const lastMsgInChat = await getLastMessageInChat('123456@s.whatsapp.net') // implement this on your end // mark it unread - await conn.chatModify({ markRead: false }, '123456@s.whatsapp.net', [lastMsgInChat]) + await sock.chatModify({ markRead: false }, '123456@s.whatsapp.net', [lastMsgInChat]) ``` - Delete message for me ``` ts // mark it unread - await conn.chatModify( + await sock.chatModify( { clear: { message: { id: 'ATWYHDNNWU81732J', fromMe: true } } }, '123456@s.whatsapp.net', [] @@ -470,15 +470,15 @@ Note: if you mess up one of your updates, WA can log you out of all your devices ``` ts const jid = '1234@s.whatsapp.net' // can also be a group // turn on disappearing messages -await conn.sendMessage( +await sock.sendMessage( jid, // this is 1 week in seconds -- how long you want messages to appear for { disappearingMessagesInChat: WA_DEFAULT_EPHEMERAL } ) // will send as a disappearing message -await conn.sendMessage(jid, { text: 'hello' }, { ephemeralExpiration: WA_DEFAULT_EPHEMERAL }) +await sock.sendMessage(jid, { text: 'hello' }, { ephemeralExpiration: WA_DEFAULT_EPHEMERAL }) // turn off disappearing messages -await conn.sendMessage( +await sock.sendMessage( jid, { disappearingMessagesInChat: false } ) @@ -490,40 +490,40 @@ await conn.sendMessage( - To check if a given ID is on WhatsApp ``` ts const id = '123456' - const [result] = await conn.onWhatsApp(id) + const [result] = await sock.onWhatsApp(id) if (result.exists) console.log (`${id} exists on WhatsApp, as jid: ${result.jid}`) ``` - To query chat history on a group or with someone TODO, if possible - To get the status of some person ``` ts - const status = await conn.fetchStatus("xyz@s.whatsapp.net") + const status = await sock.fetchStatus("xyz@s.whatsapp.net") console.log("status: " + status) ``` - To get the display picture of some person/group ``` ts // for low res picture - const ppUrl = await conn.profilePictureUrl("xyz@g.us") + const ppUrl = await sock.profilePictureUrl("xyz@g.us") console.log("download profile picture from: " + ppUrl) // for high res picture - const ppUrl = await conn.profilePictureUrl("xyz@g.us", 'image') + const ppUrl = await sock.profilePictureUrl("xyz@g.us", 'image') ``` - To change your display picture or a group's ``` ts const jid = '111234567890-1594482450@g.us' // can be your own too - await conn.updateProfilePicture(jid, { url: './new-profile-picture.jpeg' }) + await sock.updateProfilePicture(jid, { url: './new-profile-picture.jpeg' }) ``` - To get someone's presence (if they're typing, online) ``` ts // the presence update is fetched and called here - conn.ev.on('presence-update', json => console.log(json)) + sock.ev.on('presence-update', json => console.log(json)) // request updates for a chat - await conn.presenceSubscribe("xyz@s.whatsapp.net") + await sock.presenceSubscribe("xyz@s.whatsapp.net") ``` - To block or unblock user ``` ts - await conn.updateBlockStatus("xyz@s.whatsapp.net", "block") // Block user - await conn.updateBlockStatus("xyz@s.whatsapp.net", "unblock") // Unblock user + await sock.updateBlockStatus("xyz@s.whatsapp.net", "block") // Block user + await sock.updateBlockStatus("xyz@s.whatsapp.net", "unblock") // Unblock user ``` Of course, replace ``` xyz ``` with an actual ID. @@ -531,14 +531,14 @@ Of course, replace ``` xyz ``` with an actual ID. - To create a group ``` ts // title & participants - const group = await conn.groupCreate("My Fab Group", ["1234@s.whatsapp.net", "4564@s.whatsapp.net"]) + const group = await sock.groupCreate("My Fab Group", ["1234@s.whatsapp.net", "4564@s.whatsapp.net"]) console.log ("created group with id: " + group.gid) - conn.sendMessage(group.id, { text: 'hello there' }) // say hello to everyone on the group + sock.sendMessage(group.id, { text: 'hello there' }) // say hello to everyone on the group ``` - To add/remove people to a group or demote/promote people ``` ts // id & people to add to the group (will throw error if it fails) - const response = await conn.groupParticipantsUpdate( + const response = await sock.groupParticipantsUpdate( "abcd-xyz@g.us", ["abcd@s.whatsapp.net", "efgh@s.whatsapp.net"], "add" // replace this parameter with "remove", "demote" or "promote" @@ -546,38 +546,38 @@ Of course, replace ``` xyz ``` with an actual ID. ``` - To change the group's subject ``` ts - await conn.groupUpdateSubject("abcd-xyz@g.us", "New Subject!") + await sock.groupUpdateSubject("abcd-xyz@g.us", "New Subject!") ``` - To change the group's description ``` ts - await conn.groupUpdateDescription("abcd-xyz@g.us", "New Description!") + await sock.groupUpdateDescription("abcd-xyz@g.us", "New Description!") ``` - To change group settings ``` ts // only allow admins to send messages - await conn.groupSettingUpdate("abcd-xyz@g.us", 'announcement') + await sock.groupSettingUpdate("abcd-xyz@g.us", 'announcement') // allow everyone to modify the group's settings -- like display picture etc. - await conn.groupSettingUpdate("abcd-xyz@g.us", 'unlocked') + await sock.groupSettingUpdate("abcd-xyz@g.us", 'unlocked') // only allow admins to modify the group's settings - await conn.groupSettingUpdate("abcd-xyz@g.us", 'locked') + await sock.groupSettingUpdate("abcd-xyz@g.us", 'locked') ``` - To leave a group ``` ts - await conn.groupLeave("abcd-xyz@g.us") // (will throw error if it fails) + await sock.groupLeave("abcd-xyz@g.us") // (will throw error if it fails) ``` - To get the invite code for a group ``` ts - const code = await conn.groupInviteCode("abcd-xyz@g.us") + const code = await sock.groupInviteCode("abcd-xyz@g.us") console.log("group code: " + code) ``` - To query the metadata of a group ``` ts - const metadata = await conn.groupMetadata("abcd-xyz@g.us") + const metadata = await sock.groupMetadata("abcd-xyz@g.us") console.log(metadata.id + ", title: " + metadata.subject + ", description: " + metadata.desc) ``` - To join the group using the invitation code (not supported yet) ``` ts - const response = await conn.acceptInvite("xxx") + const response = await sock.acceptInvite("xxx") console.log("joined to: " + response.gid) ``` Of course, replace ``` xxx ``` with invitation code. @@ -591,7 +591,7 @@ Of course, replace ``` xyz ``` with an actual ID. - Broadcast IDs are in the format `12345678@broadcast` - To query a broadcast list's recipients & name: ``` ts - const bList = await conn.getBroadcastListInfo("1234@broadcast") + const bList = await sock.getBroadcastListInfo("1234@broadcast") console.log (`list name: ${bList.name}, recps: ${bList.recipients}`) ``` @@ -619,11 +619,11 @@ This will enable you to see all sorts of messages WhatsApp sends in the console. Hence, you can register a callback for an event using the following: ``` ts // for any message with tag 'edge_routing' - conn.ws.on(`CB:edge_routing`, (node: BinaryNode) => { }) + sock.ws.on(`CB:edge_routing`, (node: BinaryNode) => { }) // for any message with tag 'edge_routing' and id attribute = abcd - conn.ws.on(`CB:edge_routing,id:abcd`, (node: BinaryNode) => { }) + sock.ws.on(`CB:edge_routing,id:abcd`, (node: BinaryNode) => { }) // for any message with tag 'edge_routing', id attribute = abcd & first content node routing_info - conn.ws.on(`CB:edge_routing,id:abcd,routing_info`, (node: BinaryNode) => { }) + sock.ws.on(`CB:edge_routing,id:abcd,routing_info`, (node: BinaryNode) => { }) ``` ### Note From 1f8663092fa8ee7e3791e6f1636ac94e435249b1 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 15:41:34 +0530 Subject: [PATCH 183/311] fix: receipt not being sent on empty message --- src/Socket/messages-recv.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index f7cbd88..4be4838 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -357,6 +357,11 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { messageTimestamp: dec.timestamp, pushName: dec.pushname } + + if(!dec.failures.length) { + await sendMessageAck(stanza, { class: 'receipt' }) + } + // if there were some successful decryptions if(dec.successes.length) { // send message receipt @@ -388,8 +393,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { await sendNode({ tag: 'receipt', attrs: recpAttrs }) logger.debug({ msgId: dec.msgId }, 'sent message receipt') - await sendMessageAck(stanza, { class: 'receipt' }) - await sendDeliveryReceipt(dec.chatId, dec.participant, [dec.msgId]) logger.debug({ msgId: dec.msgId }, 'sent delivery receipt') } From b91a1cbcf30b6170fd1097fc6668f3e0584fb4ed Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 19:51:49 +0530 Subject: [PATCH 184/311] fix: possible leak on waitForMessage --- src/Socket/socket.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 45323d7..522a873 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -123,12 +123,14 @@ export const makeSocket = ({ ws.on(`TAG:${msgId}`, onRecv) ws.on('close', onErr) // if the socket closes, you'll never receive the message + ws.off('error', onErr) }, ) return result as any } finally { ws.off(`TAG:${msgId}`, onRecv) ws.off('close', onErr) // if the socket closes, you'll never receive the message + ws.off('error', onErr) } } /** send a query, and wait for its response. auto-generates message ID if not provided */ From 6e830c1e1b6af890407de9d2b401b5b10b4402f9 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 25 Nov 2021 19:54:56 +0530 Subject: [PATCH 185/311] feat: enforce default timeout to prevent any hanging promises --- README.md | 2 ++ src/Defaults/index.ts | 1 + src/Socket/socket.ts | 3 ++- src/Types/index.ts | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2ab53bb..aa39163 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,8 @@ type SocketConfig = { waWebSocketUrl: string | URL /** Fails the connection if the connection times out in this time interval or no data is received */ connectTimeoutMs: number + /** Default timeout for queries, undefined for no timeout */ + defaultQueryTimeoutMs: number | undefined /** ping-pong interval for WS connection */ keepAliveIntervalMs: number /** proxy agent */ diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 298d0aa..ab76ade 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -27,6 +27,7 @@ export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { logger: P().child({ class: 'baileys' }), printQRInTerminal: false, emitOwnEvents: true, + defaultQueryTimeoutMs: 60_000 } export const MEDIA_PATH_MAP: { [T in MediaType]: string } = { diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 522a873..3fb7657 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -25,6 +25,7 @@ export const makeSocket = ({ browser, auth: initialAuthState, printQRInTerminal, + defaultQueryTimeoutMs }: SocketConfig) => { const ws = new WebSocket(waWebSocketUrl, undefined, { origin: DEFAULT_ORIGIN, @@ -110,7 +111,7 @@ export const makeSocket = ({ * @param json query that was sent * @param timeoutMs timeout after which the promise will reject */ - const waitForMessage = async(msgId: string, timeoutMs?: number) => { + const waitForMessage = async(msgId: string, timeoutMs = defaultQueryTimeoutMs) => { let onRecv: (json) => void let onErr: (err) => void try { diff --git a/src/Types/index.ts b/src/Types/index.ts index 6eca814..d911a2d 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -30,6 +30,8 @@ export type SocketConfig = { waWebSocketUrl: string | URL /** Fails the connection if the socket times out in this interval */ connectTimeoutMs: number + /** Default timeout for queries, undefined for no timeout */ + defaultQueryTimeoutMs: number | undefined /** ping-pong interval for WS connection */ keepAliveIntervalMs: number /** proxy agent */ From e810f2dec5b0557800fbc2f52d7dc9a4dd265aa4 Mon Sep 17 00:00:00 2001 From: Maurilho Batista Date: Fri, 26 Nov 2021 02:00:15 -0300 Subject: [PATCH 186/311] Add support for stream as media message input (#905) * Add support for stream as media message input * refactor: use async/await on readable toBuffer * refactor: be more explicit about using a readable stream Co-authored-by: Adhiraj Singh --- src/Socket/chats.ts | 2 +- src/Types/Message.ts | 3 ++- src/Utils/messages-media.ts | 24 ++++++++++++++++++++++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 7ed3e5e..295cfcc 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -100,7 +100,7 @@ export const makeChatsSocket = (config: SocketConfig) => { } const updateProfilePicture = async(jid: string, content: WAMediaUpload) => { - const { img } = await generateProfilePicture('url' in content ? content.url.toString() : content) + const { img } = await generateProfilePicture(content) await query({ tag: 'iq', attrs: { diff --git a/src/Types/Message.ts b/src/Types/Message.ts index fb768f2..5445cdb 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -3,6 +3,7 @@ import type { Logger } from "pino" import type { URL } from "url" import type NodeCache from "node-cache" import type { GroupMetadata } from "./GroupMetadata" +import type { Readable } from "stream" import { proto } from '../../WAProto' // export the WAMessage Prototypes @@ -18,7 +19,7 @@ export type WALocationMessage = proto.ILocationMessage export type WAGenericMediaMessage = proto.IVideoMessage | proto.IImageMessage | proto.IAudioMessage | proto.IDocumentMessage | proto.IStickerMessage export import WAMessageStubType = proto.WebMessageInfo.WebMessageInfoStubType export import WAMessageStatus = proto.WebMessageInfo.WebMessageInfoStatus -export type WAMediaUpload = Buffer | { url: URL | string } +export type WAMediaUpload = Buffer | { url: URL | string } | { stream: Readable } /** Set of message types that are supported by the library */ export type MessageType = keyof proto.Message diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 05f3253..a32342a 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -51,13 +51,25 @@ const extractVideoThumb = async ( }) }) as Promise -export const compressImage = async (bufferOrFilePath: Buffer | string) => { +export const compressImage = async (bufferOrFilePath: Readable | Buffer | string) => { + if(bufferOrFilePath instanceof Readable) { + bufferOrFilePath = await toBuffer(bufferOrFilePath) + } const { read, MIME_JPEG } = await import('jimp') const jimp = await read(bufferOrFilePath as any) const result = await jimp.resize(32, 32).getBufferAsync(MIME_JPEG) return result } -export const generateProfilePicture = async (bufferOrFilePath: Buffer | string) => { +export const generateProfilePicture = async (mediaUpload: WAMediaUpload) => { + let bufferOrFilePath: Buffer | string + if(Buffer.isBuffer(mediaUpload)) { + bufferOrFilePath = mediaUpload + } else if('url' in mediaUpload) { + bufferOrFilePath = mediaUpload.url.toString() + } else { + bufferOrFilePath = await toBuffer(mediaUpload.stream) + } + const { read, MIME_JPEG } = await import('jimp') const jimp = await read(bufferOrFilePath as any) const min = Math.min(jimp.getWidth (), jimp.getHeight ()) @@ -89,8 +101,16 @@ export const toReadable = (buffer: Buffer) => { readable.push(null) return readable } +export const toBuffer = async(stream: Readable) => { + let buff = Buffer.alloc(0) + for await(const chunk of stream) { + buff = Buffer.concat([ buff, chunk ]) + } + return buff +} export const getStream = async (item: WAMediaUpload) => { if(Buffer.isBuffer(item)) return { stream: toReadable(item), type: 'buffer' } + if('stream' in item) return { stream: item.stream, type: 'readable' } if(item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) { return { stream: await getGotStream(item.url), type: 'remote' } } From 6786576d13811562ac64fdf83bfe3a760c63d3b4 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 26 Nov 2021 10:30:59 +0530 Subject: [PATCH 187/311] style: fix indentation --- src/Socket/messages-send.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 56eb181..ff881f6 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -431,7 +431,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { sendDeliveryReceipt, sendReadReceipt, refreshMediaConn, - waUploadToServer, + waUploadToServer, fetchPrivacySettings, sendMessage: async( jid: string, From b9d37a06a3ac5723765d01fedc43e89d280de0d6 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 26 Nov 2021 10:31:46 +0530 Subject: [PATCH 188/311] fix: incorrect updates being forwarded to messages.update --- src/Socket/messages-recv.ts | 48 ++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 4be4838..46921d7 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -7,7 +7,15 @@ import { KEY_BUNDLE_TYPE } from "../Defaults" import { makeChatsSocket } from "./chats" import { extractGroupMetadata } from "./groups" -const isReadReceipt = (type: string) => type === 'read' || type === 'read-self' +const getStatusFromReceiptType = (type: string | undefined) => { + if(type === 'read' || type === 'read-self') { + return proto.WebMessageInfo.WebMessageInfoStatus.READ + } + if(typeof type === 'undefined') { + return proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK + } + return undefined +} export const makeMessagesRecvSocket = (config: SocketConfig) => { const { logger } = config @@ -458,25 +466,27 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const handleReceipt = async(node: BinaryNode) => { const { attrs, content } = node - const isRead = isReadReceipt(attrs.type) - const status = isRead ? proto.WebMessageInfo.WebMessageInfoStatus.READ : proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK - const ids = [attrs.id] - if(Array.isArray(content)) { - const items = getBinaryNodeChildren(content[0], 'item') - ids.push(...items.map(i => i.attrs.id)) + const status = getStatusFromReceiptType(attrs.type) + + if(typeof status !== 'undefined' && !areJidsSameUser(attrs.from, authState.creds.me?.id)) { + const ids = [attrs.id] + if(Array.isArray(content)) { + const items = getBinaryNodeChildren(content[0], 'item') + ids.push(...items.map(i => i.attrs.id)) + } + + const remoteJid = attrs.recipient || attrs.from + const fromMe = attrs.recipient ? false : true + ev.emit('messages.update', ids.map(id => ({ + key: { + remoteJid, + id: id, + fromMe, + participant: attrs.participant + }, + update: { status } + }))) } - - const remoteJid = attrs.recipient || attrs.from - const fromMe = attrs.recipient ? false : true - ev.emit('messages.update', ids.map(id => ({ - key: { - remoteJid, - id: id, - fromMe, - participant: attrs.participant - }, - update: { status } - }))) await sendMessageAck(node, { class: 'receipt', type: attrs.type }) } From 5e94a2b6e3a6011a437b455e1a5a416eb13c0363 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 26 Nov 2021 13:08:50 +0530 Subject: [PATCH 189/311] fix: pin modification --- src/Utils/chat-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 342be90..febe0cf 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -488,7 +488,7 @@ export const chatModificationToAppPatch = ( pinned: !!mod.pin } }, - index: ['pin_v1', '919646328797@s.whatsapp.net'], + index: ['pin_v1', jid], type: 'regular_low', apiVersion: 5, operation: OP.SET From 0d27fc467b2bf32ef9da0d06052e3c6d1c6f7972 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 29 Nov 2021 23:57:07 +0530 Subject: [PATCH 190/311] feat: add sanity check for chat modifications --- src/Utils/chat-utils.ts | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index febe0cf..908f96b 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -420,9 +420,19 @@ export const chatModificationToAppPatch = ( lastMessages: Pick[] ) => { const OP = proto.SyncdMutation.SyncdMutationSyncdOperation - const messageRange: proto.ISyncActionMessageRange = { - lastMessageTimestamp: lastMessages[lastMessages.length-1]?.messageTimestamp, - messages: lastMessages + const getMessageRange = () => { + if(!lastMessages?.length) { + throw new Boom('Expected last message to be not from me', { statusCode: 400 }) + } + const lastMsg = lastMessages[lastMessages.length-1] + if(lastMsg.key.fromMe) { + throw new Boom('Expected last message in array to be not from me', { statusCode: 400 }) + } + const messageRange: proto.ISyncActionMessageRange = { + lastMessageTimestamp: lastMsg?.messageTimestamp, + messages: lastMessages + } + return messageRange } let patch: WAPatchCreate if('mute' in mod) { @@ -443,7 +453,7 @@ export const chatModificationToAppPatch = ( syncAction: { archiveChatAction: { archived: !!mod.archive, - messageRange + messageRange: getMessageRange() } }, index: ['archive', jid], @@ -456,7 +466,7 @@ export const chatModificationToAppPatch = ( syncAction: { markChatAsReadAction: { read: mod.markRead, - messageRange + messageRange: getMessageRange() } }, index: ['markChatAsRead', jid], From a8decb9c1160ca73970986a0636aaf345e4bd67d Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 29 Nov 2021 23:57:30 +0530 Subject: [PATCH 191/311] docs: add some comments for "chatModify" + logging for app patch --- src/Socket/chats.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 295cfcc..90e413e 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -412,6 +412,8 @@ export const makeChatsSocket = (config: SocketConfig) => { const name = patchCreate.type await mutationMutex.mutex( async() => { + logger.debug({ patch: patchCreate }, 'applying app patch') + await resyncAppState([name]) const initial = await authState.keys.getAppStateSyncVersion(name) const { patch, state } = await encodeSyncdPatch( @@ -463,7 +465,11 @@ export const makeChatsSocket = (config: SocketConfig) => { } ) } - + /** + * modify a chat -- mark unread, read etc. + * lastMessages must be sorted in reverse chronologically + * requires the last messages till the last message received; required for archive & unread + */ const chatModify = (mod: ChatModification, jid: string, lastMessages: Pick[]) => { const patch = chatModificationToAppPatch(mod, jid, lastMessages) return appPatch(patch) From cd9c313e47954185f0b92b2cc6414a4801ad8a25 Mon Sep 17 00:00:00 2001 From: Rajeh Taher Date: Tue, 30 Nov 2021 07:10:54 +0200 Subject: [PATCH 192/311] [MD] Added template support and footers for buttons & templates (#942) * Added template support and footers for buttons & templates * Template message readme --- README.md | 31 +++++++++++++++++++++++++++++++ src/Types/Message.ts | 14 ++++++++++---- src/Utils/messages.ts | 29 +++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index aa39163..47dba5a 100644 --- a/README.md +++ b/README.md @@ -265,6 +265,21 @@ const buttonMessage = { } const sendMsg = await sock.sendMessage(id, buttonMessage) + +//send a template message! +const templateButtons = [ + {index: 1, urlButton: {displayText: '⭐ Star Baileys on GitHub!', url: 'https://github.com/adiwajshing/Baileys'}}, + {index: 2, callButton: {displayText: 'Call me!', phoneNumber: '+1 (234) 5678-901'}}, + {index: 3, quickReplyButton: {displayText: 'This is a reply, just like normal buttons!', id: 'id-like-buttons-message'}}, +] + +const buttonMessage = { + text: "Hi it's a template message", + footer: 'Hello World', + templateButtons: templateButttons +} + +const sendMsg = await sock.sendMessage(id, templateMessage) ``` ### Media Messages @@ -325,6 +340,22 @@ const buttonMessage = { } const sendMsg = await sock.sendMessage(id, buttonMessage) + +//send a template message with an image **attached**! +const templateButtons = [ + {index: 1, urlButton: {displayText: '⭐ Star Baileys on GitHub!', url: 'https://github.com/adiwajshing/Baileys'}}, + {index: 2, callButton: {displayText: 'Call me!', phoneNumber: '+1 (234) 5678-901'}}, + {index: 3, quickReplyButton: {displayText: 'This is a reply, just like normal buttons!', id: 'id-like-buttons-message'}}, +] + +const buttonMessage = { + text: "Hi it's a template message", + footer: 'Hello World', + templateButtons: templateButttons, + image: {url: 'https://example.com/image.jpeg'} +} + +const sendMsg = await sock.sendMessage(id, templateMessage) ``` ### Notes diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 5445cdb..ac4ccb5 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -50,6 +50,12 @@ type Buttonable = { /** add buttons to the message */ buttons?: proto.IButton[] } +type Templatable = { + /** add buttons to the message (conflicts with normal buttons)*/ + templateButtons?: proto.IHydratedTemplateButton[] + + footer?: string +} type WithDimensions = { width?: number height?: number @@ -60,13 +66,13 @@ export type AnyMediaMessageContent = ( image: WAMediaUpload caption?: string jpegThumbnail?: string - } & Mentionable & Buttonable & WithDimensions) | + } & Mentionable & Buttonable & Templatable & WithDimensions) | ({ video: WAMediaUpload caption?: string gifPlayback?: boolean jpegThumbnail?: string - } & Mentionable & Buttonable & WithDimensions) | { + } & Mentionable & Buttonable & Templatable & WithDimensions) | { audio: WAMediaUpload /** if set to true, will send as a `voice note` */ pttAudio?: boolean @@ -78,14 +84,14 @@ export type AnyMediaMessageContent = ( document: WAMediaUpload mimetype: string fileName?: string - } & Buttonable)) & + } & Buttonable & Templatable)) & { mimetype?: string } export type AnyRegularMessageContent = ( ({ text: string } - & Mentionable & Buttonable) | + & Mentionable & Buttonable & Templatable) | AnyMediaMessageContent | { contacts: { diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 6900c2a..dcd26b2 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -262,8 +262,37 @@ export const generateWAMessageContent = async( Object.assign(buttonsMessage, m) } + + if ('footer' in message && !!message.footer) { + buttonsMessage.footerText = message.footer + } + m = { buttonsMessage } + } else if ('templateButtons' in message && !!message.templateButtons) { + const templateMessage: proto.ITemplateMessage = { + hydratedTemplate: { + hydratedButtons: message.templateButtons + } + } + + if ('text' in message) { + templateMessage.hydratedTemplate.hydratedContentText = message.text + } else { + + if('caption' in message) { + templateMessage.hydratedTemplate.hydratedContentText = message.caption + } + + Object.assign(templateMessage.hydratedTemplate, m) + } + + if ('footer' in message && !!message.footer) { + templateMessage.hydratedTemplate.hydratedFooterText = message.footer + } + + m = { templateMessage } } + if('viewOnce' in message && !!message.viewOnce) { m = { viewOnceMessage: { message: m } } } From b5ac28d4263c665f2d373c67daf9376912844306 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 2 Dec 2021 11:38:24 +0530 Subject: [PATCH 193/311] feat: implement partial media downloads --- jest.config.js | 11 +++++ src/Tests/test.media-download.ts | 64 ++++++++++++++++++++++++ src/Types/Message.ts | 2 + src/Utils/messages-media.ts | 84 ++++++++++++++++++++++++++++---- 4 files changed, 152 insertions(+), 9 deletions(-) create mode 100644 jest.config.js create mode 100644 src/Tests/test.media-download.ts diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..af9e3d4 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,11 @@ +module.exports = { + "roots": [ + "/src" + ], + "testMatch": [ + "**/Tests/test.*.+(ts|tsx|js)", + ], + "transform": { + "^.+\\.(ts|tsx)$": "ts-jest" + }, +} \ No newline at end of file diff --git a/src/Tests/test.media-download.ts b/src/Tests/test.media-download.ts new file mode 100644 index 0000000..a0185a6 --- /dev/null +++ b/src/Tests/test.media-download.ts @@ -0,0 +1,64 @@ +import { MediaType, DownloadableMessage } from '../Types' +import { downloadContentFromMessage } from '../Utils' +import { proto } from '../../WAProto' +import { readFileSync } from 'fs' + +type TestVector = { + type: MediaType + message: DownloadableMessage + plaintext: Buffer +} + +const TEST_VECTORS: TestVector[] = [ + { + type: 'image', + message: proto.ImageMessage.decode( + Buffer.from( + 'Ck1odHRwczovL21tZy53aGF0c2FwcC5uZXQvZC9mL0FwaHR4WG9fWXZZcDZlUVNSa0tjOHE5d2ozVUpleWdoY3poM3ExX3I0ektnLmVuYxIKaW1hZ2UvanBlZyIgKTuVFyxDc6mTm4GXPlO3Z911Wd8RBeTrPLSWAEdqW8MomcUBQiB7wH5a4nXMKyLOT0A2nFgnnM/DUH8YjQf8QtkCIekaSkogTB+BXKCWDFrmNzozY0DCPn0L4VKd7yG1ZbZwbgRhzVc=', + 'base64' + ) + ), + plaintext: readFileSync('./Media/cat.jpeg') + } +] + +describe('Media Download Tests', () => { + + it('should download a full encrypted media correctly', async() => { + for(const { type, message, plaintext } of TEST_VECTORS) { + const readPipe = await downloadContentFromMessage(message, type) + + let buffer = Buffer.alloc(0) + for await(const read of readPipe) { + buffer = Buffer.concat([ buffer, read ]) + } + + expect(buffer).toEqual(plaintext) + } + }) + + it('should download an encrypted media correctly piece', async() => { + for(const { type, message, plaintext } of TEST_VECTORS) { + // check all edge cases + const ranges = [ + { startByte: 51, endByte: plaintext.length-100 }, // random numbers + { startByte: 1024, endByte: 2038 }, // larger random multiples of 16 + { startByte: 1, endByte: plaintext.length-1 } // borders + ] + for(const range of ranges) { + const readPipe = await downloadContentFromMessage(message, type, range) + + let buffer = Buffer.alloc(0) + for await(const read of readPipe) { + buffer = Buffer.concat([ buffer, read ]) + } + + const hex = buffer.toString('hex') + const expectedHex = plaintext.slice(range.startByte || 0, range.endByte || undefined).toString('hex') + expect(hex).toBe(expectedHex) + + console.log('success on ', range) + } + } + }) +}) \ No newline at end of file diff --git a/src/Types/Message.ts b/src/Types/Message.ts index ac4ccb5..fa3bc14 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -23,6 +23,8 @@ export type WAMediaUpload = Buffer | { url: URL | string } | { stream: Readable /** Set of message types that are supported by the library */ export type MessageType = keyof proto.Message +export type DownloadableMessage = { mediaKey?: Uint8Array, directPath?: string, url?: string } + export type MediaConnInfo = { auth: string ttl: number diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index a32342a..78b9df2 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -10,7 +10,7 @@ import { URL } from 'url' import { join } from 'path' import { once } from 'events' import got, { Options, Response } from 'got' -import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType } from '../Types' +import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType, DownloadableMessage } from '../Types' import { generateMessageID } from './generics' import { hkdf } from './crypto' import { DEFAULT_ORIGIN } from '../Defaults' @@ -223,30 +223,96 @@ export const encryptedStream = async(media: WAMediaUpload, mediaType: MediaType, didSaveToTmpPath } } + const DEF_HOST = 'mmg.whatsapp.net' +const AES_CHUNK_SIZE = 16 + +const toSmallestChunkSize = (num: number) => { + return Math.floor(num / AES_CHUNK_SIZE) * AES_CHUNK_SIZE +} + +type MediaDownloadOptions = { + startByte?: number + endByte?: number +} + export const downloadContentFromMessage = async( - { mediaKey, directPath, url }: { mediaKey?: Uint8Array, directPath?: string, url?: string }, - type: MediaType + { mediaKey, directPath, url }: DownloadableMessage, + type: MediaType, + { startByte, endByte }: MediaDownloadOptions = { } ) => { const downloadUrl = url || `https://${DEF_HOST}${directPath}` + let bytesFetched = 0 + let startChunk = 0 + let firstBlockIsIV = false + // if a start byte is specified -- then we need to fetch the previous chunk as that will form the IV + if(startByte) { + const chunk = toSmallestChunkSize(startByte || 0) + if(chunk) { + startChunk = chunk-AES_CHUNK_SIZE + bytesFetched = chunk + + firstBlockIsIV = true + } + } + const endChunk = endByte ? toSmallestChunkSize(endByte || 0)+AES_CHUNK_SIZE : undefined + let rangeHeader: string | undefined = undefined + if(startChunk || endChunk) { + rangeHeader = `bytes=${startChunk}-` + if(endChunk) rangeHeader += endChunk + } // download the message const fetched = await getGotStream(downloadUrl, { - headers: { Origin: DEFAULT_ORIGIN } + headers: { + Origin: DEFAULT_ORIGIN, + Range: rangeHeader + } }) + let remainingBytes = Buffer.from([]) const { cipherKey, iv } = getMediaKeys(mediaKey, type) - const aes = Crypto.createDecipheriv("aes-256-cbc", cipherKey, iv) + + let aes: Crypto.Decipher + + const pushBytes = (bytes: Buffer, push: (bytes: Buffer) => void) => { + if(startByte || endByte) { + const start = bytesFetched >= startByte ? undefined : Math.max(startByte-bytesFetched, 0) + const end = bytesFetched+bytes.length < endByte ? undefined : Math.max(endByte-bytesFetched, 0) + + push(bytes.slice(start, end)) + + bytesFetched += bytes.length + } else { + push(bytes) + } + } const output = new Transform({ transform(chunk, _, callback) { let data = Buffer.concat([remainingBytes, chunk]) - const decryptLength = - Math.floor(data.length / 16) * 16 + + const decryptLength = toSmallestChunkSize(data.length) remainingBytes = data.slice(decryptLength) data = data.slice(0, decryptLength) + if(!aes) { + let ivValue = iv + if(firstBlockIsIV) { + ivValue = data.slice(0, AES_CHUNK_SIZE) + data = data.slice(AES_CHUNK_SIZE) + } + + aes = Crypto.createDecipheriv("aes-256-cbc", cipherKey, ivValue) + // if an end byte that is not EOF is specified + // stop auto padding (PKCS7) -- otherwise throws an error for decryption + if(endByte) { + aes.setAutoPadding(false) + } + + } + try { - this.push(aes.update(data)) + pushBytes(aes.update(data), b => this.push(b)) callback() } catch(error) { callback(error) @@ -254,7 +320,7 @@ export const downloadContentFromMessage = async( }, final(callback) { try { - this.push(aes.final()) + pushBytes(aes.final(), b => this.push(b)) callback() } catch(error) { callback(error) From 9f8223d46bc1b8deb1e1e0cc7fdc7eb334a1060d Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 2 Dec 2021 12:13:45 +0530 Subject: [PATCH 194/311] fix: 10x better compression for image thumbs --- src/Utils/messages-media.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 78b9df2..e20b847 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -55,9 +55,12 @@ export const compressImage = async (bufferOrFilePath: Readable | Buffer | string if(bufferOrFilePath instanceof Readable) { bufferOrFilePath = await toBuffer(bufferOrFilePath) } - const { read, MIME_JPEG } = await import('jimp') + const { read, MIME_JPEG, RESIZE_BILINEAR } = await import('jimp') const jimp = await read(bufferOrFilePath as any) - const result = await jimp.resize(32, 32).getBufferAsync(MIME_JPEG) + const result = await jimp + .quality(50) + .resize(32, 32, RESIZE_BILINEAR) + .getBufferAsync(MIME_JPEG) return result } export const generateProfilePicture = async (mediaUpload: WAMediaUpload) => { @@ -70,12 +73,15 @@ export const generateProfilePicture = async (mediaUpload: WAMediaUpload) => { bufferOrFilePath = await toBuffer(mediaUpload.stream) } - const { read, MIME_JPEG } = await import('jimp') + const { read, MIME_JPEG, RESIZE_BILINEAR } = await import('jimp') const jimp = await read(bufferOrFilePath as any) const min = Math.min(jimp.getWidth (), jimp.getHeight ()) const cropped = jimp.crop (0, 0, min, min) return { - img: await cropped.resize(640, 640).getBufferAsync(MIME_JPEG), + img: await cropped + .quality(50) + .resize(640, 640, RESIZE_BILINEAR) + .getBufferAsync(MIME_JPEG), } } /** gets the SHA256 of the given media message */ From 7d89b9bb954a76162a265b457798d065088a3fdf Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 3 Dec 2021 15:17:11 +0530 Subject: [PATCH 195/311] chore: update WA version --- src/Defaults/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index ab76ade..1f53db2 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -18,7 +18,7 @@ export const NOISE_WA_HEADER = new Uint8Array([87, 65, 5, 2]) // last is "DICT_V export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { - version: [2, 2144, 11], + version: [2, 2146, 9], browser: Browsers.baileys('Chrome'), waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', From d9cfed64ff668426e8419a3dc565c51747422a79 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 3 Dec 2021 15:20:17 +0530 Subject: [PATCH 196/311] fix: bad request on sending messages in some cases Issue source found out by @jackcokk --- src/Socket/messages-send.ts | 4 +--- src/Utils/signal.ts | 10 ++++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index ff881f6..eb45b51 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -178,9 +178,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { ], } const result = await query(iq) - const { device } = jidDecode(authState.creds.me!.id) - - const extracted = extractDeviceJids(result, device, ignoreZeroDevices) + const extracted = extractDeviceJids(result, authState.creds.me!.id, ignoreZeroDevices) const deviceMap: { [_: string]: JidWithDevice[] } = {} for(const item of extracted) { diff --git a/src/Utils/signal.ts b/src/Utils/signal.ts index 7caa4d7..158cbf2 100644 --- a/src/Utils/signal.ts +++ b/src/Utils/signal.ts @@ -231,7 +231,8 @@ export const parseAndInjectE2ESession = async(node: BinaryNode, auth: SignalAuth await cipher.initOutgoing(device) } -export const extractDeviceJids = (result: BinaryNode, myDeviceId: number, excludeZeroDevices: boolean) => { +export const extractDeviceJids = (result: BinaryNode, myJid: string, excludeZeroDevices: boolean) => { + const { user: myUser, device: myDevice } = jidDecode(myJid) const extracted: JidWithDevice[] = [] for(const node of result.content as BinaryNode[]) { const list = getBinaryNodeChild(node, 'list')?.content @@ -243,7 +244,12 @@ export const extractDeviceJids = (result: BinaryNode, myDeviceId: number, exclud if(Array.isArray(deviceListNode?.content)) { for(const { tag, attrs } of deviceListNode!.content) { const device = +attrs.id - if(tag === 'device' && myDeviceId !== device && (!excludeZeroDevices || device !== 0)) { + if( + tag === 'device' && // ensure the "device" tag + (!excludeZeroDevices || device !== 0) && // if zero devices are not-excluded, or device is non zero + (myUser !== user || myDevice !== device) && // either different user or if me user, not this device + (device === 0 || !!attrs['key-index']) // ensure that "key-index" is specified for "non-zero" devices, produces a bad req otherwise + ) { extracted.push({ user, device }) } } From 903871d1809f7e615ee1f97fdea483fa63c2fc2d Mon Sep 17 00:00:00 2001 From: HUGEIT <94182206+HUGEIT@users.noreply.github.com> Date: Fri, 3 Dec 2021 14:10:26 +0100 Subject: [PATCH 197/311] potential fix for QR scan. the server may expect these messages to be sent on reconnect after scan (#959) * potential fix for QR scan. the server may expect these messages to be sent on reconnect after scan. * refactor: extract dictionary reduce code into utility * refactor: convert the props + abt send req to somewhat useful query Co-authored-by: Adhiraj Singh --- src/Socket/chats.ts | 54 ++++++++++++++++++++++++++++++++++++- src/Socket/messages-send.ts | 12 +++------ src/WABinary/index.ts | 11 ++++++++ 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 90e413e..e9dbf26 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1,5 +1,5 @@ import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, LTHashState, ChatModification, Contact } from "../Types"; -import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET } from "../WABinary"; +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET, reduceBinaryNodeToDictionary } from "../WABinary"; import { proto } from '../../WAProto' import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch, decodeSyncdSnapshot, newLTHashState } from "../Utils"; import { makeMessagesSocket } from "./messages-send"; @@ -465,6 +465,56 @@ export const makeChatsSocket = (config: SocketConfig) => { } ) } + /** sending abt props may fix QR scan fail if server expects */ + const fetchAbt = async() => { + const abtNode = await query({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + xmlns: 'abt', + type: 'get', + id: generateMessageTag(), + }, + content: [ + { tag: 'props', attrs: { protocol: '1' } } + ] + }) + + const propsNode = getBinaryNodeChild(abtNode, 'props') + + let props: { [_: string]: string } = { } + if(propsNode) { + props = reduceBinaryNodeToDictionary(propsNode, 'prop') + } + logger.debug('fetched abt') + + return props + } + /** sending non-abt props may fix QR scan fail if server expects */ + const fetchProps = async() => { + const resultNode = await query({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + xmlns: 'w', + type: 'get', + id: generateMessageTag(), + }, + content: [ + { tag: 'props', attrs: { } } + ] + }) + + const propsNode = getBinaryNodeChild(resultNode, 'props') + + let props: { [_: string]: string } = { } + if(propsNode) { + props = reduceBinaryNodeToDictionary(propsNode, 'prop') + } + logger.debug('fetched props') + + return props + } /** * modify a chat -- mark unread, read etc. * lastMessages must be sorted in reverse chronologically @@ -514,6 +564,8 @@ export const makeChatsSocket = (config: SocketConfig) => { sendPresenceUpdate('available') fetchBlocklist() fetchPrivacySettings() + fetchAbt() + fetchProps() } }) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index eb45b51..cd988b7 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -1,9 +1,9 @@ import got from "got" import { Boom } from "@hapi/boom" -import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions, WAMessageKey } from "../Types" +import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions } from "../Types" import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESession } from "../Utils" -import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes, JidWithDevice } from '../WABinary' +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes, JidWithDevice, reduceBinaryNodeToDictionary } from '../WABinary' import { proto } from "../../WAProto" import { WA_DEFAULT_EPHEMERAL, DEFAULT_ORIGIN, MEDIA_PATH_MAP } from "../Defaults" import { makeGroupsSocket } from "./groups" @@ -41,13 +41,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { { tag: 'privacy', attrs: { } } ] }) - const nodes = getBinaryNodeChildren(result, 'category') - privacySettings = nodes.reduce( - (dict, { attrs }) => { - dict[attrs.name] = attrs.value - return dict - }, { } as { [_: string]: string } - ) + privacySettings = reduceBinaryNodeToDictionary(result, 'category') } return privacySettings } diff --git a/src/WABinary/index.ts b/src/WABinary/index.ts index e9d677c..644a870 100644 --- a/src/WABinary/index.ts +++ b/src/WABinary/index.ts @@ -308,5 +308,16 @@ export const assertNodeErrorFree = (node: BinaryNode) => { } } +export const reduceBinaryNodeToDictionary = (node: BinaryNode, tag: string) => { + const nodes = getBinaryNodeChildren(node, tag) + const dict = nodes.reduce( + (dict, { attrs }) => { + dict[attrs.name || attrs.config_code] = attrs.value || attrs.config_value + return dict + }, { } as { [_: string]: string } + ) + return dict +} + export * from './jid-utils' export { Binary } from '../../WABinary/Binary' \ No newline at end of file From 78fd72c8e509198aba73c509a990699de4fb57be Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 4 Dec 2021 13:47:24 +0530 Subject: [PATCH 198/311] feat: implement message retry handling so if a message fails to decrypt on the other user's end -- it can be retried --- README.md | 5 +++ src/Defaults/index.ts | 3 +- src/Socket/messages-recv.ts | 66 ++++++++++++++++++++++++++++--------- src/Socket/messages-send.ts | 42 +++++++++++++---------- src/Types/Message.ts | 2 ++ src/Types/index.ts | 6 ++++ 6 files changed, 91 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 47dba5a..b97efdf 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,11 @@ type SocketConfig = { fetchAgent?: Agent /** should the QR be printed in the terminal */ printQRInTerminal: boolean + /** + * fetch a message from your store + * implement this so that messages failed to send (solves the "this message can take a while" issue) can be retried + * */ + getMessage: (key: proto.IMessageKey) => Promise } ``` diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 1f53db2..9a542e7 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -27,7 +27,8 @@ export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { logger: P().child({ class: 'baileys' }), printQRInTerminal: false, emitOwnEvents: true, - defaultQueryTimeoutMs: 60_000 + defaultQueryTimeoutMs: 60_000, + getMessage: async() => undefined } export const MEDIA_PATH_MAP: { [T in MediaType]: string } = { diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 46921d7..06044e3 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -6,6 +6,7 @@ import { proto } from "../../WAProto" import { KEY_BUNDLE_TYPE } from "../Defaults" import { makeChatsSocket } from "./chats" import { extractGroupMetadata } from "./groups" +import { Boom } from "@hapi/boom" const getStatusFromReceiptType = (type: string | undefined) => { if(type === 'read' || type === 'read-self') { @@ -24,6 +25,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { ev, authState, ws, + assertSession, assertingPreKeys, sendNode, relayMessage, @@ -464,30 +466,64 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } }) + const sendMessagesAgain = async(key: proto.IMessageKey, ids: string[]) => { + const participant = key.participant || key.remoteJid + await assertSession(participant, true) + + logger.debug({ key, ids }, 'recv retry request, forced new session') + + const msgs = await Promise.all( + ids.map(id => ( + config.getMessage({ ...key, id }) + )) + ) + const missingMsgIdx = msgs.findIndex(m => !m) + if(missingMsgIdx >= 0) { + throw new Boom( + `recv request to retry message, but message "${ids[missingMsgIdx]}" not available`, + { statusCode: 404, data: { key } } + ) + } + + for(let i = 0; i < msgs.length;i++) { + await relayMessage(key.remoteJid, msgs[i], { + messageId: ids[i], + participant + }) + } + + } + const handleReceipt = async(node: BinaryNode) => { const { attrs, content } = node - const status = getStatusFromReceiptType(attrs.type) + const remoteJid = attrs.recipient || attrs.from + const fromMe = attrs.recipient ? false : true + const ids = [attrs.id] + if(Array.isArray(content)) { + const items = getBinaryNodeChildren(content[0], 'item') + ids.push(...items.map(i => i.attrs.id)) + } + + const key: proto.IMessageKey = { + remoteJid, + id: '', + fromMe, + participant: attrs.participant + } + + const status = getStatusFromReceiptType(attrs.type) if(typeof status !== 'undefined' && !areJidsSameUser(attrs.from, authState.creds.me?.id)) { - const ids = [attrs.id] - if(Array.isArray(content)) { - const items = getBinaryNodeChildren(content[0], 'item') - ids.push(...items.map(i => i.attrs.id)) - } - - const remoteJid = attrs.recipient || attrs.from - const fromMe = attrs.recipient ? false : true ev.emit('messages.update', ids.map(id => ({ - key: { - remoteJid, - id: id, - fromMe, - participant: attrs.participant - }, + key: { ...key, id }, update: { status } }))) } + if(attrs.type === 'retry') { + await sendMessagesAgain(key, ids) + } + await sendMessageAck(node, { class: 'receipt', type: attrs.type }) } diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index cd988b7..61e7abb 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -238,8 +238,10 @@ export const makeMessagesSocket = (config: SocketConfig) => { const relayMessage = async( jid: string, message: proto.IMessage, - { messageId: msgId, additionalAttributes, cachedGroupMetadata }: MessageRelayOptions + { messageId: msgId, participant, additionalAttributes, cachedGroupMetadata }: MessageRelayOptions ) => { + const meId = authState.creds.me!.id + const { user, server } = jidDecode(jid) const isGroup = server === 'g.us' msgId = msgId || generateMessageID() @@ -250,16 +252,23 @@ export const makeMessagesSocket = (config: SocketConfig) => { const destinationJid = jidEncode(user, isGroup ? 'g.us' : 's.whatsapp.net') + const devices: JidWithDevice[] = [] + if(participant) { + const { user, device } = jidDecode(participant) + devices.push({ user, device }) + } + if(isGroup) { - const { ciphertext, senderKeyDistributionMessageKey } = await encryptSenderKeyMsgSignalProto(destinationJid, encodedMsg, authState.creds.me!.id, authState) + const { ciphertext, senderKeyDistributionMessageKey } = await encryptSenderKeyMsgSignalProto(destinationJid, encodedMsg, meId, authState) let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined if(!groupData) groupData = await groupMetadata(jid) - const participantsList = groupData.participants.map(p => p.id) - const devices = await getUSyncDevices(participantsList, false) - - logger.debug(`got ${devices.length} additional devices`) + if(!participant) { + const participantsList = groupData.participants.map(p => p.id) + const devices = await getUSyncDevices(participantsList, false) + devices.push(...devices) + } const encSenderKeyMsg = encodeWAMessage({ senderKeyDistributionMessage: { @@ -304,7 +313,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { content: binaryNodeContent } } else { - const { user: meUser } = jidDecode(authState.creds.me!.id!) + const { user: meUser } = jidDecode(meId) const messageToMyself: proto.IMessage = { deviceSentMessage: { @@ -314,15 +323,13 @@ export const makeMessagesSocket = (config: SocketConfig) => { } const encodedMeMsg = encodeWAMessage(messageToMyself) - participants.push( - await createParticipantNode(jidEncode(user, 's.whatsapp.net'), encodedMsg) - ) - participants.push( - await createParticipantNode(jidEncode(meUser, 's.whatsapp.net'), encodedMeMsg) - ) - const devices = await getUSyncDevices([ authState.creds.me!.id!, jid ], true) - - logger.debug(`got ${devices.length} additional devices`) + if(!participant) { + devices.push({ user }) + devices.push({ user: meUser }) + + const additionalDevices = await getUSyncDevices([ meId, jid ], true) + devices.push(...additionalDevices) + } for(const { user, device } of devices) { const isMe = user === meUser @@ -363,7 +370,8 @@ export const makeMessagesSocket = (config: SocketConfig) => { content: proto.ADVSignedDeviceIdentity.encode(authState.creds.account).finish() }) } - logger.debug({ msgId }, 'sending message') + + logger.debug({ msgId }, `sending message to ${devices.length} devices`) await sendNode(stanza) diff --git a/src/Types/Message.ts b/src/Types/Message.ts index fa3bc14..903a5b8 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -117,6 +117,8 @@ export type AnyMessageContent = AnyRegularMessageContent | { export type MessageRelayOptions = { messageId?: string + /** only send to a specific participant */ + participant?: string additionalAttributes?: { [_: string]: string } cachedGroupMetadata?: (jid: string) => Promise //cachedDevices?: (jid: string) => Promise diff --git a/src/Types/index.ts b/src/Types/index.ts index d911a2d..113a92d 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -18,6 +18,7 @@ import { ConnectionState } from './State' import { GroupMetadata, ParticipantAction } from './GroupMetadata' import { MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageUpdate, WAMessageKey } from './Message' +import { proto } from '../../WAProto' export type WAVersion = [number, number, number] export type WABrowserDescription = [string, string, string] @@ -54,6 +55,11 @@ export type SocketConfig = { mediaCache?: NodeCache /** map to store the retry counts for failed messages */ msgRetryCounterMap?: { [msgId: string]: number } + /** + * fetch a message from your store + * implement this so that messages failed to send (solves the "this message can take a while" issue) can be retried + * */ + getMessage: (key: proto.IMessageKey) => Promise } export enum DisconnectReason { From e20e479d74db2491f20da346a3e67abe3a55ef6a Mon Sep 17 00:00:00 2001 From: LightningNeko <80431773+LightningNeko@users.noreply.github.com> Date: Sat, 4 Dec 2021 17:17:14 -0300 Subject: [PATCH 199/311] fix waiting for this message (#966) --- src/Socket/messages-send.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 61e7abb..19befed 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -266,8 +266,8 @@ export const makeMessagesSocket = (config: SocketConfig) => { if(!participant) { const participantsList = groupData.participants.map(p => p.id) - const devices = await getUSyncDevices(participantsList, false) - devices.push(...devices) + const additionalDevices = await getUSyncDevices(participantsList, false) + devices.push(...additionalDevices) } const encSenderKeyMsg = encodeWAMessage({ From cccd9305a26003cafaeff197066981ad66730eb8 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 5 Dec 2021 18:05:47 +0530 Subject: [PATCH 200/311] fix: do not throw error on missing message for retry --- src/Socket/messages-recv.ts | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 06044e3..2709783 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -477,21 +477,17 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { config.getMessage({ ...key, id }) )) ) - const missingMsgIdx = msgs.findIndex(m => !m) - if(missingMsgIdx >= 0) { - throw new Boom( - `recv request to retry message, but message "${ids[missingMsgIdx]}" not available`, - { statusCode: 404, data: { key } } - ) - } for(let i = 0; i < msgs.length;i++) { - await relayMessage(key.remoteJid, msgs[i], { - messageId: ids[i], - participant - }) + if(msgs[i]) { + await relayMessage(key.remoteJid, msgs[i], { + messageId: ids[i], + participant + }) + } else { + logger.debug({ jid: key.remoteJid, id: ids[i] }, 'recv retry request, but message not available') + } } - } const handleReceipt = async(node: BinaryNode) => { From 7e414a940bdcfa6407522b8aca778e9fadcc8528 Mon Sep 17 00:00:00 2001 From: LightningNeko <80431773+LightningNeko@users.noreply.github.com> Date: Mon, 6 Dec 2021 00:23:12 -0300 Subject: [PATCH 201/311] fix group announce and restrict always false (#971) * fix group announce and restrict always false * refactor: make group setting change params in line with WA Co-authored-by: Adhiraj Singh --- src/Socket/messages-recv.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 2709783..218b7f8 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -206,12 +206,12 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { emitParticipantsUpdate('add') break case WAMessageStubType.GROUP_CHANGE_ANNOUNCE: - const announce = message.messageStubParameters[0] === 'on' - emitGroupUpdate({ announce }) + const announceValue = message.messageStubParameters[0] + emitGroupUpdate({ announce: announceValue === 'true' || announceValue === 'on' }) break case WAMessageStubType.GROUP_CHANGE_RESTRICT: - const restrict = message.messageStubParameters[0] === 'on' - emitGroupUpdate({ restrict }) + const restrictValue = message.messageStubParameters[0] + emitGroupUpdate({ restrict: restrictValue === 'true' || restrictValue === 'on' }) break case WAMessageStubType.GROUP_CHANGE_SUBJECT: chatUpdate.name = message.messageStubParameters[0] @@ -321,12 +321,12 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { case 'announcement': case 'not_announcement': result.messageStubType = WAMessageStubType.GROUP_CHANGE_ANNOUNCE - result.messageStubParameters = [ (child.tag === 'announcement').toString() ] + result.messageStubParameters = [ (child.tag === 'announcement') ? 'on' : 'off' ] break case 'locked': case 'unlocked': result.messageStubType = WAMessageStubType.GROUP_CHANGE_RESTRICT - result.messageStubParameters = [ (child.tag === 'locked').toString() ] + result.messageStubParameters = [ (child.tag === 'locked') ? 'on' : 'off' ] break } From 1e386480e4a0ed8596cd1106dac4d6463a98f909 Mon Sep 17 00:00:00 2001 From: Vinicius Silva <79378773+viniciusgdr@users.noreply.github.com> Date: Mon, 6 Dec 2021 03:23:38 +0000 Subject: [PATCH 202/311] [MD] Added DeviceType (#946) * [MD] Added DeviceType * Update messages.ts * Update messages.ts * Delete index.d.ts * Add files via upload * Delete messages-recv.ts * Add files via upload * Update messages.ts --- src/Utils/messages.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index dcd26b2..a257321 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -403,4 +403,12 @@ export const extractMessageContent = (content: WAMessageContent | undefined | nu } } return content -} \ No newline at end of file +} + +/** + * Returns the device predicted by message ID + */ +export const getDevice = (id: string) => { + const deviceType = id.length > 21 ? 'android' : id.substring(0, 2) == '3A' ? 'ios' : 'web' + return deviceType +} From 49e7ad4b258026c2368e8a61bc76174e190a4bbd Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 7 Dec 2021 22:09:18 +0530 Subject: [PATCH 203/311] fix: typeerror on some group create --- src/Socket/groups.ts | 4 ++-- src/Socket/messages-recv.ts | 4 +--- src/Types/GroupMetadata.ts | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts index b002534..11a16a1 100644 --- a/src/Socket/groups.ts +++ b/src/Socket/groups.ts @@ -1,6 +1,6 @@ import { generateMessageID } from "../Utils"; import { SocketConfig, GroupMetadata, ParticipantAction } from "../Types"; -import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidEncode } from "../WABinary"; +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidEncode, jidNormalizedUser } from "../WABinary"; import { makeSocket } from "./socket"; export const makeGroupsSocket = (config: SocketConfig) => { @@ -196,7 +196,7 @@ export const extractGroupMetadata = (result: BinaryNode) => { id: groupId, subject: group.attrs.subject, creation: +group.attrs.creation, - owner: group.attrs.creator, + owner: group.attrs.creator ? jidNormalizedUser(group.attrs.creator) : undefined, desc, descId, restrict: !!getBinaryNodeChild(result, 'locked'), diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 218b7f8..3db993a 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -274,9 +274,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { result.messageStubType = WAMessageStubType.GROUP_CREATE result.messageStubParameters = [metadata.subject] - result.key = { - participant: jidNormalizedUser(metadata.owner) - } + result.key = { participant: metadata.owner } ev.emit('chats.upsert', [{ id: metadata.id, diff --git a/src/Types/GroupMetadata.ts b/src/Types/GroupMetadata.ts index baa5b96..276636f 100644 --- a/src/Types/GroupMetadata.ts +++ b/src/Types/GroupMetadata.ts @@ -6,7 +6,7 @@ export type ParticipantAction = 'add' | 'remove' | 'promote' | 'demote' export interface GroupMetadata { id: string - owner: string + owner: string | undefined subject: string creation: number desc?: string From 3cfde73718b326e5fc2f13f6a307211ca2d683b9 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 8 Dec 2021 14:02:14 +0530 Subject: [PATCH 204/311] chore: update proto Thanks to @tulir for the proto extract script --- WAProto/WAProto.proto | 422 +- WAProto/index.d.ts | 5205 +++++++++++---- WAProto/index.js | 13545 ++++++++++++++++++++++++++++++---------- 3 files changed, 14399 insertions(+), 4773 deletions(-) diff --git a/WAProto/WAProto.proto b/WAProto/WAProto.proto index 1bedf04..1d28b5d 100644 --- a/WAProto/WAProto.proto +++ b/WAProto/WAProto.proto @@ -36,7 +36,10 @@ message UserAgent { IGLITE_ANDROID = 22; PAGE = 23; MACOS = 24; - VR = 25; + OCULUS_MSG = 25; + OCULUS_CALL = 26; + MILAN = 27; + CAPI = 28; } optional UserAgentPlatform platform = 1; optional AppVersion appVersion = 2; @@ -113,21 +116,11 @@ message CompanionRegData { message ClientPayload { optional uint64 username = 1; optional bool passive = 3; - enum ClientPayloadClientFeature { - NONE = 0; - } - repeated ClientPayloadClientFeature clientFeatures = 4; optional UserAgent userAgent = 5; optional WebInfo webInfo = 6; optional string pushName = 7; optional sfixed32 sessionId = 9; optional bool shortConnect = 10; - enum ClientPayloadIOSAppExtension { - SHARE_EXTENSION = 0; - SERVICE_EXTENSION = 1; - INTENTS_EXTENSION = 2; - } - optional ClientPayloadIOSAppExtension iosAppExtension = 30; enum ClientPayloadConnectType { CELLULAR_UNKNOWN = 0; WIFI_UNKNOWN = 1; @@ -169,6 +162,15 @@ message ClientPayload { optional bytes fbCat = 21; optional bytes fbUserAgent = 22; optional bool oc = 23; + optional uint32 lc = 24; + enum ClientPayloadIOSAppExtension { + SHARE_EXTENSION = 0; + SERVICE_EXTENSION = 1; + INTENTS_EXTENSION = 2; + } + optional ClientPayloadIOSAppExtension iosAppExtension = 30; + optional uint64 fbAppId = 31; + optional bytes fbDeviceId = 32; } message Details { @@ -226,8 +228,9 @@ message BizIdentityInfo { SELF = 0; BSP = 1; } - optional BizIdentityInfoActualActorsType actualActors = 6; + optional BizIdentityInfoActualActorsType actualActors = 6; optional uint64 privacyModeTs = 7; + optional uint64 featureControls = 8; } message BizAccountLinkInfo { @@ -241,7 +244,6 @@ message BizAccountLinkInfo { optional BizAccountLinkInfoHostStorageType hostStorage = 4; enum BizAccountLinkInfoAccountType { ENTERPRISE = 0; - PAGE = 1; } optional BizAccountLinkInfoAccountType accountType = 5; } @@ -251,14 +253,6 @@ message BizAccountPayload { optional bytes bizAcctLinkInfo = 2; } -//message Details { -// optional uint64 serial = 1; -// optional string issuer = 2; -// optional string verifiedName = 4; -// repeated LocalizedName localizedNames = 8; -// optional uint64 issueTime = 10; -//} - message VerifiedNameCertificate { optional bytes details = 1; optional bytes signature = 2; @@ -345,6 +339,17 @@ message RecentEmojiWeightsAction { repeated RecentEmojiWeight weights = 1; } +message FavoriteStickerAction { + optional string directPath = 1; + optional string lastUploadTimestamp = 2; + optional string handle = 3; + optional string encFilehash = 4; + optional string stickerHashWithoutMeta = 5; + optional string mediaKey = 6; + optional int64 mediaKeyTimestamp = 7; + optional bool isFavorite = 8; +} + message ArchiveChatAction { optional bool archived = 1; optional SyncActionMessageRange messageRange = 2; @@ -387,6 +392,14 @@ message KeyExpiration { optional int32 expiredKeyEpoch = 1; } +message PrimaryFeature { + repeated string flags = 1; +} + +message AndroidUnsupportedActions { + optional bool allowed = 1; +} + message SyncActionValue { optional int64 timestamp = 1; optional StarAction starAction = 2; @@ -409,6 +422,9 @@ message SyncActionValue { optional ClearChatAction clearChatAction = 21; optional DeleteChatAction deleteChatAction = 22; optional UnarchiveChatsSetting unarchiveChatsSetting = 23; + optional PrimaryFeature primaryFeature = 24; + optional FavoriteStickerAction favoriteStickerAction = 25; + optional AndroidUnsupportedActions androidUnsupportedActions = 26; } message RecentEmojiWeight { @@ -507,8 +523,6 @@ message MediaRetryNotification { message MsgOpaqueData { optional string body = 1; optional string caption = 3; - optional string clientUrl = 4; -// optional string loc = 4; optional double lng = 5; optional double lat = 7; optional int32 paymentAmount1000 = 8; @@ -517,6 +531,9 @@ message MsgOpaqueData { optional string matchedText = 11; optional string title = 12; optional string description = 13; + optional bytes futureproofBuffer = 14; + optional string clientUrl = 15; + optional string loc = 16; } message MsgRowOpaqueData { @@ -524,6 +541,27 @@ message MsgRowOpaqueData { optional MsgOpaqueData quotedMsg = 2; } +message GlobalSettings { + optional WallpaperSettings lightThemeWallpaper = 1; + optional MediaVisibility mediaVisibility = 2; + optional WallpaperSettings darkThemeWallpaper = 3; +} + +message WallpaperSettings { + optional string filename = 1; + optional uint32 opacity = 2; +} + +message GroupParticipant { + required string userJid = 1; + enum GroupParticipantRank { + REGULAR = 0; + ADMIN = 1; + SUPERADMIN = 2; + } + optional GroupParticipantRank rank = 2; +} + message Pushname { optional string id = 1; optional string pushname = 2; @@ -554,6 +592,20 @@ message Conversation { optional string name = 13; optional string pHash = 14; optional bool notSpam = 15; + optional bool archived = 16; + optional DisappearingMode disappearingMode = 17; + optional uint32 unreadMentionCount = 18; + optional bool markedAsUnread = 19; + repeated GroupParticipant participant = 20; + optional bytes tcToken = 21; + optional uint64 tcTokenTimestamp = 22; + optional bytes contactPrimaryIdentityKey = 23; + optional uint32 pinned = 24; + optional uint64 muteEndTime = 25; + optional WallpaperSettings wallpaper = 26; + optional MediaVisibility mediaVisibility = 27; + optional uint64 tcTokenSenderTimestamp = 28; + optional bool suspended = 29; } message HistorySync { @@ -570,91 +622,21 @@ message HistorySync { optional uint32 chunkOrder = 5; optional uint32 progress = 6; repeated Pushname pushnames = 7; + optional GlobalSettings globalSettings = 8; + optional bytes threadIdUserSecret = 9; + optional uint32 threadDsTimeframeOffset = 10; } +enum MediaVisibility { + DEFAULT = 0; + OFF = 1; + ON = 2; +} message EphemeralSetting { optional sfixed32 duration = 1; optional sfixed64 timestamp = 2; } -message PaymentBackground { - optional string id = 1; - optional string fileLength = 2; - optional uint32 width = 3; - optional uint32 height = 4; - optional string mimetype = 5; - optional fixed32 placeholderArgb = 6; - optional fixed32 textArgb = 7; - optional fixed32 subtextArgb = 8; -} - -message Money { - optional int64 value = 1; - optional uint32 offset = 2; - optional string currencyCode = 3; -} - -message HydratedQuickReplyButton { - optional string displayText = 1; - optional string id = 2; -} - -message HydratedURLButton { - optional string displayText = 1; - optional string url = 2; -} - -message HydratedCallButton { - optional string displayText = 1; - optional string phoneNumber = 2; -} - -message HydratedTemplateButton { - optional uint32 index = 4; - oneof hydratedButton { - HydratedQuickReplyButton quickReplyButton = 1; - HydratedURLButton urlButton = 2; - HydratedCallButton callButton = 3; - } -} - -message QuickReplyButton { - optional HighlyStructuredMessage displayText = 1; - optional string id = 2; -} - -message URLButton { - optional HighlyStructuredMessage displayText = 1; - optional HighlyStructuredMessage url = 2; -} - -message CallButton { - optional HighlyStructuredMessage displayText = 1; - optional HighlyStructuredMessage phoneNumber = 2; -} - -message TemplateButton { - optional uint32 index = 4; - oneof button { - QuickReplyButton quickReplyButton = 1; - URLButton urlButton = 2; - CallButton callButton = 3; - } -} - -message Location { - optional double degreesLatitude = 1; - optional double degreesLongitude = 2; - optional string name = 3; -} - -message Point { - optional int32 xDeprecated = 1; - optional int32 yDeprecated = 2; - optional double x = 3; - optional double y = 4; -} - message InteractiveAnnotation { repeated Point polygonVertices = 1; oneof action { @@ -725,6 +707,10 @@ message ContextInfo { optional string entryPointConversionSource = 29; optional string entryPointConversionApp = 30; optional uint32 entryPointConversionDelaySeconds = 31; + optional DisappearingMode disappearingMode = 32; + optional ActionLink actionLink = 33; + optional string groupSubject = 34; + optional string parentGroupJid = 35; } message SenderKeyDistributionMessage { @@ -758,6 +744,7 @@ message ImageMessage { optional string thumbnailDirectPath = 26; optional bytes thumbnailSha256 = 27; optional bytes thumbnailEncSha256 = 28; + optional string staticUrl = 29; } message InvoiceMessage { @@ -830,6 +817,11 @@ message ExtendedTextMessage { optional int64 mediaKeyTimestamp = 23; optional uint32 thumbnailHeight = 24; optional uint32 thumbnailWidth = 25; + enum ExtendedTextMessageInviteLinkGroupType { + DEFAULT = 0; + PARENT = 1; + } + optional ExtendedTextMessageInviteLinkGroupType inviteLinkGroupType = 26; } message DocumentMessage { @@ -867,6 +859,7 @@ message AudioMessage { optional int64 mediaKeyTimestamp = 10; optional ContextInfo contextInfo = 17; optional bytes streamingSidecar = 18; + optional bytes waveform = 19; } message VideoMessage { @@ -897,6 +890,7 @@ message VideoMessage { optional string thumbnailDirectPath = 21; optional bytes thumbnailSha256 = 22; optional bytes thumbnailEncSha256 = 23; + optional string staticUrl = 24; } message Call { @@ -932,6 +926,7 @@ message ProtocolMessage { optional AppStateSyncKeyRequest appStateSyncKeyRequest = 8; optional InitialSecurityNotificationSettingSync initialSecurityNotificationSettingSync = 9; optional AppStateFatalExceptionNotification appStateFatalExceptionNotification = 10; + optional DisappearingMode disappearingMode = 11; } message HistorySyncNotification { @@ -1188,6 +1183,8 @@ message ProductMessage { optional ProductSnapshot product = 1; optional string businessOwnerJid = 2; optional CatalogSnapshot catalog = 4; + optional string body = 5; + optional string footer = 6; optional ContextInfo contextInfo = 17; } @@ -1275,6 +1272,67 @@ message ListResponseMessage { optional string description = 5; } +message Header { + optional string title = 1; + optional string subtitle = 2; + optional bool hasMediaAttachment = 5; + oneof media { + DocumentMessage documentMessage = 3; + ImageMessage imageMessage = 4; + bytes jpegThumbnail = 6; + VideoMessage videoMessage = 7; + } +} + +message Body { + optional string text = 1; +} + +message Footer { + optional string text = 1; +} + +message ShopMessage { + optional string id = 1; + enum ShopMessageSurface { + UNKNOWN_SURFACE = 0; + FB = 1; + IG = 2; + WA = 3; + } + optional ShopMessageSurface surface = 2; + optional int32 messageVersion = 3; +} + +message CollectionMessage { + optional string bizJid = 1; + optional string id = 2; + optional int32 messageVersion = 3; +} + +message NativeFlowButton { + optional string name = 1; + optional string buttonParamsJson = 2; +} + +message NativeFlowMessage { + repeated NativeFlowButton buttons = 1; + optional string messageParamsJson = 2; + optional int32 messageVersion = 3; +} + +message InteractiveMessage { + optional Header header = 1; + optional Body body = 2; + optional Footer footer = 3; + optional ContextInfo contextInfo = 15; + oneof interactiveMessage { + ShopMessage shopStorefrontMessage = 4; + CollectionMessage collectionMessage = 5; + NativeFlowMessage nativeFlowMessage = 6; + } +} + message GroupInviteMessage { optional string groupJid = 1; optional string inviteCode = 2; @@ -1283,6 +1341,11 @@ message GroupInviteMessage { optional bytes jpegThumbnail = 5; optional string caption = 6; optional ContextInfo contextInfo = 7; + enum GroupInviteMessageGroupType { + DEFAULT = 0; + PARENT = 1; + } + optional GroupInviteMessageGroupType groupType = 8; } message DeviceSentMessage { @@ -1353,6 +1416,19 @@ message ButtonsResponseMessage { } } +message ReactionMessage { + optional MessageKey key = 1; + optional string text = 2; + optional string groupingKey = 3; + optional int64 senderTimestampMs = 4; +} + +message StickerSyncRMRMessage { + repeated string filehash = 1; + optional string rmrSource = 2; + optional int64 requestTimestamp = 3; +} + message Message { optional string conversation = 1; optional SenderKeyDistributionMessage senderKeyDistributionMessage = 2; @@ -1390,6 +1466,115 @@ message Message { optional ButtonsMessage buttonsMessage = 42; optional ButtonsResponseMessage buttonsResponseMessage = 43; optional PaymentInviteMessage paymentInviteMessage = 44; + optional InteractiveMessage interactiveMessage = 45; + optional ReactionMessage reactionMessage = 46; + optional StickerSyncRMRMessage stickerSyncRmrMessage = 47; +} + +message ActionLink { + optional string url = 1; + optional string buttonTitle = 2; +} + +message DisappearingMode { + enum DisappearingModeInitiator { + CHANGED_IN_CHAT = 0; + INITIATED_BY_ME = 1; + INITIATED_BY_OTHER = 2; + } + optional DisappearingModeInitiator initiator = 1; +} + +message MediaData { + optional bytes mediaKey = 1; + optional int64 mediaKeyTimestamp = 2; + optional bytes fileSha256 = 3; + optional bytes fileEncSha256 = 4; + optional string directPath = 5; +} + +message PaymentBackground { + optional string id = 1; + optional uint64 fileLength = 2; + optional uint32 width = 3; + optional uint32 height = 4; + optional string mimetype = 5; + optional fixed32 placeholderArgb = 6; + optional fixed32 textArgb = 7; + optional fixed32 subtextArgb = 8; + optional MediaData mediaData = 9; + enum PaymentBackgroundType { + UNKNOWN = 0; + DEFAULT = 1; + } + optional PaymentBackgroundType type = 10; +} + +message Money { + optional int64 value = 1; + optional uint32 offset = 2; + optional string currencyCode = 3; +} + +message HydratedQuickReplyButton { + optional string displayText = 1; + optional string id = 2; +} + +message HydratedURLButton { + optional string displayText = 1; + optional string url = 2; +} + +message HydratedCallButton { + optional string displayText = 1; + optional string phoneNumber = 2; +} + +message HydratedTemplateButton { + optional uint32 index = 4; + oneof hydratedButton { + HydratedQuickReplyButton quickReplyButton = 1; + HydratedURLButton urlButton = 2; + HydratedCallButton callButton = 3; + } +} + +message QuickReplyButton { + optional HighlyStructuredMessage displayText = 1; + optional string id = 2; +} + +message URLButton { + optional HighlyStructuredMessage displayText = 1; + optional HighlyStructuredMessage url = 2; +} + +message CallButton { + optional HighlyStructuredMessage displayText = 1; + optional HighlyStructuredMessage phoneNumber = 2; +} + +message TemplateButton { + optional uint32 index = 4; + oneof button { + QuickReplyButton quickReplyButton = 1; + URLButton urlButton = 2; + CallButton callButton = 3; + } +} + +message Location { + optional double degreesLatitude = 1; + optional double degreesLongitude = 2; + optional string name = 3; +} + +message Point { + optional int32 xDeprecated = 1; + optional int32 yDeprecated = 2; + optional double x = 3; + optional double y = 4; } message CompanionProps { @@ -1451,16 +1636,29 @@ message MessageKey { optional string participant = 4; } +message Reaction { + optional MessageKey key = 1; + optional string text = 2; + optional string groupingKey = 3; + optional int64 senderTimestampMs = 4; + optional bool unread = 5; +} + +message UserReceipt { + required string userJid = 1; + optional int64 receiptTimestamp = 2; + optional int64 readTimestamp = 3; + optional int64 playedTimestamp = 4; + repeated string pendingDeviceJid = 5; + repeated string deliveredDeviceJid = 6; +} + message PhotoChange { optional bytes oldPhoto = 1; optional bytes newPhoto = 2; optional uint32 newPhotoId = 3; } -message MediaData { - optional string localPath = 1; -} - message WebFeatures { enum WebFeaturesFlag { NOT_STARTED = 0; @@ -1510,6 +1708,9 @@ message WebFeatures { optional WebFeaturesFlag ephemeralAllowGroupMembers = 44; optional WebFeaturesFlag ephemeral24HDuration = 45; optional WebFeaturesFlag mdForceUpgrade = 46; + optional WebFeaturesFlag disappearingMode = 47; + optional WebFeaturesFlag externalMdOptInAvailable = 48; + optional WebFeaturesFlag noDeleteMessageTimeLimit = 49; } message NotificationMessageInfo { @@ -1745,6 +1946,8 @@ message WebMessageInfo { BIZ_PRIVACY_MODE_INIT_BSP = 127; BIZ_PRIVACY_MODE_TO_FB = 128; BIZ_PRIVACY_MODE_TO_BSP = 129; + DISAPPEARING_MODE = 130; + E2E_DEVICE_FETCH_FAILED = 131; } optional WebMessageInfoStubType messageStubType = 24; optional bool clearMedia = 25; @@ -1768,4 +1971,11 @@ message WebMessageInfo { optional string verifiedBizName = 37; optional MediaData mediaData = 38; optional PhotoChange photoChange = 39; -} \ No newline at end of file + repeated UserReceipt userReceipt = 40; + repeated Reaction reactions = 41; + optional MediaData quotedStickerData = 42; + optional bytes futureproofData = 43; + optional string statusPsaCampaignId = 44; + optional uint32 statusPsaCampaignDuration = 45; + optional uint64 statusPsaCampaignReadTimestamp = 46; +} diff --git a/WAProto/index.d.ts b/WAProto/index.d.ts index 9299a7b..b5e645c 100644 --- a/WAProto/index.d.ts +++ b/WAProto/index.d.ts @@ -307,7 +307,10 @@ export namespace proto { IGLITE_ANDROID = 22, PAGE = 23, MACOS = 24, - VR = 25 + OCULUS_MSG = 25, + OCULUS_CALL = 26, + MILAN = 27, + CAPI = 28 } /** UserAgentReleaseChannel enum. */ @@ -838,9 +841,6 @@ export namespace proto { /** ClientPayload passive */ passive?: (boolean|null); - /** ClientPayload clientFeatures */ - clientFeatures?: (proto.ClientPayload.ClientPayloadClientFeature[]|null); - /** ClientPayload userAgent */ userAgent?: (proto.IUserAgent|null); @@ -856,9 +856,6 @@ export namespace proto { /** ClientPayload shortConnect */ shortConnect?: (boolean|null); - /** ClientPayload iosAppExtension */ - iosAppExtension?: (proto.ClientPayload.ClientPayloadIOSAppExtension|null); - /** ClientPayload connectType */ connectType?: (proto.ClientPayload.ClientPayloadConnectType|null); @@ -894,6 +891,18 @@ export namespace proto { /** ClientPayload oc */ oc?: (boolean|null); + + /** ClientPayload lc */ + lc?: (number|null); + + /** ClientPayload iosAppExtension */ + iosAppExtension?: (proto.ClientPayload.ClientPayloadIOSAppExtension|null); + + /** ClientPayload fbAppId */ + fbAppId?: (number|Long|null); + + /** ClientPayload fbDeviceId */ + fbDeviceId?: (Uint8Array|null); } /** Represents a ClientPayload. */ @@ -911,9 +920,6 @@ export namespace proto { /** ClientPayload passive. */ public passive: boolean; - /** ClientPayload clientFeatures. */ - public clientFeatures: proto.ClientPayload.ClientPayloadClientFeature[]; - /** ClientPayload userAgent. */ public userAgent?: (proto.IUserAgent|null); @@ -929,9 +935,6 @@ export namespace proto { /** ClientPayload shortConnect. */ public shortConnect: boolean; - /** ClientPayload iosAppExtension. */ - public iosAppExtension: proto.ClientPayload.ClientPayloadIOSAppExtension; - /** ClientPayload connectType. */ public connectType: proto.ClientPayload.ClientPayloadConnectType; @@ -968,6 +971,18 @@ export namespace proto { /** ClientPayload oc. */ public oc: boolean; + /** ClientPayload lc. */ + public lc: number; + + /** ClientPayload iosAppExtension. */ + public iosAppExtension: proto.ClientPayload.ClientPayloadIOSAppExtension; + + /** ClientPayload fbAppId. */ + public fbAppId: (number|Long); + + /** ClientPayload fbDeviceId. */ + public fbDeviceId: Uint8Array; + /** * Creates a new ClientPayload instance using the specified properties. * @param [properties] Properties to set @@ -1041,18 +1056,6 @@ export namespace proto { namespace ClientPayload { - /** ClientPayloadClientFeature enum. */ - enum ClientPayloadClientFeature { - NONE = 0 - } - - /** ClientPayloadIOSAppExtension enum. */ - enum ClientPayloadIOSAppExtension { - SHARE_EXTENSION = 0, - SERVICE_EXTENSION = 1, - INTENTS_EXTENSION = 2 - } - /** ClientPayloadConnectType enum. */ enum ClientPayloadConnectType { CELLULAR_UNKNOWN = 0, @@ -1087,6 +1090,13 @@ export namespace proto { WHATSAPP = 0, MESSENGER = 1 } + + /** ClientPayloadIOSAppExtension enum. */ + enum ClientPayloadIOSAppExtension { + SHARE_EXTENSION = 0, + SERVICE_EXTENSION = 1, + INTENTS_EXTENSION = 2 + } } /** Properties of a Details. */ @@ -1724,6 +1734,9 @@ export namespace proto { /** BizIdentityInfo privacyModeTs */ privacyModeTs?: (number|Long|null); + + /** BizIdentityInfo featureControls */ + featureControls?: (number|Long|null); } /** Represents a BizIdentityInfo. */ @@ -1756,6 +1769,9 @@ export namespace proto { /** BizIdentityInfo privacyModeTs. */ public privacyModeTs: (number|Long); + /** BizIdentityInfo featureControls. */ + public featureControls: (number|Long); + /** * Creates a new BizIdentityInfo instance using the specified properties. * @param [properties] Properties to set @@ -1973,8 +1989,7 @@ export namespace proto { /** BizAccountLinkInfoAccountType enum. */ enum BizAccountLinkInfoAccountType { - ENTERPRISE = 0, - PAGE = 1 + ENTERPRISE = 0 } } @@ -3646,6 +3661,138 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + /** Properties of a FavoriteStickerAction. */ + interface IFavoriteStickerAction { + + /** FavoriteStickerAction directPath */ + directPath?: (string|null); + + /** FavoriteStickerAction lastUploadTimestamp */ + lastUploadTimestamp?: (string|null); + + /** FavoriteStickerAction handle */ + handle?: (string|null); + + /** FavoriteStickerAction encFilehash */ + encFilehash?: (string|null); + + /** FavoriteStickerAction stickerHashWithoutMeta */ + stickerHashWithoutMeta?: (string|null); + + /** FavoriteStickerAction mediaKey */ + mediaKey?: (string|null); + + /** FavoriteStickerAction mediaKeyTimestamp */ + mediaKeyTimestamp?: (number|Long|null); + + /** FavoriteStickerAction isFavorite */ + isFavorite?: (boolean|null); + } + + /** Represents a FavoriteStickerAction. */ + class FavoriteStickerAction implements IFavoriteStickerAction { + + /** + * Constructs a new FavoriteStickerAction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IFavoriteStickerAction); + + /** FavoriteStickerAction directPath. */ + public directPath: string; + + /** FavoriteStickerAction lastUploadTimestamp. */ + public lastUploadTimestamp: string; + + /** FavoriteStickerAction handle. */ + public handle: string; + + /** FavoriteStickerAction encFilehash. */ + public encFilehash: string; + + /** FavoriteStickerAction stickerHashWithoutMeta. */ + public stickerHashWithoutMeta: string; + + /** FavoriteStickerAction mediaKey. */ + public mediaKey: string; + + /** FavoriteStickerAction mediaKeyTimestamp. */ + public mediaKeyTimestamp: (number|Long); + + /** FavoriteStickerAction isFavorite. */ + public isFavorite: boolean; + + /** + * Creates a new FavoriteStickerAction instance using the specified properties. + * @param [properties] Properties to set + * @returns FavoriteStickerAction instance + */ + public static create(properties?: proto.IFavoriteStickerAction): proto.FavoriteStickerAction; + + /** + * Encodes the specified FavoriteStickerAction message. Does not implicitly {@link proto.FavoriteStickerAction.verify|verify} messages. + * @param message FavoriteStickerAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IFavoriteStickerAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified FavoriteStickerAction message, length delimited. Does not implicitly {@link proto.FavoriteStickerAction.verify|verify} messages. + * @param message FavoriteStickerAction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IFavoriteStickerAction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a FavoriteStickerAction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns FavoriteStickerAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.FavoriteStickerAction; + + /** + * Decodes a FavoriteStickerAction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns FavoriteStickerAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.FavoriteStickerAction; + + /** + * Verifies a FavoriteStickerAction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a FavoriteStickerAction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns FavoriteStickerAction + */ + public static fromObject(object: { [k: string]: any }): proto.FavoriteStickerAction; + + /** + * Creates a plain object from a FavoriteStickerAction message. Also converts values to other types if specified. + * @param message FavoriteStickerAction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.FavoriteStickerAction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this FavoriteStickerAction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of an ArchiveChatAction. */ interface IArchiveChatAction { @@ -4492,6 +4639,186 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + /** Properties of a PrimaryFeature. */ + interface IPrimaryFeature { + + /** PrimaryFeature flags */ + flags?: (string[]|null); + } + + /** Represents a PrimaryFeature. */ + class PrimaryFeature implements IPrimaryFeature { + + /** + * Constructs a new PrimaryFeature. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPrimaryFeature); + + /** PrimaryFeature flags. */ + public flags: string[]; + + /** + * Creates a new PrimaryFeature instance using the specified properties. + * @param [properties] Properties to set + * @returns PrimaryFeature instance + */ + public static create(properties?: proto.IPrimaryFeature): proto.PrimaryFeature; + + /** + * Encodes the specified PrimaryFeature message. Does not implicitly {@link proto.PrimaryFeature.verify|verify} messages. + * @param message PrimaryFeature message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPrimaryFeature, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified PrimaryFeature message, length delimited. Does not implicitly {@link proto.PrimaryFeature.verify|verify} messages. + * @param message PrimaryFeature message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPrimaryFeature, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a PrimaryFeature message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns PrimaryFeature + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PrimaryFeature; + + /** + * Decodes a PrimaryFeature message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns PrimaryFeature + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PrimaryFeature; + + /** + * Verifies a PrimaryFeature message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a PrimaryFeature message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns PrimaryFeature + */ + public static fromObject(object: { [k: string]: any }): proto.PrimaryFeature; + + /** + * Creates a plain object from a PrimaryFeature message. Also converts values to other types if specified. + * @param message PrimaryFeature + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.PrimaryFeature, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this PrimaryFeature to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an AndroidUnsupportedActions. */ + interface IAndroidUnsupportedActions { + + /** AndroidUnsupportedActions allowed */ + allowed?: (boolean|null); + } + + /** Represents an AndroidUnsupportedActions. */ + class AndroidUnsupportedActions implements IAndroidUnsupportedActions { + + /** + * Constructs a new AndroidUnsupportedActions. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IAndroidUnsupportedActions); + + /** AndroidUnsupportedActions allowed. */ + public allowed: boolean; + + /** + * Creates a new AndroidUnsupportedActions instance using the specified properties. + * @param [properties] Properties to set + * @returns AndroidUnsupportedActions instance + */ + public static create(properties?: proto.IAndroidUnsupportedActions): proto.AndroidUnsupportedActions; + + /** + * Encodes the specified AndroidUnsupportedActions message. Does not implicitly {@link proto.AndroidUnsupportedActions.verify|verify} messages. + * @param message AndroidUnsupportedActions message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IAndroidUnsupportedActions, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified AndroidUnsupportedActions message, length delimited. Does not implicitly {@link proto.AndroidUnsupportedActions.verify|verify} messages. + * @param message AndroidUnsupportedActions message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IAndroidUnsupportedActions, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an AndroidUnsupportedActions message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns AndroidUnsupportedActions + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.AndroidUnsupportedActions; + + /** + * Decodes an AndroidUnsupportedActions message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns AndroidUnsupportedActions + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.AndroidUnsupportedActions; + + /** + * Verifies an AndroidUnsupportedActions message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an AndroidUnsupportedActions message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns AndroidUnsupportedActions + */ + public static fromObject(object: { [k: string]: any }): proto.AndroidUnsupportedActions; + + /** + * Creates a plain object from an AndroidUnsupportedActions message. Also converts values to other types if specified. + * @param message AndroidUnsupportedActions + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.AndroidUnsupportedActions, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this AndroidUnsupportedActions to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of a SyncActionValue. */ interface ISyncActionValue { @@ -4557,6 +4884,15 @@ export namespace proto { /** SyncActionValue unarchiveChatsSetting */ unarchiveChatsSetting?: (proto.IUnarchiveChatsSetting|null); + + /** SyncActionValue primaryFeature */ + primaryFeature?: (proto.IPrimaryFeature|null); + + /** SyncActionValue favoriteStickerAction */ + favoriteStickerAction?: (proto.IFavoriteStickerAction|null); + + /** SyncActionValue androidUnsupportedActions */ + androidUnsupportedActions?: (proto.IAndroidUnsupportedActions|null); } /** Represents a SyncActionValue. */ @@ -4631,6 +4967,15 @@ export namespace proto { /** SyncActionValue unarchiveChatsSetting. */ public unarchiveChatsSetting?: (proto.IUnarchiveChatsSetting|null); + /** SyncActionValue primaryFeature. */ + public primaryFeature?: (proto.IPrimaryFeature|null); + + /** SyncActionValue favoriteStickerAction. */ + public favoriteStickerAction?: (proto.IFavoriteStickerAction|null); + + /** SyncActionValue androidUnsupportedActions. */ + public androidUnsupportedActions?: (proto.IAndroidUnsupportedActions|null); + /** * Creates a new SyncActionValue instance using the specified properties. * @param [properties] Properties to set @@ -6219,9 +6564,6 @@ export namespace proto { /** MsgOpaqueData caption */ caption?: (string|null); - /** MsgOpaqueData clientUrl */ - clientUrl?: (string|null); - /** MsgOpaqueData lng */ lng?: (number|null); @@ -6245,6 +6587,15 @@ export namespace proto { /** MsgOpaqueData description */ description?: (string|null); + + /** MsgOpaqueData futureproofBuffer */ + futureproofBuffer?: (Uint8Array|null); + + /** MsgOpaqueData clientUrl */ + clientUrl?: (string|null); + + /** MsgOpaqueData loc */ + loc?: (string|null); } /** Represents a MsgOpaqueData. */ @@ -6262,9 +6613,6 @@ export namespace proto { /** MsgOpaqueData caption. */ public caption: string; - /** MsgOpaqueData clientUrl. */ - public clientUrl: string; - /** MsgOpaqueData lng. */ public lng: number; @@ -6289,6 +6637,15 @@ export namespace proto { /** MsgOpaqueData description. */ public description: string; + /** MsgOpaqueData futureproofBuffer. */ + public futureproofBuffer: Uint8Array; + + /** MsgOpaqueData clientUrl. */ + public clientUrl: string; + + /** MsgOpaqueData loc. */ + public loc: string; + /** * Creates a new MsgOpaqueData instance using the specified properties. * @param [properties] Properties to set @@ -6456,6 +6813,310 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + /** Properties of a GlobalSettings. */ + interface IGlobalSettings { + + /** GlobalSettings lightThemeWallpaper */ + lightThemeWallpaper?: (proto.IWallpaperSettings|null); + + /** GlobalSettings mediaVisibility */ + mediaVisibility?: (proto.MediaVisibility|null); + + /** GlobalSettings darkThemeWallpaper */ + darkThemeWallpaper?: (proto.IWallpaperSettings|null); + } + + /** Represents a GlobalSettings. */ + class GlobalSettings implements IGlobalSettings { + + /** + * Constructs a new GlobalSettings. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IGlobalSettings); + + /** GlobalSettings lightThemeWallpaper. */ + public lightThemeWallpaper?: (proto.IWallpaperSettings|null); + + /** GlobalSettings mediaVisibility. */ + public mediaVisibility: proto.MediaVisibility; + + /** GlobalSettings darkThemeWallpaper. */ + public darkThemeWallpaper?: (proto.IWallpaperSettings|null); + + /** + * Creates a new GlobalSettings instance using the specified properties. + * @param [properties] Properties to set + * @returns GlobalSettings instance + */ + public static create(properties?: proto.IGlobalSettings): proto.GlobalSettings; + + /** + * Encodes the specified GlobalSettings message. Does not implicitly {@link proto.GlobalSettings.verify|verify} messages. + * @param message GlobalSettings message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IGlobalSettings, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified GlobalSettings message, length delimited. Does not implicitly {@link proto.GlobalSettings.verify|verify} messages. + * @param message GlobalSettings message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IGlobalSettings, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a GlobalSettings message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns GlobalSettings + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.GlobalSettings; + + /** + * Decodes a GlobalSettings message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns GlobalSettings + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.GlobalSettings; + + /** + * Verifies a GlobalSettings message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a GlobalSettings message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns GlobalSettings + */ + public static fromObject(object: { [k: string]: any }): proto.GlobalSettings; + + /** + * Creates a plain object from a GlobalSettings message. Also converts values to other types if specified. + * @param message GlobalSettings + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.GlobalSettings, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this GlobalSettings to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a WallpaperSettings. */ + interface IWallpaperSettings { + + /** WallpaperSettings filename */ + filename?: (string|null); + + /** WallpaperSettings opacity */ + opacity?: (number|null); + } + + /** Represents a WallpaperSettings. */ + class WallpaperSettings implements IWallpaperSettings { + + /** + * Constructs a new WallpaperSettings. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IWallpaperSettings); + + /** WallpaperSettings filename. */ + public filename: string; + + /** WallpaperSettings opacity. */ + public opacity: number; + + /** + * Creates a new WallpaperSettings instance using the specified properties. + * @param [properties] Properties to set + * @returns WallpaperSettings instance + */ + public static create(properties?: proto.IWallpaperSettings): proto.WallpaperSettings; + + /** + * Encodes the specified WallpaperSettings message. Does not implicitly {@link proto.WallpaperSettings.verify|verify} messages. + * @param message WallpaperSettings message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IWallpaperSettings, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified WallpaperSettings message, length delimited. Does not implicitly {@link proto.WallpaperSettings.verify|verify} messages. + * @param message WallpaperSettings message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IWallpaperSettings, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a WallpaperSettings message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns WallpaperSettings + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.WallpaperSettings; + + /** + * Decodes a WallpaperSettings message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns WallpaperSettings + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.WallpaperSettings; + + /** + * Verifies a WallpaperSettings message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a WallpaperSettings message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns WallpaperSettings + */ + public static fromObject(object: { [k: string]: any }): proto.WallpaperSettings; + + /** + * Creates a plain object from a WallpaperSettings message. Also converts values to other types if specified. + * @param message WallpaperSettings + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.WallpaperSettings, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this WallpaperSettings to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a GroupParticipant. */ + interface IGroupParticipant { + + /** GroupParticipant userJid */ + userJid: string; + + /** GroupParticipant rank */ + rank?: (proto.GroupParticipant.GroupParticipantRank|null); + } + + /** Represents a GroupParticipant. */ + class GroupParticipant implements IGroupParticipant { + + /** + * Constructs a new GroupParticipant. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IGroupParticipant); + + /** GroupParticipant userJid. */ + public userJid: string; + + /** GroupParticipant rank. */ + public rank: proto.GroupParticipant.GroupParticipantRank; + + /** + * Creates a new GroupParticipant instance using the specified properties. + * @param [properties] Properties to set + * @returns GroupParticipant instance + */ + public static create(properties?: proto.IGroupParticipant): proto.GroupParticipant; + + /** + * Encodes the specified GroupParticipant message. Does not implicitly {@link proto.GroupParticipant.verify|verify} messages. + * @param message GroupParticipant message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IGroupParticipant, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified GroupParticipant message, length delimited. Does not implicitly {@link proto.GroupParticipant.verify|verify} messages. + * @param message GroupParticipant message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IGroupParticipant, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a GroupParticipant message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns GroupParticipant + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.GroupParticipant; + + /** + * Decodes a GroupParticipant message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns GroupParticipant + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.GroupParticipant; + + /** + * Verifies a GroupParticipant message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a GroupParticipant message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns GroupParticipant + */ + public static fromObject(object: { [k: string]: any }): proto.GroupParticipant; + + /** + * Creates a plain object from a GroupParticipant message. Also converts values to other types if specified. + * @param message GroupParticipant + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.GroupParticipant, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this GroupParticipant to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace GroupParticipant { + + /** GroupParticipantRank enum. */ + enum GroupParticipantRank { + REGULAR = 0, + ADMIN = 1, + SUPERADMIN = 2 + } + } + /** Properties of a Pushname. */ interface IPushname { @@ -6695,6 +7356,48 @@ export namespace proto { /** Conversation notSpam */ notSpam?: (boolean|null); + + /** Conversation archived */ + archived?: (boolean|null); + + /** Conversation disappearingMode */ + disappearingMode?: (proto.IDisappearingMode|null); + + /** Conversation unreadMentionCount */ + unreadMentionCount?: (number|null); + + /** Conversation markedAsUnread */ + markedAsUnread?: (boolean|null); + + /** Conversation participant */ + participant?: (proto.IGroupParticipant[]|null); + + /** Conversation tcToken */ + tcToken?: (Uint8Array|null); + + /** Conversation tcTokenTimestamp */ + tcTokenTimestamp?: (number|Long|null); + + /** Conversation contactPrimaryIdentityKey */ + contactPrimaryIdentityKey?: (Uint8Array|null); + + /** Conversation pinned */ + pinned?: (number|null); + + /** Conversation muteEndTime */ + muteEndTime?: (number|Long|null); + + /** Conversation wallpaper */ + wallpaper?: (proto.IWallpaperSettings|null); + + /** Conversation mediaVisibility */ + mediaVisibility?: (proto.MediaVisibility|null); + + /** Conversation tcTokenSenderTimestamp */ + tcTokenSenderTimestamp?: (number|Long|null); + + /** Conversation suspended */ + suspended?: (boolean|null); } /** Represents a Conversation. */ @@ -6751,6 +7454,48 @@ export namespace proto { /** Conversation notSpam. */ public notSpam: boolean; + /** Conversation archived. */ + public archived: boolean; + + /** Conversation disappearingMode. */ + public disappearingMode?: (proto.IDisappearingMode|null); + + /** Conversation unreadMentionCount. */ + public unreadMentionCount: number; + + /** Conversation markedAsUnread. */ + public markedAsUnread: boolean; + + /** Conversation participant. */ + public participant: proto.IGroupParticipant[]; + + /** Conversation tcToken. */ + public tcToken: Uint8Array; + + /** Conversation tcTokenTimestamp. */ + public tcTokenTimestamp: (number|Long); + + /** Conversation contactPrimaryIdentityKey. */ + public contactPrimaryIdentityKey: Uint8Array; + + /** Conversation pinned. */ + public pinned: number; + + /** Conversation muteEndTime. */ + public muteEndTime: (number|Long); + + /** Conversation wallpaper. */ + public wallpaper?: (proto.IWallpaperSettings|null); + + /** Conversation mediaVisibility. */ + public mediaVisibility: proto.MediaVisibility; + + /** Conversation tcTokenSenderTimestamp. */ + public tcTokenSenderTimestamp: (number|Long); + + /** Conversation suspended. */ + public suspended: boolean; + /** * Creates a new Conversation instance using the specified properties. * @param [properties] Properties to set @@ -6851,6 +7596,15 @@ export namespace proto { /** HistorySync pushnames */ pushnames?: (proto.IPushname[]|null); + + /** HistorySync globalSettings */ + globalSettings?: (proto.IGlobalSettings|null); + + /** HistorySync threadIdUserSecret */ + threadIdUserSecret?: (Uint8Array|null); + + /** HistorySync threadDsTimeframeOffset */ + threadDsTimeframeOffset?: (number|null); } /** Represents a HistorySync. */ @@ -6880,6 +7634,15 @@ export namespace proto { /** HistorySync pushnames. */ public pushnames: proto.IPushname[]; + /** HistorySync globalSettings. */ + public globalSettings?: (proto.IGlobalSettings|null); + + /** HistorySync threadIdUserSecret. */ + public threadIdUserSecret: Uint8Array; + + /** HistorySync threadDsTimeframeOffset. */ + public threadDsTimeframeOffset: number; + /** * Creates a new HistorySync instance using the specified properties. * @param [properties] Properties to set @@ -6963,6 +7726,13 @@ export namespace proto { } } + /** MediaVisibility enum. */ + enum MediaVisibility { + DEFAULT = 0, + OFF = 1, + ON = 2 + } + /** Properties of an EphemeralSetting. */ interface IEphemeralSetting { @@ -7059,1248 +7829,6 @@ export namespace proto { public toJSON(): { [k: string]: any }; } - /** Properties of a PaymentBackground. */ - interface IPaymentBackground { - - /** PaymentBackground id */ - id?: (string|null); - - /** PaymentBackground fileLength */ - fileLength?: (string|null); - - /** PaymentBackground width */ - width?: (number|null); - - /** PaymentBackground height */ - height?: (number|null); - - /** PaymentBackground mimetype */ - mimetype?: (string|null); - - /** PaymentBackground placeholderArgb */ - placeholderArgb?: (number|null); - - /** PaymentBackground textArgb */ - textArgb?: (number|null); - - /** PaymentBackground subtextArgb */ - subtextArgb?: (number|null); - } - - /** Represents a PaymentBackground. */ - class PaymentBackground implements IPaymentBackground { - - /** - * Constructs a new PaymentBackground. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IPaymentBackground); - - /** PaymentBackground id. */ - public id: string; - - /** PaymentBackground fileLength. */ - public fileLength: string; - - /** PaymentBackground width. */ - public width: number; - - /** PaymentBackground height. */ - public height: number; - - /** PaymentBackground mimetype. */ - public mimetype: string; - - /** PaymentBackground placeholderArgb. */ - public placeholderArgb: number; - - /** PaymentBackground textArgb. */ - public textArgb: number; - - /** PaymentBackground subtextArgb. */ - public subtextArgb: number; - - /** - * Creates a new PaymentBackground instance using the specified properties. - * @param [properties] Properties to set - * @returns PaymentBackground instance - */ - public static create(properties?: proto.IPaymentBackground): proto.PaymentBackground; - - /** - * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. - * @param message PaymentBackground message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. - * @param message PaymentBackground message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a PaymentBackground message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns PaymentBackground - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PaymentBackground; - - /** - * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns PaymentBackground - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PaymentBackground; - - /** - * Verifies a PaymentBackground message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns PaymentBackground - */ - public static fromObject(object: { [k: string]: any }): proto.PaymentBackground; - - /** - * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. - * @param message PaymentBackground - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.PaymentBackground, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this PaymentBackground to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a Money. */ - interface IMoney { - - /** Money value */ - value?: (number|Long|null); - - /** Money offset */ - offset?: (number|null); - - /** Money currencyCode */ - currencyCode?: (string|null); - } - - /** Represents a Money. */ - class Money implements IMoney { - - /** - * Constructs a new Money. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IMoney); - - /** Money value. */ - public value: (number|Long); - - /** Money offset. */ - public offset: number; - - /** Money currencyCode. */ - public currencyCode: string; - - /** - * Creates a new Money instance using the specified properties. - * @param [properties] Properties to set - * @returns Money instance - */ - public static create(properties?: proto.IMoney): proto.Money; - - /** - * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. - * @param message Money message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. - * @param message Money message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a Money message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns Money - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Money; - - /** - * Decodes a Money message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns Money - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Money; - - /** - * Verifies a Money message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a Money message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns Money - */ - public static fromObject(object: { [k: string]: any }): proto.Money; - - /** - * Creates a plain object from a Money message. Also converts values to other types if specified. - * @param message Money - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.Money, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this Money to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HydratedQuickReplyButton. */ - interface IHydratedQuickReplyButton { - - /** HydratedQuickReplyButton displayText */ - displayText?: (string|null); - - /** HydratedQuickReplyButton id */ - id?: (string|null); - } - - /** Represents a HydratedQuickReplyButton. */ - class HydratedQuickReplyButton implements IHydratedQuickReplyButton { - - /** - * Constructs a new HydratedQuickReplyButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHydratedQuickReplyButton); - - /** HydratedQuickReplyButton displayText. */ - public displayText: string; - - /** HydratedQuickReplyButton id. */ - public id: string; - - /** - * Creates a new HydratedQuickReplyButton instance using the specified properties. - * @param [properties] Properties to set - * @returns HydratedQuickReplyButton instance - */ - public static create(properties?: proto.IHydratedQuickReplyButton): proto.HydratedQuickReplyButton; - - /** - * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. - * @param message HydratedQuickReplyButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHydratedQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. - * @param message HydratedQuickReplyButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHydratedQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HydratedQuickReplyButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HydratedQuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedQuickReplyButton; - - /** - * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HydratedQuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedQuickReplyButton; - - /** - * Verifies a HydratedQuickReplyButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HydratedQuickReplyButton - */ - public static fromObject(object: { [k: string]: any }): proto.HydratedQuickReplyButton; - - /** - * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified. - * @param message HydratedQuickReplyButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HydratedQuickReplyButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HydratedQuickReplyButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HydratedURLButton. */ - interface IHydratedURLButton { - - /** HydratedURLButton displayText */ - displayText?: (string|null); - - /** HydratedURLButton url */ - url?: (string|null); - } - - /** Represents a HydratedURLButton. */ - class HydratedURLButton implements IHydratedURLButton { - - /** - * Constructs a new HydratedURLButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHydratedURLButton); - - /** HydratedURLButton displayText. */ - public displayText: string; - - /** HydratedURLButton url. */ - public url: string; - - /** - * Creates a new HydratedURLButton instance using the specified properties. - * @param [properties] Properties to set - * @returns HydratedURLButton instance - */ - public static create(properties?: proto.IHydratedURLButton): proto.HydratedURLButton; - - /** - * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. - * @param message HydratedURLButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHydratedURLButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. - * @param message HydratedURLButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHydratedURLButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HydratedURLButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HydratedURLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedURLButton; - - /** - * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HydratedURLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedURLButton; - - /** - * Verifies a HydratedURLButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HydratedURLButton - */ - public static fromObject(object: { [k: string]: any }): proto.HydratedURLButton; - - /** - * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified. - * @param message HydratedURLButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HydratedURLButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HydratedURLButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HydratedCallButton. */ - interface IHydratedCallButton { - - /** HydratedCallButton displayText */ - displayText?: (string|null); - - /** HydratedCallButton phoneNumber */ - phoneNumber?: (string|null); - } - - /** Represents a HydratedCallButton. */ - class HydratedCallButton implements IHydratedCallButton { - - /** - * Constructs a new HydratedCallButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHydratedCallButton); - - /** HydratedCallButton displayText. */ - public displayText: string; - - /** HydratedCallButton phoneNumber. */ - public phoneNumber: string; - - /** - * Creates a new HydratedCallButton instance using the specified properties. - * @param [properties] Properties to set - * @returns HydratedCallButton instance - */ - public static create(properties?: proto.IHydratedCallButton): proto.HydratedCallButton; - - /** - * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. - * @param message HydratedCallButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHydratedCallButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. - * @param message HydratedCallButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHydratedCallButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HydratedCallButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HydratedCallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedCallButton; - - /** - * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HydratedCallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedCallButton; - - /** - * Verifies a HydratedCallButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HydratedCallButton - */ - public static fromObject(object: { [k: string]: any }): proto.HydratedCallButton; - - /** - * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified. - * @param message HydratedCallButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HydratedCallButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HydratedCallButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a HydratedTemplateButton. */ - interface IHydratedTemplateButton { - - /** HydratedTemplateButton index */ - index?: (number|null); - - /** HydratedTemplateButton quickReplyButton */ - quickReplyButton?: (proto.IHydratedQuickReplyButton|null); - - /** HydratedTemplateButton urlButton */ - urlButton?: (proto.IHydratedURLButton|null); - - /** HydratedTemplateButton callButton */ - callButton?: (proto.IHydratedCallButton|null); - } - - /** Represents a HydratedTemplateButton. */ - class HydratedTemplateButton implements IHydratedTemplateButton { - - /** - * Constructs a new HydratedTemplateButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IHydratedTemplateButton); - - /** HydratedTemplateButton index. */ - public index: number; - - /** HydratedTemplateButton quickReplyButton. */ - public quickReplyButton?: (proto.IHydratedQuickReplyButton|null); - - /** HydratedTemplateButton urlButton. */ - public urlButton?: (proto.IHydratedURLButton|null); - - /** HydratedTemplateButton callButton. */ - public callButton?: (proto.IHydratedCallButton|null); - - /** HydratedTemplateButton hydratedButton. */ - public hydratedButton?: ("quickReplyButton"|"urlButton"|"callButton"); - - /** - * Creates a new HydratedTemplateButton instance using the specified properties. - * @param [properties] Properties to set - * @returns HydratedTemplateButton instance - */ - public static create(properties?: proto.IHydratedTemplateButton): proto.HydratedTemplateButton; - - /** - * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. - * @param message HydratedTemplateButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IHydratedTemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. - * @param message HydratedTemplateButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IHydratedTemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a HydratedTemplateButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns HydratedTemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedTemplateButton; - - /** - * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns HydratedTemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedTemplateButton; - - /** - * Verifies a HydratedTemplateButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns HydratedTemplateButton - */ - public static fromObject(object: { [k: string]: any }): proto.HydratedTemplateButton; - - /** - * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified. - * @param message HydratedTemplateButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.HydratedTemplateButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this HydratedTemplateButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a QuickReplyButton. */ - interface IQuickReplyButton { - - /** QuickReplyButton displayText */ - displayText?: (proto.IHighlyStructuredMessage|null); - - /** QuickReplyButton id */ - id?: (string|null); - } - - /** Represents a QuickReplyButton. */ - class QuickReplyButton implements IQuickReplyButton { - - /** - * Constructs a new QuickReplyButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IQuickReplyButton); - - /** QuickReplyButton displayText. */ - public displayText?: (proto.IHighlyStructuredMessage|null); - - /** QuickReplyButton id. */ - public id: string; - - /** - * Creates a new QuickReplyButton instance using the specified properties. - * @param [properties] Properties to set - * @returns QuickReplyButton instance - */ - public static create(properties?: proto.IQuickReplyButton): proto.QuickReplyButton; - - /** - * Encodes the specified QuickReplyButton message. Does not implicitly {@link proto.QuickReplyButton.verify|verify} messages. - * @param message QuickReplyButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified QuickReplyButton message, length delimited. Does not implicitly {@link proto.QuickReplyButton.verify|verify} messages. - * @param message QuickReplyButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a QuickReplyButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns QuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.QuickReplyButton; - - /** - * Decodes a QuickReplyButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns QuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.QuickReplyButton; - - /** - * Verifies a QuickReplyButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a QuickReplyButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns QuickReplyButton - */ - public static fromObject(object: { [k: string]: any }): proto.QuickReplyButton; - - /** - * Creates a plain object from a QuickReplyButton message. Also converts values to other types if specified. - * @param message QuickReplyButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.QuickReplyButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this QuickReplyButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a URLButton. */ - interface IURLButton { - - /** URLButton displayText */ - displayText?: (proto.IHighlyStructuredMessage|null); - - /** URLButton url */ - url?: (proto.IHighlyStructuredMessage|null); - } - - /** Represents a URLButton. */ - class URLButton implements IURLButton { - - /** - * Constructs a new URLButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IURLButton); - - /** URLButton displayText. */ - public displayText?: (proto.IHighlyStructuredMessage|null); - - /** URLButton url. */ - public url?: (proto.IHighlyStructuredMessage|null); - - /** - * Creates a new URLButton instance using the specified properties. - * @param [properties] Properties to set - * @returns URLButton instance - */ - public static create(properties?: proto.IURLButton): proto.URLButton; - - /** - * Encodes the specified URLButton message. Does not implicitly {@link proto.URLButton.verify|verify} messages. - * @param message URLButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IURLButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified URLButton message, length delimited. Does not implicitly {@link proto.URLButton.verify|verify} messages. - * @param message URLButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IURLButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a URLButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns URLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.URLButton; - - /** - * Decodes a URLButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns URLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.URLButton; - - /** - * Verifies a URLButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a URLButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns URLButton - */ - public static fromObject(object: { [k: string]: any }): proto.URLButton; - - /** - * Creates a plain object from a URLButton message. Also converts values to other types if specified. - * @param message URLButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.URLButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this URLButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a CallButton. */ - interface ICallButton { - - /** CallButton displayText */ - displayText?: (proto.IHighlyStructuredMessage|null); - - /** CallButton phoneNumber */ - phoneNumber?: (proto.IHighlyStructuredMessage|null); - } - - /** Represents a CallButton. */ - class CallButton implements ICallButton { - - /** - * Constructs a new CallButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ICallButton); - - /** CallButton displayText. */ - public displayText?: (proto.IHighlyStructuredMessage|null); - - /** CallButton phoneNumber. */ - public phoneNumber?: (proto.IHighlyStructuredMessage|null); - - /** - * Creates a new CallButton instance using the specified properties. - * @param [properties] Properties to set - * @returns CallButton instance - */ - public static create(properties?: proto.ICallButton): proto.CallButton; - - /** - * Encodes the specified CallButton message. Does not implicitly {@link proto.CallButton.verify|verify} messages. - * @param message CallButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ICallButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified CallButton message, length delimited. Does not implicitly {@link proto.CallButton.verify|verify} messages. - * @param message CallButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ICallButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a CallButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns CallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.CallButton; - - /** - * Decodes a CallButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns CallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.CallButton; - - /** - * Verifies a CallButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a CallButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns CallButton - */ - public static fromObject(object: { [k: string]: any }): proto.CallButton; - - /** - * Creates a plain object from a CallButton message. Also converts values to other types if specified. - * @param message CallButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.CallButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this CallButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a TemplateButton. */ - interface ITemplateButton { - - /** TemplateButton index */ - index?: (number|null); - - /** TemplateButton quickReplyButton */ - quickReplyButton?: (proto.IQuickReplyButton|null); - - /** TemplateButton urlButton */ - urlButton?: (proto.IURLButton|null); - - /** TemplateButton callButton */ - callButton?: (proto.ICallButton|null); - } - - /** Represents a TemplateButton. */ - class TemplateButton implements ITemplateButton { - - /** - * Constructs a new TemplateButton. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ITemplateButton); - - /** TemplateButton index. */ - public index: number; - - /** TemplateButton quickReplyButton. */ - public quickReplyButton?: (proto.IQuickReplyButton|null); - - /** TemplateButton urlButton. */ - public urlButton?: (proto.IURLButton|null); - - /** TemplateButton callButton. */ - public callButton?: (proto.ICallButton|null); - - /** TemplateButton button. */ - public button?: ("quickReplyButton"|"urlButton"|"callButton"); - - /** - * Creates a new TemplateButton instance using the specified properties. - * @param [properties] Properties to set - * @returns TemplateButton instance - */ - public static create(properties?: proto.ITemplateButton): proto.TemplateButton; - - /** - * Encodes the specified TemplateButton message. Does not implicitly {@link proto.TemplateButton.verify|verify} messages. - * @param message TemplateButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ITemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified TemplateButton message, length delimited. Does not implicitly {@link proto.TemplateButton.verify|verify} messages. - * @param message TemplateButton message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ITemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a TemplateButton message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns TemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.TemplateButton; - - /** - * Decodes a TemplateButton message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns TemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.TemplateButton; - - /** - * Verifies a TemplateButton message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a TemplateButton message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns TemplateButton - */ - public static fromObject(object: { [k: string]: any }): proto.TemplateButton; - - /** - * Creates a plain object from a TemplateButton message. Also converts values to other types if specified. - * @param message TemplateButton - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.TemplateButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this TemplateButton to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a Location. */ - interface ILocation { - - /** Location degreesLatitude */ - degreesLatitude?: (number|null); - - /** Location degreesLongitude */ - degreesLongitude?: (number|null); - - /** Location name */ - name?: (string|null); - } - - /** Represents a Location. */ - class Location implements ILocation { - - /** - * Constructs a new Location. - * @param [properties] Properties to set - */ - constructor(properties?: proto.ILocation); - - /** Location degreesLatitude. */ - public degreesLatitude: number; - - /** Location degreesLongitude. */ - public degreesLongitude: number; - - /** Location name. */ - public name: string; - - /** - * Creates a new Location instance using the specified properties. - * @param [properties] Properties to set - * @returns Location instance - */ - public static create(properties?: proto.ILocation): proto.Location; - - /** - * Encodes the specified Location message. Does not implicitly {@link proto.Location.verify|verify} messages. - * @param message Location message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.ILocation, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified Location message, length delimited. Does not implicitly {@link proto.Location.verify|verify} messages. - * @param message Location message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.ILocation, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a Location message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns Location - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Location; - - /** - * Decodes a Location message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns Location - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Location; - - /** - * Verifies a Location message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a Location message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns Location - */ - public static fromObject(object: { [k: string]: any }): proto.Location; - - /** - * Creates a plain object from a Location message. Also converts values to other types if specified. - * @param message Location - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.Location, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this Location to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - - /** Properties of a Point. */ - interface IPoint { - - /** Point xDeprecated */ - xDeprecated?: (number|null); - - /** Point yDeprecated */ - yDeprecated?: (number|null); - - /** Point x */ - x?: (number|null); - - /** Point y */ - y?: (number|null); - } - - /** Represents a Point. */ - class Point implements IPoint { - - /** - * Constructs a new Point. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IPoint); - - /** Point xDeprecated. */ - public xDeprecated: number; - - /** Point yDeprecated. */ - public yDeprecated: number; - - /** Point x. */ - public x: number; - - /** Point y. */ - public y: number; - - /** - * Creates a new Point instance using the specified properties. - * @param [properties] Properties to set - * @returns Point instance - */ - public static create(properties?: proto.IPoint): proto.Point; - - /** - * Encodes the specified Point message. Does not implicitly {@link proto.Point.verify|verify} messages. - * @param message Point message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IPoint, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified Point message, length delimited. Does not implicitly {@link proto.Point.verify|verify} messages. - * @param message Point message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IPoint, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a Point message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns Point - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Point; - - /** - * Decodes a Point message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns Point - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Point; - - /** - * Verifies a Point message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a Point message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns Point - */ - public static fromObject(object: { [k: string]: any }): proto.Point; - - /** - * Creates a plain object from a Point message. Also converts values to other types if specified. - * @param message Point - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.Point, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this Point to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - /** Properties of an InteractiveAnnotation. */ interface IInteractiveAnnotation { @@ -8941,6 +8469,18 @@ export namespace proto { /** ContextInfo entryPointConversionDelaySeconds */ entryPointConversionDelaySeconds?: (number|null); + + /** ContextInfo disappearingMode */ + disappearingMode?: (proto.IDisappearingMode|null); + + /** ContextInfo actionLink */ + actionLink?: (proto.IActionLink|null); + + /** ContextInfo groupSubject */ + groupSubject?: (string|null); + + /** ContextInfo parentGroupJid */ + parentGroupJid?: (string|null); } /** Represents a ContextInfo. */ @@ -9009,6 +8549,18 @@ export namespace proto { /** ContextInfo entryPointConversionDelaySeconds. */ public entryPointConversionDelaySeconds: number; + /** ContextInfo disappearingMode. */ + public disappearingMode?: (proto.IDisappearingMode|null); + + /** ContextInfo actionLink. */ + public actionLink?: (proto.IActionLink|null); + + /** ContextInfo groupSubject. */ + public groupSubject: string; + + /** ContextInfo parentGroupJid. */ + public parentGroupJid: string; + /** * Creates a new ContextInfo instance using the specified properties. * @param [properties] Properties to set @@ -9253,6 +8805,9 @@ export namespace proto { /** ImageMessage thumbnailEncSha256 */ thumbnailEncSha256?: (Uint8Array|null); + + /** ImageMessage staticUrl */ + staticUrl?: (string|null); } /** Represents an ImageMessage. */ @@ -9339,6 +8894,9 @@ export namespace proto { /** ImageMessage thumbnailEncSha256. */ public thumbnailEncSha256: Uint8Array; + /** ImageMessage staticUrl. */ + public staticUrl: string; + /** * Creates a new ImageMessage instance using the specified properties. * @param [properties] Properties to set @@ -9880,6 +9438,9 @@ export namespace proto { /** ExtendedTextMessage thumbnailWidth */ thumbnailWidth?: (number|null); + + /** ExtendedTextMessage inviteLinkGroupType */ + inviteLinkGroupType?: (proto.ExtendedTextMessage.ExtendedTextMessageInviteLinkGroupType|null); } /** Represents an ExtendedTextMessage. */ @@ -9948,6 +9509,9 @@ export namespace proto { /** ExtendedTextMessage thumbnailWidth. */ public thumbnailWidth: number; + /** ExtendedTextMessage inviteLinkGroupType. */ + public inviteLinkGroupType: proto.ExtendedTextMessage.ExtendedTextMessageInviteLinkGroupType; + /** * Creates a new ExtendedTextMessage instance using the specified properties. * @param [properties] Properties to set @@ -10036,6 +9600,12 @@ export namespace proto { NONE = 0, VIDEO = 1 } + + /** ExtendedTextMessageInviteLinkGroupType enum. */ + enum ExtendedTextMessageInviteLinkGroupType { + DEFAULT = 0, + PARENT = 1 + } } /** Properties of a DocumentMessage. */ @@ -10274,6 +9844,9 @@ export namespace proto { /** AudioMessage streamingSidecar */ streamingSidecar?: (Uint8Array|null); + + /** AudioMessage waveform */ + waveform?: (Uint8Array|null); } /** Represents an AudioMessage. */ @@ -10321,6 +9894,9 @@ export namespace proto { /** AudioMessage streamingSidecar. */ public streamingSidecar: Uint8Array; + /** AudioMessage waveform. */ + public waveform: Uint8Array; + /** * Creates a new AudioMessage instance using the specified properties. * @param [properties] Properties to set @@ -10460,6 +10036,9 @@ export namespace proto { /** VideoMessage thumbnailEncSha256 */ thumbnailEncSha256?: (Uint8Array|null); + + /** VideoMessage staticUrl */ + staticUrl?: (string|null); } /** Represents a VideoMessage. */ @@ -10537,6 +10116,9 @@ export namespace proto { /** VideoMessage thumbnailEncSha256. */ public thumbnailEncSha256: Uint8Array; + /** VideoMessage staticUrl. */ + public staticUrl: string; + /** * Creates a new VideoMessage instance using the specified properties. * @param [properties] Properties to set @@ -10851,6 +10433,9 @@ export namespace proto { /** ProtocolMessage appStateFatalExceptionNotification */ appStateFatalExceptionNotification?: (proto.IAppStateFatalExceptionNotification|null); + + /** ProtocolMessage disappearingMode */ + disappearingMode?: (proto.IDisappearingMode|null); } /** Represents a ProtocolMessage. */ @@ -10889,6 +10474,9 @@ export namespace proto { /** ProtocolMessage appStateFatalExceptionNotification. */ public appStateFatalExceptionNotification?: (proto.IAppStateFatalExceptionNotification|null); + /** ProtocolMessage disappearingMode. */ + public disappearingMode?: (proto.IDisappearingMode|null); + /** * Creates a new ProtocolMessage instance using the specified properties. * @param [properties] Properties to set @@ -14244,6 +13832,12 @@ export namespace proto { /** ProductMessage catalog */ catalog?: (proto.ICatalogSnapshot|null); + /** ProductMessage body */ + body?: (string|null); + + /** ProductMessage footer */ + footer?: (string|null); + /** ProductMessage contextInfo */ contextInfo?: (proto.IContextInfo|null); } @@ -14266,6 +13860,12 @@ export namespace proto { /** ProductMessage catalog. */ public catalog?: (proto.ICatalogSnapshot|null); + /** ProductMessage body. */ + public body: string; + + /** ProductMessage footer. */ + public footer: string; + /** ProductMessage contextInfo. */ public contextInfo?: (proto.IContextInfo|null); @@ -15446,6 +15046,857 @@ export namespace proto { } } + /** Properties of a Header. */ + interface IHeader { + + /** Header title */ + title?: (string|null); + + /** Header subtitle */ + subtitle?: (string|null); + + /** Header hasMediaAttachment */ + hasMediaAttachment?: (boolean|null); + + /** Header documentMessage */ + documentMessage?: (proto.IDocumentMessage|null); + + /** Header imageMessage */ + imageMessage?: (proto.IImageMessage|null); + + /** Header jpegThumbnail */ + jpegThumbnail?: (Uint8Array|null); + + /** Header videoMessage */ + videoMessage?: (proto.IVideoMessage|null); + } + + /** Represents a Header. */ + class Header implements IHeader { + + /** + * Constructs a new Header. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHeader); + + /** Header title. */ + public title: string; + + /** Header subtitle. */ + public subtitle: string; + + /** Header hasMediaAttachment. */ + public hasMediaAttachment: boolean; + + /** Header documentMessage. */ + public documentMessage?: (proto.IDocumentMessage|null); + + /** Header imageMessage. */ + public imageMessage?: (proto.IImageMessage|null); + + /** Header jpegThumbnail. */ + public jpegThumbnail?: (Uint8Array|null); + + /** Header videoMessage. */ + public videoMessage?: (proto.IVideoMessage|null); + + /** Header media. */ + public media?: ("documentMessage"|"imageMessage"|"jpegThumbnail"|"videoMessage"); + + /** + * Creates a new Header instance using the specified properties. + * @param [properties] Properties to set + * @returns Header instance + */ + public static create(properties?: proto.IHeader): proto.Header; + + /** + * Encodes the specified Header message. Does not implicitly {@link proto.Header.verify|verify} messages. + * @param message Header message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHeader, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Header message, length delimited. Does not implicitly {@link proto.Header.verify|verify} messages. + * @param message Header message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHeader, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Header message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Header + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Header; + + /** + * Decodes a Header message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Header + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Header; + + /** + * Verifies a Header message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Header message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Header + */ + public static fromObject(object: { [k: string]: any }): proto.Header; + + /** + * Creates a plain object from a Header message. Also converts values to other types if specified. + * @param message Header + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Header, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Header to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Body. */ + interface IBody { + + /** Body text */ + text?: (string|null); + } + + /** Represents a Body. */ + class Body implements IBody { + + /** + * Constructs a new Body. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IBody); + + /** Body text. */ + public text: string; + + /** + * Creates a new Body instance using the specified properties. + * @param [properties] Properties to set + * @returns Body instance + */ + public static create(properties?: proto.IBody): proto.Body; + + /** + * Encodes the specified Body message. Does not implicitly {@link proto.Body.verify|verify} messages. + * @param message Body message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IBody, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Body message, length delimited. Does not implicitly {@link proto.Body.verify|verify} messages. + * @param message Body message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IBody, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Body message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Body + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Body; + + /** + * Decodes a Body message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Body + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Body; + + /** + * Verifies a Body message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Body message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Body + */ + public static fromObject(object: { [k: string]: any }): proto.Body; + + /** + * Creates a plain object from a Body message. Also converts values to other types if specified. + * @param message Body + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Body, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Body to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Footer. */ + interface IFooter { + + /** Footer text */ + text?: (string|null); + } + + /** Represents a Footer. */ + class Footer implements IFooter { + + /** + * Constructs a new Footer. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IFooter); + + /** Footer text. */ + public text: string; + + /** + * Creates a new Footer instance using the specified properties. + * @param [properties] Properties to set + * @returns Footer instance + */ + public static create(properties?: proto.IFooter): proto.Footer; + + /** + * Encodes the specified Footer message. Does not implicitly {@link proto.Footer.verify|verify} messages. + * @param message Footer message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IFooter, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Footer message, length delimited. Does not implicitly {@link proto.Footer.verify|verify} messages. + * @param message Footer message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IFooter, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Footer message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Footer + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Footer; + + /** + * Decodes a Footer message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Footer + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Footer; + + /** + * Verifies a Footer message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Footer message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Footer + */ + public static fromObject(object: { [k: string]: any }): proto.Footer; + + /** + * Creates a plain object from a Footer message. Also converts values to other types if specified. + * @param message Footer + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Footer, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Footer to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ShopMessage. */ + interface IShopMessage { + + /** ShopMessage id */ + id?: (string|null); + + /** ShopMessage surface */ + surface?: (proto.ShopMessage.ShopMessageSurface|null); + + /** ShopMessage messageVersion */ + messageVersion?: (number|null); + } + + /** Represents a ShopMessage. */ + class ShopMessage implements IShopMessage { + + /** + * Constructs a new ShopMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IShopMessage); + + /** ShopMessage id. */ + public id: string; + + /** ShopMessage surface. */ + public surface: proto.ShopMessage.ShopMessageSurface; + + /** ShopMessage messageVersion. */ + public messageVersion: number; + + /** + * Creates a new ShopMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns ShopMessage instance + */ + public static create(properties?: proto.IShopMessage): proto.ShopMessage; + + /** + * Encodes the specified ShopMessage message. Does not implicitly {@link proto.ShopMessage.verify|verify} messages. + * @param message ShopMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IShopMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ShopMessage message, length delimited. Does not implicitly {@link proto.ShopMessage.verify|verify} messages. + * @param message ShopMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IShopMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ShopMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ShopMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ShopMessage; + + /** + * Decodes a ShopMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ShopMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ShopMessage; + + /** + * Verifies a ShopMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ShopMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ShopMessage + */ + public static fromObject(object: { [k: string]: any }): proto.ShopMessage; + + /** + * Creates a plain object from a ShopMessage message. Also converts values to other types if specified. + * @param message ShopMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ShopMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ShopMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace ShopMessage { + + /** ShopMessageSurface enum. */ + enum ShopMessageSurface { + UNKNOWN_SURFACE = 0, + FB = 1, + IG = 2, + WA = 3 + } + } + + /** Properties of a CollectionMessage. */ + interface ICollectionMessage { + + /** CollectionMessage bizJid */ + bizJid?: (string|null); + + /** CollectionMessage id */ + id?: (string|null); + + /** CollectionMessage messageVersion */ + messageVersion?: (number|null); + } + + /** Represents a CollectionMessage. */ + class CollectionMessage implements ICollectionMessage { + + /** + * Constructs a new CollectionMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ICollectionMessage); + + /** CollectionMessage bizJid. */ + public bizJid: string; + + /** CollectionMessage id. */ + public id: string; + + /** CollectionMessage messageVersion. */ + public messageVersion: number; + + /** + * Creates a new CollectionMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns CollectionMessage instance + */ + public static create(properties?: proto.ICollectionMessage): proto.CollectionMessage; + + /** + * Encodes the specified CollectionMessage message. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages. + * @param message CollectionMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ICollectionMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified CollectionMessage message, length delimited. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages. + * @param message CollectionMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ICollectionMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a CollectionMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns CollectionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.CollectionMessage; + + /** + * Decodes a CollectionMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns CollectionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.CollectionMessage; + + /** + * Verifies a CollectionMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a CollectionMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns CollectionMessage + */ + public static fromObject(object: { [k: string]: any }): proto.CollectionMessage; + + /** + * Creates a plain object from a CollectionMessage message. Also converts values to other types if specified. + * @param message CollectionMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.CollectionMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this CollectionMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a NativeFlowButton. */ + interface INativeFlowButton { + + /** NativeFlowButton name */ + name?: (string|null); + + /** NativeFlowButton buttonParamsJson */ + buttonParamsJson?: (string|null); + } + + /** Represents a NativeFlowButton. */ + class NativeFlowButton implements INativeFlowButton { + + /** + * Constructs a new NativeFlowButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.INativeFlowButton); + + /** NativeFlowButton name. */ + public name: string; + + /** NativeFlowButton buttonParamsJson. */ + public buttonParamsJson: string; + + /** + * Creates a new NativeFlowButton instance using the specified properties. + * @param [properties] Properties to set + * @returns NativeFlowButton instance + */ + public static create(properties?: proto.INativeFlowButton): proto.NativeFlowButton; + + /** + * Encodes the specified NativeFlowButton message. Does not implicitly {@link proto.NativeFlowButton.verify|verify} messages. + * @param message NativeFlowButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.INativeFlowButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified NativeFlowButton message, length delimited. Does not implicitly {@link proto.NativeFlowButton.verify|verify} messages. + * @param message NativeFlowButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.INativeFlowButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a NativeFlowButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns NativeFlowButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.NativeFlowButton; + + /** + * Decodes a NativeFlowButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns NativeFlowButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.NativeFlowButton; + + /** + * Verifies a NativeFlowButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a NativeFlowButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns NativeFlowButton + */ + public static fromObject(object: { [k: string]: any }): proto.NativeFlowButton; + + /** + * Creates a plain object from a NativeFlowButton message. Also converts values to other types if specified. + * @param message NativeFlowButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.NativeFlowButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this NativeFlowButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a NativeFlowMessage. */ + interface INativeFlowMessage { + + /** NativeFlowMessage buttons */ + buttons?: (proto.INativeFlowButton[]|null); + + /** NativeFlowMessage messageParamsJson */ + messageParamsJson?: (string|null); + + /** NativeFlowMessage messageVersion */ + messageVersion?: (number|null); + } + + /** Represents a NativeFlowMessage. */ + class NativeFlowMessage implements INativeFlowMessage { + + /** + * Constructs a new NativeFlowMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.INativeFlowMessage); + + /** NativeFlowMessage buttons. */ + public buttons: proto.INativeFlowButton[]; + + /** NativeFlowMessage messageParamsJson. */ + public messageParamsJson: string; + + /** NativeFlowMessage messageVersion. */ + public messageVersion: number; + + /** + * Creates a new NativeFlowMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns NativeFlowMessage instance + */ + public static create(properties?: proto.INativeFlowMessage): proto.NativeFlowMessage; + + /** + * Encodes the specified NativeFlowMessage message. Does not implicitly {@link proto.NativeFlowMessage.verify|verify} messages. + * @param message NativeFlowMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.INativeFlowMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified NativeFlowMessage message, length delimited. Does not implicitly {@link proto.NativeFlowMessage.verify|verify} messages. + * @param message NativeFlowMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.INativeFlowMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a NativeFlowMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns NativeFlowMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.NativeFlowMessage; + + /** + * Decodes a NativeFlowMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns NativeFlowMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.NativeFlowMessage; + + /** + * Verifies a NativeFlowMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a NativeFlowMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns NativeFlowMessage + */ + public static fromObject(object: { [k: string]: any }): proto.NativeFlowMessage; + + /** + * Creates a plain object from a NativeFlowMessage message. Also converts values to other types if specified. + * @param message NativeFlowMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.NativeFlowMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this NativeFlowMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an InteractiveMessage. */ + interface IInteractiveMessage { + + /** InteractiveMessage header */ + header?: (proto.IHeader|null); + + /** InteractiveMessage body */ + body?: (proto.IBody|null); + + /** InteractiveMessage footer */ + footer?: (proto.IFooter|null); + + /** InteractiveMessage contextInfo */ + contextInfo?: (proto.IContextInfo|null); + + /** InteractiveMessage shopStorefrontMessage */ + shopStorefrontMessage?: (proto.IShopMessage|null); + + /** InteractiveMessage collectionMessage */ + collectionMessage?: (proto.ICollectionMessage|null); + + /** InteractiveMessage nativeFlowMessage */ + nativeFlowMessage?: (proto.INativeFlowMessage|null); + } + + /** Represents an InteractiveMessage. */ + class InteractiveMessage implements IInteractiveMessage { + + /** + * Constructs a new InteractiveMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IInteractiveMessage); + + /** InteractiveMessage header. */ + public header?: (proto.IHeader|null); + + /** InteractiveMessage body. */ + public body?: (proto.IBody|null); + + /** InteractiveMessage footer. */ + public footer?: (proto.IFooter|null); + + /** InteractiveMessage contextInfo. */ + public contextInfo?: (proto.IContextInfo|null); + + /** InteractiveMessage shopStorefrontMessage. */ + public shopStorefrontMessage?: (proto.IShopMessage|null); + + /** InteractiveMessage collectionMessage. */ + public collectionMessage?: (proto.ICollectionMessage|null); + + /** InteractiveMessage nativeFlowMessage. */ + public nativeFlowMessage?: (proto.INativeFlowMessage|null); + + /** InteractiveMessage interactiveMessage. */ + public interactiveMessage?: ("shopStorefrontMessage"|"collectionMessage"|"nativeFlowMessage"); + + /** + * Creates a new InteractiveMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns InteractiveMessage instance + */ + public static create(properties?: proto.IInteractiveMessage): proto.InteractiveMessage; + + /** + * Encodes the specified InteractiveMessage message. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages. + * @param message InteractiveMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IInteractiveMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified InteractiveMessage message, length delimited. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages. + * @param message InteractiveMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IInteractiveMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an InteractiveMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns InteractiveMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.InteractiveMessage; + + /** + * Decodes an InteractiveMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns InteractiveMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.InteractiveMessage; + + /** + * Verifies an InteractiveMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an InteractiveMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns InteractiveMessage + */ + public static fromObject(object: { [k: string]: any }): proto.InteractiveMessage; + + /** + * Creates a plain object from an InteractiveMessage message. Also converts values to other types if specified. + * @param message InteractiveMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.InteractiveMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this InteractiveMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of a GroupInviteMessage. */ interface IGroupInviteMessage { @@ -15469,6 +15920,9 @@ export namespace proto { /** GroupInviteMessage contextInfo */ contextInfo?: (proto.IContextInfo|null); + + /** GroupInviteMessage groupType */ + groupType?: (proto.GroupInviteMessage.GroupInviteMessageGroupType|null); } /** Represents a GroupInviteMessage. */ @@ -15501,6 +15955,9 @@ export namespace proto { /** GroupInviteMessage contextInfo. */ public contextInfo?: (proto.IContextInfo|null); + /** GroupInviteMessage groupType. */ + public groupType: proto.GroupInviteMessage.GroupInviteMessageGroupType; + /** * Creates a new GroupInviteMessage instance using the specified properties. * @param [properties] Properties to set @@ -15572,6 +16029,15 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + namespace GroupInviteMessage { + + /** GroupInviteMessageGroupType enum. */ + enum GroupInviteMessageGroupType { + DEFAULT = 0, + PARENT = 1 + } + } + /** Properties of a DeviceSentMessage. */ interface IDeviceSentMessage { @@ -16349,6 +16815,216 @@ export namespace proto { } } + /** Properties of a ReactionMessage. */ + interface IReactionMessage { + + /** ReactionMessage key */ + key?: (proto.IMessageKey|null); + + /** ReactionMessage text */ + text?: (string|null); + + /** ReactionMessage groupingKey */ + groupingKey?: (string|null); + + /** ReactionMessage senderTimestampMs */ + senderTimestampMs?: (number|Long|null); + } + + /** Represents a ReactionMessage. */ + class ReactionMessage implements IReactionMessage { + + /** + * Constructs a new ReactionMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IReactionMessage); + + /** ReactionMessage key. */ + public key?: (proto.IMessageKey|null); + + /** ReactionMessage text. */ + public text: string; + + /** ReactionMessage groupingKey. */ + public groupingKey: string; + + /** ReactionMessage senderTimestampMs. */ + public senderTimestampMs: (number|Long); + + /** + * Creates a new ReactionMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns ReactionMessage instance + */ + public static create(properties?: proto.IReactionMessage): proto.ReactionMessage; + + /** + * Encodes the specified ReactionMessage message. Does not implicitly {@link proto.ReactionMessage.verify|verify} messages. + * @param message ReactionMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IReactionMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ReactionMessage message, length delimited. Does not implicitly {@link proto.ReactionMessage.verify|verify} messages. + * @param message ReactionMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IReactionMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ReactionMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ReactionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ReactionMessage; + + /** + * Decodes a ReactionMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ReactionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ReactionMessage; + + /** + * Verifies a ReactionMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a ReactionMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ReactionMessage + */ + public static fromObject(object: { [k: string]: any }): proto.ReactionMessage; + + /** + * Creates a plain object from a ReactionMessage message. Also converts values to other types if specified. + * @param message ReactionMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ReactionMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ReactionMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a StickerSyncRMRMessage. */ + interface IStickerSyncRMRMessage { + + /** StickerSyncRMRMessage filehash */ + filehash?: (string[]|null); + + /** StickerSyncRMRMessage rmrSource */ + rmrSource?: (string|null); + + /** StickerSyncRMRMessage requestTimestamp */ + requestTimestamp?: (number|Long|null); + } + + /** Represents a StickerSyncRMRMessage. */ + class StickerSyncRMRMessage implements IStickerSyncRMRMessage { + + /** + * Constructs a new StickerSyncRMRMessage. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IStickerSyncRMRMessage); + + /** StickerSyncRMRMessage filehash. */ + public filehash: string[]; + + /** StickerSyncRMRMessage rmrSource. */ + public rmrSource: string; + + /** StickerSyncRMRMessage requestTimestamp. */ + public requestTimestamp: (number|Long); + + /** + * Creates a new StickerSyncRMRMessage instance using the specified properties. + * @param [properties] Properties to set + * @returns StickerSyncRMRMessage instance + */ + public static create(properties?: proto.IStickerSyncRMRMessage): proto.StickerSyncRMRMessage; + + /** + * Encodes the specified StickerSyncRMRMessage message. Does not implicitly {@link proto.StickerSyncRMRMessage.verify|verify} messages. + * @param message StickerSyncRMRMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IStickerSyncRMRMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified StickerSyncRMRMessage message, length delimited. Does not implicitly {@link proto.StickerSyncRMRMessage.verify|verify} messages. + * @param message StickerSyncRMRMessage message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IStickerSyncRMRMessage, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a StickerSyncRMRMessage message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns StickerSyncRMRMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.StickerSyncRMRMessage; + + /** + * Decodes a StickerSyncRMRMessage message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns StickerSyncRMRMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.StickerSyncRMRMessage; + + /** + * Verifies a StickerSyncRMRMessage message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a StickerSyncRMRMessage message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns StickerSyncRMRMessage + */ + public static fromObject(object: { [k: string]: any }): proto.StickerSyncRMRMessage; + + /** + * Creates a plain object from a StickerSyncRMRMessage message. Also converts values to other types if specified. + * @param message StickerSyncRMRMessage + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.StickerSyncRMRMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this StickerSyncRMRMessage to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of a Message. */ interface IMessage { @@ -16459,6 +17135,15 @@ export namespace proto { /** Message paymentInviteMessage */ paymentInviteMessage?: (proto.IPaymentInviteMessage|null); + + /** Message interactiveMessage */ + interactiveMessage?: (proto.IInteractiveMessage|null); + + /** Message reactionMessage */ + reactionMessage?: (proto.IReactionMessage|null); + + /** Message stickerSyncRmrMessage */ + stickerSyncRmrMessage?: (proto.IStickerSyncRMRMessage|null); } /** Represents a Message. */ @@ -16578,6 +17263,15 @@ export namespace proto { /** Message paymentInviteMessage. */ public paymentInviteMessage?: (proto.IPaymentInviteMessage|null); + /** Message interactiveMessage. */ + public interactiveMessage?: (proto.IInteractiveMessage|null); + + /** Message reactionMessage. */ + public reactionMessage?: (proto.IReactionMessage|null); + + /** Message stickerSyncRmrMessage. */ + public stickerSyncRmrMessage?: (proto.IStickerSyncRMRMessage|null); + /** * Creates a new Message instance using the specified properties. * @param [properties] Properties to set @@ -16649,6 +17343,1579 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + /** Properties of an ActionLink. */ + interface IActionLink { + + /** ActionLink url */ + url?: (string|null); + + /** ActionLink buttonTitle */ + buttonTitle?: (string|null); + } + + /** Represents an ActionLink. */ + class ActionLink implements IActionLink { + + /** + * Constructs a new ActionLink. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IActionLink); + + /** ActionLink url. */ + public url: string; + + /** ActionLink buttonTitle. */ + public buttonTitle: string; + + /** + * Creates a new ActionLink instance using the specified properties. + * @param [properties] Properties to set + * @returns ActionLink instance + */ + public static create(properties?: proto.IActionLink): proto.ActionLink; + + /** + * Encodes the specified ActionLink message. Does not implicitly {@link proto.ActionLink.verify|verify} messages. + * @param message ActionLink message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IActionLink, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ActionLink message, length delimited. Does not implicitly {@link proto.ActionLink.verify|verify} messages. + * @param message ActionLink message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IActionLink, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an ActionLink message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ActionLink + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.ActionLink; + + /** + * Decodes an ActionLink message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ActionLink + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.ActionLink; + + /** + * Verifies an ActionLink message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an ActionLink message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ActionLink + */ + public static fromObject(object: { [k: string]: any }): proto.ActionLink; + + /** + * Creates a plain object from an ActionLink message. Also converts values to other types if specified. + * @param message ActionLink + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.ActionLink, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ActionLink to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a DisappearingMode. */ + interface IDisappearingMode { + + /** DisappearingMode initiator */ + initiator?: (proto.DisappearingMode.DisappearingModeInitiator|null); + } + + /** Represents a DisappearingMode. */ + class DisappearingMode implements IDisappearingMode { + + /** + * Constructs a new DisappearingMode. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IDisappearingMode); + + /** DisappearingMode initiator. */ + public initiator: proto.DisappearingMode.DisappearingModeInitiator; + + /** + * Creates a new DisappearingMode instance using the specified properties. + * @param [properties] Properties to set + * @returns DisappearingMode instance + */ + public static create(properties?: proto.IDisappearingMode): proto.DisappearingMode; + + /** + * Encodes the specified DisappearingMode message. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages. + * @param message DisappearingMode message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IDisappearingMode, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified DisappearingMode message, length delimited. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages. + * @param message DisappearingMode message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IDisappearingMode, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a DisappearingMode message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns DisappearingMode + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.DisappearingMode; + + /** + * Decodes a DisappearingMode message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns DisappearingMode + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.DisappearingMode; + + /** + * Verifies a DisappearingMode message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a DisappearingMode message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns DisappearingMode + */ + public static fromObject(object: { [k: string]: any }): proto.DisappearingMode; + + /** + * Creates a plain object from a DisappearingMode message. Also converts values to other types if specified. + * @param message DisappearingMode + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.DisappearingMode, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this DisappearingMode to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace DisappearingMode { + + /** DisappearingModeInitiator enum. */ + enum DisappearingModeInitiator { + CHANGED_IN_CHAT = 0, + INITIATED_BY_ME = 1, + INITIATED_BY_OTHER = 2 + } + } + + /** Properties of a MediaData. */ + interface IMediaData { + + /** MediaData mediaKey */ + mediaKey?: (Uint8Array|null); + + /** MediaData mediaKeyTimestamp */ + mediaKeyTimestamp?: (number|Long|null); + + /** MediaData fileSha256 */ + fileSha256?: (Uint8Array|null); + + /** MediaData fileEncSha256 */ + fileEncSha256?: (Uint8Array|null); + + /** MediaData directPath */ + directPath?: (string|null); + } + + /** Represents a MediaData. */ + class MediaData implements IMediaData { + + /** + * Constructs a new MediaData. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMediaData); + + /** MediaData mediaKey. */ + public mediaKey: Uint8Array; + + /** MediaData mediaKeyTimestamp. */ + public mediaKeyTimestamp: (number|Long); + + /** MediaData fileSha256. */ + public fileSha256: Uint8Array; + + /** MediaData fileEncSha256. */ + public fileEncSha256: Uint8Array; + + /** MediaData directPath. */ + public directPath: string; + + /** + * Creates a new MediaData instance using the specified properties. + * @param [properties] Properties to set + * @returns MediaData instance + */ + public static create(properties?: proto.IMediaData): proto.MediaData; + + /** + * Encodes the specified MediaData message. Does not implicitly {@link proto.MediaData.verify|verify} messages. + * @param message MediaData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMediaData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MediaData message, length delimited. Does not implicitly {@link proto.MediaData.verify|verify} messages. + * @param message MediaData message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMediaData, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MediaData message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MediaData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MediaData; + + /** + * Decodes a MediaData message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MediaData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MediaData; + + /** + * Verifies a MediaData message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MediaData message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MediaData + */ + public static fromObject(object: { [k: string]: any }): proto.MediaData; + + /** + * Creates a plain object from a MediaData message. Also converts values to other types if specified. + * @param message MediaData + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.MediaData, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MediaData to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a PaymentBackground. */ + interface IPaymentBackground { + + /** PaymentBackground id */ + id?: (string|null); + + /** PaymentBackground fileLength */ + fileLength?: (number|Long|null); + + /** PaymentBackground width */ + width?: (number|null); + + /** PaymentBackground height */ + height?: (number|null); + + /** PaymentBackground mimetype */ + mimetype?: (string|null); + + /** PaymentBackground placeholderArgb */ + placeholderArgb?: (number|null); + + /** PaymentBackground textArgb */ + textArgb?: (number|null); + + /** PaymentBackground subtextArgb */ + subtextArgb?: (number|null); + + /** PaymentBackground mediaData */ + mediaData?: (proto.IMediaData|null); + + /** PaymentBackground type */ + type?: (proto.PaymentBackground.PaymentBackgroundType|null); + } + + /** Represents a PaymentBackground. */ + class PaymentBackground implements IPaymentBackground { + + /** + * Constructs a new PaymentBackground. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPaymentBackground); + + /** PaymentBackground id. */ + public id: string; + + /** PaymentBackground fileLength. */ + public fileLength: (number|Long); + + /** PaymentBackground width. */ + public width: number; + + /** PaymentBackground height. */ + public height: number; + + /** PaymentBackground mimetype. */ + public mimetype: string; + + /** PaymentBackground placeholderArgb. */ + public placeholderArgb: number; + + /** PaymentBackground textArgb. */ + public textArgb: number; + + /** PaymentBackground subtextArgb. */ + public subtextArgb: number; + + /** PaymentBackground mediaData. */ + public mediaData?: (proto.IMediaData|null); + + /** PaymentBackground type. */ + public type: proto.PaymentBackground.PaymentBackgroundType; + + /** + * Creates a new PaymentBackground instance using the specified properties. + * @param [properties] Properties to set + * @returns PaymentBackground instance + */ + public static create(properties?: proto.IPaymentBackground): proto.PaymentBackground; + + /** + * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @param message PaymentBackground message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @param message PaymentBackground message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPaymentBackground, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a PaymentBackground message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns PaymentBackground + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.PaymentBackground; + + /** + * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns PaymentBackground + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.PaymentBackground; + + /** + * Verifies a PaymentBackground message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns PaymentBackground + */ + public static fromObject(object: { [k: string]: any }): proto.PaymentBackground; + + /** + * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. + * @param message PaymentBackground + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.PaymentBackground, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this PaymentBackground to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + namespace PaymentBackground { + + /** PaymentBackgroundType enum. */ + enum PaymentBackgroundType { + UNKNOWN = 0, + DEFAULT = 1 + } + } + + /** Properties of a Money. */ + interface IMoney { + + /** Money value */ + value?: (number|Long|null); + + /** Money offset */ + offset?: (number|null); + + /** Money currencyCode */ + currencyCode?: (string|null); + } + + /** Represents a Money. */ + class Money implements IMoney { + + /** + * Constructs a new Money. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IMoney); + + /** Money value. */ + public value: (number|Long); + + /** Money offset. */ + public offset: number; + + /** Money currencyCode. */ + public currencyCode: string; + + /** + * Creates a new Money instance using the specified properties. + * @param [properties] Properties to set + * @returns Money instance + */ + public static create(properties?: proto.IMoney): proto.Money; + + /** + * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. + * @param message Money message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. + * @param message Money message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IMoney, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Money message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Money; + + /** + * Decodes a Money message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Money; + + /** + * Verifies a Money message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Money message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Money + */ + public static fromObject(object: { [k: string]: any }): proto.Money; + + /** + * Creates a plain object from a Money message. Also converts values to other types if specified. + * @param message Money + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Money, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Money to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HydratedQuickReplyButton. */ + interface IHydratedQuickReplyButton { + + /** HydratedQuickReplyButton displayText */ + displayText?: (string|null); + + /** HydratedQuickReplyButton id */ + id?: (string|null); + } + + /** Represents a HydratedQuickReplyButton. */ + class HydratedQuickReplyButton implements IHydratedQuickReplyButton { + + /** + * Constructs a new HydratedQuickReplyButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHydratedQuickReplyButton); + + /** HydratedQuickReplyButton displayText. */ + public displayText: string; + + /** HydratedQuickReplyButton id. */ + public id: string; + + /** + * Creates a new HydratedQuickReplyButton instance using the specified properties. + * @param [properties] Properties to set + * @returns HydratedQuickReplyButton instance + */ + public static create(properties?: proto.IHydratedQuickReplyButton): proto.HydratedQuickReplyButton; + + /** + * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * @param message HydratedQuickReplyButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHydratedQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * @param message HydratedQuickReplyButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHydratedQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HydratedQuickReplyButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HydratedQuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedQuickReplyButton; + + /** + * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HydratedQuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedQuickReplyButton; + + /** + * Verifies a HydratedQuickReplyButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HydratedQuickReplyButton + */ + public static fromObject(object: { [k: string]: any }): proto.HydratedQuickReplyButton; + + /** + * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified. + * @param message HydratedQuickReplyButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HydratedQuickReplyButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HydratedQuickReplyButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HydratedURLButton. */ + interface IHydratedURLButton { + + /** HydratedURLButton displayText */ + displayText?: (string|null); + + /** HydratedURLButton url */ + url?: (string|null); + } + + /** Represents a HydratedURLButton. */ + class HydratedURLButton implements IHydratedURLButton { + + /** + * Constructs a new HydratedURLButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHydratedURLButton); + + /** HydratedURLButton displayText. */ + public displayText: string; + + /** HydratedURLButton url. */ + public url: string; + + /** + * Creates a new HydratedURLButton instance using the specified properties. + * @param [properties] Properties to set + * @returns HydratedURLButton instance + */ + public static create(properties?: proto.IHydratedURLButton): proto.HydratedURLButton; + + /** + * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. + * @param message HydratedURLButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHydratedURLButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. + * @param message HydratedURLButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHydratedURLButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HydratedURLButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HydratedURLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedURLButton; + + /** + * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HydratedURLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedURLButton; + + /** + * Verifies a HydratedURLButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HydratedURLButton + */ + public static fromObject(object: { [k: string]: any }): proto.HydratedURLButton; + + /** + * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified. + * @param message HydratedURLButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HydratedURLButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HydratedURLButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HydratedCallButton. */ + interface IHydratedCallButton { + + /** HydratedCallButton displayText */ + displayText?: (string|null); + + /** HydratedCallButton phoneNumber */ + phoneNumber?: (string|null); + } + + /** Represents a HydratedCallButton. */ + class HydratedCallButton implements IHydratedCallButton { + + /** + * Constructs a new HydratedCallButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHydratedCallButton); + + /** HydratedCallButton displayText. */ + public displayText: string; + + /** HydratedCallButton phoneNumber. */ + public phoneNumber: string; + + /** + * Creates a new HydratedCallButton instance using the specified properties. + * @param [properties] Properties to set + * @returns HydratedCallButton instance + */ + public static create(properties?: proto.IHydratedCallButton): proto.HydratedCallButton; + + /** + * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. + * @param message HydratedCallButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHydratedCallButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. + * @param message HydratedCallButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHydratedCallButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HydratedCallButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HydratedCallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedCallButton; + + /** + * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HydratedCallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedCallButton; + + /** + * Verifies a HydratedCallButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HydratedCallButton + */ + public static fromObject(object: { [k: string]: any }): proto.HydratedCallButton; + + /** + * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified. + * @param message HydratedCallButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HydratedCallButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HydratedCallButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a HydratedTemplateButton. */ + interface IHydratedTemplateButton { + + /** HydratedTemplateButton index */ + index?: (number|null); + + /** HydratedTemplateButton quickReplyButton */ + quickReplyButton?: (proto.IHydratedQuickReplyButton|null); + + /** HydratedTemplateButton urlButton */ + urlButton?: (proto.IHydratedURLButton|null); + + /** HydratedTemplateButton callButton */ + callButton?: (proto.IHydratedCallButton|null); + } + + /** Represents a HydratedTemplateButton. */ + class HydratedTemplateButton implements IHydratedTemplateButton { + + /** + * Constructs a new HydratedTemplateButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IHydratedTemplateButton); + + /** HydratedTemplateButton index. */ + public index: number; + + /** HydratedTemplateButton quickReplyButton. */ + public quickReplyButton?: (proto.IHydratedQuickReplyButton|null); + + /** HydratedTemplateButton urlButton. */ + public urlButton?: (proto.IHydratedURLButton|null); + + /** HydratedTemplateButton callButton. */ + public callButton?: (proto.IHydratedCallButton|null); + + /** HydratedTemplateButton hydratedButton. */ + public hydratedButton?: ("quickReplyButton"|"urlButton"|"callButton"); + + /** + * Creates a new HydratedTemplateButton instance using the specified properties. + * @param [properties] Properties to set + * @returns HydratedTemplateButton instance + */ + public static create(properties?: proto.IHydratedTemplateButton): proto.HydratedTemplateButton; + + /** + * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. + * @param message HydratedTemplateButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IHydratedTemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. + * @param message HydratedTemplateButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IHydratedTemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a HydratedTemplateButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns HydratedTemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.HydratedTemplateButton; + + /** + * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns HydratedTemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.HydratedTemplateButton; + + /** + * Verifies a HydratedTemplateButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns HydratedTemplateButton + */ + public static fromObject(object: { [k: string]: any }): proto.HydratedTemplateButton; + + /** + * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified. + * @param message HydratedTemplateButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.HydratedTemplateButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this HydratedTemplateButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a QuickReplyButton. */ + interface IQuickReplyButton { + + /** QuickReplyButton displayText */ + displayText?: (proto.IHighlyStructuredMessage|null); + + /** QuickReplyButton id */ + id?: (string|null); + } + + /** Represents a QuickReplyButton. */ + class QuickReplyButton implements IQuickReplyButton { + + /** + * Constructs a new QuickReplyButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IQuickReplyButton); + + /** QuickReplyButton displayText. */ + public displayText?: (proto.IHighlyStructuredMessage|null); + + /** QuickReplyButton id. */ + public id: string; + + /** + * Creates a new QuickReplyButton instance using the specified properties. + * @param [properties] Properties to set + * @returns QuickReplyButton instance + */ + public static create(properties?: proto.IQuickReplyButton): proto.QuickReplyButton; + + /** + * Encodes the specified QuickReplyButton message. Does not implicitly {@link proto.QuickReplyButton.verify|verify} messages. + * @param message QuickReplyButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified QuickReplyButton message, length delimited. Does not implicitly {@link proto.QuickReplyButton.verify|verify} messages. + * @param message QuickReplyButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IQuickReplyButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a QuickReplyButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns QuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.QuickReplyButton; + + /** + * Decodes a QuickReplyButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns QuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.QuickReplyButton; + + /** + * Verifies a QuickReplyButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a QuickReplyButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns QuickReplyButton + */ + public static fromObject(object: { [k: string]: any }): proto.QuickReplyButton; + + /** + * Creates a plain object from a QuickReplyButton message. Also converts values to other types if specified. + * @param message QuickReplyButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.QuickReplyButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this QuickReplyButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a URLButton. */ + interface IURLButton { + + /** URLButton displayText */ + displayText?: (proto.IHighlyStructuredMessage|null); + + /** URLButton url */ + url?: (proto.IHighlyStructuredMessage|null); + } + + /** Represents a URLButton. */ + class URLButton implements IURLButton { + + /** + * Constructs a new URLButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IURLButton); + + /** URLButton displayText. */ + public displayText?: (proto.IHighlyStructuredMessage|null); + + /** URLButton url. */ + public url?: (proto.IHighlyStructuredMessage|null); + + /** + * Creates a new URLButton instance using the specified properties. + * @param [properties] Properties to set + * @returns URLButton instance + */ + public static create(properties?: proto.IURLButton): proto.URLButton; + + /** + * Encodes the specified URLButton message. Does not implicitly {@link proto.URLButton.verify|verify} messages. + * @param message URLButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IURLButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified URLButton message, length delimited. Does not implicitly {@link proto.URLButton.verify|verify} messages. + * @param message URLButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IURLButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a URLButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns URLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.URLButton; + + /** + * Decodes a URLButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns URLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.URLButton; + + /** + * Verifies a URLButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a URLButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns URLButton + */ + public static fromObject(object: { [k: string]: any }): proto.URLButton; + + /** + * Creates a plain object from a URLButton message. Also converts values to other types if specified. + * @param message URLButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.URLButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this URLButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a CallButton. */ + interface ICallButton { + + /** CallButton displayText */ + displayText?: (proto.IHighlyStructuredMessage|null); + + /** CallButton phoneNumber */ + phoneNumber?: (proto.IHighlyStructuredMessage|null); + } + + /** Represents a CallButton. */ + class CallButton implements ICallButton { + + /** + * Constructs a new CallButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ICallButton); + + /** CallButton displayText. */ + public displayText?: (proto.IHighlyStructuredMessage|null); + + /** CallButton phoneNumber. */ + public phoneNumber?: (proto.IHighlyStructuredMessage|null); + + /** + * Creates a new CallButton instance using the specified properties. + * @param [properties] Properties to set + * @returns CallButton instance + */ + public static create(properties?: proto.ICallButton): proto.CallButton; + + /** + * Encodes the specified CallButton message. Does not implicitly {@link proto.CallButton.verify|verify} messages. + * @param message CallButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ICallButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified CallButton message, length delimited. Does not implicitly {@link proto.CallButton.verify|verify} messages. + * @param message CallButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ICallButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a CallButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns CallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.CallButton; + + /** + * Decodes a CallButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns CallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.CallButton; + + /** + * Verifies a CallButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a CallButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns CallButton + */ + public static fromObject(object: { [k: string]: any }): proto.CallButton; + + /** + * Creates a plain object from a CallButton message. Also converts values to other types if specified. + * @param message CallButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.CallButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this CallButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a TemplateButton. */ + interface ITemplateButton { + + /** TemplateButton index */ + index?: (number|null); + + /** TemplateButton quickReplyButton */ + quickReplyButton?: (proto.IQuickReplyButton|null); + + /** TemplateButton urlButton */ + urlButton?: (proto.IURLButton|null); + + /** TemplateButton callButton */ + callButton?: (proto.ICallButton|null); + } + + /** Represents a TemplateButton. */ + class TemplateButton implements ITemplateButton { + + /** + * Constructs a new TemplateButton. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ITemplateButton); + + /** TemplateButton index. */ + public index: number; + + /** TemplateButton quickReplyButton. */ + public quickReplyButton?: (proto.IQuickReplyButton|null); + + /** TemplateButton urlButton. */ + public urlButton?: (proto.IURLButton|null); + + /** TemplateButton callButton. */ + public callButton?: (proto.ICallButton|null); + + /** TemplateButton button. */ + public button?: ("quickReplyButton"|"urlButton"|"callButton"); + + /** + * Creates a new TemplateButton instance using the specified properties. + * @param [properties] Properties to set + * @returns TemplateButton instance + */ + public static create(properties?: proto.ITemplateButton): proto.TemplateButton; + + /** + * Encodes the specified TemplateButton message. Does not implicitly {@link proto.TemplateButton.verify|verify} messages. + * @param message TemplateButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ITemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified TemplateButton message, length delimited. Does not implicitly {@link proto.TemplateButton.verify|verify} messages. + * @param message TemplateButton message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ITemplateButton, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a TemplateButton message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns TemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.TemplateButton; + + /** + * Decodes a TemplateButton message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns TemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.TemplateButton; + + /** + * Verifies a TemplateButton message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a TemplateButton message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns TemplateButton + */ + public static fromObject(object: { [k: string]: any }): proto.TemplateButton; + + /** + * Creates a plain object from a TemplateButton message. Also converts values to other types if specified. + * @param message TemplateButton + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.TemplateButton, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this TemplateButton to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Location. */ + interface ILocation { + + /** Location degreesLatitude */ + degreesLatitude?: (number|null); + + /** Location degreesLongitude */ + degreesLongitude?: (number|null); + + /** Location name */ + name?: (string|null); + } + + /** Represents a Location. */ + class Location implements ILocation { + + /** + * Constructs a new Location. + * @param [properties] Properties to set + */ + constructor(properties?: proto.ILocation); + + /** Location degreesLatitude. */ + public degreesLatitude: number; + + /** Location degreesLongitude. */ + public degreesLongitude: number; + + /** Location name. */ + public name: string; + + /** + * Creates a new Location instance using the specified properties. + * @param [properties] Properties to set + * @returns Location instance + */ + public static create(properties?: proto.ILocation): proto.Location; + + /** + * Encodes the specified Location message. Does not implicitly {@link proto.Location.verify|verify} messages. + * @param message Location message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.ILocation, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Location message, length delimited. Does not implicitly {@link proto.Location.verify|verify} messages. + * @param message Location message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.ILocation, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Location message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Location + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Location; + + /** + * Decodes a Location message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Location + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Location; + + /** + * Verifies a Location message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Location message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Location + */ + public static fromObject(object: { [k: string]: any }): proto.Location; + + /** + * Creates a plain object from a Location message. Also converts values to other types if specified. + * @param message Location + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Location, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Location to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Point. */ + interface IPoint { + + /** Point xDeprecated */ + xDeprecated?: (number|null); + + /** Point yDeprecated */ + yDeprecated?: (number|null); + + /** Point x */ + x?: (number|null); + + /** Point y */ + y?: (number|null); + } + + /** Represents a Point. */ + class Point implements IPoint { + + /** + * Constructs a new Point. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IPoint); + + /** Point xDeprecated. */ + public xDeprecated: number; + + /** Point yDeprecated. */ + public yDeprecated: number; + + /** Point x. */ + public x: number; + + /** Point y. */ + public y: number; + + /** + * Creates a new Point instance using the specified properties. + * @param [properties] Properties to set + * @returns Point instance + */ + public static create(properties?: proto.IPoint): proto.Point; + + /** + * Encodes the specified Point message. Does not implicitly {@link proto.Point.verify|verify} messages. + * @param message Point message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IPoint, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Point message, length delimited. Does not implicitly {@link proto.Point.verify|verify} messages. + * @param message Point message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IPoint, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Point message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Point + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Point; + + /** + * Decodes a Point message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Point + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Point; + + /** + * Verifies a Point message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Point message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Point + */ + public static fromObject(object: { [k: string]: any }): proto.Point; + + /** + * Creates a plain object from a Point message. Also converts values to other types if specified. + * @param message Point + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Point, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Point to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of a CompanionProps. */ interface ICompanionProps { @@ -17395,6 +19662,240 @@ export namespace proto { public toJSON(): { [k: string]: any }; } + /** Properties of a Reaction. */ + interface IReaction { + + /** Reaction key */ + key?: (proto.IMessageKey|null); + + /** Reaction text */ + text?: (string|null); + + /** Reaction groupingKey */ + groupingKey?: (string|null); + + /** Reaction senderTimestampMs */ + senderTimestampMs?: (number|Long|null); + + /** Reaction unread */ + unread?: (boolean|null); + } + + /** Represents a Reaction. */ + class Reaction implements IReaction { + + /** + * Constructs a new Reaction. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IReaction); + + /** Reaction key. */ + public key?: (proto.IMessageKey|null); + + /** Reaction text. */ + public text: string; + + /** Reaction groupingKey. */ + public groupingKey: string; + + /** Reaction senderTimestampMs. */ + public senderTimestampMs: (number|Long); + + /** Reaction unread. */ + public unread: boolean; + + /** + * Creates a new Reaction instance using the specified properties. + * @param [properties] Properties to set + * @returns Reaction instance + */ + public static create(properties?: proto.IReaction): proto.Reaction; + + /** + * Encodes the specified Reaction message. Does not implicitly {@link proto.Reaction.verify|verify} messages. + * @param message Reaction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IReaction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Reaction message, length delimited. Does not implicitly {@link proto.Reaction.verify|verify} messages. + * @param message Reaction message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IReaction, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Reaction message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Reaction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.Reaction; + + /** + * Decodes a Reaction message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Reaction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.Reaction; + + /** + * Verifies a Reaction message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Reaction message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Reaction + */ + public static fromObject(object: { [k: string]: any }): proto.Reaction; + + /** + * Creates a plain object from a Reaction message. Also converts values to other types if specified. + * @param message Reaction + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.Reaction, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Reaction to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a UserReceipt. */ + interface IUserReceipt { + + /** UserReceipt userJid */ + userJid: string; + + /** UserReceipt receiptTimestamp */ + receiptTimestamp?: (number|Long|null); + + /** UserReceipt readTimestamp */ + readTimestamp?: (number|Long|null); + + /** UserReceipt playedTimestamp */ + playedTimestamp?: (number|Long|null); + + /** UserReceipt pendingDeviceJid */ + pendingDeviceJid?: (string[]|null); + + /** UserReceipt deliveredDeviceJid */ + deliveredDeviceJid?: (string[]|null); + } + + /** Represents a UserReceipt. */ + class UserReceipt implements IUserReceipt { + + /** + * Constructs a new UserReceipt. + * @param [properties] Properties to set + */ + constructor(properties?: proto.IUserReceipt); + + /** UserReceipt userJid. */ + public userJid: string; + + /** UserReceipt receiptTimestamp. */ + public receiptTimestamp: (number|Long); + + /** UserReceipt readTimestamp. */ + public readTimestamp: (number|Long); + + /** UserReceipt playedTimestamp. */ + public playedTimestamp: (number|Long); + + /** UserReceipt pendingDeviceJid. */ + public pendingDeviceJid: string[]; + + /** UserReceipt deliveredDeviceJid. */ + public deliveredDeviceJid: string[]; + + /** + * Creates a new UserReceipt instance using the specified properties. + * @param [properties] Properties to set + * @returns UserReceipt instance + */ + public static create(properties?: proto.IUserReceipt): proto.UserReceipt; + + /** + * Encodes the specified UserReceipt message. Does not implicitly {@link proto.UserReceipt.verify|verify} messages. + * @param message UserReceipt message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: proto.IUserReceipt, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified UserReceipt message, length delimited. Does not implicitly {@link proto.UserReceipt.verify|verify} messages. + * @param message UserReceipt message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: proto.IUserReceipt, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a UserReceipt message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns UserReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.UserReceipt; + + /** + * Decodes a UserReceipt message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns UserReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.UserReceipt; + + /** + * Verifies a UserReceipt message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a UserReceipt message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns UserReceipt + */ + public static fromObject(object: { [k: string]: any }): proto.UserReceipt; + + /** + * Creates a plain object from a UserReceipt message. Also converts values to other types if specified. + * @param message UserReceipt + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: proto.UserReceipt, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this UserReceipt to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of a PhotoChange. */ interface IPhotoChange { @@ -17497,96 +19998,6 @@ export namespace proto { public toJSON(): { [k: string]: any }; } - /** Properties of a MediaData. */ - interface IMediaData { - - /** MediaData localPath */ - localPath?: (string|null); - } - - /** Represents a MediaData. */ - class MediaData implements IMediaData { - - /** - * Constructs a new MediaData. - * @param [properties] Properties to set - */ - constructor(properties?: proto.IMediaData); - - /** MediaData localPath. */ - public localPath: string; - - /** - * Creates a new MediaData instance using the specified properties. - * @param [properties] Properties to set - * @returns MediaData instance - */ - public static create(properties?: proto.IMediaData): proto.MediaData; - - /** - * Encodes the specified MediaData message. Does not implicitly {@link proto.MediaData.verify|verify} messages. - * @param message MediaData message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: proto.IMediaData, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified MediaData message, length delimited. Does not implicitly {@link proto.MediaData.verify|verify} messages. - * @param message MediaData message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: proto.IMediaData, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes a MediaData message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns MediaData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): proto.MediaData; - - /** - * Decodes a MediaData message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns MediaData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): proto.MediaData; - - /** - * Verifies a MediaData message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates a MediaData message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns MediaData - */ - public static fromObject(object: { [k: string]: any }): proto.MediaData; - - /** - * Creates a plain object from a MediaData message. Also converts values to other types if specified. - * @param message MediaData - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: proto.MediaData, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this MediaData to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - } - /** Properties of a WebFeatures. */ interface IWebFeatures { @@ -17715,6 +20126,15 @@ export namespace proto { /** WebFeatures mdForceUpgrade */ mdForceUpgrade?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures disappearingMode */ + disappearingMode?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures externalMdOptInAvailable */ + externalMdOptInAvailable?: (proto.WebFeatures.WebFeaturesFlag|null); + + /** WebFeatures noDeleteMessageTimeLimit */ + noDeleteMessageTimeLimit?: (proto.WebFeatures.WebFeaturesFlag|null); } /** Represents a WebFeatures. */ @@ -17852,6 +20272,15 @@ export namespace proto { /** WebFeatures mdForceUpgrade. */ public mdForceUpgrade: proto.WebFeatures.WebFeaturesFlag; + /** WebFeatures disappearingMode. */ + public disappearingMode: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures externalMdOptInAvailable. */ + public externalMdOptInAvailable: proto.WebFeatures.WebFeaturesFlag; + + /** WebFeatures noDeleteMessageTimeLimit. */ + public noDeleteMessageTimeLimit: proto.WebFeatures.WebFeaturesFlag; + /** * Creates a new WebFeatures instance using the specified properties. * @param [properties] Properties to set @@ -18462,6 +20891,27 @@ export namespace proto { /** WebMessageInfo photoChange */ photoChange?: (proto.IPhotoChange|null); + + /** WebMessageInfo userReceipt */ + userReceipt?: (proto.IUserReceipt[]|null); + + /** WebMessageInfo reactions */ + reactions?: (proto.IReaction[]|null); + + /** WebMessageInfo quotedStickerData */ + quotedStickerData?: (proto.IMediaData|null); + + /** WebMessageInfo futureproofData */ + futureproofData?: (Uint8Array|null); + + /** WebMessageInfo statusPsaCampaignId */ + statusPsaCampaignId?: (string|null); + + /** WebMessageInfo statusPsaCampaignDuration */ + statusPsaCampaignDuration?: (number|null); + + /** WebMessageInfo statusPsaCampaignReadTimestamp */ + statusPsaCampaignReadTimestamp?: (number|Long|null); } /** Represents a WebMessageInfo. */ @@ -18563,6 +21013,27 @@ export namespace proto { /** WebMessageInfo photoChange. */ public photoChange?: (proto.IPhotoChange|null); + /** WebMessageInfo userReceipt. */ + public userReceipt: proto.IUserReceipt[]; + + /** WebMessageInfo reactions. */ + public reactions: proto.IReaction[]; + + /** WebMessageInfo quotedStickerData. */ + public quotedStickerData?: (proto.IMediaData|null); + + /** WebMessageInfo futureproofData. */ + public futureproofData: Uint8Array; + + /** WebMessageInfo statusPsaCampaignId. */ + public statusPsaCampaignId: string; + + /** WebMessageInfo statusPsaCampaignDuration. */ + public statusPsaCampaignDuration: number; + + /** WebMessageInfo statusPsaCampaignReadTimestamp. */ + public statusPsaCampaignReadTimestamp: (number|Long); + /** * Creates a new WebMessageInfo instance using the specified properties. * @param [properties] Properties to set @@ -18777,7 +21248,9 @@ export namespace proto { BIZ_PRIVACY_MODE_INIT_FB = 126, BIZ_PRIVACY_MODE_INIT_BSP = 127, BIZ_PRIVACY_MODE_TO_FB = 128, - BIZ_PRIVACY_MODE_TO_BSP = 129 + BIZ_PRIVACY_MODE_TO_BSP = 129, + DISAPPEARING_MODE = 130, + E2E_DEVICE_FETCH_FAILED = 131 } /** WebMessageInfoBizPrivacyStatus enum. */ diff --git a/WAProto/index.js b/WAProto/index.js index c2604c7..fa9f78b 100644 --- a/WAProto/index.js +++ b/WAProto/index.js @@ -622,6 +622,9 @@ $root.proto = (function() { case 23: case 24: case 25: + case 26: + case 27: + case 28: break; } if (message.appVersion != null && message.hasOwnProperty("appVersion")) { @@ -785,10 +788,22 @@ $root.proto = (function() { case 24: message.platform = 24; break; - case "VR": + case "OCULUS_MSG": case 25: message.platform = 25; break; + case "OCULUS_CALL": + case 26: + message.platform = 26; + break; + case "MILAN": + case 27: + message.platform = 27; + break; + case "CAPI": + case 28: + message.platform = 28; + break; } if (object.appVersion != null) { if (typeof object.appVersion !== "object") @@ -933,7 +948,10 @@ $root.proto = (function() { * @property {number} IGLITE_ANDROID=22 IGLITE_ANDROID value * @property {number} PAGE=23 PAGE value * @property {number} MACOS=24 MACOS value - * @property {number} VR=25 VR value + * @property {number} OCULUS_MSG=25 OCULUS_MSG value + * @property {number} OCULUS_CALL=26 OCULUS_CALL value + * @property {number} MILAN=27 MILAN value + * @property {number} CAPI=28 CAPI value */ UserAgent.UserAgentPlatform = (function() { var valuesById = {}, values = Object.create(valuesById); @@ -962,7 +980,10 @@ $root.proto = (function() { values[valuesById[22] = "IGLITE_ANDROID"] = 22; values[valuesById[23] = "PAGE"] = 23; values[valuesById[24] = "MACOS"] = 24; - values[valuesById[25] = "VR"] = 25; + values[valuesById[25] = "OCULUS_MSG"] = 25; + values[valuesById[26] = "OCULUS_CALL"] = 26; + values[valuesById[27] = "MILAN"] = 27; + values[valuesById[28] = "CAPI"] = 28; return values; })(); @@ -2391,13 +2412,11 @@ $root.proto = (function() { * @interface IClientPayload * @property {number|Long|null} [username] ClientPayload username * @property {boolean|null} [passive] ClientPayload passive - * @property {Array.|null} [clientFeatures] ClientPayload clientFeatures * @property {proto.IUserAgent|null} [userAgent] ClientPayload userAgent * @property {proto.IWebInfo|null} [webInfo] ClientPayload webInfo * @property {string|null} [pushName] ClientPayload pushName * @property {number|null} [sessionId] ClientPayload sessionId * @property {boolean|null} [shortConnect] ClientPayload shortConnect - * @property {proto.ClientPayload.ClientPayloadIOSAppExtension|null} [iosAppExtension] ClientPayload iosAppExtension * @property {proto.ClientPayload.ClientPayloadConnectType|null} [connectType] ClientPayload connectType * @property {proto.ClientPayload.ClientPayloadConnectReason|null} [connectReason] ClientPayload connectReason * @property {Array.|null} [shards] ClientPayload shards @@ -2410,6 +2429,10 @@ $root.proto = (function() { * @property {Uint8Array|null} [fbCat] ClientPayload fbCat * @property {Uint8Array|null} [fbUserAgent] ClientPayload fbUserAgent * @property {boolean|null} [oc] ClientPayload oc + * @property {number|null} [lc] ClientPayload lc + * @property {proto.ClientPayload.ClientPayloadIOSAppExtension|null} [iosAppExtension] ClientPayload iosAppExtension + * @property {number|Long|null} [fbAppId] ClientPayload fbAppId + * @property {Uint8Array|null} [fbDeviceId] ClientPayload fbDeviceId */ /** @@ -2421,7 +2444,6 @@ $root.proto = (function() { * @param {proto.IClientPayload=} [properties] Properties to set */ function ClientPayload(properties) { - this.clientFeatures = []; this.shards = []; if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) @@ -2445,14 +2467,6 @@ $root.proto = (function() { */ ClientPayload.prototype.passive = false; - /** - * ClientPayload clientFeatures. - * @member {Array.} clientFeatures - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.clientFeatures = $util.emptyArray; - /** * ClientPayload userAgent. * @member {proto.IUserAgent|null|undefined} userAgent @@ -2493,14 +2507,6 @@ $root.proto = (function() { */ ClientPayload.prototype.shortConnect = false; - /** - * ClientPayload iosAppExtension. - * @member {proto.ClientPayload.ClientPayloadIOSAppExtension} iosAppExtension - * @memberof proto.ClientPayload - * @instance - */ - ClientPayload.prototype.iosAppExtension = 0; - /** * ClientPayload connectType. * @member {proto.ClientPayload.ClientPayloadConnectType} connectType @@ -2597,6 +2603,38 @@ $root.proto = (function() { */ ClientPayload.prototype.oc = false; + /** + * ClientPayload lc. + * @member {number} lc + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.lc = 0; + + /** + * ClientPayload iosAppExtension. + * @member {proto.ClientPayload.ClientPayloadIOSAppExtension} iosAppExtension + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.iosAppExtension = 0; + + /** + * ClientPayload fbAppId. + * @member {number|Long} fbAppId + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.fbAppId = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * ClientPayload fbDeviceId. + * @member {Uint8Array} fbDeviceId + * @memberof proto.ClientPayload + * @instance + */ + ClientPayload.prototype.fbDeviceId = $util.newBuffer([]); + /** * Creates a new ClientPayload instance using the specified properties. * @function create @@ -2625,9 +2663,6 @@ $root.proto = (function() { writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.username); if (message.passive != null && Object.hasOwnProperty.call(message, "passive")) writer.uint32(/* id 3, wireType 0 =*/24).bool(message.passive); - if (message.clientFeatures != null && message.clientFeatures.length) - for (var i = 0; i < message.clientFeatures.length; ++i) - writer.uint32(/* id 4, wireType 0 =*/32).int32(message.clientFeatures[i]); if (message.userAgent != null && Object.hasOwnProperty.call(message, "userAgent")) $root.proto.UserAgent.encode(message.userAgent, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); if (message.webInfo != null && Object.hasOwnProperty.call(message, "webInfo")) @@ -2663,8 +2698,14 @@ $root.proto = (function() { writer.uint32(/* id 22, wireType 2 =*/178).bytes(message.fbUserAgent); if (message.oc != null && Object.hasOwnProperty.call(message, "oc")) writer.uint32(/* id 23, wireType 0 =*/184).bool(message.oc); + if (message.lc != null && Object.hasOwnProperty.call(message, "lc")) + writer.uint32(/* id 24, wireType 0 =*/192).uint32(message.lc); if (message.iosAppExtension != null && Object.hasOwnProperty.call(message, "iosAppExtension")) writer.uint32(/* id 30, wireType 0 =*/240).int32(message.iosAppExtension); + if (message.fbAppId != null && Object.hasOwnProperty.call(message, "fbAppId")) + writer.uint32(/* id 31, wireType 0 =*/248).uint64(message.fbAppId); + if (message.fbDeviceId != null && Object.hasOwnProperty.call(message, "fbDeviceId")) + writer.uint32(/* id 32, wireType 2 =*/258).bytes(message.fbDeviceId); return writer; }; @@ -2705,16 +2746,6 @@ $root.proto = (function() { case 3: message.passive = reader.bool(); break; - case 4: - if (!(message.clientFeatures && message.clientFeatures.length)) - message.clientFeatures = []; - if ((tag & 7) === 2) { - var end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) - message.clientFeatures.push(reader.int32()); - } else - message.clientFeatures.push(reader.int32()); - break; case 5: message.userAgent = $root.proto.UserAgent.decode(reader, reader.uint32()); break; @@ -2730,9 +2761,6 @@ $root.proto = (function() { case 10: message.shortConnect = reader.bool(); break; - case 30: - message.iosAppExtension = reader.int32(); - break; case 12: message.connectType = reader.int32(); break; @@ -2776,6 +2804,18 @@ $root.proto = (function() { case 23: message.oc = reader.bool(); break; + case 24: + message.lc = reader.uint32(); + break; + case 30: + message.iosAppExtension = reader.int32(); + break; + case 31: + message.fbAppId = reader.uint64(); + break; + case 32: + message.fbDeviceId = reader.bytes(); + break; default: reader.skipType(tag & 7); break; @@ -2817,17 +2857,6 @@ $root.proto = (function() { if (message.passive != null && message.hasOwnProperty("passive")) if (typeof message.passive !== "boolean") return "passive: boolean expected"; - if (message.clientFeatures != null && message.hasOwnProperty("clientFeatures")) { - if (!Array.isArray(message.clientFeatures)) - return "clientFeatures: array expected"; - for (var i = 0; i < message.clientFeatures.length; ++i) - switch (message.clientFeatures[i]) { - default: - return "clientFeatures: enum value[] expected"; - case 0: - break; - } - } if (message.userAgent != null && message.hasOwnProperty("userAgent")) { var error = $root.proto.UserAgent.verify(message.userAgent); if (error) @@ -2847,15 +2876,6 @@ $root.proto = (function() { if (message.shortConnect != null && message.hasOwnProperty("shortConnect")) if (typeof message.shortConnect !== "boolean") return "shortConnect: boolean expected"; - if (message.iosAppExtension != null && message.hasOwnProperty("iosAppExtension")) - switch (message.iosAppExtension) { - default: - return "iosAppExtension: enum value expected"; - case 0: - case 1: - case 2: - break; - } if (message.connectType != null && message.hasOwnProperty("connectType")) switch (message.connectType) { default: @@ -2932,6 +2952,24 @@ $root.proto = (function() { if (message.oc != null && message.hasOwnProperty("oc")) if (typeof message.oc !== "boolean") return "oc: boolean expected"; + if (message.lc != null && message.hasOwnProperty("lc")) + if (!$util.isInteger(message.lc)) + return "lc: integer expected"; + if (message.iosAppExtension != null && message.hasOwnProperty("iosAppExtension")) + switch (message.iosAppExtension) { + default: + return "iosAppExtension: enum value expected"; + case 0: + case 1: + case 2: + break; + } + if (message.fbAppId != null && message.hasOwnProperty("fbAppId")) + if (!$util.isInteger(message.fbAppId) && !(message.fbAppId && $util.isInteger(message.fbAppId.low) && $util.isInteger(message.fbAppId.high))) + return "fbAppId: integer|Long expected"; + if (message.fbDeviceId != null && message.hasOwnProperty("fbDeviceId")) + if (!(message.fbDeviceId && typeof message.fbDeviceId.length === "number" || $util.isString(message.fbDeviceId))) + return "fbDeviceId: buffer expected"; return null; }; @@ -2958,19 +2996,6 @@ $root.proto = (function() { message.username = new $util.LongBits(object.username.low >>> 0, object.username.high >>> 0).toNumber(true); if (object.passive != null) message.passive = Boolean(object.passive); - if (object.clientFeatures) { - if (!Array.isArray(object.clientFeatures)) - throw TypeError(".proto.ClientPayload.clientFeatures: array expected"); - message.clientFeatures = []; - for (var i = 0; i < object.clientFeatures.length; ++i) - switch (object.clientFeatures[i]) { - default: - case "NONE": - case 0: - message.clientFeatures[i] = 0; - break; - } - } if (object.userAgent != null) { if (typeof object.userAgent !== "object") throw TypeError(".proto.ClientPayload.userAgent: object expected"); @@ -2987,20 +3012,6 @@ $root.proto = (function() { message.sessionId = object.sessionId | 0; if (object.shortConnect != null) message.shortConnect = Boolean(object.shortConnect); - switch (object.iosAppExtension) { - case "SHARE_EXTENSION": - case 0: - message.iosAppExtension = 0; - break; - case "SERVICE_EXTENSION": - case 1: - message.iosAppExtension = 1; - break; - case "INTENTS_EXTENSION": - case 2: - message.iosAppExtension = 2; - break; - } switch (object.connectType) { case "CELLULAR_UNKNOWN": case 0: @@ -3134,6 +3145,36 @@ $root.proto = (function() { message.fbUserAgent = object.fbUserAgent; if (object.oc != null) message.oc = Boolean(object.oc); + if (object.lc != null) + message.lc = object.lc >>> 0; + switch (object.iosAppExtension) { + case "SHARE_EXTENSION": + case 0: + message.iosAppExtension = 0; + break; + case "SERVICE_EXTENSION": + case 1: + message.iosAppExtension = 1; + break; + case "INTENTS_EXTENSION": + case 2: + message.iosAppExtension = 2; + break; + } + if (object.fbAppId != null) + if ($util.Long) + (message.fbAppId = $util.Long.fromValue(object.fbAppId)).unsigned = true; + else if (typeof object.fbAppId === "string") + message.fbAppId = parseInt(object.fbAppId, 10); + else if (typeof object.fbAppId === "number") + message.fbAppId = object.fbAppId; + else if (typeof object.fbAppId === "object") + message.fbAppId = new $util.LongBits(object.fbAppId.low >>> 0, object.fbAppId.high >>> 0).toNumber(true); + if (object.fbDeviceId != null) + if (typeof object.fbDeviceId === "string") + $util.base64.decode(object.fbDeviceId, message.fbDeviceId = $util.newBuffer($util.base64.length(object.fbDeviceId)), 0); + else if (object.fbDeviceId.length) + message.fbDeviceId = object.fbDeviceId; return message; }; @@ -3150,10 +3191,8 @@ $root.proto = (function() { if (!options) options = {}; var object = {}; - if (options.arrays || options.defaults) { - object.clientFeatures = []; + if (options.arrays || options.defaults) object.shards = []; - } if (options.defaults) { if ($util.Long) { var long = new $util.Long(0, 0, true); @@ -3189,7 +3228,20 @@ $root.proto = (function() { object.fbUserAgent = $util.newBuffer(object.fbUserAgent); } object.oc = false; + object.lc = 0; object.iosAppExtension = options.enums === String ? "SHARE_EXTENSION" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.fbAppId = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.fbAppId = options.longs === String ? "0" : 0; + if (options.bytes === String) + object.fbDeviceId = ""; + else { + object.fbDeviceId = []; + if (options.bytes !== Array) + object.fbDeviceId = $util.newBuffer(object.fbDeviceId); + } } if (message.username != null && message.hasOwnProperty("username")) if (typeof message.username === "number") @@ -3198,11 +3250,6 @@ $root.proto = (function() { object.username = options.longs === String ? $util.Long.prototype.toString.call(message.username) : options.longs === Number ? new $util.LongBits(message.username.low >>> 0, message.username.high >>> 0).toNumber(true) : message.username; if (message.passive != null && message.hasOwnProperty("passive")) object.passive = message.passive; - if (message.clientFeatures && message.clientFeatures.length) { - object.clientFeatures = []; - for (var j = 0; j < message.clientFeatures.length; ++j) - object.clientFeatures[j] = options.enums === String ? $root.proto.ClientPayload.ClientPayloadClientFeature[message.clientFeatures[j]] : message.clientFeatures[j]; - } if (message.userAgent != null && message.hasOwnProperty("userAgent")) object.userAgent = $root.proto.UserAgent.toObject(message.userAgent, options); if (message.webInfo != null && message.hasOwnProperty("webInfo")) @@ -3240,8 +3287,17 @@ $root.proto = (function() { object.fbUserAgent = options.bytes === String ? $util.base64.encode(message.fbUserAgent, 0, message.fbUserAgent.length) : options.bytes === Array ? Array.prototype.slice.call(message.fbUserAgent) : message.fbUserAgent; if (message.oc != null && message.hasOwnProperty("oc")) object.oc = message.oc; + if (message.lc != null && message.hasOwnProperty("lc")) + object.lc = message.lc; if (message.iosAppExtension != null && message.hasOwnProperty("iosAppExtension")) object.iosAppExtension = options.enums === String ? $root.proto.ClientPayload.ClientPayloadIOSAppExtension[message.iosAppExtension] : message.iosAppExtension; + if (message.fbAppId != null && message.hasOwnProperty("fbAppId")) + if (typeof message.fbAppId === "number") + object.fbAppId = options.longs === String ? String(message.fbAppId) : message.fbAppId; + else + object.fbAppId = options.longs === String ? $util.Long.prototype.toString.call(message.fbAppId) : options.longs === Number ? new $util.LongBits(message.fbAppId.low >>> 0, message.fbAppId.high >>> 0).toNumber(true) : message.fbAppId; + if (message.fbDeviceId != null && message.hasOwnProperty("fbDeviceId")) + object.fbDeviceId = options.bytes === String ? $util.base64.encode(message.fbDeviceId, 0, message.fbDeviceId.length) : options.bytes === Array ? Array.prototype.slice.call(message.fbDeviceId) : message.fbDeviceId; return object; }; @@ -3256,34 +3312,6 @@ $root.proto = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; - /** - * ClientPayloadClientFeature enum. - * @name proto.ClientPayload.ClientPayloadClientFeature - * @enum {number} - * @property {number} NONE=0 NONE value - */ - ClientPayload.ClientPayloadClientFeature = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "NONE"] = 0; - return values; - })(); - - /** - * ClientPayloadIOSAppExtension enum. - * @name proto.ClientPayload.ClientPayloadIOSAppExtension - * @enum {number} - * @property {number} SHARE_EXTENSION=0 SHARE_EXTENSION value - * @property {number} SERVICE_EXTENSION=1 SERVICE_EXTENSION value - * @property {number} INTENTS_EXTENSION=2 INTENTS_EXTENSION value - */ - ClientPayload.ClientPayloadIOSAppExtension = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "SHARE_EXTENSION"] = 0; - values[valuesById[1] = "SERVICE_EXTENSION"] = 1; - values[valuesById[2] = "INTENTS_EXTENSION"] = 2; - return values; - })(); - /** * ClientPayloadConnectType enum. * @name proto.ClientPayload.ClientPayloadConnectType @@ -3360,6 +3388,22 @@ $root.proto = (function() { return values; })(); + /** + * ClientPayloadIOSAppExtension enum. + * @name proto.ClientPayload.ClientPayloadIOSAppExtension + * @enum {number} + * @property {number} SHARE_EXTENSION=0 SHARE_EXTENSION value + * @property {number} SERVICE_EXTENSION=1 SERVICE_EXTENSION value + * @property {number} INTENTS_EXTENSION=2 INTENTS_EXTENSION value + */ + ClientPayload.ClientPayloadIOSAppExtension = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "SHARE_EXTENSION"] = 0; + values[valuesById[1] = "SERVICE_EXTENSION"] = 1; + values[valuesById[2] = "INTENTS_EXTENSION"] = 2; + return values; + })(); + return ClientPayload; })(); @@ -4896,6 +4940,7 @@ $root.proto = (function() { * @property {proto.BizIdentityInfo.BizIdentityInfoHostStorageType|null} [hostStorage] BizIdentityInfo hostStorage * @property {proto.BizIdentityInfo.BizIdentityInfoActualActorsType|null} [actualActors] BizIdentityInfo actualActors * @property {number|Long|null} [privacyModeTs] BizIdentityInfo privacyModeTs + * @property {number|Long|null} [featureControls] BizIdentityInfo featureControls */ /** @@ -4969,6 +5014,14 @@ $root.proto = (function() { */ BizIdentityInfo.prototype.privacyModeTs = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + /** + * BizIdentityInfo featureControls. + * @member {number|Long} featureControls + * @memberof proto.BizIdentityInfo + * @instance + */ + BizIdentityInfo.prototype.featureControls = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + /** * Creates a new BizIdentityInfo instance using the specified properties. * @function create @@ -5007,6 +5060,8 @@ $root.proto = (function() { writer.uint32(/* id 6, wireType 0 =*/48).int32(message.actualActors); if (message.privacyModeTs != null && Object.hasOwnProperty.call(message, "privacyModeTs")) writer.uint32(/* id 7, wireType 0 =*/56).uint64(message.privacyModeTs); + if (message.featureControls != null && Object.hasOwnProperty.call(message, "featureControls")) + writer.uint32(/* id 8, wireType 0 =*/64).uint64(message.featureControls); return writer; }; @@ -5062,6 +5117,9 @@ $root.proto = (function() { case 7: message.privacyModeTs = reader.uint64(); break; + case 8: + message.featureControls = reader.uint64(); + break; default: reader.skipType(tag & 7); break; @@ -5136,6 +5194,9 @@ $root.proto = (function() { if (message.privacyModeTs != null && message.hasOwnProperty("privacyModeTs")) if (!$util.isInteger(message.privacyModeTs) && !(message.privacyModeTs && $util.isInteger(message.privacyModeTs.low) && $util.isInteger(message.privacyModeTs.high))) return "privacyModeTs: integer|Long expected"; + if (message.featureControls != null && message.hasOwnProperty("featureControls")) + if (!$util.isInteger(message.featureControls) && !(message.featureControls && $util.isInteger(message.featureControls.low) && $util.isInteger(message.featureControls.high))) + return "featureControls: integer|Long expected"; return null; }; @@ -5203,6 +5264,15 @@ $root.proto = (function() { message.privacyModeTs = object.privacyModeTs; else if (typeof object.privacyModeTs === "object") message.privacyModeTs = new $util.LongBits(object.privacyModeTs.low >>> 0, object.privacyModeTs.high >>> 0).toNumber(true); + if (object.featureControls != null) + if ($util.Long) + (message.featureControls = $util.Long.fromValue(object.featureControls)).unsigned = true; + else if (typeof object.featureControls === "string") + message.featureControls = parseInt(object.featureControls, 10); + else if (typeof object.featureControls === "number") + message.featureControls = object.featureControls; + else if (typeof object.featureControls === "object") + message.featureControls = new $util.LongBits(object.featureControls.low >>> 0, object.featureControls.high >>> 0).toNumber(true); return message; }; @@ -5231,6 +5301,11 @@ $root.proto = (function() { object.privacyModeTs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; } else object.privacyModeTs = options.longs === String ? "0" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.featureControls = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.featureControls = options.longs === String ? "0" : 0; } if (message.vlevel != null && message.hasOwnProperty("vlevel")) object.vlevel = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue[message.vlevel] : message.vlevel; @@ -5249,6 +5324,11 @@ $root.proto = (function() { object.privacyModeTs = options.longs === String ? String(message.privacyModeTs) : message.privacyModeTs; else object.privacyModeTs = options.longs === String ? $util.Long.prototype.toString.call(message.privacyModeTs) : options.longs === Number ? new $util.LongBits(message.privacyModeTs.low >>> 0, message.privacyModeTs.high >>> 0).toNumber(true) : message.privacyModeTs; + if (message.featureControls != null && message.hasOwnProperty("featureControls")) + if (typeof message.featureControls === "number") + object.featureControls = options.longs === String ? String(message.featureControls) : message.featureControls; + else + object.featureControls = options.longs === String ? $util.Long.prototype.toString.call(message.featureControls) : options.longs === Number ? new $util.LongBits(message.featureControls.low >>> 0, message.featureControls.high >>> 0).toNumber(true) : message.featureControls; return object; }; @@ -5518,7 +5598,6 @@ $root.proto = (function() { default: return "accountType: enum value expected"; case 0: - case 1: break; } return null; @@ -5571,10 +5650,6 @@ $root.proto = (function() { case 0: message.accountType = 0; break; - case "PAGE": - case 1: - message.accountType = 1; - break; } return message; }; @@ -5656,12 +5731,10 @@ $root.proto = (function() { * @name proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType * @enum {number} * @property {number} ENTERPRISE=0 ENTERPRISE value - * @property {number} PAGE=1 PAGE value */ BizAccountLinkInfo.BizAccountLinkInfoAccountType = (function() { var valuesById = {}, values = Object.create(valuesById); values[valuesById[0] = "ENTERPRISE"] = 0; - values[valuesById[1] = "PAGE"] = 1; return values; })(); @@ -9499,6 +9572,362 @@ $root.proto = (function() { return RecentEmojiWeightsAction; })(); + proto.FavoriteStickerAction = (function() { + + /** + * Properties of a FavoriteStickerAction. + * @memberof proto + * @interface IFavoriteStickerAction + * @property {string|null} [directPath] FavoriteStickerAction directPath + * @property {string|null} [lastUploadTimestamp] FavoriteStickerAction lastUploadTimestamp + * @property {string|null} [handle] FavoriteStickerAction handle + * @property {string|null} [encFilehash] FavoriteStickerAction encFilehash + * @property {string|null} [stickerHashWithoutMeta] FavoriteStickerAction stickerHashWithoutMeta + * @property {string|null} [mediaKey] FavoriteStickerAction mediaKey + * @property {number|Long|null} [mediaKeyTimestamp] FavoriteStickerAction mediaKeyTimestamp + * @property {boolean|null} [isFavorite] FavoriteStickerAction isFavorite + */ + + /** + * Constructs a new FavoriteStickerAction. + * @memberof proto + * @classdesc Represents a FavoriteStickerAction. + * @implements IFavoriteStickerAction + * @constructor + * @param {proto.IFavoriteStickerAction=} [properties] Properties to set + */ + function FavoriteStickerAction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * FavoriteStickerAction directPath. + * @member {string} directPath + * @memberof proto.FavoriteStickerAction + * @instance + */ + FavoriteStickerAction.prototype.directPath = ""; + + /** + * FavoriteStickerAction lastUploadTimestamp. + * @member {string} lastUploadTimestamp + * @memberof proto.FavoriteStickerAction + * @instance + */ + FavoriteStickerAction.prototype.lastUploadTimestamp = ""; + + /** + * FavoriteStickerAction handle. + * @member {string} handle + * @memberof proto.FavoriteStickerAction + * @instance + */ + FavoriteStickerAction.prototype.handle = ""; + + /** + * FavoriteStickerAction encFilehash. + * @member {string} encFilehash + * @memberof proto.FavoriteStickerAction + * @instance + */ + FavoriteStickerAction.prototype.encFilehash = ""; + + /** + * FavoriteStickerAction stickerHashWithoutMeta. + * @member {string} stickerHashWithoutMeta + * @memberof proto.FavoriteStickerAction + * @instance + */ + FavoriteStickerAction.prototype.stickerHashWithoutMeta = ""; + + /** + * FavoriteStickerAction mediaKey. + * @member {string} mediaKey + * @memberof proto.FavoriteStickerAction + * @instance + */ + FavoriteStickerAction.prototype.mediaKey = ""; + + /** + * FavoriteStickerAction mediaKeyTimestamp. + * @member {number|Long} mediaKeyTimestamp + * @memberof proto.FavoriteStickerAction + * @instance + */ + FavoriteStickerAction.prototype.mediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * FavoriteStickerAction isFavorite. + * @member {boolean} isFavorite + * @memberof proto.FavoriteStickerAction + * @instance + */ + FavoriteStickerAction.prototype.isFavorite = false; + + /** + * Creates a new FavoriteStickerAction instance using the specified properties. + * @function create + * @memberof proto.FavoriteStickerAction + * @static + * @param {proto.IFavoriteStickerAction=} [properties] Properties to set + * @returns {proto.FavoriteStickerAction} FavoriteStickerAction instance + */ + FavoriteStickerAction.create = function create(properties) { + return new FavoriteStickerAction(properties); + }; + + /** + * Encodes the specified FavoriteStickerAction message. Does not implicitly {@link proto.FavoriteStickerAction.verify|verify} messages. + * @function encode + * @memberof proto.FavoriteStickerAction + * @static + * @param {proto.IFavoriteStickerAction} message FavoriteStickerAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + FavoriteStickerAction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.directPath); + if (message.lastUploadTimestamp != null && Object.hasOwnProperty.call(message, "lastUploadTimestamp")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.lastUploadTimestamp); + if (message.handle != null && Object.hasOwnProperty.call(message, "handle")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.handle); + if (message.encFilehash != null && Object.hasOwnProperty.call(message, "encFilehash")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.encFilehash); + if (message.stickerHashWithoutMeta != null && Object.hasOwnProperty.call(message, "stickerHashWithoutMeta")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.stickerHashWithoutMeta); + if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey")) + writer.uint32(/* id 6, wireType 2 =*/50).string(message.mediaKey); + if (message.mediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "mediaKeyTimestamp")) + writer.uint32(/* id 7, wireType 0 =*/56).int64(message.mediaKeyTimestamp); + if (message.isFavorite != null && Object.hasOwnProperty.call(message, "isFavorite")) + writer.uint32(/* id 8, wireType 0 =*/64).bool(message.isFavorite); + return writer; + }; + + /** + * Encodes the specified FavoriteStickerAction message, length delimited. Does not implicitly {@link proto.FavoriteStickerAction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.FavoriteStickerAction + * @static + * @param {proto.IFavoriteStickerAction} message FavoriteStickerAction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + FavoriteStickerAction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a FavoriteStickerAction message from the specified reader or buffer. + * @function decode + * @memberof proto.FavoriteStickerAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.FavoriteStickerAction} FavoriteStickerAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + FavoriteStickerAction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.FavoriteStickerAction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.directPath = reader.string(); + break; + case 2: + message.lastUploadTimestamp = reader.string(); + break; + case 3: + message.handle = reader.string(); + break; + case 4: + message.encFilehash = reader.string(); + break; + case 5: + message.stickerHashWithoutMeta = reader.string(); + break; + case 6: + message.mediaKey = reader.string(); + break; + case 7: + message.mediaKeyTimestamp = reader.int64(); + break; + case 8: + message.isFavorite = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a FavoriteStickerAction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.FavoriteStickerAction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.FavoriteStickerAction} FavoriteStickerAction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + FavoriteStickerAction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a FavoriteStickerAction message. + * @function verify + * @memberof proto.FavoriteStickerAction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + FavoriteStickerAction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.directPath != null && message.hasOwnProperty("directPath")) + if (!$util.isString(message.directPath)) + return "directPath: string expected"; + if (message.lastUploadTimestamp != null && message.hasOwnProperty("lastUploadTimestamp")) + if (!$util.isString(message.lastUploadTimestamp)) + return "lastUploadTimestamp: string expected"; + if (message.handle != null && message.hasOwnProperty("handle")) + if (!$util.isString(message.handle)) + return "handle: string expected"; + if (message.encFilehash != null && message.hasOwnProperty("encFilehash")) + if (!$util.isString(message.encFilehash)) + return "encFilehash: string expected"; + if (message.stickerHashWithoutMeta != null && message.hasOwnProperty("stickerHashWithoutMeta")) + if (!$util.isString(message.stickerHashWithoutMeta)) + return "stickerHashWithoutMeta: string expected"; + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + if (!$util.isString(message.mediaKey)) + return "mediaKey: string expected"; + if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp")) + if (!$util.isInteger(message.mediaKeyTimestamp) && !(message.mediaKeyTimestamp && $util.isInteger(message.mediaKeyTimestamp.low) && $util.isInteger(message.mediaKeyTimestamp.high))) + return "mediaKeyTimestamp: integer|Long expected"; + if (message.isFavorite != null && message.hasOwnProperty("isFavorite")) + if (typeof message.isFavorite !== "boolean") + return "isFavorite: boolean expected"; + return null; + }; + + /** + * Creates a FavoriteStickerAction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.FavoriteStickerAction + * @static + * @param {Object.} object Plain object + * @returns {proto.FavoriteStickerAction} FavoriteStickerAction + */ + FavoriteStickerAction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.FavoriteStickerAction) + return object; + var message = new $root.proto.FavoriteStickerAction(); + if (object.directPath != null) + message.directPath = String(object.directPath); + if (object.lastUploadTimestamp != null) + message.lastUploadTimestamp = String(object.lastUploadTimestamp); + if (object.handle != null) + message.handle = String(object.handle); + if (object.encFilehash != null) + message.encFilehash = String(object.encFilehash); + if (object.stickerHashWithoutMeta != null) + message.stickerHashWithoutMeta = String(object.stickerHashWithoutMeta); + if (object.mediaKey != null) + message.mediaKey = String(object.mediaKey); + if (object.mediaKeyTimestamp != null) + if ($util.Long) + (message.mediaKeyTimestamp = $util.Long.fromValue(object.mediaKeyTimestamp)).unsigned = false; + else if (typeof object.mediaKeyTimestamp === "string") + message.mediaKeyTimestamp = parseInt(object.mediaKeyTimestamp, 10); + else if (typeof object.mediaKeyTimestamp === "number") + message.mediaKeyTimestamp = object.mediaKeyTimestamp; + else if (typeof object.mediaKeyTimestamp === "object") + message.mediaKeyTimestamp = new $util.LongBits(object.mediaKeyTimestamp.low >>> 0, object.mediaKeyTimestamp.high >>> 0).toNumber(); + if (object.isFavorite != null) + message.isFavorite = Boolean(object.isFavorite); + return message; + }; + + /** + * Creates a plain object from a FavoriteStickerAction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.FavoriteStickerAction + * @static + * @param {proto.FavoriteStickerAction} message FavoriteStickerAction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + FavoriteStickerAction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.directPath = ""; + object.lastUploadTimestamp = ""; + object.handle = ""; + object.encFilehash = ""; + object.stickerHashWithoutMeta = ""; + object.mediaKey = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.mediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.mediaKeyTimestamp = options.longs === String ? "0" : 0; + object.isFavorite = false; + } + if (message.directPath != null && message.hasOwnProperty("directPath")) + object.directPath = message.directPath; + if (message.lastUploadTimestamp != null && message.hasOwnProperty("lastUploadTimestamp")) + object.lastUploadTimestamp = message.lastUploadTimestamp; + if (message.handle != null && message.hasOwnProperty("handle")) + object.handle = message.handle; + if (message.encFilehash != null && message.hasOwnProperty("encFilehash")) + object.encFilehash = message.encFilehash; + if (message.stickerHashWithoutMeta != null && message.hasOwnProperty("stickerHashWithoutMeta")) + object.stickerHashWithoutMeta = message.stickerHashWithoutMeta; + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + object.mediaKey = message.mediaKey; + if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp")) + if (typeof message.mediaKeyTimestamp === "number") + object.mediaKeyTimestamp = options.longs === String ? String(message.mediaKeyTimestamp) : message.mediaKeyTimestamp; + else + object.mediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.mediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.mediaKeyTimestamp.low >>> 0, message.mediaKeyTimestamp.high >>> 0).toNumber() : message.mediaKeyTimestamp; + if (message.isFavorite != null && message.hasOwnProperty("isFavorite")) + object.isFavorite = message.isFavorite; + return object; + }; + + /** + * Converts this FavoriteStickerAction to JSON. + * @function toJSON + * @memberof proto.FavoriteStickerAction + * @instance + * @returns {Object.} JSON object + */ + FavoriteStickerAction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return FavoriteStickerAction; + })(); + proto.ArchiveChatAction = (function() { /** @@ -11422,6 +11851,396 @@ $root.proto = (function() { return KeyExpiration; })(); + proto.PrimaryFeature = (function() { + + /** + * Properties of a PrimaryFeature. + * @memberof proto + * @interface IPrimaryFeature + * @property {Array.|null} [flags] PrimaryFeature flags + */ + + /** + * Constructs a new PrimaryFeature. + * @memberof proto + * @classdesc Represents a PrimaryFeature. + * @implements IPrimaryFeature + * @constructor + * @param {proto.IPrimaryFeature=} [properties] Properties to set + */ + function PrimaryFeature(properties) { + this.flags = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * PrimaryFeature flags. + * @member {Array.} flags + * @memberof proto.PrimaryFeature + * @instance + */ + PrimaryFeature.prototype.flags = $util.emptyArray; + + /** + * Creates a new PrimaryFeature instance using the specified properties. + * @function create + * @memberof proto.PrimaryFeature + * @static + * @param {proto.IPrimaryFeature=} [properties] Properties to set + * @returns {proto.PrimaryFeature} PrimaryFeature instance + */ + PrimaryFeature.create = function create(properties) { + return new PrimaryFeature(properties); + }; + + /** + * Encodes the specified PrimaryFeature message. Does not implicitly {@link proto.PrimaryFeature.verify|verify} messages. + * @function encode + * @memberof proto.PrimaryFeature + * @static + * @param {proto.IPrimaryFeature} message PrimaryFeature message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PrimaryFeature.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.flags != null && message.flags.length) + for (var i = 0; i < message.flags.length; ++i) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.flags[i]); + return writer; + }; + + /** + * Encodes the specified PrimaryFeature message, length delimited. Does not implicitly {@link proto.PrimaryFeature.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.PrimaryFeature + * @static + * @param {proto.IPrimaryFeature} message PrimaryFeature message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PrimaryFeature.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a PrimaryFeature message from the specified reader or buffer. + * @function decode + * @memberof proto.PrimaryFeature + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.PrimaryFeature} PrimaryFeature + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PrimaryFeature.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PrimaryFeature(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.flags && message.flags.length)) + message.flags = []; + message.flags.push(reader.string()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a PrimaryFeature message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.PrimaryFeature + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.PrimaryFeature} PrimaryFeature + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PrimaryFeature.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a PrimaryFeature message. + * @function verify + * @memberof proto.PrimaryFeature + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + PrimaryFeature.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.flags != null && message.hasOwnProperty("flags")) { + if (!Array.isArray(message.flags)) + return "flags: array expected"; + for (var i = 0; i < message.flags.length; ++i) + if (!$util.isString(message.flags[i])) + return "flags: string[] expected"; + } + return null; + }; + + /** + * Creates a PrimaryFeature message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.PrimaryFeature + * @static + * @param {Object.} object Plain object + * @returns {proto.PrimaryFeature} PrimaryFeature + */ + PrimaryFeature.fromObject = function fromObject(object) { + if (object instanceof $root.proto.PrimaryFeature) + return object; + var message = new $root.proto.PrimaryFeature(); + if (object.flags) { + if (!Array.isArray(object.flags)) + throw TypeError(".proto.PrimaryFeature.flags: array expected"); + message.flags = []; + for (var i = 0; i < object.flags.length; ++i) + message.flags[i] = String(object.flags[i]); + } + return message; + }; + + /** + * Creates a plain object from a PrimaryFeature message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.PrimaryFeature + * @static + * @param {proto.PrimaryFeature} message PrimaryFeature + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + PrimaryFeature.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.flags = []; + if (message.flags && message.flags.length) { + object.flags = []; + for (var j = 0; j < message.flags.length; ++j) + object.flags[j] = message.flags[j]; + } + return object; + }; + + /** + * Converts this PrimaryFeature to JSON. + * @function toJSON + * @memberof proto.PrimaryFeature + * @instance + * @returns {Object.} JSON object + */ + PrimaryFeature.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return PrimaryFeature; + })(); + + proto.AndroidUnsupportedActions = (function() { + + /** + * Properties of an AndroidUnsupportedActions. + * @memberof proto + * @interface IAndroidUnsupportedActions + * @property {boolean|null} [allowed] AndroidUnsupportedActions allowed + */ + + /** + * Constructs a new AndroidUnsupportedActions. + * @memberof proto + * @classdesc Represents an AndroidUnsupportedActions. + * @implements IAndroidUnsupportedActions + * @constructor + * @param {proto.IAndroidUnsupportedActions=} [properties] Properties to set + */ + function AndroidUnsupportedActions(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * AndroidUnsupportedActions allowed. + * @member {boolean} allowed + * @memberof proto.AndroidUnsupportedActions + * @instance + */ + AndroidUnsupportedActions.prototype.allowed = false; + + /** + * Creates a new AndroidUnsupportedActions instance using the specified properties. + * @function create + * @memberof proto.AndroidUnsupportedActions + * @static + * @param {proto.IAndroidUnsupportedActions=} [properties] Properties to set + * @returns {proto.AndroidUnsupportedActions} AndroidUnsupportedActions instance + */ + AndroidUnsupportedActions.create = function create(properties) { + return new AndroidUnsupportedActions(properties); + }; + + /** + * Encodes the specified AndroidUnsupportedActions message. Does not implicitly {@link proto.AndroidUnsupportedActions.verify|verify} messages. + * @function encode + * @memberof proto.AndroidUnsupportedActions + * @static + * @param {proto.IAndroidUnsupportedActions} message AndroidUnsupportedActions message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + AndroidUnsupportedActions.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.allowed != null && Object.hasOwnProperty.call(message, "allowed")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.allowed); + return writer; + }; + + /** + * Encodes the specified AndroidUnsupportedActions message, length delimited. Does not implicitly {@link proto.AndroidUnsupportedActions.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.AndroidUnsupportedActions + * @static + * @param {proto.IAndroidUnsupportedActions} message AndroidUnsupportedActions message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + AndroidUnsupportedActions.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an AndroidUnsupportedActions message from the specified reader or buffer. + * @function decode + * @memberof proto.AndroidUnsupportedActions + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.AndroidUnsupportedActions} AndroidUnsupportedActions + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + AndroidUnsupportedActions.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AndroidUnsupportedActions(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.allowed = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an AndroidUnsupportedActions message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.AndroidUnsupportedActions + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.AndroidUnsupportedActions} AndroidUnsupportedActions + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + AndroidUnsupportedActions.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an AndroidUnsupportedActions message. + * @function verify + * @memberof proto.AndroidUnsupportedActions + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + AndroidUnsupportedActions.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.allowed != null && message.hasOwnProperty("allowed")) + if (typeof message.allowed !== "boolean") + return "allowed: boolean expected"; + return null; + }; + + /** + * Creates an AndroidUnsupportedActions message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.AndroidUnsupportedActions + * @static + * @param {Object.} object Plain object + * @returns {proto.AndroidUnsupportedActions} AndroidUnsupportedActions + */ + AndroidUnsupportedActions.fromObject = function fromObject(object) { + if (object instanceof $root.proto.AndroidUnsupportedActions) + return object; + var message = new $root.proto.AndroidUnsupportedActions(); + if (object.allowed != null) + message.allowed = Boolean(object.allowed); + return message; + }; + + /** + * Creates a plain object from an AndroidUnsupportedActions message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.AndroidUnsupportedActions + * @static + * @param {proto.AndroidUnsupportedActions} message AndroidUnsupportedActions + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + AndroidUnsupportedActions.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.allowed = false; + if (message.allowed != null && message.hasOwnProperty("allowed")) + object.allowed = message.allowed; + return object; + }; + + /** + * Converts this AndroidUnsupportedActions to JSON. + * @function toJSON + * @memberof proto.AndroidUnsupportedActions + * @instance + * @returns {Object.} JSON object + */ + AndroidUnsupportedActions.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return AndroidUnsupportedActions; + })(); + proto.SyncActionValue = (function() { /** @@ -11449,6 +12268,9 @@ $root.proto = (function() { * @property {proto.IClearChatAction|null} [clearChatAction] SyncActionValue clearChatAction * @property {proto.IDeleteChatAction|null} [deleteChatAction] SyncActionValue deleteChatAction * @property {proto.IUnarchiveChatsSetting|null} [unarchiveChatsSetting] SyncActionValue unarchiveChatsSetting + * @property {proto.IPrimaryFeature|null} [primaryFeature] SyncActionValue primaryFeature + * @property {proto.IFavoriteStickerAction|null} [favoriteStickerAction] SyncActionValue favoriteStickerAction + * @property {proto.IAndroidUnsupportedActions|null} [androidUnsupportedActions] SyncActionValue androidUnsupportedActions */ /** @@ -11634,6 +12456,30 @@ $root.proto = (function() { */ SyncActionValue.prototype.unarchiveChatsSetting = null; + /** + * SyncActionValue primaryFeature. + * @member {proto.IPrimaryFeature|null|undefined} primaryFeature + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.primaryFeature = null; + + /** + * SyncActionValue favoriteStickerAction. + * @member {proto.IFavoriteStickerAction|null|undefined} favoriteStickerAction + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.favoriteStickerAction = null; + + /** + * SyncActionValue androidUnsupportedActions. + * @member {proto.IAndroidUnsupportedActions|null|undefined} androidUnsupportedActions + * @memberof proto.SyncActionValue + * @instance + */ + SyncActionValue.prototype.androidUnsupportedActions = null; + /** * Creates a new SyncActionValue instance using the specified properties. * @function create @@ -11700,6 +12546,12 @@ $root.proto = (function() { $root.proto.DeleteChatAction.encode(message.deleteChatAction, writer.uint32(/* id 22, wireType 2 =*/178).fork()).ldelim(); if (message.unarchiveChatsSetting != null && Object.hasOwnProperty.call(message, "unarchiveChatsSetting")) $root.proto.UnarchiveChatsSetting.encode(message.unarchiveChatsSetting, writer.uint32(/* id 23, wireType 2 =*/186).fork()).ldelim(); + if (message.primaryFeature != null && Object.hasOwnProperty.call(message, "primaryFeature")) + $root.proto.PrimaryFeature.encode(message.primaryFeature, writer.uint32(/* id 24, wireType 2 =*/194).fork()).ldelim(); + if (message.favoriteStickerAction != null && Object.hasOwnProperty.call(message, "favoriteStickerAction")) + $root.proto.FavoriteStickerAction.encode(message.favoriteStickerAction, writer.uint32(/* id 25, wireType 2 =*/202).fork()).ldelim(); + if (message.androidUnsupportedActions != null && Object.hasOwnProperty.call(message, "androidUnsupportedActions")) + $root.proto.AndroidUnsupportedActions.encode(message.androidUnsupportedActions, writer.uint32(/* id 26, wireType 2 =*/210).fork()).ldelim(); return writer; }; @@ -11797,6 +12649,15 @@ $root.proto = (function() { case 23: message.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.decode(reader, reader.uint32()); break; + case 24: + message.primaryFeature = $root.proto.PrimaryFeature.decode(reader, reader.uint32()); + break; + case 25: + message.favoriteStickerAction = $root.proto.FavoriteStickerAction.decode(reader, reader.uint32()); + break; + case 26: + message.androidUnsupportedActions = $root.proto.AndroidUnsupportedActions.decode(reader, reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -11935,6 +12796,21 @@ $root.proto = (function() { if (error) return "unarchiveChatsSetting." + error; } + if (message.primaryFeature != null && message.hasOwnProperty("primaryFeature")) { + var error = $root.proto.PrimaryFeature.verify(message.primaryFeature); + if (error) + return "primaryFeature." + error; + } + if (message.favoriteStickerAction != null && message.hasOwnProperty("favoriteStickerAction")) { + var error = $root.proto.FavoriteStickerAction.verify(message.favoriteStickerAction); + if (error) + return "favoriteStickerAction." + error; + } + if (message.androidUnsupportedActions != null && message.hasOwnProperty("androidUnsupportedActions")) { + var error = $root.proto.AndroidUnsupportedActions.verify(message.androidUnsupportedActions); + if (error) + return "androidUnsupportedActions." + error; + } return null; }; @@ -12059,6 +12935,21 @@ $root.proto = (function() { throw TypeError(".proto.SyncActionValue.unarchiveChatsSetting: object expected"); message.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.fromObject(object.unarchiveChatsSetting); } + if (object.primaryFeature != null) { + if (typeof object.primaryFeature !== "object") + throw TypeError(".proto.SyncActionValue.primaryFeature: object expected"); + message.primaryFeature = $root.proto.PrimaryFeature.fromObject(object.primaryFeature); + } + if (object.favoriteStickerAction != null) { + if (typeof object.favoriteStickerAction !== "object") + throw TypeError(".proto.SyncActionValue.favoriteStickerAction: object expected"); + message.favoriteStickerAction = $root.proto.FavoriteStickerAction.fromObject(object.favoriteStickerAction); + } + if (object.androidUnsupportedActions != null) { + if (typeof object.androidUnsupportedActions !== "object") + throw TypeError(".proto.SyncActionValue.androidUnsupportedActions: object expected"); + message.androidUnsupportedActions = $root.proto.AndroidUnsupportedActions.fromObject(object.androidUnsupportedActions); + } return message; }; @@ -12101,6 +12992,9 @@ $root.proto = (function() { object.clearChatAction = null; object.deleteChatAction = null; object.unarchiveChatsSetting = null; + object.primaryFeature = null; + object.favoriteStickerAction = null; + object.androidUnsupportedActions = null; } if (message.timestamp != null && message.hasOwnProperty("timestamp")) if (typeof message.timestamp === "number") @@ -12147,6 +13041,12 @@ $root.proto = (function() { object.deleteChatAction = $root.proto.DeleteChatAction.toObject(message.deleteChatAction, options); if (message.unarchiveChatsSetting != null && message.hasOwnProperty("unarchiveChatsSetting")) object.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.toObject(message.unarchiveChatsSetting, options); + if (message.primaryFeature != null && message.hasOwnProperty("primaryFeature")) + object.primaryFeature = $root.proto.PrimaryFeature.toObject(message.primaryFeature, options); + if (message.favoriteStickerAction != null && message.hasOwnProperty("favoriteStickerAction")) + object.favoriteStickerAction = $root.proto.FavoriteStickerAction.toObject(message.favoriteStickerAction, options); + if (message.androidUnsupportedActions != null && message.hasOwnProperty("androidUnsupportedActions")) + object.androidUnsupportedActions = $root.proto.AndroidUnsupportedActions.toObject(message.androidUnsupportedActions, options); return object; }; @@ -15798,7 +16698,6 @@ $root.proto = (function() { * @interface IMsgOpaqueData * @property {string|null} [body] MsgOpaqueData body * @property {string|null} [caption] MsgOpaqueData caption - * @property {string|null} [clientUrl] MsgOpaqueData clientUrl * @property {number|null} [lng] MsgOpaqueData lng * @property {number|null} [lat] MsgOpaqueData lat * @property {number|null} [paymentAmount1000] MsgOpaqueData paymentAmount1000 @@ -15807,6 +16706,9 @@ $root.proto = (function() { * @property {string|null} [matchedText] MsgOpaqueData matchedText * @property {string|null} [title] MsgOpaqueData title * @property {string|null} [description] MsgOpaqueData description + * @property {Uint8Array|null} [futureproofBuffer] MsgOpaqueData futureproofBuffer + * @property {string|null} [clientUrl] MsgOpaqueData clientUrl + * @property {string|null} [loc] MsgOpaqueData loc */ /** @@ -15840,14 +16742,6 @@ $root.proto = (function() { */ MsgOpaqueData.prototype.caption = ""; - /** - * MsgOpaqueData clientUrl. - * @member {string} clientUrl - * @memberof proto.MsgOpaqueData - * @instance - */ - MsgOpaqueData.prototype.clientUrl = ""; - /** * MsgOpaqueData lng. * @member {number} lng @@ -15912,6 +16806,30 @@ $root.proto = (function() { */ MsgOpaqueData.prototype.description = ""; + /** + * MsgOpaqueData futureproofBuffer. + * @member {Uint8Array} futureproofBuffer + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.futureproofBuffer = $util.newBuffer([]); + + /** + * MsgOpaqueData clientUrl. + * @member {string} clientUrl + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.clientUrl = ""; + + /** + * MsgOpaqueData loc. + * @member {string} loc + * @memberof proto.MsgOpaqueData + * @instance + */ + MsgOpaqueData.prototype.loc = ""; + /** * Creates a new MsgOpaqueData instance using the specified properties. * @function create @@ -15940,8 +16858,6 @@ $root.proto = (function() { writer.uint32(/* id 1, wireType 2 =*/10).string(message.body); if (message.caption != null && Object.hasOwnProperty.call(message, "caption")) writer.uint32(/* id 3, wireType 2 =*/26).string(message.caption); - if (message.clientUrl != null && Object.hasOwnProperty.call(message, "clientUrl")) - writer.uint32(/* id 4, wireType 2 =*/34).string(message.clientUrl); if (message.lng != null && Object.hasOwnProperty.call(message, "lng")) writer.uint32(/* id 5, wireType 1 =*/41).double(message.lng); if (message.lat != null && Object.hasOwnProperty.call(message, "lat")) @@ -15958,6 +16874,12 @@ $root.proto = (function() { writer.uint32(/* id 12, wireType 2 =*/98).string(message.title); if (message.description != null && Object.hasOwnProperty.call(message, "description")) writer.uint32(/* id 13, wireType 2 =*/106).string(message.description); + if (message.futureproofBuffer != null && Object.hasOwnProperty.call(message, "futureproofBuffer")) + writer.uint32(/* id 14, wireType 2 =*/114).bytes(message.futureproofBuffer); + if (message.clientUrl != null && Object.hasOwnProperty.call(message, "clientUrl")) + writer.uint32(/* id 15, wireType 2 =*/122).string(message.clientUrl); + if (message.loc != null && Object.hasOwnProperty.call(message, "loc")) + writer.uint32(/* id 16, wireType 2 =*/130).string(message.loc); return writer; }; @@ -15998,9 +16920,6 @@ $root.proto = (function() { case 3: message.caption = reader.string(); break; - case 4: - message.clientUrl = reader.string(); - break; case 5: message.lng = reader.double(); break; @@ -16025,6 +16944,15 @@ $root.proto = (function() { case 13: message.description = reader.string(); break; + case 14: + message.futureproofBuffer = reader.bytes(); + break; + case 15: + message.clientUrl = reader.string(); + break; + case 16: + message.loc = reader.string(); + break; default: reader.skipType(tag & 7); break; @@ -16066,9 +16994,6 @@ $root.proto = (function() { if (message.caption != null && message.hasOwnProperty("caption")) if (!$util.isString(message.caption)) return "caption: string expected"; - if (message.clientUrl != null && message.hasOwnProperty("clientUrl")) - if (!$util.isString(message.clientUrl)) - return "clientUrl: string expected"; if (message.lng != null && message.hasOwnProperty("lng")) if (typeof message.lng !== "number") return "lng: number expected"; @@ -16093,6 +17018,15 @@ $root.proto = (function() { if (message.description != null && message.hasOwnProperty("description")) if (!$util.isString(message.description)) return "description: string expected"; + if (message.futureproofBuffer != null && message.hasOwnProperty("futureproofBuffer")) + if (!(message.futureproofBuffer && typeof message.futureproofBuffer.length === "number" || $util.isString(message.futureproofBuffer))) + return "futureproofBuffer: buffer expected"; + if (message.clientUrl != null && message.hasOwnProperty("clientUrl")) + if (!$util.isString(message.clientUrl)) + return "clientUrl: string expected"; + if (message.loc != null && message.hasOwnProperty("loc")) + if (!$util.isString(message.loc)) + return "loc: string expected"; return null; }; @@ -16112,8 +17046,6 @@ $root.proto = (function() { message.body = String(object.body); if (object.caption != null) message.caption = String(object.caption); - if (object.clientUrl != null) - message.clientUrl = String(object.clientUrl); if (object.lng != null) message.lng = Number(object.lng); if (object.lat != null) @@ -16130,6 +17062,15 @@ $root.proto = (function() { message.title = String(object.title); if (object.description != null) message.description = String(object.description); + if (object.futureproofBuffer != null) + if (typeof object.futureproofBuffer === "string") + $util.base64.decode(object.futureproofBuffer, message.futureproofBuffer = $util.newBuffer($util.base64.length(object.futureproofBuffer)), 0); + else if (object.futureproofBuffer.length) + message.futureproofBuffer = object.futureproofBuffer; + if (object.clientUrl != null) + message.clientUrl = String(object.clientUrl); + if (object.loc != null) + message.loc = String(object.loc); return message; }; @@ -16149,7 +17090,6 @@ $root.proto = (function() { if (options.defaults) { object.body = ""; object.caption = ""; - object.clientUrl = ""; object.lng = 0; object.lat = 0; object.paymentAmount1000 = 0; @@ -16158,13 +17098,20 @@ $root.proto = (function() { object.matchedText = ""; object.title = ""; object.description = ""; + if (options.bytes === String) + object.futureproofBuffer = ""; + else { + object.futureproofBuffer = []; + if (options.bytes !== Array) + object.futureproofBuffer = $util.newBuffer(object.futureproofBuffer); + } + object.clientUrl = ""; + object.loc = ""; } if (message.body != null && message.hasOwnProperty("body")) object.body = message.body; if (message.caption != null && message.hasOwnProperty("caption")) object.caption = message.caption; - if (message.clientUrl != null && message.hasOwnProperty("clientUrl")) - object.clientUrl = message.clientUrl; if (message.lng != null && message.hasOwnProperty("lng")) object.lng = options.json && !isFinite(message.lng) ? String(message.lng) : message.lng; if (message.lat != null && message.hasOwnProperty("lat")) @@ -16181,6 +17128,12 @@ $root.proto = (function() { object.title = message.title; if (message.description != null && message.hasOwnProperty("description")) object.description = message.description; + if (message.futureproofBuffer != null && message.hasOwnProperty("futureproofBuffer")) + object.futureproofBuffer = options.bytes === String ? $util.base64.encode(message.futureproofBuffer, 0, message.futureproofBuffer.length) : options.bytes === Array ? Array.prototype.slice.call(message.futureproofBuffer) : message.futureproofBuffer; + if (message.clientUrl != null && message.hasOwnProperty("clientUrl")) + object.clientUrl = message.clientUrl; + if (message.loc != null && message.hasOwnProperty("loc")) + object.loc = message.loc; return object; }; @@ -16418,6 +17371,720 @@ $root.proto = (function() { return MsgRowOpaqueData; })(); + proto.GlobalSettings = (function() { + + /** + * Properties of a GlobalSettings. + * @memberof proto + * @interface IGlobalSettings + * @property {proto.IWallpaperSettings|null} [lightThemeWallpaper] GlobalSettings lightThemeWallpaper + * @property {proto.MediaVisibility|null} [mediaVisibility] GlobalSettings mediaVisibility + * @property {proto.IWallpaperSettings|null} [darkThemeWallpaper] GlobalSettings darkThemeWallpaper + */ + + /** + * Constructs a new GlobalSettings. + * @memberof proto + * @classdesc Represents a GlobalSettings. + * @implements IGlobalSettings + * @constructor + * @param {proto.IGlobalSettings=} [properties] Properties to set + */ + function GlobalSettings(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * GlobalSettings lightThemeWallpaper. + * @member {proto.IWallpaperSettings|null|undefined} lightThemeWallpaper + * @memberof proto.GlobalSettings + * @instance + */ + GlobalSettings.prototype.lightThemeWallpaper = null; + + /** + * GlobalSettings mediaVisibility. + * @member {proto.MediaVisibility} mediaVisibility + * @memberof proto.GlobalSettings + * @instance + */ + GlobalSettings.prototype.mediaVisibility = 0; + + /** + * GlobalSettings darkThemeWallpaper. + * @member {proto.IWallpaperSettings|null|undefined} darkThemeWallpaper + * @memberof proto.GlobalSettings + * @instance + */ + GlobalSettings.prototype.darkThemeWallpaper = null; + + /** + * Creates a new GlobalSettings instance using the specified properties. + * @function create + * @memberof proto.GlobalSettings + * @static + * @param {proto.IGlobalSettings=} [properties] Properties to set + * @returns {proto.GlobalSettings} GlobalSettings instance + */ + GlobalSettings.create = function create(properties) { + return new GlobalSettings(properties); + }; + + /** + * Encodes the specified GlobalSettings message. Does not implicitly {@link proto.GlobalSettings.verify|verify} messages. + * @function encode + * @memberof proto.GlobalSettings + * @static + * @param {proto.IGlobalSettings} message GlobalSettings message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GlobalSettings.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.lightThemeWallpaper != null && Object.hasOwnProperty.call(message, "lightThemeWallpaper")) + $root.proto.WallpaperSettings.encode(message.lightThemeWallpaper, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.mediaVisibility != null && Object.hasOwnProperty.call(message, "mediaVisibility")) + writer.uint32(/* id 2, wireType 0 =*/16).int32(message.mediaVisibility); + if (message.darkThemeWallpaper != null && Object.hasOwnProperty.call(message, "darkThemeWallpaper")) + $root.proto.WallpaperSettings.encode(message.darkThemeWallpaper, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified GlobalSettings message, length delimited. Does not implicitly {@link proto.GlobalSettings.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.GlobalSettings + * @static + * @param {proto.IGlobalSettings} message GlobalSettings message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GlobalSettings.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a GlobalSettings message from the specified reader or buffer. + * @function decode + * @memberof proto.GlobalSettings + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.GlobalSettings} GlobalSettings + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GlobalSettings.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.GlobalSettings(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.lightThemeWallpaper = $root.proto.WallpaperSettings.decode(reader, reader.uint32()); + break; + case 2: + message.mediaVisibility = reader.int32(); + break; + case 3: + message.darkThemeWallpaper = $root.proto.WallpaperSettings.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a GlobalSettings message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.GlobalSettings + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.GlobalSettings} GlobalSettings + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GlobalSettings.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a GlobalSettings message. + * @function verify + * @memberof proto.GlobalSettings + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + GlobalSettings.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.lightThemeWallpaper != null && message.hasOwnProperty("lightThemeWallpaper")) { + var error = $root.proto.WallpaperSettings.verify(message.lightThemeWallpaper); + if (error) + return "lightThemeWallpaper." + error; + } + if (message.mediaVisibility != null && message.hasOwnProperty("mediaVisibility")) + switch (message.mediaVisibility) { + default: + return "mediaVisibility: enum value expected"; + case 0: + case 1: + case 2: + break; + } + if (message.darkThemeWallpaper != null && message.hasOwnProperty("darkThemeWallpaper")) { + var error = $root.proto.WallpaperSettings.verify(message.darkThemeWallpaper); + if (error) + return "darkThemeWallpaper." + error; + } + return null; + }; + + /** + * Creates a GlobalSettings message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.GlobalSettings + * @static + * @param {Object.} object Plain object + * @returns {proto.GlobalSettings} GlobalSettings + */ + GlobalSettings.fromObject = function fromObject(object) { + if (object instanceof $root.proto.GlobalSettings) + return object; + var message = new $root.proto.GlobalSettings(); + if (object.lightThemeWallpaper != null) { + if (typeof object.lightThemeWallpaper !== "object") + throw TypeError(".proto.GlobalSettings.lightThemeWallpaper: object expected"); + message.lightThemeWallpaper = $root.proto.WallpaperSettings.fromObject(object.lightThemeWallpaper); + } + switch (object.mediaVisibility) { + case "DEFAULT": + case 0: + message.mediaVisibility = 0; + break; + case "OFF": + case 1: + message.mediaVisibility = 1; + break; + case "ON": + case 2: + message.mediaVisibility = 2; + break; + } + if (object.darkThemeWallpaper != null) { + if (typeof object.darkThemeWallpaper !== "object") + throw TypeError(".proto.GlobalSettings.darkThemeWallpaper: object expected"); + message.darkThemeWallpaper = $root.proto.WallpaperSettings.fromObject(object.darkThemeWallpaper); + } + return message; + }; + + /** + * Creates a plain object from a GlobalSettings message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.GlobalSettings + * @static + * @param {proto.GlobalSettings} message GlobalSettings + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + GlobalSettings.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.lightThemeWallpaper = null; + object.mediaVisibility = options.enums === String ? "DEFAULT" : 0; + object.darkThemeWallpaper = null; + } + if (message.lightThemeWallpaper != null && message.hasOwnProperty("lightThemeWallpaper")) + object.lightThemeWallpaper = $root.proto.WallpaperSettings.toObject(message.lightThemeWallpaper, options); + if (message.mediaVisibility != null && message.hasOwnProperty("mediaVisibility")) + object.mediaVisibility = options.enums === String ? $root.proto.MediaVisibility[message.mediaVisibility] : message.mediaVisibility; + if (message.darkThemeWallpaper != null && message.hasOwnProperty("darkThemeWallpaper")) + object.darkThemeWallpaper = $root.proto.WallpaperSettings.toObject(message.darkThemeWallpaper, options); + return object; + }; + + /** + * Converts this GlobalSettings to JSON. + * @function toJSON + * @memberof proto.GlobalSettings + * @instance + * @returns {Object.} JSON object + */ + GlobalSettings.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return GlobalSettings; + })(); + + proto.WallpaperSettings = (function() { + + /** + * Properties of a WallpaperSettings. + * @memberof proto + * @interface IWallpaperSettings + * @property {string|null} [filename] WallpaperSettings filename + * @property {number|null} [opacity] WallpaperSettings opacity + */ + + /** + * Constructs a new WallpaperSettings. + * @memberof proto + * @classdesc Represents a WallpaperSettings. + * @implements IWallpaperSettings + * @constructor + * @param {proto.IWallpaperSettings=} [properties] Properties to set + */ + function WallpaperSettings(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * WallpaperSettings filename. + * @member {string} filename + * @memberof proto.WallpaperSettings + * @instance + */ + WallpaperSettings.prototype.filename = ""; + + /** + * WallpaperSettings opacity. + * @member {number} opacity + * @memberof proto.WallpaperSettings + * @instance + */ + WallpaperSettings.prototype.opacity = 0; + + /** + * Creates a new WallpaperSettings instance using the specified properties. + * @function create + * @memberof proto.WallpaperSettings + * @static + * @param {proto.IWallpaperSettings=} [properties] Properties to set + * @returns {proto.WallpaperSettings} WallpaperSettings instance + */ + WallpaperSettings.create = function create(properties) { + return new WallpaperSettings(properties); + }; + + /** + * Encodes the specified WallpaperSettings message. Does not implicitly {@link proto.WallpaperSettings.verify|verify} messages. + * @function encode + * @memberof proto.WallpaperSettings + * @static + * @param {proto.IWallpaperSettings} message WallpaperSettings message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WallpaperSettings.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.filename != null && Object.hasOwnProperty.call(message, "filename")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.filename); + if (message.opacity != null && Object.hasOwnProperty.call(message, "opacity")) + writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.opacity); + return writer; + }; + + /** + * Encodes the specified WallpaperSettings message, length delimited. Does not implicitly {@link proto.WallpaperSettings.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.WallpaperSettings + * @static + * @param {proto.IWallpaperSettings} message WallpaperSettings message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WallpaperSettings.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a WallpaperSettings message from the specified reader or buffer. + * @function decode + * @memberof proto.WallpaperSettings + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.WallpaperSettings} WallpaperSettings + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WallpaperSettings.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WallpaperSettings(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.filename = reader.string(); + break; + case 2: + message.opacity = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a WallpaperSettings message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.WallpaperSettings + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.WallpaperSettings} WallpaperSettings + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WallpaperSettings.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a WallpaperSettings message. + * @function verify + * @memberof proto.WallpaperSettings + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + WallpaperSettings.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.filename != null && message.hasOwnProperty("filename")) + if (!$util.isString(message.filename)) + return "filename: string expected"; + if (message.opacity != null && message.hasOwnProperty("opacity")) + if (!$util.isInteger(message.opacity)) + return "opacity: integer expected"; + return null; + }; + + /** + * Creates a WallpaperSettings message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.WallpaperSettings + * @static + * @param {Object.} object Plain object + * @returns {proto.WallpaperSettings} WallpaperSettings + */ + WallpaperSettings.fromObject = function fromObject(object) { + if (object instanceof $root.proto.WallpaperSettings) + return object; + var message = new $root.proto.WallpaperSettings(); + if (object.filename != null) + message.filename = String(object.filename); + if (object.opacity != null) + message.opacity = object.opacity >>> 0; + return message; + }; + + /** + * Creates a plain object from a WallpaperSettings message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.WallpaperSettings + * @static + * @param {proto.WallpaperSettings} message WallpaperSettings + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + WallpaperSettings.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.filename = ""; + object.opacity = 0; + } + if (message.filename != null && message.hasOwnProperty("filename")) + object.filename = message.filename; + if (message.opacity != null && message.hasOwnProperty("opacity")) + object.opacity = message.opacity; + return object; + }; + + /** + * Converts this WallpaperSettings to JSON. + * @function toJSON + * @memberof proto.WallpaperSettings + * @instance + * @returns {Object.} JSON object + */ + WallpaperSettings.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return WallpaperSettings; + })(); + + proto.GroupParticipant = (function() { + + /** + * Properties of a GroupParticipant. + * @memberof proto + * @interface IGroupParticipant + * @property {string} userJid GroupParticipant userJid + * @property {proto.GroupParticipant.GroupParticipantRank|null} [rank] GroupParticipant rank + */ + + /** + * Constructs a new GroupParticipant. + * @memberof proto + * @classdesc Represents a GroupParticipant. + * @implements IGroupParticipant + * @constructor + * @param {proto.IGroupParticipant=} [properties] Properties to set + */ + function GroupParticipant(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * GroupParticipant userJid. + * @member {string} userJid + * @memberof proto.GroupParticipant + * @instance + */ + GroupParticipant.prototype.userJid = ""; + + /** + * GroupParticipant rank. + * @member {proto.GroupParticipant.GroupParticipantRank} rank + * @memberof proto.GroupParticipant + * @instance + */ + GroupParticipant.prototype.rank = 0; + + /** + * Creates a new GroupParticipant instance using the specified properties. + * @function create + * @memberof proto.GroupParticipant + * @static + * @param {proto.IGroupParticipant=} [properties] Properties to set + * @returns {proto.GroupParticipant} GroupParticipant instance + */ + GroupParticipant.create = function create(properties) { + return new GroupParticipant(properties); + }; + + /** + * Encodes the specified GroupParticipant message. Does not implicitly {@link proto.GroupParticipant.verify|verify} messages. + * @function encode + * @memberof proto.GroupParticipant + * @static + * @param {proto.IGroupParticipant} message GroupParticipant message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GroupParticipant.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + writer.uint32(/* id 1, wireType 2 =*/10).string(message.userJid); + if (message.rank != null && Object.hasOwnProperty.call(message, "rank")) + writer.uint32(/* id 2, wireType 0 =*/16).int32(message.rank); + return writer; + }; + + /** + * Encodes the specified GroupParticipant message, length delimited. Does not implicitly {@link proto.GroupParticipant.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.GroupParticipant + * @static + * @param {proto.IGroupParticipant} message GroupParticipant message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GroupParticipant.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a GroupParticipant message from the specified reader or buffer. + * @function decode + * @memberof proto.GroupParticipant + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.GroupParticipant} GroupParticipant + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GroupParticipant.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.GroupParticipant(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.userJid = reader.string(); + break; + case 2: + message.rank = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + if (!message.hasOwnProperty("userJid")) + throw $util.ProtocolError("missing required 'userJid'", { instance: message }); + return message; + }; + + /** + * Decodes a GroupParticipant message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.GroupParticipant + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.GroupParticipant} GroupParticipant + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GroupParticipant.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a GroupParticipant message. + * @function verify + * @memberof proto.GroupParticipant + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + GroupParticipant.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isString(message.userJid)) + return "userJid: string expected"; + if (message.rank != null && message.hasOwnProperty("rank")) + switch (message.rank) { + default: + return "rank: enum value expected"; + case 0: + case 1: + case 2: + break; + } + return null; + }; + + /** + * Creates a GroupParticipant message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.GroupParticipant + * @static + * @param {Object.} object Plain object + * @returns {proto.GroupParticipant} GroupParticipant + */ + GroupParticipant.fromObject = function fromObject(object) { + if (object instanceof $root.proto.GroupParticipant) + return object; + var message = new $root.proto.GroupParticipant(); + if (object.userJid != null) + message.userJid = String(object.userJid); + switch (object.rank) { + case "REGULAR": + case 0: + message.rank = 0; + break; + case "ADMIN": + case 1: + message.rank = 1; + break; + case "SUPERADMIN": + case 2: + message.rank = 2; + break; + } + return message; + }; + + /** + * Creates a plain object from a GroupParticipant message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.GroupParticipant + * @static + * @param {proto.GroupParticipant} message GroupParticipant + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + GroupParticipant.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.userJid = ""; + object.rank = options.enums === String ? "REGULAR" : 0; + } + if (message.userJid != null && message.hasOwnProperty("userJid")) + object.userJid = message.userJid; + if (message.rank != null && message.hasOwnProperty("rank")) + object.rank = options.enums === String ? $root.proto.GroupParticipant.GroupParticipantRank[message.rank] : message.rank; + return object; + }; + + /** + * Converts this GroupParticipant to JSON. + * @function toJSON + * @memberof proto.GroupParticipant + * @instance + * @returns {Object.} JSON object + */ + GroupParticipant.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * GroupParticipantRank enum. + * @name proto.GroupParticipant.GroupParticipantRank + * @enum {number} + * @property {number} REGULAR=0 REGULAR value + * @property {number} ADMIN=1 ADMIN value + * @property {number} SUPERADMIN=2 SUPERADMIN value + */ + GroupParticipant.GroupParticipantRank = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "REGULAR"] = 0; + values[valuesById[1] = "ADMIN"] = 1; + values[valuesById[2] = "SUPERADMIN"] = 2; + return values; + })(); + + return GroupParticipant; + })(); + proto.Pushname = (function() { /** @@ -16878,6 +18545,20 @@ $root.proto = (function() { * @property {string|null} [name] Conversation name * @property {string|null} [pHash] Conversation pHash * @property {boolean|null} [notSpam] Conversation notSpam + * @property {boolean|null} [archived] Conversation archived + * @property {proto.IDisappearingMode|null} [disappearingMode] Conversation disappearingMode + * @property {number|null} [unreadMentionCount] Conversation unreadMentionCount + * @property {boolean|null} [markedAsUnread] Conversation markedAsUnread + * @property {Array.|null} [participant] Conversation participant + * @property {Uint8Array|null} [tcToken] Conversation tcToken + * @property {number|Long|null} [tcTokenTimestamp] Conversation tcTokenTimestamp + * @property {Uint8Array|null} [contactPrimaryIdentityKey] Conversation contactPrimaryIdentityKey + * @property {number|null} [pinned] Conversation pinned + * @property {number|Long|null} [muteEndTime] Conversation muteEndTime + * @property {proto.IWallpaperSettings|null} [wallpaper] Conversation wallpaper + * @property {proto.MediaVisibility|null} [mediaVisibility] Conversation mediaVisibility + * @property {number|Long|null} [tcTokenSenderTimestamp] Conversation tcTokenSenderTimestamp + * @property {boolean|null} [suspended] Conversation suspended */ /** @@ -16890,6 +18571,7 @@ $root.proto = (function() { */ function Conversation(properties) { this.messages = []; + this.participant = []; if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -17016,6 +18698,118 @@ $root.proto = (function() { */ Conversation.prototype.notSpam = false; + /** + * Conversation archived. + * @member {boolean} archived + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.archived = false; + + /** + * Conversation disappearingMode. + * @member {proto.IDisappearingMode|null|undefined} disappearingMode + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.disappearingMode = null; + + /** + * Conversation unreadMentionCount. + * @member {number} unreadMentionCount + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.unreadMentionCount = 0; + + /** + * Conversation markedAsUnread. + * @member {boolean} markedAsUnread + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.markedAsUnread = false; + + /** + * Conversation participant. + * @member {Array.} participant + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.participant = $util.emptyArray; + + /** + * Conversation tcToken. + * @member {Uint8Array} tcToken + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.tcToken = $util.newBuffer([]); + + /** + * Conversation tcTokenTimestamp. + * @member {number|Long} tcTokenTimestamp + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.tcTokenTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Conversation contactPrimaryIdentityKey. + * @member {Uint8Array} contactPrimaryIdentityKey + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.contactPrimaryIdentityKey = $util.newBuffer([]); + + /** + * Conversation pinned. + * @member {number} pinned + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.pinned = 0; + + /** + * Conversation muteEndTime. + * @member {number|Long} muteEndTime + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.muteEndTime = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Conversation wallpaper. + * @member {proto.IWallpaperSettings|null|undefined} wallpaper + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.wallpaper = null; + + /** + * Conversation mediaVisibility. + * @member {proto.MediaVisibility} mediaVisibility + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.mediaVisibility = 0; + + /** + * Conversation tcTokenSenderTimestamp. + * @member {number|Long} tcTokenSenderTimestamp + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.tcTokenSenderTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * Conversation suspended. + * @member {boolean} suspended + * @memberof proto.Conversation + * @instance + */ + Conversation.prototype.suspended = false; + /** * Creates a new Conversation instance using the specified properties. * @function create @@ -17070,6 +18864,35 @@ $root.proto = (function() { writer.uint32(/* id 14, wireType 2 =*/114).string(message.pHash); if (message.notSpam != null && Object.hasOwnProperty.call(message, "notSpam")) writer.uint32(/* id 15, wireType 0 =*/120).bool(message.notSpam); + if (message.archived != null && Object.hasOwnProperty.call(message, "archived")) + writer.uint32(/* id 16, wireType 0 =*/128).bool(message.archived); + if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode")) + $root.proto.DisappearingMode.encode(message.disappearingMode, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim(); + if (message.unreadMentionCount != null && Object.hasOwnProperty.call(message, "unreadMentionCount")) + writer.uint32(/* id 18, wireType 0 =*/144).uint32(message.unreadMentionCount); + if (message.markedAsUnread != null && Object.hasOwnProperty.call(message, "markedAsUnread")) + writer.uint32(/* id 19, wireType 0 =*/152).bool(message.markedAsUnread); + if (message.participant != null && message.participant.length) + for (var i = 0; i < message.participant.length; ++i) + $root.proto.GroupParticipant.encode(message.participant[i], writer.uint32(/* id 20, wireType 2 =*/162).fork()).ldelim(); + if (message.tcToken != null && Object.hasOwnProperty.call(message, "tcToken")) + writer.uint32(/* id 21, wireType 2 =*/170).bytes(message.tcToken); + if (message.tcTokenTimestamp != null && Object.hasOwnProperty.call(message, "tcTokenTimestamp")) + writer.uint32(/* id 22, wireType 0 =*/176).uint64(message.tcTokenTimestamp); + if (message.contactPrimaryIdentityKey != null && Object.hasOwnProperty.call(message, "contactPrimaryIdentityKey")) + writer.uint32(/* id 23, wireType 2 =*/186).bytes(message.contactPrimaryIdentityKey); + if (message.pinned != null && Object.hasOwnProperty.call(message, "pinned")) + writer.uint32(/* id 24, wireType 0 =*/192).uint32(message.pinned); + if (message.muteEndTime != null && Object.hasOwnProperty.call(message, "muteEndTime")) + writer.uint32(/* id 25, wireType 0 =*/200).uint64(message.muteEndTime); + if (message.wallpaper != null && Object.hasOwnProperty.call(message, "wallpaper")) + $root.proto.WallpaperSettings.encode(message.wallpaper, writer.uint32(/* id 26, wireType 2 =*/210).fork()).ldelim(); + if (message.mediaVisibility != null && Object.hasOwnProperty.call(message, "mediaVisibility")) + writer.uint32(/* id 27, wireType 0 =*/216).int32(message.mediaVisibility); + if (message.tcTokenSenderTimestamp != null && Object.hasOwnProperty.call(message, "tcTokenSenderTimestamp")) + writer.uint32(/* id 28, wireType 0 =*/224).uint64(message.tcTokenSenderTimestamp); + if (message.suspended != null && Object.hasOwnProperty.call(message, "suspended")) + writer.uint32(/* id 29, wireType 0 =*/232).bool(message.suspended); return writer; }; @@ -17151,6 +18974,50 @@ $root.proto = (function() { case 15: message.notSpam = reader.bool(); break; + case 16: + message.archived = reader.bool(); + break; + case 17: + message.disappearingMode = $root.proto.DisappearingMode.decode(reader, reader.uint32()); + break; + case 18: + message.unreadMentionCount = reader.uint32(); + break; + case 19: + message.markedAsUnread = reader.bool(); + break; + case 20: + if (!(message.participant && message.participant.length)) + message.participant = []; + message.participant.push($root.proto.GroupParticipant.decode(reader, reader.uint32())); + break; + case 21: + message.tcToken = reader.bytes(); + break; + case 22: + message.tcTokenTimestamp = reader.uint64(); + break; + case 23: + message.contactPrimaryIdentityKey = reader.bytes(); + break; + case 24: + message.pinned = reader.uint32(); + break; + case 25: + message.muteEndTime = reader.uint64(); + break; + case 26: + message.wallpaper = $root.proto.WallpaperSettings.decode(reader, reader.uint32()); + break; + case 27: + message.mediaVisibility = reader.int32(); + break; + case 28: + message.tcTokenSenderTimestamp = reader.uint64(); + break; + case 29: + message.suspended = reader.bool(); + break; default: reader.skipType(tag & 7); break; @@ -17243,6 +19110,64 @@ $root.proto = (function() { if (message.notSpam != null && message.hasOwnProperty("notSpam")) if (typeof message.notSpam !== "boolean") return "notSpam: boolean expected"; + if (message.archived != null && message.hasOwnProperty("archived")) + if (typeof message.archived !== "boolean") + return "archived: boolean expected"; + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) { + var error = $root.proto.DisappearingMode.verify(message.disappearingMode); + if (error) + return "disappearingMode." + error; + } + if (message.unreadMentionCount != null && message.hasOwnProperty("unreadMentionCount")) + if (!$util.isInteger(message.unreadMentionCount)) + return "unreadMentionCount: integer expected"; + if (message.markedAsUnread != null && message.hasOwnProperty("markedAsUnread")) + if (typeof message.markedAsUnread !== "boolean") + return "markedAsUnread: boolean expected"; + if (message.participant != null && message.hasOwnProperty("participant")) { + if (!Array.isArray(message.participant)) + return "participant: array expected"; + for (var i = 0; i < message.participant.length; ++i) { + var error = $root.proto.GroupParticipant.verify(message.participant[i]); + if (error) + return "participant." + error; + } + } + if (message.tcToken != null && message.hasOwnProperty("tcToken")) + if (!(message.tcToken && typeof message.tcToken.length === "number" || $util.isString(message.tcToken))) + return "tcToken: buffer expected"; + if (message.tcTokenTimestamp != null && message.hasOwnProperty("tcTokenTimestamp")) + if (!$util.isInteger(message.tcTokenTimestamp) && !(message.tcTokenTimestamp && $util.isInteger(message.tcTokenTimestamp.low) && $util.isInteger(message.tcTokenTimestamp.high))) + return "tcTokenTimestamp: integer|Long expected"; + if (message.contactPrimaryIdentityKey != null && message.hasOwnProperty("contactPrimaryIdentityKey")) + if (!(message.contactPrimaryIdentityKey && typeof message.contactPrimaryIdentityKey.length === "number" || $util.isString(message.contactPrimaryIdentityKey))) + return "contactPrimaryIdentityKey: buffer expected"; + if (message.pinned != null && message.hasOwnProperty("pinned")) + if (!$util.isInteger(message.pinned)) + return "pinned: integer expected"; + if (message.muteEndTime != null && message.hasOwnProperty("muteEndTime")) + if (!$util.isInteger(message.muteEndTime) && !(message.muteEndTime && $util.isInteger(message.muteEndTime.low) && $util.isInteger(message.muteEndTime.high))) + return "muteEndTime: integer|Long expected"; + if (message.wallpaper != null && message.hasOwnProperty("wallpaper")) { + var error = $root.proto.WallpaperSettings.verify(message.wallpaper); + if (error) + return "wallpaper." + error; + } + if (message.mediaVisibility != null && message.hasOwnProperty("mediaVisibility")) + switch (message.mediaVisibility) { + default: + return "mediaVisibility: enum value expected"; + case 0: + case 1: + case 2: + break; + } + if (message.tcTokenSenderTimestamp != null && message.hasOwnProperty("tcTokenSenderTimestamp")) + if (!$util.isInteger(message.tcTokenSenderTimestamp) && !(message.tcTokenSenderTimestamp && $util.isInteger(message.tcTokenSenderTimestamp.low) && $util.isInteger(message.tcTokenSenderTimestamp.high))) + return "tcTokenSenderTimestamp: integer|Long expected"; + if (message.suspended != null && message.hasOwnProperty("suspended")) + if (typeof message.suspended !== "boolean") + return "suspended: boolean expected"; return null; }; @@ -17325,6 +19250,87 @@ $root.proto = (function() { message.pHash = String(object.pHash); if (object.notSpam != null) message.notSpam = Boolean(object.notSpam); + if (object.archived != null) + message.archived = Boolean(object.archived); + if (object.disappearingMode != null) { + if (typeof object.disappearingMode !== "object") + throw TypeError(".proto.Conversation.disappearingMode: object expected"); + message.disappearingMode = $root.proto.DisappearingMode.fromObject(object.disappearingMode); + } + if (object.unreadMentionCount != null) + message.unreadMentionCount = object.unreadMentionCount >>> 0; + if (object.markedAsUnread != null) + message.markedAsUnread = Boolean(object.markedAsUnread); + if (object.participant) { + if (!Array.isArray(object.participant)) + throw TypeError(".proto.Conversation.participant: array expected"); + message.participant = []; + for (var i = 0; i < object.participant.length; ++i) { + if (typeof object.participant[i] !== "object") + throw TypeError(".proto.Conversation.participant: object expected"); + message.participant[i] = $root.proto.GroupParticipant.fromObject(object.participant[i]); + } + } + if (object.tcToken != null) + if (typeof object.tcToken === "string") + $util.base64.decode(object.tcToken, message.tcToken = $util.newBuffer($util.base64.length(object.tcToken)), 0); + else if (object.tcToken.length) + message.tcToken = object.tcToken; + if (object.tcTokenTimestamp != null) + if ($util.Long) + (message.tcTokenTimestamp = $util.Long.fromValue(object.tcTokenTimestamp)).unsigned = true; + else if (typeof object.tcTokenTimestamp === "string") + message.tcTokenTimestamp = parseInt(object.tcTokenTimestamp, 10); + else if (typeof object.tcTokenTimestamp === "number") + message.tcTokenTimestamp = object.tcTokenTimestamp; + else if (typeof object.tcTokenTimestamp === "object") + message.tcTokenTimestamp = new $util.LongBits(object.tcTokenTimestamp.low >>> 0, object.tcTokenTimestamp.high >>> 0).toNumber(true); + if (object.contactPrimaryIdentityKey != null) + if (typeof object.contactPrimaryIdentityKey === "string") + $util.base64.decode(object.contactPrimaryIdentityKey, message.contactPrimaryIdentityKey = $util.newBuffer($util.base64.length(object.contactPrimaryIdentityKey)), 0); + else if (object.contactPrimaryIdentityKey.length) + message.contactPrimaryIdentityKey = object.contactPrimaryIdentityKey; + if (object.pinned != null) + message.pinned = object.pinned >>> 0; + if (object.muteEndTime != null) + if ($util.Long) + (message.muteEndTime = $util.Long.fromValue(object.muteEndTime)).unsigned = true; + else if (typeof object.muteEndTime === "string") + message.muteEndTime = parseInt(object.muteEndTime, 10); + else if (typeof object.muteEndTime === "number") + message.muteEndTime = object.muteEndTime; + else if (typeof object.muteEndTime === "object") + message.muteEndTime = new $util.LongBits(object.muteEndTime.low >>> 0, object.muteEndTime.high >>> 0).toNumber(true); + if (object.wallpaper != null) { + if (typeof object.wallpaper !== "object") + throw TypeError(".proto.Conversation.wallpaper: object expected"); + message.wallpaper = $root.proto.WallpaperSettings.fromObject(object.wallpaper); + } + switch (object.mediaVisibility) { + case "DEFAULT": + case 0: + message.mediaVisibility = 0; + break; + case "OFF": + case 1: + message.mediaVisibility = 1; + break; + case "ON": + case 2: + message.mediaVisibility = 2; + break; + } + if (object.tcTokenSenderTimestamp != null) + if ($util.Long) + (message.tcTokenSenderTimestamp = $util.Long.fromValue(object.tcTokenSenderTimestamp)).unsigned = true; + else if (typeof object.tcTokenSenderTimestamp === "string") + message.tcTokenSenderTimestamp = parseInt(object.tcTokenSenderTimestamp, 10); + else if (typeof object.tcTokenSenderTimestamp === "number") + message.tcTokenSenderTimestamp = object.tcTokenSenderTimestamp; + else if (typeof object.tcTokenSenderTimestamp === "object") + message.tcTokenSenderTimestamp = new $util.LongBits(object.tcTokenSenderTimestamp.low >>> 0, object.tcTokenSenderTimestamp.high >>> 0).toNumber(true); + if (object.suspended != null) + message.suspended = Boolean(object.suspended); return message; }; @@ -17341,8 +19347,10 @@ $root.proto = (function() { if (!options) options = {}; var object = {}; - if (options.arrays || options.defaults) + if (options.arrays || options.defaults) { object.messages = []; + object.participant = []; + } if (options.defaults) { object.id = ""; object.newJid = ""; @@ -17370,6 +19378,43 @@ $root.proto = (function() { object.name = ""; object.pHash = ""; object.notSpam = false; + object.archived = false; + object.disappearingMode = null; + object.unreadMentionCount = 0; + object.markedAsUnread = false; + if (options.bytes === String) + object.tcToken = ""; + else { + object.tcToken = []; + if (options.bytes !== Array) + object.tcToken = $util.newBuffer(object.tcToken); + } + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.tcTokenTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.tcTokenTimestamp = options.longs === String ? "0" : 0; + if (options.bytes === String) + object.contactPrimaryIdentityKey = ""; + else { + object.contactPrimaryIdentityKey = []; + if (options.bytes !== Array) + object.contactPrimaryIdentityKey = $util.newBuffer(object.contactPrimaryIdentityKey); + } + object.pinned = 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.muteEndTime = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.muteEndTime = options.longs === String ? "0" : 0; + object.wallpaper = null; + object.mediaVisibility = options.enums === String ? "DEFAULT" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.tcTokenSenderTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.tcTokenSenderTimestamp = options.longs === String ? "0" : 0; + object.suspended = false; } if (message.id != null && message.hasOwnProperty("id")) object.id = message.id; @@ -17413,6 +19458,46 @@ $root.proto = (function() { object.pHash = message.pHash; if (message.notSpam != null && message.hasOwnProperty("notSpam")) object.notSpam = message.notSpam; + if (message.archived != null && message.hasOwnProperty("archived")) + object.archived = message.archived; + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) + object.disappearingMode = $root.proto.DisappearingMode.toObject(message.disappearingMode, options); + if (message.unreadMentionCount != null && message.hasOwnProperty("unreadMentionCount")) + object.unreadMentionCount = message.unreadMentionCount; + if (message.markedAsUnread != null && message.hasOwnProperty("markedAsUnread")) + object.markedAsUnread = message.markedAsUnread; + if (message.participant && message.participant.length) { + object.participant = []; + for (var j = 0; j < message.participant.length; ++j) + object.participant[j] = $root.proto.GroupParticipant.toObject(message.participant[j], options); + } + if (message.tcToken != null && message.hasOwnProperty("tcToken")) + object.tcToken = options.bytes === String ? $util.base64.encode(message.tcToken, 0, message.tcToken.length) : options.bytes === Array ? Array.prototype.slice.call(message.tcToken) : message.tcToken; + if (message.tcTokenTimestamp != null && message.hasOwnProperty("tcTokenTimestamp")) + if (typeof message.tcTokenTimestamp === "number") + object.tcTokenTimestamp = options.longs === String ? String(message.tcTokenTimestamp) : message.tcTokenTimestamp; + else + object.tcTokenTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.tcTokenTimestamp) : options.longs === Number ? new $util.LongBits(message.tcTokenTimestamp.low >>> 0, message.tcTokenTimestamp.high >>> 0).toNumber(true) : message.tcTokenTimestamp; + if (message.contactPrimaryIdentityKey != null && message.hasOwnProperty("contactPrimaryIdentityKey")) + object.contactPrimaryIdentityKey = options.bytes === String ? $util.base64.encode(message.contactPrimaryIdentityKey, 0, message.contactPrimaryIdentityKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.contactPrimaryIdentityKey) : message.contactPrimaryIdentityKey; + if (message.pinned != null && message.hasOwnProperty("pinned")) + object.pinned = message.pinned; + if (message.muteEndTime != null && message.hasOwnProperty("muteEndTime")) + if (typeof message.muteEndTime === "number") + object.muteEndTime = options.longs === String ? String(message.muteEndTime) : message.muteEndTime; + else + object.muteEndTime = options.longs === String ? $util.Long.prototype.toString.call(message.muteEndTime) : options.longs === Number ? new $util.LongBits(message.muteEndTime.low >>> 0, message.muteEndTime.high >>> 0).toNumber(true) : message.muteEndTime; + if (message.wallpaper != null && message.hasOwnProperty("wallpaper")) + object.wallpaper = $root.proto.WallpaperSettings.toObject(message.wallpaper, options); + if (message.mediaVisibility != null && message.hasOwnProperty("mediaVisibility")) + object.mediaVisibility = options.enums === String ? $root.proto.MediaVisibility[message.mediaVisibility] : message.mediaVisibility; + if (message.tcTokenSenderTimestamp != null && message.hasOwnProperty("tcTokenSenderTimestamp")) + if (typeof message.tcTokenSenderTimestamp === "number") + object.tcTokenSenderTimestamp = options.longs === String ? String(message.tcTokenSenderTimestamp) : message.tcTokenSenderTimestamp; + else + object.tcTokenSenderTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.tcTokenSenderTimestamp) : options.longs === Number ? new $util.LongBits(message.tcTokenSenderTimestamp.low >>> 0, message.tcTokenSenderTimestamp.high >>> 0).toNumber(true) : message.tcTokenSenderTimestamp; + if (message.suspended != null && message.hasOwnProperty("suspended")) + object.suspended = message.suspended; return object; }; @@ -17456,6 +19541,9 @@ $root.proto = (function() { * @property {number|null} [chunkOrder] HistorySync chunkOrder * @property {number|null} [progress] HistorySync progress * @property {Array.|null} [pushnames] HistorySync pushnames + * @property {proto.IGlobalSettings|null} [globalSettings] HistorySync globalSettings + * @property {Uint8Array|null} [threadIdUserSecret] HistorySync threadIdUserSecret + * @property {number|null} [threadDsTimeframeOffset] HistorySync threadDsTimeframeOffset */ /** @@ -17524,6 +19612,30 @@ $root.proto = (function() { */ HistorySync.prototype.pushnames = $util.emptyArray; + /** + * HistorySync globalSettings. + * @member {proto.IGlobalSettings|null|undefined} globalSettings + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.globalSettings = null; + + /** + * HistorySync threadIdUserSecret. + * @member {Uint8Array} threadIdUserSecret + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.threadIdUserSecret = $util.newBuffer([]); + + /** + * HistorySync threadDsTimeframeOffset. + * @member {number} threadDsTimeframeOffset + * @memberof proto.HistorySync + * @instance + */ + HistorySync.prototype.threadDsTimeframeOffset = 0; + /** * Creates a new HistorySync instance using the specified properties. * @function create @@ -17562,6 +19674,12 @@ $root.proto = (function() { if (message.pushnames != null && message.pushnames.length) for (var i = 0; i < message.pushnames.length; ++i) $root.proto.Pushname.encode(message.pushnames[i], writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); + if (message.globalSettings != null && Object.hasOwnProperty.call(message, "globalSettings")) + $root.proto.GlobalSettings.encode(message.globalSettings, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim(); + if (message.threadIdUserSecret != null && Object.hasOwnProperty.call(message, "threadIdUserSecret")) + writer.uint32(/* id 9, wireType 2 =*/74).bytes(message.threadIdUserSecret); + if (message.threadDsTimeframeOffset != null && Object.hasOwnProperty.call(message, "threadDsTimeframeOffset")) + writer.uint32(/* id 10, wireType 0 =*/80).uint32(message.threadDsTimeframeOffset); return writer; }; @@ -17620,6 +19738,15 @@ $root.proto = (function() { message.pushnames = []; message.pushnames.push($root.proto.Pushname.decode(reader, reader.uint32())); break; + case 8: + message.globalSettings = $root.proto.GlobalSettings.decode(reader, reader.uint32()); + break; + case 9: + message.threadIdUserSecret = reader.bytes(); + break; + case 10: + message.threadDsTimeframeOffset = reader.uint32(); + break; default: reader.skipType(tag & 7); break; @@ -17700,6 +19827,17 @@ $root.proto = (function() { return "pushnames." + error; } } + if (message.globalSettings != null && message.hasOwnProperty("globalSettings")) { + var error = $root.proto.GlobalSettings.verify(message.globalSettings); + if (error) + return "globalSettings." + error; + } + if (message.threadIdUserSecret != null && message.hasOwnProperty("threadIdUserSecret")) + if (!(message.threadIdUserSecret && typeof message.threadIdUserSecret.length === "number" || $util.isString(message.threadIdUserSecret))) + return "threadIdUserSecret: buffer expected"; + if (message.threadDsTimeframeOffset != null && message.hasOwnProperty("threadDsTimeframeOffset")) + if (!$util.isInteger(message.threadDsTimeframeOffset)) + return "threadDsTimeframeOffset: integer expected"; return null; }; @@ -17771,6 +19909,18 @@ $root.proto = (function() { message.pushnames[i] = $root.proto.Pushname.fromObject(object.pushnames[i]); } } + if (object.globalSettings != null) { + if (typeof object.globalSettings !== "object") + throw TypeError(".proto.HistorySync.globalSettings: object expected"); + message.globalSettings = $root.proto.GlobalSettings.fromObject(object.globalSettings); + } + if (object.threadIdUserSecret != null) + if (typeof object.threadIdUserSecret === "string") + $util.base64.decode(object.threadIdUserSecret, message.threadIdUserSecret = $util.newBuffer($util.base64.length(object.threadIdUserSecret)), 0); + else if (object.threadIdUserSecret.length) + message.threadIdUserSecret = object.threadIdUserSecret; + if (object.threadDsTimeframeOffset != null) + message.threadDsTimeframeOffset = object.threadDsTimeframeOffset >>> 0; return message; }; @@ -17796,6 +19946,15 @@ $root.proto = (function() { object.syncType = options.enums === String ? "INITIAL_BOOTSTRAP" : 0; object.chunkOrder = 0; object.progress = 0; + object.globalSettings = null; + if (options.bytes === String) + object.threadIdUserSecret = ""; + else { + object.threadIdUserSecret = []; + if (options.bytes !== Array) + object.threadIdUserSecret = $util.newBuffer(object.threadIdUserSecret); + } + object.threadDsTimeframeOffset = 0; } if (message.syncType != null && message.hasOwnProperty("syncType")) object.syncType = options.enums === String ? $root.proto.HistorySync.HistorySyncHistorySyncType[message.syncType] : message.syncType; @@ -17818,6 +19977,12 @@ $root.proto = (function() { for (var j = 0; j < message.pushnames.length; ++j) object.pushnames[j] = $root.proto.Pushname.toObject(message.pushnames[j], options); } + if (message.globalSettings != null && message.hasOwnProperty("globalSettings")) + object.globalSettings = $root.proto.GlobalSettings.toObject(message.globalSettings, options); + if (message.threadIdUserSecret != null && message.hasOwnProperty("threadIdUserSecret")) + object.threadIdUserSecret = options.bytes === String ? $util.base64.encode(message.threadIdUserSecret, 0, message.threadIdUserSecret.length) : options.bytes === Array ? Array.prototype.slice.call(message.threadIdUserSecret) : message.threadIdUserSecret; + if (message.threadDsTimeframeOffset != null && message.hasOwnProperty("threadDsTimeframeOffset")) + object.threadDsTimeframeOffset = message.threadDsTimeframeOffset; return object; }; @@ -17855,6 +20020,22 @@ $root.proto = (function() { return HistorySync; })(); + /** + * MediaVisibility enum. + * @name proto.MediaVisibility + * @enum {number} + * @property {number} DEFAULT=0 DEFAULT value + * @property {number} OFF=1 OFF value + * @property {number} ON=2 ON value + */ + proto.MediaVisibility = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "DEFAULT"] = 0; + values[valuesById[1] = "OFF"] = 1; + values[valuesById[2] = "ON"] = 2; + return values; + })(); + proto.EphemeralSetting = (function() { /** @@ -18079,2969 +20260,6 @@ $root.proto = (function() { return EphemeralSetting; })(); - proto.PaymentBackground = (function() { - - /** - * Properties of a PaymentBackground. - * @memberof proto - * @interface IPaymentBackground - * @property {string|null} [id] PaymentBackground id - * @property {string|null} [fileLength] PaymentBackground fileLength - * @property {number|null} [width] PaymentBackground width - * @property {number|null} [height] PaymentBackground height - * @property {string|null} [mimetype] PaymentBackground mimetype - * @property {number|null} [placeholderArgb] PaymentBackground placeholderArgb - * @property {number|null} [textArgb] PaymentBackground textArgb - * @property {number|null} [subtextArgb] PaymentBackground subtextArgb - */ - - /** - * Constructs a new PaymentBackground. - * @memberof proto - * @classdesc Represents a PaymentBackground. - * @implements IPaymentBackground - * @constructor - * @param {proto.IPaymentBackground=} [properties] Properties to set - */ - function PaymentBackground(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * PaymentBackground id. - * @member {string} id - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.id = ""; - - /** - * PaymentBackground fileLength. - * @member {string} fileLength - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.fileLength = ""; - - /** - * PaymentBackground width. - * @member {number} width - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.width = 0; - - /** - * PaymentBackground height. - * @member {number} height - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.height = 0; - - /** - * PaymentBackground mimetype. - * @member {string} mimetype - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.mimetype = ""; - - /** - * PaymentBackground placeholderArgb. - * @member {number} placeholderArgb - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.placeholderArgb = 0; - - /** - * PaymentBackground textArgb. - * @member {number} textArgb - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.textArgb = 0; - - /** - * PaymentBackground subtextArgb. - * @member {number} subtextArgb - * @memberof proto.PaymentBackground - * @instance - */ - PaymentBackground.prototype.subtextArgb = 0; - - /** - * Creates a new PaymentBackground instance using the specified properties. - * @function create - * @memberof proto.PaymentBackground - * @static - * @param {proto.IPaymentBackground=} [properties] Properties to set - * @returns {proto.PaymentBackground} PaymentBackground instance - */ - PaymentBackground.create = function create(properties) { - return new PaymentBackground(properties); - }; - - /** - * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. - * @function encode - * @memberof proto.PaymentBackground - * @static - * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - PaymentBackground.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); - if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.fileLength); - if (message.width != null && Object.hasOwnProperty.call(message, "width")) - writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.width); - if (message.height != null && Object.hasOwnProperty.call(message, "height")) - writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.height); - if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype")) - writer.uint32(/* id 5, wireType 2 =*/42).string(message.mimetype); - if (message.placeholderArgb != null && Object.hasOwnProperty.call(message, "placeholderArgb")) - writer.uint32(/* id 6, wireType 5 =*/53).fixed32(message.placeholderArgb); - if (message.textArgb != null && Object.hasOwnProperty.call(message, "textArgb")) - writer.uint32(/* id 7, wireType 5 =*/61).fixed32(message.textArgb); - if (message.subtextArgb != null && Object.hasOwnProperty.call(message, "subtextArgb")) - writer.uint32(/* id 8, wireType 5 =*/69).fixed32(message.subtextArgb); - return writer; - }; - - /** - * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.PaymentBackground - * @static - * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - PaymentBackground.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a PaymentBackground message from the specified reader or buffer. - * @function decode - * @memberof proto.PaymentBackground - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.PaymentBackground} PaymentBackground - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - PaymentBackground.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentBackground(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.id = reader.string(); - break; - case 2: - message.fileLength = reader.string(); - break; - case 3: - message.width = reader.uint32(); - break; - case 4: - message.height = reader.uint32(); - break; - case 5: - message.mimetype = reader.string(); - break; - case 6: - message.placeholderArgb = reader.fixed32(); - break; - case 7: - message.textArgb = reader.fixed32(); - break; - case 8: - message.subtextArgb = reader.fixed32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.PaymentBackground - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.PaymentBackground} PaymentBackground - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - PaymentBackground.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a PaymentBackground message. - * @function verify - * @memberof proto.PaymentBackground - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - PaymentBackground.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.id != null && message.hasOwnProperty("id")) - if (!$util.isString(message.id)) - return "id: string expected"; - if (message.fileLength != null && message.hasOwnProperty("fileLength")) - if (!$util.isString(message.fileLength)) - return "fileLength: string expected"; - if (message.width != null && message.hasOwnProperty("width")) - if (!$util.isInteger(message.width)) - return "width: integer expected"; - if (message.height != null && message.hasOwnProperty("height")) - if (!$util.isInteger(message.height)) - return "height: integer expected"; - if (message.mimetype != null && message.hasOwnProperty("mimetype")) - if (!$util.isString(message.mimetype)) - return "mimetype: string expected"; - if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) - if (!$util.isInteger(message.placeholderArgb)) - return "placeholderArgb: integer expected"; - if (message.textArgb != null && message.hasOwnProperty("textArgb")) - if (!$util.isInteger(message.textArgb)) - return "textArgb: integer expected"; - if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) - if (!$util.isInteger(message.subtextArgb)) - return "subtextArgb: integer expected"; - return null; - }; - - /** - * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.PaymentBackground - * @static - * @param {Object.} object Plain object - * @returns {proto.PaymentBackground} PaymentBackground - */ - PaymentBackground.fromObject = function fromObject(object) { - if (object instanceof $root.proto.PaymentBackground) - return object; - var message = new $root.proto.PaymentBackground(); - if (object.id != null) - message.id = String(object.id); - if (object.fileLength != null) - message.fileLength = String(object.fileLength); - if (object.width != null) - message.width = object.width >>> 0; - if (object.height != null) - message.height = object.height >>> 0; - if (object.mimetype != null) - message.mimetype = String(object.mimetype); - if (object.placeholderArgb != null) - message.placeholderArgb = object.placeholderArgb >>> 0; - if (object.textArgb != null) - message.textArgb = object.textArgb >>> 0; - if (object.subtextArgb != null) - message.subtextArgb = object.subtextArgb >>> 0; - return message; - }; - - /** - * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.PaymentBackground - * @static - * @param {proto.PaymentBackground} message PaymentBackground - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - PaymentBackground.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.id = ""; - object.fileLength = ""; - object.width = 0; - object.height = 0; - object.mimetype = ""; - object.placeholderArgb = 0; - object.textArgb = 0; - object.subtextArgb = 0; - } - if (message.id != null && message.hasOwnProperty("id")) - object.id = message.id; - if (message.fileLength != null && message.hasOwnProperty("fileLength")) - object.fileLength = message.fileLength; - if (message.width != null && message.hasOwnProperty("width")) - object.width = message.width; - if (message.height != null && message.hasOwnProperty("height")) - object.height = message.height; - if (message.mimetype != null && message.hasOwnProperty("mimetype")) - object.mimetype = message.mimetype; - if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) - object.placeholderArgb = message.placeholderArgb; - if (message.textArgb != null && message.hasOwnProperty("textArgb")) - object.textArgb = message.textArgb; - if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) - object.subtextArgb = message.subtextArgb; - return object; - }; - - /** - * Converts this PaymentBackground to JSON. - * @function toJSON - * @memberof proto.PaymentBackground - * @instance - * @returns {Object.} JSON object - */ - PaymentBackground.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return PaymentBackground; - })(); - - proto.Money = (function() { - - /** - * Properties of a Money. - * @memberof proto - * @interface IMoney - * @property {number|Long|null} [value] Money value - * @property {number|null} [offset] Money offset - * @property {string|null} [currencyCode] Money currencyCode - */ - - /** - * Constructs a new Money. - * @memberof proto - * @classdesc Represents a Money. - * @implements IMoney - * @constructor - * @param {proto.IMoney=} [properties] Properties to set - */ - function Money(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * Money value. - * @member {number|Long} value - * @memberof proto.Money - * @instance - */ - Money.prototype.value = $util.Long ? $util.Long.fromBits(0,0,false) : 0; - - /** - * Money offset. - * @member {number} offset - * @memberof proto.Money - * @instance - */ - Money.prototype.offset = 0; - - /** - * Money currencyCode. - * @member {string} currencyCode - * @memberof proto.Money - * @instance - */ - Money.prototype.currencyCode = ""; - - /** - * Creates a new Money instance using the specified properties. - * @function create - * @memberof proto.Money - * @static - * @param {proto.IMoney=} [properties] Properties to set - * @returns {proto.Money} Money instance - */ - Money.create = function create(properties) { - return new Money(properties); - }; - - /** - * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. - * @function encode - * @memberof proto.Money - * @static - * @param {proto.IMoney} message Money message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Money.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.value != null && Object.hasOwnProperty.call(message, "value")) - writer.uint32(/* id 1, wireType 0 =*/8).int64(message.value); - if (message.offset != null && Object.hasOwnProperty.call(message, "offset")) - writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.offset); - if (message.currencyCode != null && Object.hasOwnProperty.call(message, "currencyCode")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.currencyCode); - return writer; - }; - - /** - * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.Money - * @static - * @param {proto.IMoney} message Money message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Money.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a Money message from the specified reader or buffer. - * @function decode - * @memberof proto.Money - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.Money} Money - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Money.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Money(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.value = reader.int64(); - break; - case 2: - message.offset = reader.uint32(); - break; - case 3: - message.currencyCode = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a Money message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.Money - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.Money} Money - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Money.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a Money message. - * @function verify - * @memberof proto.Money - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - Money.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.value != null && message.hasOwnProperty("value")) - if (!$util.isInteger(message.value) && !(message.value && $util.isInteger(message.value.low) && $util.isInteger(message.value.high))) - return "value: integer|Long expected"; - if (message.offset != null && message.hasOwnProperty("offset")) - if (!$util.isInteger(message.offset)) - return "offset: integer expected"; - if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) - if (!$util.isString(message.currencyCode)) - return "currencyCode: string expected"; - return null; - }; - - /** - * Creates a Money message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.Money - * @static - * @param {Object.} object Plain object - * @returns {proto.Money} Money - */ - Money.fromObject = function fromObject(object) { - if (object instanceof $root.proto.Money) - return object; - var message = new $root.proto.Money(); - if (object.value != null) - if ($util.Long) - (message.value = $util.Long.fromValue(object.value)).unsigned = false; - else if (typeof object.value === "string") - message.value = parseInt(object.value, 10); - else if (typeof object.value === "number") - message.value = object.value; - else if (typeof object.value === "object") - message.value = new $util.LongBits(object.value.low >>> 0, object.value.high >>> 0).toNumber(); - if (object.offset != null) - message.offset = object.offset >>> 0; - if (object.currencyCode != null) - message.currencyCode = String(object.currencyCode); - return message; - }; - - /** - * Creates a plain object from a Money message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.Money - * @static - * @param {proto.Money} message Money - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - Money.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if ($util.Long) { - var long = new $util.Long(0, 0, false); - object.value = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.value = options.longs === String ? "0" : 0; - object.offset = 0; - object.currencyCode = ""; - } - if (message.value != null && message.hasOwnProperty("value")) - if (typeof message.value === "number") - object.value = options.longs === String ? String(message.value) : message.value; - else - object.value = options.longs === String ? $util.Long.prototype.toString.call(message.value) : options.longs === Number ? new $util.LongBits(message.value.low >>> 0, message.value.high >>> 0).toNumber() : message.value; - if (message.offset != null && message.hasOwnProperty("offset")) - object.offset = message.offset; - if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) - object.currencyCode = message.currencyCode; - return object; - }; - - /** - * Converts this Money to JSON. - * @function toJSON - * @memberof proto.Money - * @instance - * @returns {Object.} JSON object - */ - Money.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return Money; - })(); - - proto.HydratedQuickReplyButton = (function() { - - /** - * Properties of a HydratedQuickReplyButton. - * @memberof proto - * @interface IHydratedQuickReplyButton - * @property {string|null} [displayText] HydratedQuickReplyButton displayText - * @property {string|null} [id] HydratedQuickReplyButton id - */ - - /** - * Constructs a new HydratedQuickReplyButton. - * @memberof proto - * @classdesc Represents a HydratedQuickReplyButton. - * @implements IHydratedQuickReplyButton - * @constructor - * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set - */ - function HydratedQuickReplyButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HydratedQuickReplyButton displayText. - * @member {string} displayText - * @memberof proto.HydratedQuickReplyButton - * @instance - */ - HydratedQuickReplyButton.prototype.displayText = ""; - - /** - * HydratedQuickReplyButton id. - * @member {string} id - * @memberof proto.HydratedQuickReplyButton - * @instance - */ - HydratedQuickReplyButton.prototype.id = ""; - - /** - * Creates a new HydratedQuickReplyButton instance using the specified properties. - * @function create - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set - * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton instance - */ - HydratedQuickReplyButton.create = function create(properties) { - return new HydratedQuickReplyButton(properties); - }; - - /** - * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. - * @function encode - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedQuickReplyButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.id); - return writer; - }; - - /** - * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedQuickReplyButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HydratedQuickReplyButton message from the specified reader or buffer. - * @function decode - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedQuickReplyButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedQuickReplyButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.displayText = reader.string(); - break; - case 2: - message.id = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedQuickReplyButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HydratedQuickReplyButton message. - * @function verify - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HydratedQuickReplyButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.displayText != null && message.hasOwnProperty("displayText")) - if (!$util.isString(message.displayText)) - return "displayText: string expected"; - if (message.id != null && message.hasOwnProperty("id")) - if (!$util.isString(message.id)) - return "id: string expected"; - return null; - }; - - /** - * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {Object.} object Plain object - * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton - */ - HydratedQuickReplyButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HydratedQuickReplyButton) - return object; - var message = new $root.proto.HydratedQuickReplyButton(); - if (object.displayText != null) - message.displayText = String(object.displayText); - if (object.id != null) - message.id = String(object.id); - return message; - }; - - /** - * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HydratedQuickReplyButton - * @static - * @param {proto.HydratedQuickReplyButton} message HydratedQuickReplyButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HydratedQuickReplyButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.displayText = ""; - object.id = ""; - } - if (message.displayText != null && message.hasOwnProperty("displayText")) - object.displayText = message.displayText; - if (message.id != null && message.hasOwnProperty("id")) - object.id = message.id; - return object; - }; - - /** - * Converts this HydratedQuickReplyButton to JSON. - * @function toJSON - * @memberof proto.HydratedQuickReplyButton - * @instance - * @returns {Object.} JSON object - */ - HydratedQuickReplyButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HydratedQuickReplyButton; - })(); - - proto.HydratedURLButton = (function() { - - /** - * Properties of a HydratedURLButton. - * @memberof proto - * @interface IHydratedURLButton - * @property {string|null} [displayText] HydratedURLButton displayText - * @property {string|null} [url] HydratedURLButton url - */ - - /** - * Constructs a new HydratedURLButton. - * @memberof proto - * @classdesc Represents a HydratedURLButton. - * @implements IHydratedURLButton - * @constructor - * @param {proto.IHydratedURLButton=} [properties] Properties to set - */ - function HydratedURLButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HydratedURLButton displayText. - * @member {string} displayText - * @memberof proto.HydratedURLButton - * @instance - */ - HydratedURLButton.prototype.displayText = ""; - - /** - * HydratedURLButton url. - * @member {string} url - * @memberof proto.HydratedURLButton - * @instance - */ - HydratedURLButton.prototype.url = ""; - - /** - * Creates a new HydratedURLButton instance using the specified properties. - * @function create - * @memberof proto.HydratedURLButton - * @static - * @param {proto.IHydratedURLButton=} [properties] Properties to set - * @returns {proto.HydratedURLButton} HydratedURLButton instance - */ - HydratedURLButton.create = function create(properties) { - return new HydratedURLButton(properties); - }; - - /** - * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. - * @function encode - * @memberof proto.HydratedURLButton - * @static - * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedURLButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); - if (message.url != null && Object.hasOwnProperty.call(message, "url")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.url); - return writer; - }; - - /** - * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HydratedURLButton - * @static - * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedURLButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HydratedURLButton message from the specified reader or buffer. - * @function decode - * @memberof proto.HydratedURLButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HydratedURLButton} HydratedURLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedURLButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedURLButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.displayText = reader.string(); - break; - case 2: - message.url = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HydratedURLButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HydratedURLButton} HydratedURLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedURLButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HydratedURLButton message. - * @function verify - * @memberof proto.HydratedURLButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HydratedURLButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.displayText != null && message.hasOwnProperty("displayText")) - if (!$util.isString(message.displayText)) - return "displayText: string expected"; - if (message.url != null && message.hasOwnProperty("url")) - if (!$util.isString(message.url)) - return "url: string expected"; - return null; - }; - - /** - * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HydratedURLButton - * @static - * @param {Object.} object Plain object - * @returns {proto.HydratedURLButton} HydratedURLButton - */ - HydratedURLButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HydratedURLButton) - return object; - var message = new $root.proto.HydratedURLButton(); - if (object.displayText != null) - message.displayText = String(object.displayText); - if (object.url != null) - message.url = String(object.url); - return message; - }; - - /** - * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HydratedURLButton - * @static - * @param {proto.HydratedURLButton} message HydratedURLButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HydratedURLButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.displayText = ""; - object.url = ""; - } - if (message.displayText != null && message.hasOwnProperty("displayText")) - object.displayText = message.displayText; - if (message.url != null && message.hasOwnProperty("url")) - object.url = message.url; - return object; - }; - - /** - * Converts this HydratedURLButton to JSON. - * @function toJSON - * @memberof proto.HydratedURLButton - * @instance - * @returns {Object.} JSON object - */ - HydratedURLButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HydratedURLButton; - })(); - - proto.HydratedCallButton = (function() { - - /** - * Properties of a HydratedCallButton. - * @memberof proto - * @interface IHydratedCallButton - * @property {string|null} [displayText] HydratedCallButton displayText - * @property {string|null} [phoneNumber] HydratedCallButton phoneNumber - */ - - /** - * Constructs a new HydratedCallButton. - * @memberof proto - * @classdesc Represents a HydratedCallButton. - * @implements IHydratedCallButton - * @constructor - * @param {proto.IHydratedCallButton=} [properties] Properties to set - */ - function HydratedCallButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HydratedCallButton displayText. - * @member {string} displayText - * @memberof proto.HydratedCallButton - * @instance - */ - HydratedCallButton.prototype.displayText = ""; - - /** - * HydratedCallButton phoneNumber. - * @member {string} phoneNumber - * @memberof proto.HydratedCallButton - * @instance - */ - HydratedCallButton.prototype.phoneNumber = ""; - - /** - * Creates a new HydratedCallButton instance using the specified properties. - * @function create - * @memberof proto.HydratedCallButton - * @static - * @param {proto.IHydratedCallButton=} [properties] Properties to set - * @returns {proto.HydratedCallButton} HydratedCallButton instance - */ - HydratedCallButton.create = function create(properties) { - return new HydratedCallButton(properties); - }; - - /** - * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. - * @function encode - * @memberof proto.HydratedCallButton - * @static - * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedCallButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); - if (message.phoneNumber != null && Object.hasOwnProperty.call(message, "phoneNumber")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.phoneNumber); - return writer; - }; - - /** - * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HydratedCallButton - * @static - * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedCallButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HydratedCallButton message from the specified reader or buffer. - * @function decode - * @memberof proto.HydratedCallButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HydratedCallButton} HydratedCallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedCallButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedCallButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.displayText = reader.string(); - break; - case 2: - message.phoneNumber = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HydratedCallButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HydratedCallButton} HydratedCallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedCallButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HydratedCallButton message. - * @function verify - * @memberof proto.HydratedCallButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HydratedCallButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.displayText != null && message.hasOwnProperty("displayText")) - if (!$util.isString(message.displayText)) - return "displayText: string expected"; - if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) - if (!$util.isString(message.phoneNumber)) - return "phoneNumber: string expected"; - return null; - }; - - /** - * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HydratedCallButton - * @static - * @param {Object.} object Plain object - * @returns {proto.HydratedCallButton} HydratedCallButton - */ - HydratedCallButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HydratedCallButton) - return object; - var message = new $root.proto.HydratedCallButton(); - if (object.displayText != null) - message.displayText = String(object.displayText); - if (object.phoneNumber != null) - message.phoneNumber = String(object.phoneNumber); - return message; - }; - - /** - * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HydratedCallButton - * @static - * @param {proto.HydratedCallButton} message HydratedCallButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HydratedCallButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.displayText = ""; - object.phoneNumber = ""; - } - if (message.displayText != null && message.hasOwnProperty("displayText")) - object.displayText = message.displayText; - if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) - object.phoneNumber = message.phoneNumber; - return object; - }; - - /** - * Converts this HydratedCallButton to JSON. - * @function toJSON - * @memberof proto.HydratedCallButton - * @instance - * @returns {Object.} JSON object - */ - HydratedCallButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HydratedCallButton; - })(); - - proto.HydratedTemplateButton = (function() { - - /** - * Properties of a HydratedTemplateButton. - * @memberof proto - * @interface IHydratedTemplateButton - * @property {number|null} [index] HydratedTemplateButton index - * @property {proto.IHydratedQuickReplyButton|null} [quickReplyButton] HydratedTemplateButton quickReplyButton - * @property {proto.IHydratedURLButton|null} [urlButton] HydratedTemplateButton urlButton - * @property {proto.IHydratedCallButton|null} [callButton] HydratedTemplateButton callButton - */ - - /** - * Constructs a new HydratedTemplateButton. - * @memberof proto - * @classdesc Represents a HydratedTemplateButton. - * @implements IHydratedTemplateButton - * @constructor - * @param {proto.IHydratedTemplateButton=} [properties] Properties to set - */ - function HydratedTemplateButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * HydratedTemplateButton index. - * @member {number} index - * @memberof proto.HydratedTemplateButton - * @instance - */ - HydratedTemplateButton.prototype.index = 0; - - /** - * HydratedTemplateButton quickReplyButton. - * @member {proto.IHydratedQuickReplyButton|null|undefined} quickReplyButton - * @memberof proto.HydratedTemplateButton - * @instance - */ - HydratedTemplateButton.prototype.quickReplyButton = null; - - /** - * HydratedTemplateButton urlButton. - * @member {proto.IHydratedURLButton|null|undefined} urlButton - * @memberof proto.HydratedTemplateButton - * @instance - */ - HydratedTemplateButton.prototype.urlButton = null; - - /** - * HydratedTemplateButton callButton. - * @member {proto.IHydratedCallButton|null|undefined} callButton - * @memberof proto.HydratedTemplateButton - * @instance - */ - HydratedTemplateButton.prototype.callButton = null; - - // OneOf field names bound to virtual getters and setters - var $oneOfFields; - - /** - * HydratedTemplateButton hydratedButton. - * @member {"quickReplyButton"|"urlButton"|"callButton"|undefined} hydratedButton - * @memberof proto.HydratedTemplateButton - * @instance - */ - Object.defineProperty(HydratedTemplateButton.prototype, "hydratedButton", { - get: $util.oneOfGetter($oneOfFields = ["quickReplyButton", "urlButton", "callButton"]), - set: $util.oneOfSetter($oneOfFields) - }); - - /** - * Creates a new HydratedTemplateButton instance using the specified properties. - * @function create - * @memberof proto.HydratedTemplateButton - * @static - * @param {proto.IHydratedTemplateButton=} [properties] Properties to set - * @returns {proto.HydratedTemplateButton} HydratedTemplateButton instance - */ - HydratedTemplateButton.create = function create(properties) { - return new HydratedTemplateButton(properties); - }; - - /** - * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. - * @function encode - * @memberof proto.HydratedTemplateButton - * @static - * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedTemplateButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.quickReplyButton != null && Object.hasOwnProperty.call(message, "quickReplyButton")) - $root.proto.HydratedQuickReplyButton.encode(message.quickReplyButton, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.urlButton != null && Object.hasOwnProperty.call(message, "urlButton")) - $root.proto.HydratedURLButton.encode(message.urlButton, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.callButton != null && Object.hasOwnProperty.call(message, "callButton")) - $root.proto.HydratedCallButton.encode(message.callButton, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - if (message.index != null && Object.hasOwnProperty.call(message, "index")) - writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.index); - return writer; - }; - - /** - * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.HydratedTemplateButton - * @static - * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - HydratedTemplateButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a HydratedTemplateButton message from the specified reader or buffer. - * @function decode - * @memberof proto.HydratedTemplateButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.HydratedTemplateButton} HydratedTemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedTemplateButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedTemplateButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 4: - message.index = reader.uint32(); - break; - case 1: - message.quickReplyButton = $root.proto.HydratedQuickReplyButton.decode(reader, reader.uint32()); - break; - case 2: - message.urlButton = $root.proto.HydratedURLButton.decode(reader, reader.uint32()); - break; - case 3: - message.callButton = $root.proto.HydratedCallButton.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.HydratedTemplateButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.HydratedTemplateButton} HydratedTemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - HydratedTemplateButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a HydratedTemplateButton message. - * @function verify - * @memberof proto.HydratedTemplateButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - HydratedTemplateButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - var properties = {}; - if (message.index != null && message.hasOwnProperty("index")) - if (!$util.isInteger(message.index)) - return "index: integer expected"; - if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { - properties.hydratedButton = 1; - { - var error = $root.proto.HydratedQuickReplyButton.verify(message.quickReplyButton); - if (error) - return "quickReplyButton." + error; - } - } - if (message.urlButton != null && message.hasOwnProperty("urlButton")) { - if (properties.hydratedButton === 1) - return "hydratedButton: multiple values"; - properties.hydratedButton = 1; - { - var error = $root.proto.HydratedURLButton.verify(message.urlButton); - if (error) - return "urlButton." + error; - } - } - if (message.callButton != null && message.hasOwnProperty("callButton")) { - if (properties.hydratedButton === 1) - return "hydratedButton: multiple values"; - properties.hydratedButton = 1; - { - var error = $root.proto.HydratedCallButton.verify(message.callButton); - if (error) - return "callButton." + error; - } - } - return null; - }; - - /** - * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.HydratedTemplateButton - * @static - * @param {Object.} object Plain object - * @returns {proto.HydratedTemplateButton} HydratedTemplateButton - */ - HydratedTemplateButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.HydratedTemplateButton) - return object; - var message = new $root.proto.HydratedTemplateButton(); - if (object.index != null) - message.index = object.index >>> 0; - if (object.quickReplyButton != null) { - if (typeof object.quickReplyButton !== "object") - throw TypeError(".proto.HydratedTemplateButton.quickReplyButton: object expected"); - message.quickReplyButton = $root.proto.HydratedQuickReplyButton.fromObject(object.quickReplyButton); - } - if (object.urlButton != null) { - if (typeof object.urlButton !== "object") - throw TypeError(".proto.HydratedTemplateButton.urlButton: object expected"); - message.urlButton = $root.proto.HydratedURLButton.fromObject(object.urlButton); - } - if (object.callButton != null) { - if (typeof object.callButton !== "object") - throw TypeError(".proto.HydratedTemplateButton.callButton: object expected"); - message.callButton = $root.proto.HydratedCallButton.fromObject(object.callButton); - } - return message; - }; - - /** - * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.HydratedTemplateButton - * @static - * @param {proto.HydratedTemplateButton} message HydratedTemplateButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - HydratedTemplateButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.index = 0; - if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { - object.quickReplyButton = $root.proto.HydratedQuickReplyButton.toObject(message.quickReplyButton, options); - if (options.oneofs) - object.hydratedButton = "quickReplyButton"; - } - if (message.urlButton != null && message.hasOwnProperty("urlButton")) { - object.urlButton = $root.proto.HydratedURLButton.toObject(message.urlButton, options); - if (options.oneofs) - object.hydratedButton = "urlButton"; - } - if (message.callButton != null && message.hasOwnProperty("callButton")) { - object.callButton = $root.proto.HydratedCallButton.toObject(message.callButton, options); - if (options.oneofs) - object.hydratedButton = "callButton"; - } - if (message.index != null && message.hasOwnProperty("index")) - object.index = message.index; - return object; - }; - - /** - * Converts this HydratedTemplateButton to JSON. - * @function toJSON - * @memberof proto.HydratedTemplateButton - * @instance - * @returns {Object.} JSON object - */ - HydratedTemplateButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return HydratedTemplateButton; - })(); - - proto.QuickReplyButton = (function() { - - /** - * Properties of a QuickReplyButton. - * @memberof proto - * @interface IQuickReplyButton - * @property {proto.IHighlyStructuredMessage|null} [displayText] QuickReplyButton displayText - * @property {string|null} [id] QuickReplyButton id - */ - - /** - * Constructs a new QuickReplyButton. - * @memberof proto - * @classdesc Represents a QuickReplyButton. - * @implements IQuickReplyButton - * @constructor - * @param {proto.IQuickReplyButton=} [properties] Properties to set - */ - function QuickReplyButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * QuickReplyButton displayText. - * @member {proto.IHighlyStructuredMessage|null|undefined} displayText - * @memberof proto.QuickReplyButton - * @instance - */ - QuickReplyButton.prototype.displayText = null; - - /** - * QuickReplyButton id. - * @member {string} id - * @memberof proto.QuickReplyButton - * @instance - */ - QuickReplyButton.prototype.id = ""; - - /** - * Creates a new QuickReplyButton instance using the specified properties. - * @function create - * @memberof proto.QuickReplyButton - * @static - * @param {proto.IQuickReplyButton=} [properties] Properties to set - * @returns {proto.QuickReplyButton} QuickReplyButton instance - */ - QuickReplyButton.create = function create(properties) { - return new QuickReplyButton(properties); - }; - - /** - * Encodes the specified QuickReplyButton message. Does not implicitly {@link proto.QuickReplyButton.verify|verify} messages. - * @function encode - * @memberof proto.QuickReplyButton - * @static - * @param {proto.IQuickReplyButton} message QuickReplyButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - QuickReplyButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) - $root.proto.HighlyStructuredMessage.encode(message.displayText, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.id != null && Object.hasOwnProperty.call(message, "id")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.id); - return writer; - }; - - /** - * Encodes the specified QuickReplyButton message, length delimited. Does not implicitly {@link proto.QuickReplyButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.QuickReplyButton - * @static - * @param {proto.IQuickReplyButton} message QuickReplyButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - QuickReplyButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a QuickReplyButton message from the specified reader or buffer. - * @function decode - * @memberof proto.QuickReplyButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.QuickReplyButton} QuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - QuickReplyButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.QuickReplyButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.displayText = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32()); - break; - case 2: - message.id = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a QuickReplyButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.QuickReplyButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.QuickReplyButton} QuickReplyButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - QuickReplyButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a QuickReplyButton message. - * @function verify - * @memberof proto.QuickReplyButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - QuickReplyButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.displayText != null && message.hasOwnProperty("displayText")) { - var error = $root.proto.HighlyStructuredMessage.verify(message.displayText); - if (error) - return "displayText." + error; - } - if (message.id != null && message.hasOwnProperty("id")) - if (!$util.isString(message.id)) - return "id: string expected"; - return null; - }; - - /** - * Creates a QuickReplyButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.QuickReplyButton - * @static - * @param {Object.} object Plain object - * @returns {proto.QuickReplyButton} QuickReplyButton - */ - QuickReplyButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.QuickReplyButton) - return object; - var message = new $root.proto.QuickReplyButton(); - if (object.displayText != null) { - if (typeof object.displayText !== "object") - throw TypeError(".proto.QuickReplyButton.displayText: object expected"); - message.displayText = $root.proto.HighlyStructuredMessage.fromObject(object.displayText); - } - if (object.id != null) - message.id = String(object.id); - return message; - }; - - /** - * Creates a plain object from a QuickReplyButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.QuickReplyButton - * @static - * @param {proto.QuickReplyButton} message QuickReplyButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - QuickReplyButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.displayText = null; - object.id = ""; - } - if (message.displayText != null && message.hasOwnProperty("displayText")) - object.displayText = $root.proto.HighlyStructuredMessage.toObject(message.displayText, options); - if (message.id != null && message.hasOwnProperty("id")) - object.id = message.id; - return object; - }; - - /** - * Converts this QuickReplyButton to JSON. - * @function toJSON - * @memberof proto.QuickReplyButton - * @instance - * @returns {Object.} JSON object - */ - QuickReplyButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return QuickReplyButton; - })(); - - proto.URLButton = (function() { - - /** - * Properties of a URLButton. - * @memberof proto - * @interface IURLButton - * @property {proto.IHighlyStructuredMessage|null} [displayText] URLButton displayText - * @property {proto.IHighlyStructuredMessage|null} [url] URLButton url - */ - - /** - * Constructs a new URLButton. - * @memberof proto - * @classdesc Represents a URLButton. - * @implements IURLButton - * @constructor - * @param {proto.IURLButton=} [properties] Properties to set - */ - function URLButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * URLButton displayText. - * @member {proto.IHighlyStructuredMessage|null|undefined} displayText - * @memberof proto.URLButton - * @instance - */ - URLButton.prototype.displayText = null; - - /** - * URLButton url. - * @member {proto.IHighlyStructuredMessage|null|undefined} url - * @memberof proto.URLButton - * @instance - */ - URLButton.prototype.url = null; - - /** - * Creates a new URLButton instance using the specified properties. - * @function create - * @memberof proto.URLButton - * @static - * @param {proto.IURLButton=} [properties] Properties to set - * @returns {proto.URLButton} URLButton instance - */ - URLButton.create = function create(properties) { - return new URLButton(properties); - }; - - /** - * Encodes the specified URLButton message. Does not implicitly {@link proto.URLButton.verify|verify} messages. - * @function encode - * @memberof proto.URLButton - * @static - * @param {proto.IURLButton} message URLButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - URLButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) - $root.proto.HighlyStructuredMessage.encode(message.displayText, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.url != null && Object.hasOwnProperty.call(message, "url")) - $root.proto.HighlyStructuredMessage.encode(message.url, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified URLButton message, length delimited. Does not implicitly {@link proto.URLButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.URLButton - * @static - * @param {proto.IURLButton} message URLButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - URLButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a URLButton message from the specified reader or buffer. - * @function decode - * @memberof proto.URLButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.URLButton} URLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - URLButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.URLButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.displayText = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32()); - break; - case 2: - message.url = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a URLButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.URLButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.URLButton} URLButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - URLButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a URLButton message. - * @function verify - * @memberof proto.URLButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - URLButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.displayText != null && message.hasOwnProperty("displayText")) { - var error = $root.proto.HighlyStructuredMessage.verify(message.displayText); - if (error) - return "displayText." + error; - } - if (message.url != null && message.hasOwnProperty("url")) { - var error = $root.proto.HighlyStructuredMessage.verify(message.url); - if (error) - return "url." + error; - } - return null; - }; - - /** - * Creates a URLButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.URLButton - * @static - * @param {Object.} object Plain object - * @returns {proto.URLButton} URLButton - */ - URLButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.URLButton) - return object; - var message = new $root.proto.URLButton(); - if (object.displayText != null) { - if (typeof object.displayText !== "object") - throw TypeError(".proto.URLButton.displayText: object expected"); - message.displayText = $root.proto.HighlyStructuredMessage.fromObject(object.displayText); - } - if (object.url != null) { - if (typeof object.url !== "object") - throw TypeError(".proto.URLButton.url: object expected"); - message.url = $root.proto.HighlyStructuredMessage.fromObject(object.url); - } - return message; - }; - - /** - * Creates a plain object from a URLButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.URLButton - * @static - * @param {proto.URLButton} message URLButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - URLButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.displayText = null; - object.url = null; - } - if (message.displayText != null && message.hasOwnProperty("displayText")) - object.displayText = $root.proto.HighlyStructuredMessage.toObject(message.displayText, options); - if (message.url != null && message.hasOwnProperty("url")) - object.url = $root.proto.HighlyStructuredMessage.toObject(message.url, options); - return object; - }; - - /** - * Converts this URLButton to JSON. - * @function toJSON - * @memberof proto.URLButton - * @instance - * @returns {Object.} JSON object - */ - URLButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return URLButton; - })(); - - proto.CallButton = (function() { - - /** - * Properties of a CallButton. - * @memberof proto - * @interface ICallButton - * @property {proto.IHighlyStructuredMessage|null} [displayText] CallButton displayText - * @property {proto.IHighlyStructuredMessage|null} [phoneNumber] CallButton phoneNumber - */ - - /** - * Constructs a new CallButton. - * @memberof proto - * @classdesc Represents a CallButton. - * @implements ICallButton - * @constructor - * @param {proto.ICallButton=} [properties] Properties to set - */ - function CallButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * CallButton displayText. - * @member {proto.IHighlyStructuredMessage|null|undefined} displayText - * @memberof proto.CallButton - * @instance - */ - CallButton.prototype.displayText = null; - - /** - * CallButton phoneNumber. - * @member {proto.IHighlyStructuredMessage|null|undefined} phoneNumber - * @memberof proto.CallButton - * @instance - */ - CallButton.prototype.phoneNumber = null; - - /** - * Creates a new CallButton instance using the specified properties. - * @function create - * @memberof proto.CallButton - * @static - * @param {proto.ICallButton=} [properties] Properties to set - * @returns {proto.CallButton} CallButton instance - */ - CallButton.create = function create(properties) { - return new CallButton(properties); - }; - - /** - * Encodes the specified CallButton message. Does not implicitly {@link proto.CallButton.verify|verify} messages. - * @function encode - * @memberof proto.CallButton - * @static - * @param {proto.ICallButton} message CallButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - CallButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) - $root.proto.HighlyStructuredMessage.encode(message.displayText, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.phoneNumber != null && Object.hasOwnProperty.call(message, "phoneNumber")) - $root.proto.HighlyStructuredMessage.encode(message.phoneNumber, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - return writer; - }; - - /** - * Encodes the specified CallButton message, length delimited. Does not implicitly {@link proto.CallButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.CallButton - * @static - * @param {proto.ICallButton} message CallButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - CallButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a CallButton message from the specified reader or buffer. - * @function decode - * @memberof proto.CallButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.CallButton} CallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - CallButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CallButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.displayText = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32()); - break; - case 2: - message.phoneNumber = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a CallButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.CallButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.CallButton} CallButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - CallButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a CallButton message. - * @function verify - * @memberof proto.CallButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - CallButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.displayText != null && message.hasOwnProperty("displayText")) { - var error = $root.proto.HighlyStructuredMessage.verify(message.displayText); - if (error) - return "displayText." + error; - } - if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) { - var error = $root.proto.HighlyStructuredMessage.verify(message.phoneNumber); - if (error) - return "phoneNumber." + error; - } - return null; - }; - - /** - * Creates a CallButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.CallButton - * @static - * @param {Object.} object Plain object - * @returns {proto.CallButton} CallButton - */ - CallButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.CallButton) - return object; - var message = new $root.proto.CallButton(); - if (object.displayText != null) { - if (typeof object.displayText !== "object") - throw TypeError(".proto.CallButton.displayText: object expected"); - message.displayText = $root.proto.HighlyStructuredMessage.fromObject(object.displayText); - } - if (object.phoneNumber != null) { - if (typeof object.phoneNumber !== "object") - throw TypeError(".proto.CallButton.phoneNumber: object expected"); - message.phoneNumber = $root.proto.HighlyStructuredMessage.fromObject(object.phoneNumber); - } - return message; - }; - - /** - * Creates a plain object from a CallButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.CallButton - * @static - * @param {proto.CallButton} message CallButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - CallButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.displayText = null; - object.phoneNumber = null; - } - if (message.displayText != null && message.hasOwnProperty("displayText")) - object.displayText = $root.proto.HighlyStructuredMessage.toObject(message.displayText, options); - if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) - object.phoneNumber = $root.proto.HighlyStructuredMessage.toObject(message.phoneNumber, options); - return object; - }; - - /** - * Converts this CallButton to JSON. - * @function toJSON - * @memberof proto.CallButton - * @instance - * @returns {Object.} JSON object - */ - CallButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return CallButton; - })(); - - proto.TemplateButton = (function() { - - /** - * Properties of a TemplateButton. - * @memberof proto - * @interface ITemplateButton - * @property {number|null} [index] TemplateButton index - * @property {proto.IQuickReplyButton|null} [quickReplyButton] TemplateButton quickReplyButton - * @property {proto.IURLButton|null} [urlButton] TemplateButton urlButton - * @property {proto.ICallButton|null} [callButton] TemplateButton callButton - */ - - /** - * Constructs a new TemplateButton. - * @memberof proto - * @classdesc Represents a TemplateButton. - * @implements ITemplateButton - * @constructor - * @param {proto.ITemplateButton=} [properties] Properties to set - */ - function TemplateButton(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * TemplateButton index. - * @member {number} index - * @memberof proto.TemplateButton - * @instance - */ - TemplateButton.prototype.index = 0; - - /** - * TemplateButton quickReplyButton. - * @member {proto.IQuickReplyButton|null|undefined} quickReplyButton - * @memberof proto.TemplateButton - * @instance - */ - TemplateButton.prototype.quickReplyButton = null; - - /** - * TemplateButton urlButton. - * @member {proto.IURLButton|null|undefined} urlButton - * @memberof proto.TemplateButton - * @instance - */ - TemplateButton.prototype.urlButton = null; - - /** - * TemplateButton callButton. - * @member {proto.ICallButton|null|undefined} callButton - * @memberof proto.TemplateButton - * @instance - */ - TemplateButton.prototype.callButton = null; - - // OneOf field names bound to virtual getters and setters - var $oneOfFields; - - /** - * TemplateButton button. - * @member {"quickReplyButton"|"urlButton"|"callButton"|undefined} button - * @memberof proto.TemplateButton - * @instance - */ - Object.defineProperty(TemplateButton.prototype, "button", { - get: $util.oneOfGetter($oneOfFields = ["quickReplyButton", "urlButton", "callButton"]), - set: $util.oneOfSetter($oneOfFields) - }); - - /** - * Creates a new TemplateButton instance using the specified properties. - * @function create - * @memberof proto.TemplateButton - * @static - * @param {proto.ITemplateButton=} [properties] Properties to set - * @returns {proto.TemplateButton} TemplateButton instance - */ - TemplateButton.create = function create(properties) { - return new TemplateButton(properties); - }; - - /** - * Encodes the specified TemplateButton message. Does not implicitly {@link proto.TemplateButton.verify|verify} messages. - * @function encode - * @memberof proto.TemplateButton - * @static - * @param {proto.ITemplateButton} message TemplateButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - TemplateButton.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.quickReplyButton != null && Object.hasOwnProperty.call(message, "quickReplyButton")) - $root.proto.QuickReplyButton.encode(message.quickReplyButton, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.urlButton != null && Object.hasOwnProperty.call(message, "urlButton")) - $root.proto.URLButton.encode(message.urlButton, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); - if (message.callButton != null && Object.hasOwnProperty.call(message, "callButton")) - $root.proto.CallButton.encode(message.callButton, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); - if (message.index != null && Object.hasOwnProperty.call(message, "index")) - writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.index); - return writer; - }; - - /** - * Encodes the specified TemplateButton message, length delimited. Does not implicitly {@link proto.TemplateButton.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.TemplateButton - * @static - * @param {proto.ITemplateButton} message TemplateButton message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - TemplateButton.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a TemplateButton message from the specified reader or buffer. - * @function decode - * @memberof proto.TemplateButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.TemplateButton} TemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - TemplateButton.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.TemplateButton(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 4: - message.index = reader.uint32(); - break; - case 1: - message.quickReplyButton = $root.proto.QuickReplyButton.decode(reader, reader.uint32()); - break; - case 2: - message.urlButton = $root.proto.URLButton.decode(reader, reader.uint32()); - break; - case 3: - message.callButton = $root.proto.CallButton.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a TemplateButton message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.TemplateButton - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.TemplateButton} TemplateButton - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - TemplateButton.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a TemplateButton message. - * @function verify - * @memberof proto.TemplateButton - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - TemplateButton.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - var properties = {}; - if (message.index != null && message.hasOwnProperty("index")) - if (!$util.isInteger(message.index)) - return "index: integer expected"; - if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { - properties.button = 1; - { - var error = $root.proto.QuickReplyButton.verify(message.quickReplyButton); - if (error) - return "quickReplyButton." + error; - } - } - if (message.urlButton != null && message.hasOwnProperty("urlButton")) { - if (properties.button === 1) - return "button: multiple values"; - properties.button = 1; - { - var error = $root.proto.URLButton.verify(message.urlButton); - if (error) - return "urlButton." + error; - } - } - if (message.callButton != null && message.hasOwnProperty("callButton")) { - if (properties.button === 1) - return "button: multiple values"; - properties.button = 1; - { - var error = $root.proto.CallButton.verify(message.callButton); - if (error) - return "callButton." + error; - } - } - return null; - }; - - /** - * Creates a TemplateButton message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.TemplateButton - * @static - * @param {Object.} object Plain object - * @returns {proto.TemplateButton} TemplateButton - */ - TemplateButton.fromObject = function fromObject(object) { - if (object instanceof $root.proto.TemplateButton) - return object; - var message = new $root.proto.TemplateButton(); - if (object.index != null) - message.index = object.index >>> 0; - if (object.quickReplyButton != null) { - if (typeof object.quickReplyButton !== "object") - throw TypeError(".proto.TemplateButton.quickReplyButton: object expected"); - message.quickReplyButton = $root.proto.QuickReplyButton.fromObject(object.quickReplyButton); - } - if (object.urlButton != null) { - if (typeof object.urlButton !== "object") - throw TypeError(".proto.TemplateButton.urlButton: object expected"); - message.urlButton = $root.proto.URLButton.fromObject(object.urlButton); - } - if (object.callButton != null) { - if (typeof object.callButton !== "object") - throw TypeError(".proto.TemplateButton.callButton: object expected"); - message.callButton = $root.proto.CallButton.fromObject(object.callButton); - } - return message; - }; - - /** - * Creates a plain object from a TemplateButton message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.TemplateButton - * @static - * @param {proto.TemplateButton} message TemplateButton - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - TemplateButton.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.index = 0; - if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { - object.quickReplyButton = $root.proto.QuickReplyButton.toObject(message.quickReplyButton, options); - if (options.oneofs) - object.button = "quickReplyButton"; - } - if (message.urlButton != null && message.hasOwnProperty("urlButton")) { - object.urlButton = $root.proto.URLButton.toObject(message.urlButton, options); - if (options.oneofs) - object.button = "urlButton"; - } - if (message.callButton != null && message.hasOwnProperty("callButton")) { - object.callButton = $root.proto.CallButton.toObject(message.callButton, options); - if (options.oneofs) - object.button = "callButton"; - } - if (message.index != null && message.hasOwnProperty("index")) - object.index = message.index; - return object; - }; - - /** - * Converts this TemplateButton to JSON. - * @function toJSON - * @memberof proto.TemplateButton - * @instance - * @returns {Object.} JSON object - */ - TemplateButton.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return TemplateButton; - })(); - - proto.Location = (function() { - - /** - * Properties of a Location. - * @memberof proto - * @interface ILocation - * @property {number|null} [degreesLatitude] Location degreesLatitude - * @property {number|null} [degreesLongitude] Location degreesLongitude - * @property {string|null} [name] Location name - */ - - /** - * Constructs a new Location. - * @memberof proto - * @classdesc Represents a Location. - * @implements ILocation - * @constructor - * @param {proto.ILocation=} [properties] Properties to set - */ - function Location(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * Location degreesLatitude. - * @member {number} degreesLatitude - * @memberof proto.Location - * @instance - */ - Location.prototype.degreesLatitude = 0; - - /** - * Location degreesLongitude. - * @member {number} degreesLongitude - * @memberof proto.Location - * @instance - */ - Location.prototype.degreesLongitude = 0; - - /** - * Location name. - * @member {string} name - * @memberof proto.Location - * @instance - */ - Location.prototype.name = ""; - - /** - * Creates a new Location instance using the specified properties. - * @function create - * @memberof proto.Location - * @static - * @param {proto.ILocation=} [properties] Properties to set - * @returns {proto.Location} Location instance - */ - Location.create = function create(properties) { - return new Location(properties); - }; - - /** - * Encodes the specified Location message. Does not implicitly {@link proto.Location.verify|verify} messages. - * @function encode - * @memberof proto.Location - * @static - * @param {proto.ILocation} message Location message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Location.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.degreesLatitude != null && Object.hasOwnProperty.call(message, "degreesLatitude")) - writer.uint32(/* id 1, wireType 1 =*/9).double(message.degreesLatitude); - if (message.degreesLongitude != null && Object.hasOwnProperty.call(message, "degreesLongitude")) - writer.uint32(/* id 2, wireType 1 =*/17).double(message.degreesLongitude); - if (message.name != null && Object.hasOwnProperty.call(message, "name")) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.name); - return writer; - }; - - /** - * Encodes the specified Location message, length delimited. Does not implicitly {@link proto.Location.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.Location - * @static - * @param {proto.ILocation} message Location message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Location.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a Location message from the specified reader or buffer. - * @function decode - * @memberof proto.Location - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.Location} Location - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Location.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Location(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.degreesLatitude = reader.double(); - break; - case 2: - message.degreesLongitude = reader.double(); - break; - case 3: - message.name = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a Location message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.Location - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.Location} Location - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Location.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a Location message. - * @function verify - * @memberof proto.Location - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - Location.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.degreesLatitude != null && message.hasOwnProperty("degreesLatitude")) - if (typeof message.degreesLatitude !== "number") - return "degreesLatitude: number expected"; - if (message.degreesLongitude != null && message.hasOwnProperty("degreesLongitude")) - if (typeof message.degreesLongitude !== "number") - return "degreesLongitude: number expected"; - if (message.name != null && message.hasOwnProperty("name")) - if (!$util.isString(message.name)) - return "name: string expected"; - return null; - }; - - /** - * Creates a Location message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.Location - * @static - * @param {Object.} object Plain object - * @returns {proto.Location} Location - */ - Location.fromObject = function fromObject(object) { - if (object instanceof $root.proto.Location) - return object; - var message = new $root.proto.Location(); - if (object.degreesLatitude != null) - message.degreesLatitude = Number(object.degreesLatitude); - if (object.degreesLongitude != null) - message.degreesLongitude = Number(object.degreesLongitude); - if (object.name != null) - message.name = String(object.name); - return message; - }; - - /** - * Creates a plain object from a Location message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.Location - * @static - * @param {proto.Location} message Location - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - Location.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.degreesLatitude = 0; - object.degreesLongitude = 0; - object.name = ""; - } - if (message.degreesLatitude != null && message.hasOwnProperty("degreesLatitude")) - object.degreesLatitude = options.json && !isFinite(message.degreesLatitude) ? String(message.degreesLatitude) : message.degreesLatitude; - if (message.degreesLongitude != null && message.hasOwnProperty("degreesLongitude")) - object.degreesLongitude = options.json && !isFinite(message.degreesLongitude) ? String(message.degreesLongitude) : message.degreesLongitude; - if (message.name != null && message.hasOwnProperty("name")) - object.name = message.name; - return object; - }; - - /** - * Converts this Location to JSON. - * @function toJSON - * @memberof proto.Location - * @instance - * @returns {Object.} JSON object - */ - Location.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return Location; - })(); - - proto.Point = (function() { - - /** - * Properties of a Point. - * @memberof proto - * @interface IPoint - * @property {number|null} [xDeprecated] Point xDeprecated - * @property {number|null} [yDeprecated] Point yDeprecated - * @property {number|null} [x] Point x - * @property {number|null} [y] Point y - */ - - /** - * Constructs a new Point. - * @memberof proto - * @classdesc Represents a Point. - * @implements IPoint - * @constructor - * @param {proto.IPoint=} [properties] Properties to set - */ - function Point(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * Point xDeprecated. - * @member {number} xDeprecated - * @memberof proto.Point - * @instance - */ - Point.prototype.xDeprecated = 0; - - /** - * Point yDeprecated. - * @member {number} yDeprecated - * @memberof proto.Point - * @instance - */ - Point.prototype.yDeprecated = 0; - - /** - * Point x. - * @member {number} x - * @memberof proto.Point - * @instance - */ - Point.prototype.x = 0; - - /** - * Point y. - * @member {number} y - * @memberof proto.Point - * @instance - */ - Point.prototype.y = 0; - - /** - * Creates a new Point instance using the specified properties. - * @function create - * @memberof proto.Point - * @static - * @param {proto.IPoint=} [properties] Properties to set - * @returns {proto.Point} Point instance - */ - Point.create = function create(properties) { - return new Point(properties); - }; - - /** - * Encodes the specified Point message. Does not implicitly {@link proto.Point.verify|verify} messages. - * @function encode - * @memberof proto.Point - * @static - * @param {proto.IPoint} message Point message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Point.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.xDeprecated != null && Object.hasOwnProperty.call(message, "xDeprecated")) - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.xDeprecated); - if (message.yDeprecated != null && Object.hasOwnProperty.call(message, "yDeprecated")) - writer.uint32(/* id 2, wireType 0 =*/16).int32(message.yDeprecated); - if (message.x != null && Object.hasOwnProperty.call(message, "x")) - writer.uint32(/* id 3, wireType 1 =*/25).double(message.x); - if (message.y != null && Object.hasOwnProperty.call(message, "y")) - writer.uint32(/* id 4, wireType 1 =*/33).double(message.y); - return writer; - }; - - /** - * Encodes the specified Point message, length delimited. Does not implicitly {@link proto.Point.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.Point - * @static - * @param {proto.IPoint} message Point message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - Point.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a Point message from the specified reader or buffer. - * @function decode - * @memberof proto.Point - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.Point} Point - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Point.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Point(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.xDeprecated = reader.int32(); - break; - case 2: - message.yDeprecated = reader.int32(); - break; - case 3: - message.x = reader.double(); - break; - case 4: - message.y = reader.double(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a Point message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.Point - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.Point} Point - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - Point.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a Point message. - * @function verify - * @memberof proto.Point - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - Point.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.xDeprecated != null && message.hasOwnProperty("xDeprecated")) - if (!$util.isInteger(message.xDeprecated)) - return "xDeprecated: integer expected"; - if (message.yDeprecated != null && message.hasOwnProperty("yDeprecated")) - if (!$util.isInteger(message.yDeprecated)) - return "yDeprecated: integer expected"; - if (message.x != null && message.hasOwnProperty("x")) - if (typeof message.x !== "number") - return "x: number expected"; - if (message.y != null && message.hasOwnProperty("y")) - if (typeof message.y !== "number") - return "y: number expected"; - return null; - }; - - /** - * Creates a Point message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.Point - * @static - * @param {Object.} object Plain object - * @returns {proto.Point} Point - */ - Point.fromObject = function fromObject(object) { - if (object instanceof $root.proto.Point) - return object; - var message = new $root.proto.Point(); - if (object.xDeprecated != null) - message.xDeprecated = object.xDeprecated | 0; - if (object.yDeprecated != null) - message.yDeprecated = object.yDeprecated | 0; - if (object.x != null) - message.x = Number(object.x); - if (object.y != null) - message.y = Number(object.y); - return message; - }; - - /** - * Creates a plain object from a Point message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.Point - * @static - * @param {proto.Point} message Point - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - Point.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.xDeprecated = 0; - object.yDeprecated = 0; - object.x = 0; - object.y = 0; - } - if (message.xDeprecated != null && message.hasOwnProperty("xDeprecated")) - object.xDeprecated = message.xDeprecated; - if (message.yDeprecated != null && message.hasOwnProperty("yDeprecated")) - object.yDeprecated = message.yDeprecated; - if (message.x != null && message.hasOwnProperty("x")) - object.x = options.json && !isFinite(message.x) ? String(message.x) : message.x; - if (message.y != null && message.hasOwnProperty("y")) - object.y = options.json && !isFinite(message.y) ? String(message.y) : message.y; - return object; - }; - - /** - * Converts this Point to JSON. - * @function toJSON - * @memberof proto.Point - * @instance - * @returns {Object.} JSON object - */ - Point.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return Point; - })(); - proto.InteractiveAnnotation = (function() { /** @@ -22635,6 +21853,10 @@ $root.proto = (function() { * @property {string|null} [entryPointConversionSource] ContextInfo entryPointConversionSource * @property {string|null} [entryPointConversionApp] ContextInfo entryPointConversionApp * @property {number|null} [entryPointConversionDelaySeconds] ContextInfo entryPointConversionDelaySeconds + * @property {proto.IDisappearingMode|null} [disappearingMode] ContextInfo disappearingMode + * @property {proto.IActionLink|null} [actionLink] ContextInfo actionLink + * @property {string|null} [groupSubject] ContextInfo groupSubject + * @property {string|null} [parentGroupJid] ContextInfo parentGroupJid */ /** @@ -22805,6 +22027,38 @@ $root.proto = (function() { */ ContextInfo.prototype.entryPointConversionDelaySeconds = 0; + /** + * ContextInfo disappearingMode. + * @member {proto.IDisappearingMode|null|undefined} disappearingMode + * @memberof proto.ContextInfo + * @instance + */ + ContextInfo.prototype.disappearingMode = null; + + /** + * ContextInfo actionLink. + * @member {proto.IActionLink|null|undefined} actionLink + * @memberof proto.ContextInfo + * @instance + */ + ContextInfo.prototype.actionLink = null; + + /** + * ContextInfo groupSubject. + * @member {string} groupSubject + * @memberof proto.ContextInfo + * @instance + */ + ContextInfo.prototype.groupSubject = ""; + + /** + * ContextInfo parentGroupJid. + * @member {string} parentGroupJid + * @memberof proto.ContextInfo + * @instance + */ + ContextInfo.prototype.parentGroupJid = ""; + /** * Creates a new ContextInfo instance using the specified properties. * @function create @@ -22868,6 +22122,14 @@ $root.proto = (function() { writer.uint32(/* id 30, wireType 2 =*/242).string(message.entryPointConversionApp); if (message.entryPointConversionDelaySeconds != null && Object.hasOwnProperty.call(message, "entryPointConversionDelaySeconds")) writer.uint32(/* id 31, wireType 0 =*/248).uint32(message.entryPointConversionDelaySeconds); + if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode")) + $root.proto.DisappearingMode.encode(message.disappearingMode, writer.uint32(/* id 32, wireType 2 =*/258).fork()).ldelim(); + if (message.actionLink != null && Object.hasOwnProperty.call(message, "actionLink")) + $root.proto.ActionLink.encode(message.actionLink, writer.uint32(/* id 33, wireType 2 =*/266).fork()).ldelim(); + if (message.groupSubject != null && Object.hasOwnProperty.call(message, "groupSubject")) + writer.uint32(/* id 34, wireType 2 =*/274).string(message.groupSubject); + if (message.parentGroupJid != null && Object.hasOwnProperty.call(message, "parentGroupJid")) + writer.uint32(/* id 35, wireType 2 =*/282).string(message.parentGroupJid); return writer; }; @@ -22961,6 +22223,18 @@ $root.proto = (function() { case 31: message.entryPointConversionDelaySeconds = reader.uint32(); break; + case 32: + message.disappearingMode = $root.proto.DisappearingMode.decode(reader, reader.uint32()); + break; + case 33: + message.actionLink = $root.proto.ActionLink.decode(reader, reader.uint32()); + break; + case 34: + message.groupSubject = reader.string(); + break; + case 35: + message.parentGroupJid = reader.string(); + break; default: reader.skipType(tag & 7); break; @@ -23065,6 +22339,22 @@ $root.proto = (function() { if (message.entryPointConversionDelaySeconds != null && message.hasOwnProperty("entryPointConversionDelaySeconds")) if (!$util.isInteger(message.entryPointConversionDelaySeconds)) return "entryPointConversionDelaySeconds: integer expected"; + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) { + var error = $root.proto.DisappearingMode.verify(message.disappearingMode); + if (error) + return "disappearingMode." + error; + } + if (message.actionLink != null && message.hasOwnProperty("actionLink")) { + var error = $root.proto.ActionLink.verify(message.actionLink); + if (error) + return "actionLink." + error; + } + if (message.groupSubject != null && message.hasOwnProperty("groupSubject")) + if (!$util.isString(message.groupSubject)) + return "groupSubject: string expected"; + if (message.parentGroupJid != null && message.hasOwnProperty("parentGroupJid")) + if (!$util.isString(message.parentGroupJid)) + return "parentGroupJid: string expected"; return null; }; @@ -23148,6 +22438,20 @@ $root.proto = (function() { message.entryPointConversionApp = String(object.entryPointConversionApp); if (object.entryPointConversionDelaySeconds != null) message.entryPointConversionDelaySeconds = object.entryPointConversionDelaySeconds >>> 0; + if (object.disappearingMode != null) { + if (typeof object.disappearingMode !== "object") + throw TypeError(".proto.ContextInfo.disappearingMode: object expected"); + message.disappearingMode = $root.proto.DisappearingMode.fromObject(object.disappearingMode); + } + if (object.actionLink != null) { + if (typeof object.actionLink !== "object") + throw TypeError(".proto.ContextInfo.actionLink: object expected"); + message.actionLink = $root.proto.ActionLink.fromObject(object.actionLink); + } + if (object.groupSubject != null) + message.groupSubject = String(object.groupSubject); + if (object.parentGroupJid != null) + message.parentGroupJid = String(object.parentGroupJid); return message; }; @@ -23201,6 +22505,10 @@ $root.proto = (function() { object.entryPointConversionSource = ""; object.entryPointConversionApp = ""; object.entryPointConversionDelaySeconds = 0; + object.disappearingMode = null; + object.actionLink = null; + object.groupSubject = ""; + object.parentGroupJid = ""; } if (message.stanzaId != null && message.hasOwnProperty("stanzaId")) object.stanzaId = message.stanzaId; @@ -23246,6 +22554,14 @@ $root.proto = (function() { object.entryPointConversionApp = message.entryPointConversionApp; if (message.entryPointConversionDelaySeconds != null && message.hasOwnProperty("entryPointConversionDelaySeconds")) object.entryPointConversionDelaySeconds = message.entryPointConversionDelaySeconds; + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) + object.disappearingMode = $root.proto.DisappearingMode.toObject(message.disappearingMode, options); + if (message.actionLink != null && message.hasOwnProperty("actionLink")) + object.actionLink = $root.proto.ActionLink.toObject(message.actionLink, options); + if (message.groupSubject != null && message.hasOwnProperty("groupSubject")) + object.groupSubject = message.groupSubject; + if (message.parentGroupJid != null && message.hasOwnProperty("parentGroupJid")) + object.parentGroupJid = message.parentGroupJid; return object; }; @@ -23513,6 +22829,7 @@ $root.proto = (function() { * @property {string|null} [thumbnailDirectPath] ImageMessage thumbnailDirectPath * @property {Uint8Array|null} [thumbnailSha256] ImageMessage thumbnailSha256 * @property {Uint8Array|null} [thumbnailEncSha256] ImageMessage thumbnailEncSha256 + * @property {string|null} [staticUrl] ImageMessage staticUrl */ /** @@ -23732,6 +23049,14 @@ $root.proto = (function() { */ ImageMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]); + /** + * ImageMessage staticUrl. + * @member {string} staticUrl + * @memberof proto.ImageMessage + * @instance + */ + ImageMessage.prototype.staticUrl = ""; + /** * Creates a new ImageMessage instance using the specified properties. * @function create @@ -23808,6 +23133,8 @@ $root.proto = (function() { writer.uint32(/* id 27, wireType 2 =*/218).bytes(message.thumbnailSha256); if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256")) writer.uint32(/* id 28, wireType 2 =*/226).bytes(message.thumbnailEncSha256); + if (message.staticUrl != null && Object.hasOwnProperty.call(message, "staticUrl")) + writer.uint32(/* id 29, wireType 2 =*/234).string(message.staticUrl); return writer; }; @@ -23926,6 +23253,9 @@ $root.proto = (function() { case 28: message.thumbnailEncSha256 = reader.bytes(); break; + case 29: + message.staticUrl = reader.string(); + break; default: reader.skipType(tag & 7); break; @@ -24048,6 +23378,9 @@ $root.proto = (function() { if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256))) return "thumbnailEncSha256: buffer expected"; + if (message.staticUrl != null && message.hasOwnProperty("staticUrl")) + if (!$util.isString(message.staticUrl)) + return "staticUrl: string expected"; return null; }; @@ -24173,6 +23506,8 @@ $root.proto = (function() { $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0); else if (object.thumbnailEncSha256.length) message.thumbnailEncSha256 = object.thumbnailEncSha256; + if (object.staticUrl != null) + message.staticUrl = String(object.staticUrl); return message; }; @@ -24285,6 +23620,7 @@ $root.proto = (function() { if (options.bytes !== Array) object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256); } + object.staticUrl = ""; } if (message.url != null && message.hasOwnProperty("url")) object.url = message.url; @@ -24348,6 +23684,8 @@ $root.proto = (function() { object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256; if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256; + if (message.staticUrl != null && message.hasOwnProperty("staticUrl")) + object.staticUrl = message.staticUrl; return object; }; @@ -25534,6 +24872,7 @@ $root.proto = (function() { * @property {number|Long|null} [mediaKeyTimestamp] ExtendedTextMessage mediaKeyTimestamp * @property {number|null} [thumbnailHeight] ExtendedTextMessage thumbnailHeight * @property {number|null} [thumbnailWidth] ExtendedTextMessage thumbnailWidth + * @property {proto.ExtendedTextMessage.ExtendedTextMessageInviteLinkGroupType|null} [inviteLinkGroupType] ExtendedTextMessage inviteLinkGroupType */ /** @@ -25703,6 +25042,14 @@ $root.proto = (function() { */ ExtendedTextMessage.prototype.thumbnailWidth = 0; + /** + * ExtendedTextMessage inviteLinkGroupType. + * @member {proto.ExtendedTextMessage.ExtendedTextMessageInviteLinkGroupType} inviteLinkGroupType + * @memberof proto.ExtendedTextMessage + * @instance + */ + ExtendedTextMessage.prototype.inviteLinkGroupType = 0; + /** * Creates a new ExtendedTextMessage instance using the specified properties. * @function create @@ -25765,6 +25112,8 @@ $root.proto = (function() { writer.uint32(/* id 24, wireType 0 =*/192).uint32(message.thumbnailHeight); if (message.thumbnailWidth != null && Object.hasOwnProperty.call(message, "thumbnailWidth")) writer.uint32(/* id 25, wireType 0 =*/200).uint32(message.thumbnailWidth); + if (message.inviteLinkGroupType != null && Object.hasOwnProperty.call(message, "inviteLinkGroupType")) + writer.uint32(/* id 26, wireType 0 =*/208).int32(message.inviteLinkGroupType); return writer; }; @@ -25856,6 +25205,9 @@ $root.proto = (function() { case 25: message.thumbnailWidth = reader.uint32(); break; + case 26: + message.inviteLinkGroupType = reader.int32(); + break; default: reader.skipType(tag & 7); break; @@ -25964,6 +25316,14 @@ $root.proto = (function() { if (message.thumbnailWidth != null && message.hasOwnProperty("thumbnailWidth")) if (!$util.isInteger(message.thumbnailWidth)) return "thumbnailWidth: integer expected"; + if (message.inviteLinkGroupType != null && message.hasOwnProperty("inviteLinkGroupType")) + switch (message.inviteLinkGroupType) { + default: + return "inviteLinkGroupType: enum value expected"; + case 0: + case 1: + break; + } return null; }; @@ -26071,6 +25431,16 @@ $root.proto = (function() { message.thumbnailHeight = object.thumbnailHeight >>> 0; if (object.thumbnailWidth != null) message.thumbnailWidth = object.thumbnailWidth >>> 0; + switch (object.inviteLinkGroupType) { + case "DEFAULT": + case 0: + message.inviteLinkGroupType = 0; + break; + case "PARENT": + case 1: + message.inviteLinkGroupType = 1; + break; + } return message; }; @@ -26135,6 +25505,7 @@ $root.proto = (function() { object.mediaKeyTimestamp = options.longs === String ? "0" : 0; object.thumbnailHeight = 0; object.thumbnailWidth = 0; + object.inviteLinkGroupType = options.enums === String ? "DEFAULT" : 0; } if (message.text != null && message.hasOwnProperty("text")) object.text = message.text; @@ -26177,6 +25548,8 @@ $root.proto = (function() { object.thumbnailHeight = message.thumbnailHeight; if (message.thumbnailWidth != null && message.hasOwnProperty("thumbnailWidth")) object.thumbnailWidth = message.thumbnailWidth; + if (message.inviteLinkGroupType != null && message.hasOwnProperty("inviteLinkGroupType")) + object.inviteLinkGroupType = options.enums === String ? $root.proto.ExtendedTextMessage.ExtendedTextMessageInviteLinkGroupType[message.inviteLinkGroupType] : message.inviteLinkGroupType; return object; }; @@ -26227,6 +25600,20 @@ $root.proto = (function() { return values; })(); + /** + * ExtendedTextMessageInviteLinkGroupType enum. + * @name proto.ExtendedTextMessage.ExtendedTextMessageInviteLinkGroupType + * @enum {number} + * @property {number} DEFAULT=0 DEFAULT value + * @property {number} PARENT=1 PARENT value + */ + ExtendedTextMessage.ExtendedTextMessageInviteLinkGroupType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "DEFAULT"] = 0; + values[valuesById[1] = "PARENT"] = 1; + return values; + })(); + return ExtendedTextMessage; })(); @@ -26919,6 +26306,7 @@ $root.proto = (function() { * @property {number|Long|null} [mediaKeyTimestamp] AudioMessage mediaKeyTimestamp * @property {proto.IContextInfo|null} [contextInfo] AudioMessage contextInfo * @property {Uint8Array|null} [streamingSidecar] AudioMessage streamingSidecar + * @property {Uint8Array|null} [waveform] AudioMessage waveform */ /** @@ -27032,6 +26420,14 @@ $root.proto = (function() { */ AudioMessage.prototype.streamingSidecar = $util.newBuffer([]); + /** + * AudioMessage waveform. + * @member {Uint8Array} waveform + * @memberof proto.AudioMessage + * @instance + */ + AudioMessage.prototype.waveform = $util.newBuffer([]); + /** * Creates a new AudioMessage instance using the specified properties. * @function create @@ -27080,6 +26476,8 @@ $root.proto = (function() { $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim(); if (message.streamingSidecar != null && Object.hasOwnProperty.call(message, "streamingSidecar")) writer.uint32(/* id 18, wireType 2 =*/146).bytes(message.streamingSidecar); + if (message.waveform != null && Object.hasOwnProperty.call(message, "waveform")) + writer.uint32(/* id 19, wireType 2 =*/154).bytes(message.waveform); return writer; }; @@ -27150,6 +26548,9 @@ $root.proto = (function() { case 18: message.streamingSidecar = reader.bytes(); break; + case 19: + message.waveform = reader.bytes(); + break; default: reader.skipType(tag & 7); break; @@ -27223,6 +26624,9 @@ $root.proto = (function() { if (message.streamingSidecar != null && message.hasOwnProperty("streamingSidecar")) if (!(message.streamingSidecar && typeof message.streamingSidecar.length === "number" || $util.isString(message.streamingSidecar))) return "streamingSidecar: buffer expected"; + if (message.waveform != null && message.hasOwnProperty("waveform")) + if (!(message.waveform && typeof message.waveform.length === "number" || $util.isString(message.waveform))) + return "waveform: buffer expected"; return null; }; @@ -27291,6 +26695,11 @@ $root.proto = (function() { $util.base64.decode(object.streamingSidecar, message.streamingSidecar = $util.newBuffer($util.base64.length(object.streamingSidecar)), 0); else if (object.streamingSidecar.length) message.streamingSidecar = object.streamingSidecar; + if (object.waveform != null) + if (typeof object.waveform === "string") + $util.base64.decode(object.waveform, message.waveform = $util.newBuffer($util.base64.length(object.waveform)), 0); + else if (object.waveform.length) + message.waveform = object.waveform; return message; }; @@ -27352,6 +26761,13 @@ $root.proto = (function() { if (options.bytes !== Array) object.streamingSidecar = $util.newBuffer(object.streamingSidecar); } + if (options.bytes === String) + object.waveform = ""; + else { + object.waveform = []; + if (options.bytes !== Array) + object.waveform = $util.newBuffer(object.waveform); + } } if (message.url != null && message.hasOwnProperty("url")) object.url = message.url; @@ -27383,6 +26799,8 @@ $root.proto = (function() { object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options); if (message.streamingSidecar != null && message.hasOwnProperty("streamingSidecar")) object.streamingSidecar = options.bytes === String ? $util.base64.encode(message.streamingSidecar, 0, message.streamingSidecar.length) : options.bytes === Array ? Array.prototype.slice.call(message.streamingSidecar) : message.streamingSidecar; + if (message.waveform != null && message.hasOwnProperty("waveform")) + object.waveform = options.bytes === String ? $util.base64.encode(message.waveform, 0, message.waveform.length) : options.bytes === Array ? Array.prototype.slice.call(message.waveform) : message.waveform; return object; }; @@ -27428,6 +26846,7 @@ $root.proto = (function() { * @property {string|null} [thumbnailDirectPath] VideoMessage thumbnailDirectPath * @property {Uint8Array|null} [thumbnailSha256] VideoMessage thumbnailSha256 * @property {Uint8Array|null} [thumbnailEncSha256] VideoMessage thumbnailEncSha256 + * @property {string|null} [staticUrl] VideoMessage staticUrl */ /** @@ -27622,6 +27041,14 @@ $root.proto = (function() { */ VideoMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]); + /** + * VideoMessage staticUrl. + * @member {string} staticUrl + * @memberof proto.VideoMessage + * @instance + */ + VideoMessage.prototype.staticUrl = ""; + /** * Creates a new VideoMessage instance using the specified properties. * @function create @@ -27691,6 +27118,8 @@ $root.proto = (function() { writer.uint32(/* id 22, wireType 2 =*/178).bytes(message.thumbnailSha256); if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256")) writer.uint32(/* id 23, wireType 2 =*/186).bytes(message.thumbnailEncSha256); + if (message.staticUrl != null && Object.hasOwnProperty.call(message, "staticUrl")) + writer.uint32(/* id 24, wireType 2 =*/194).string(message.staticUrl); return writer; }; @@ -27793,6 +27222,9 @@ $root.proto = (function() { case 23: message.thumbnailEncSha256 = reader.bytes(); break; + case 24: + message.staticUrl = reader.string(); + break; default: reader.skipType(tag & 7); break; @@ -27908,6 +27340,9 @@ $root.proto = (function() { if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256))) return "thumbnailEncSha256: buffer expected"; + if (message.staticUrl != null && message.hasOwnProperty("staticUrl")) + if (!$util.isString(message.staticUrl)) + return "staticUrl: string expected"; return null; }; @@ -28025,6 +27460,8 @@ $root.proto = (function() { $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0); else if (object.thumbnailEncSha256.length) message.thumbnailEncSha256 = object.thumbnailEncSha256; + if (object.staticUrl != null) + message.staticUrl = String(object.staticUrl); return message; }; @@ -28115,6 +27552,7 @@ $root.proto = (function() { if (options.bytes !== Array) object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256); } + object.staticUrl = ""; } if (message.url != null && message.hasOwnProperty("url")) object.url = message.url; @@ -28169,6 +27607,8 @@ $root.proto = (function() { object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256; if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256")) object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256; + if (message.staticUrl != null && message.hasOwnProperty("staticUrl")) + object.staticUrl = message.staticUrl; return object; }; @@ -28699,6 +28139,7 @@ $root.proto = (function() { * @property {proto.IAppStateSyncKeyRequest|null} [appStateSyncKeyRequest] ProtocolMessage appStateSyncKeyRequest * @property {proto.IInitialSecurityNotificationSettingSync|null} [initialSecurityNotificationSettingSync] ProtocolMessage initialSecurityNotificationSettingSync * @property {proto.IAppStateFatalExceptionNotification|null} [appStateFatalExceptionNotification] ProtocolMessage appStateFatalExceptionNotification + * @property {proto.IDisappearingMode|null} [disappearingMode] ProtocolMessage disappearingMode */ /** @@ -28788,6 +28229,14 @@ $root.proto = (function() { */ ProtocolMessage.prototype.appStateFatalExceptionNotification = null; + /** + * ProtocolMessage disappearingMode. + * @member {proto.IDisappearingMode|null|undefined} disappearingMode + * @memberof proto.ProtocolMessage + * @instance + */ + ProtocolMessage.prototype.disappearingMode = null; + /** * Creates a new ProtocolMessage instance using the specified properties. * @function create @@ -28830,6 +28279,8 @@ $root.proto = (function() { $root.proto.InitialSecurityNotificationSettingSync.encode(message.initialSecurityNotificationSettingSync, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim(); if (message.appStateFatalExceptionNotification != null && Object.hasOwnProperty.call(message, "appStateFatalExceptionNotification")) $root.proto.AppStateFatalExceptionNotification.encode(message.appStateFatalExceptionNotification, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim(); + if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode")) + $root.proto.DisappearingMode.encode(message.disappearingMode, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim(); return writer; }; @@ -28891,6 +28342,9 @@ $root.proto = (function() { case 10: message.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.decode(reader, reader.uint32()); break; + case 11: + message.disappearingMode = $root.proto.DisappearingMode.decode(reader, reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -28977,6 +28431,11 @@ $root.proto = (function() { if (error) return "appStateFatalExceptionNotification." + error; } + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) { + var error = $root.proto.DisappearingMode.verify(message.disappearingMode); + if (error) + return "disappearingMode." + error; + } return null; }; @@ -29071,6 +28530,11 @@ $root.proto = (function() { throw TypeError(".proto.ProtocolMessage.appStateFatalExceptionNotification: object expected"); message.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.fromObject(object.appStateFatalExceptionNotification); } + if (object.disappearingMode != null) { + if (typeof object.disappearingMode !== "object") + throw TypeError(".proto.ProtocolMessage.disappearingMode: object expected"); + message.disappearingMode = $root.proto.DisappearingMode.fromObject(object.disappearingMode); + } return message; }; @@ -29101,6 +28565,7 @@ $root.proto = (function() { object.appStateSyncKeyRequest = null; object.initialSecurityNotificationSettingSync = null; object.appStateFatalExceptionNotification = null; + object.disappearingMode = null; } if (message.key != null && message.hasOwnProperty("key")) object.key = $root.proto.MessageKey.toObject(message.key, options); @@ -29123,6 +28588,8 @@ $root.proto = (function() { object.initialSecurityNotificationSettingSync = $root.proto.InitialSecurityNotificationSettingSync.toObject(message.initialSecurityNotificationSettingSync, options); if (message.appStateFatalExceptionNotification != null && message.hasOwnProperty("appStateFatalExceptionNotification")) object.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.toObject(message.appStateFatalExceptionNotification, options); + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) + object.disappearingMode = $root.proto.DisappearingMode.toObject(message.disappearingMode, options); return object; }; @@ -37783,6 +37250,8 @@ $root.proto = (function() { * @property {proto.IProductSnapshot|null} [product] ProductMessage product * @property {string|null} [businessOwnerJid] ProductMessage businessOwnerJid * @property {proto.ICatalogSnapshot|null} [catalog] ProductMessage catalog + * @property {string|null} [body] ProductMessage body + * @property {string|null} [footer] ProductMessage footer * @property {proto.IContextInfo|null} [contextInfo] ProductMessage contextInfo */ @@ -37825,6 +37294,22 @@ $root.proto = (function() { */ ProductMessage.prototype.catalog = null; + /** + * ProductMessage body. + * @member {string} body + * @memberof proto.ProductMessage + * @instance + */ + ProductMessage.prototype.body = ""; + + /** + * ProductMessage footer. + * @member {string} footer + * @memberof proto.ProductMessage + * @instance + */ + ProductMessage.prototype.footer = ""; + /** * ProductMessage contextInfo. * @member {proto.IContextInfo|null|undefined} contextInfo @@ -37863,6 +37348,10 @@ $root.proto = (function() { writer.uint32(/* id 2, wireType 2 =*/18).string(message.businessOwnerJid); if (message.catalog != null && Object.hasOwnProperty.call(message, "catalog")) $root.proto.CatalogSnapshot.encode(message.catalog, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + if (message.body != null && Object.hasOwnProperty.call(message, "body")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.body); + if (message.footer != null && Object.hasOwnProperty.call(message, "footer")) + writer.uint32(/* id 6, wireType 2 =*/50).string(message.footer); if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo")) $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim(); return writer; @@ -37908,6 +37397,12 @@ $root.proto = (function() { case 4: message.catalog = $root.proto.CatalogSnapshot.decode(reader, reader.uint32()); break; + case 5: + message.body = reader.string(); + break; + case 6: + message.footer = reader.string(); + break; case 17: message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32()); break; @@ -37959,6 +37454,12 @@ $root.proto = (function() { if (error) return "catalog." + error; } + if (message.body != null && message.hasOwnProperty("body")) + if (!$util.isString(message.body)) + return "body: string expected"; + if (message.footer != null && message.hasOwnProperty("footer")) + if (!$util.isString(message.footer)) + return "footer: string expected"; if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) { var error = $root.proto.ContextInfo.verify(message.contextInfo); if (error) @@ -37991,6 +37492,10 @@ $root.proto = (function() { throw TypeError(".proto.ProductMessage.catalog: object expected"); message.catalog = $root.proto.CatalogSnapshot.fromObject(object.catalog); } + if (object.body != null) + message.body = String(object.body); + if (object.footer != null) + message.footer = String(object.footer); if (object.contextInfo != null) { if (typeof object.contextInfo !== "object") throw TypeError(".proto.ProductMessage.contextInfo: object expected"); @@ -38016,6 +37521,8 @@ $root.proto = (function() { object.product = null; object.businessOwnerJid = ""; object.catalog = null; + object.body = ""; + object.footer = ""; object.contextInfo = null; } if (message.product != null && message.hasOwnProperty("product")) @@ -38024,6 +37531,10 @@ $root.proto = (function() { object.businessOwnerJid = message.businessOwnerJid; if (message.catalog != null && message.hasOwnProperty("catalog")) object.catalog = $root.proto.CatalogSnapshot.toObject(message.catalog, options); + if (message.body != null && message.hasOwnProperty("body")) + object.body = message.body; + if (message.footer != null && message.hasOwnProperty("footer")) + object.footer = message.footer; if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options); return object; @@ -40808,6 +40319,2116 @@ $root.proto = (function() { return ListResponseMessage; })(); + proto.Header = (function() { + + /** + * Properties of a Header. + * @memberof proto + * @interface IHeader + * @property {string|null} [title] Header title + * @property {string|null} [subtitle] Header subtitle + * @property {boolean|null} [hasMediaAttachment] Header hasMediaAttachment + * @property {proto.IDocumentMessage|null} [documentMessage] Header documentMessage + * @property {proto.IImageMessage|null} [imageMessage] Header imageMessage + * @property {Uint8Array|null} [jpegThumbnail] Header jpegThumbnail + * @property {proto.IVideoMessage|null} [videoMessage] Header videoMessage + */ + + /** + * Constructs a new Header. + * @memberof proto + * @classdesc Represents a Header. + * @implements IHeader + * @constructor + * @param {proto.IHeader=} [properties] Properties to set + */ + function Header(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Header title. + * @member {string} title + * @memberof proto.Header + * @instance + */ + Header.prototype.title = ""; + + /** + * Header subtitle. + * @member {string} subtitle + * @memberof proto.Header + * @instance + */ + Header.prototype.subtitle = ""; + + /** + * Header hasMediaAttachment. + * @member {boolean} hasMediaAttachment + * @memberof proto.Header + * @instance + */ + Header.prototype.hasMediaAttachment = false; + + /** + * Header documentMessage. + * @member {proto.IDocumentMessage|null|undefined} documentMessage + * @memberof proto.Header + * @instance + */ + Header.prototype.documentMessage = null; + + /** + * Header imageMessage. + * @member {proto.IImageMessage|null|undefined} imageMessage + * @memberof proto.Header + * @instance + */ + Header.prototype.imageMessage = null; + + /** + * Header jpegThumbnail. + * @member {Uint8Array|null|undefined} jpegThumbnail + * @memberof proto.Header + * @instance + */ + Header.prototype.jpegThumbnail = null; + + /** + * Header videoMessage. + * @member {proto.IVideoMessage|null|undefined} videoMessage + * @memberof proto.Header + * @instance + */ + Header.prototype.videoMessage = null; + + // OneOf field names bound to virtual getters and setters + var $oneOfFields; + + /** + * Header media. + * @member {"documentMessage"|"imageMessage"|"jpegThumbnail"|"videoMessage"|undefined} media + * @memberof proto.Header + * @instance + */ + Object.defineProperty(Header.prototype, "media", { + get: $util.oneOfGetter($oneOfFields = ["documentMessage", "imageMessage", "jpegThumbnail", "videoMessage"]), + set: $util.oneOfSetter($oneOfFields) + }); + + /** + * Creates a new Header instance using the specified properties. + * @function create + * @memberof proto.Header + * @static + * @param {proto.IHeader=} [properties] Properties to set + * @returns {proto.Header} Header instance + */ + Header.create = function create(properties) { + return new Header(properties); + }; + + /** + * Encodes the specified Header message. Does not implicitly {@link proto.Header.verify|verify} messages. + * @function encode + * @memberof proto.Header + * @static + * @param {proto.IHeader} message Header message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Header.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.title != null && Object.hasOwnProperty.call(message, "title")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.title); + if (message.subtitle != null && Object.hasOwnProperty.call(message, "subtitle")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.subtitle); + if (message.documentMessage != null && Object.hasOwnProperty.call(message, "documentMessage")) + $root.proto.DocumentMessage.encode(message.documentMessage, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.imageMessage != null && Object.hasOwnProperty.call(message, "imageMessage")) + $root.proto.ImageMessage.encode(message.imageMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + if (message.hasMediaAttachment != null && Object.hasOwnProperty.call(message, "hasMediaAttachment")) + writer.uint32(/* id 5, wireType 0 =*/40).bool(message.hasMediaAttachment); + if (message.jpegThumbnail != null && Object.hasOwnProperty.call(message, "jpegThumbnail")) + writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.jpegThumbnail); + if (message.videoMessage != null && Object.hasOwnProperty.call(message, "videoMessage")) + $root.proto.VideoMessage.encode(message.videoMessage, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified Header message, length delimited. Does not implicitly {@link proto.Header.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Header + * @static + * @param {proto.IHeader} message Header message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Header.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Header message from the specified reader or buffer. + * @function decode + * @memberof proto.Header + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Header} Header + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Header.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Header(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.title = reader.string(); + break; + case 2: + message.subtitle = reader.string(); + break; + case 5: + message.hasMediaAttachment = reader.bool(); + break; + case 3: + message.documentMessage = $root.proto.DocumentMessage.decode(reader, reader.uint32()); + break; + case 4: + message.imageMessage = $root.proto.ImageMessage.decode(reader, reader.uint32()); + break; + case 6: + message.jpegThumbnail = reader.bytes(); + break; + case 7: + message.videoMessage = $root.proto.VideoMessage.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Header message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Header + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Header} Header + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Header.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Header message. + * @function verify + * @memberof proto.Header + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Header.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var properties = {}; + if (message.title != null && message.hasOwnProperty("title")) + if (!$util.isString(message.title)) + return "title: string expected"; + if (message.subtitle != null && message.hasOwnProperty("subtitle")) + if (!$util.isString(message.subtitle)) + return "subtitle: string expected"; + if (message.hasMediaAttachment != null && message.hasOwnProperty("hasMediaAttachment")) + if (typeof message.hasMediaAttachment !== "boolean") + return "hasMediaAttachment: boolean expected"; + if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) { + properties.media = 1; + { + var error = $root.proto.DocumentMessage.verify(message.documentMessage); + if (error) + return "documentMessage." + error; + } + } + if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) { + if (properties.media === 1) + return "media: multiple values"; + properties.media = 1; + { + var error = $root.proto.ImageMessage.verify(message.imageMessage); + if (error) + return "imageMessage." + error; + } + } + if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail")) { + if (properties.media === 1) + return "media: multiple values"; + properties.media = 1; + if (!(message.jpegThumbnail && typeof message.jpegThumbnail.length === "number" || $util.isString(message.jpegThumbnail))) + return "jpegThumbnail: buffer expected"; + } + if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) { + if (properties.media === 1) + return "media: multiple values"; + properties.media = 1; + { + var error = $root.proto.VideoMessage.verify(message.videoMessage); + if (error) + return "videoMessage." + error; + } + } + return null; + }; + + /** + * Creates a Header message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Header + * @static + * @param {Object.} object Plain object + * @returns {proto.Header} Header + */ + Header.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Header) + return object; + var message = new $root.proto.Header(); + if (object.title != null) + message.title = String(object.title); + if (object.subtitle != null) + message.subtitle = String(object.subtitle); + if (object.hasMediaAttachment != null) + message.hasMediaAttachment = Boolean(object.hasMediaAttachment); + if (object.documentMessage != null) { + if (typeof object.documentMessage !== "object") + throw TypeError(".proto.Header.documentMessage: object expected"); + message.documentMessage = $root.proto.DocumentMessage.fromObject(object.documentMessage); + } + if (object.imageMessage != null) { + if (typeof object.imageMessage !== "object") + throw TypeError(".proto.Header.imageMessage: object expected"); + message.imageMessage = $root.proto.ImageMessage.fromObject(object.imageMessage); + } + if (object.jpegThumbnail != null) + if (typeof object.jpegThumbnail === "string") + $util.base64.decode(object.jpegThumbnail, message.jpegThumbnail = $util.newBuffer($util.base64.length(object.jpegThumbnail)), 0); + else if (object.jpegThumbnail.length) + message.jpegThumbnail = object.jpegThumbnail; + if (object.videoMessage != null) { + if (typeof object.videoMessage !== "object") + throw TypeError(".proto.Header.videoMessage: object expected"); + message.videoMessage = $root.proto.VideoMessage.fromObject(object.videoMessage); + } + return message; + }; + + /** + * Creates a plain object from a Header message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Header + * @static + * @param {proto.Header} message Header + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Header.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.title = ""; + object.subtitle = ""; + object.hasMediaAttachment = false; + } + if (message.title != null && message.hasOwnProperty("title")) + object.title = message.title; + if (message.subtitle != null && message.hasOwnProperty("subtitle")) + object.subtitle = message.subtitle; + if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) { + object.documentMessage = $root.proto.DocumentMessage.toObject(message.documentMessage, options); + if (options.oneofs) + object.media = "documentMessage"; + } + if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) { + object.imageMessage = $root.proto.ImageMessage.toObject(message.imageMessage, options); + if (options.oneofs) + object.media = "imageMessage"; + } + if (message.hasMediaAttachment != null && message.hasOwnProperty("hasMediaAttachment")) + object.hasMediaAttachment = message.hasMediaAttachment; + if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail")) { + object.jpegThumbnail = options.bytes === String ? $util.base64.encode(message.jpegThumbnail, 0, message.jpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.jpegThumbnail) : message.jpegThumbnail; + if (options.oneofs) + object.media = "jpegThumbnail"; + } + if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) { + object.videoMessage = $root.proto.VideoMessage.toObject(message.videoMessage, options); + if (options.oneofs) + object.media = "videoMessage"; + } + return object; + }; + + /** + * Converts this Header to JSON. + * @function toJSON + * @memberof proto.Header + * @instance + * @returns {Object.} JSON object + */ + Header.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Header; + })(); + + proto.Body = (function() { + + /** + * Properties of a Body. + * @memberof proto + * @interface IBody + * @property {string|null} [text] Body text + */ + + /** + * Constructs a new Body. + * @memberof proto + * @classdesc Represents a Body. + * @implements IBody + * @constructor + * @param {proto.IBody=} [properties] Properties to set + */ + function Body(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Body text. + * @member {string} text + * @memberof proto.Body + * @instance + */ + Body.prototype.text = ""; + + /** + * Creates a new Body instance using the specified properties. + * @function create + * @memberof proto.Body + * @static + * @param {proto.IBody=} [properties] Properties to set + * @returns {proto.Body} Body instance + */ + Body.create = function create(properties) { + return new Body(properties); + }; + + /** + * Encodes the specified Body message. Does not implicitly {@link proto.Body.verify|verify} messages. + * @function encode + * @memberof proto.Body + * @static + * @param {proto.IBody} message Body message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Body.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.text != null && Object.hasOwnProperty.call(message, "text")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.text); + return writer; + }; + + /** + * Encodes the specified Body message, length delimited. Does not implicitly {@link proto.Body.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Body + * @static + * @param {proto.IBody} message Body message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Body.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Body message from the specified reader or buffer. + * @function decode + * @memberof proto.Body + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Body} Body + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Body.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Body(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.text = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Body message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Body + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Body} Body + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Body.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Body message. + * @function verify + * @memberof proto.Body + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Body.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.text != null && message.hasOwnProperty("text")) + if (!$util.isString(message.text)) + return "text: string expected"; + return null; + }; + + /** + * Creates a Body message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Body + * @static + * @param {Object.} object Plain object + * @returns {proto.Body} Body + */ + Body.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Body) + return object; + var message = new $root.proto.Body(); + if (object.text != null) + message.text = String(object.text); + return message; + }; + + /** + * Creates a plain object from a Body message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Body + * @static + * @param {proto.Body} message Body + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Body.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.text = ""; + if (message.text != null && message.hasOwnProperty("text")) + object.text = message.text; + return object; + }; + + /** + * Converts this Body to JSON. + * @function toJSON + * @memberof proto.Body + * @instance + * @returns {Object.} JSON object + */ + Body.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Body; + })(); + + proto.Footer = (function() { + + /** + * Properties of a Footer. + * @memberof proto + * @interface IFooter + * @property {string|null} [text] Footer text + */ + + /** + * Constructs a new Footer. + * @memberof proto + * @classdesc Represents a Footer. + * @implements IFooter + * @constructor + * @param {proto.IFooter=} [properties] Properties to set + */ + function Footer(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Footer text. + * @member {string} text + * @memberof proto.Footer + * @instance + */ + Footer.prototype.text = ""; + + /** + * Creates a new Footer instance using the specified properties. + * @function create + * @memberof proto.Footer + * @static + * @param {proto.IFooter=} [properties] Properties to set + * @returns {proto.Footer} Footer instance + */ + Footer.create = function create(properties) { + return new Footer(properties); + }; + + /** + * Encodes the specified Footer message. Does not implicitly {@link proto.Footer.verify|verify} messages. + * @function encode + * @memberof proto.Footer + * @static + * @param {proto.IFooter} message Footer message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Footer.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.text != null && Object.hasOwnProperty.call(message, "text")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.text); + return writer; + }; + + /** + * Encodes the specified Footer message, length delimited. Does not implicitly {@link proto.Footer.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Footer + * @static + * @param {proto.IFooter} message Footer message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Footer.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Footer message from the specified reader or buffer. + * @function decode + * @memberof proto.Footer + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Footer} Footer + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Footer.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Footer(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.text = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Footer message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Footer + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Footer} Footer + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Footer.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Footer message. + * @function verify + * @memberof proto.Footer + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Footer.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.text != null && message.hasOwnProperty("text")) + if (!$util.isString(message.text)) + return "text: string expected"; + return null; + }; + + /** + * Creates a Footer message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Footer + * @static + * @param {Object.} object Plain object + * @returns {proto.Footer} Footer + */ + Footer.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Footer) + return object; + var message = new $root.proto.Footer(); + if (object.text != null) + message.text = String(object.text); + return message; + }; + + /** + * Creates a plain object from a Footer message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Footer + * @static + * @param {proto.Footer} message Footer + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Footer.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.text = ""; + if (message.text != null && message.hasOwnProperty("text")) + object.text = message.text; + return object; + }; + + /** + * Converts this Footer to JSON. + * @function toJSON + * @memberof proto.Footer + * @instance + * @returns {Object.} JSON object + */ + Footer.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Footer; + })(); + + proto.ShopMessage = (function() { + + /** + * Properties of a ShopMessage. + * @memberof proto + * @interface IShopMessage + * @property {string|null} [id] ShopMessage id + * @property {proto.ShopMessage.ShopMessageSurface|null} [surface] ShopMessage surface + * @property {number|null} [messageVersion] ShopMessage messageVersion + */ + + /** + * Constructs a new ShopMessage. + * @memberof proto + * @classdesc Represents a ShopMessage. + * @implements IShopMessage + * @constructor + * @param {proto.IShopMessage=} [properties] Properties to set + */ + function ShopMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ShopMessage id. + * @member {string} id + * @memberof proto.ShopMessage + * @instance + */ + ShopMessage.prototype.id = ""; + + /** + * ShopMessage surface. + * @member {proto.ShopMessage.ShopMessageSurface} surface + * @memberof proto.ShopMessage + * @instance + */ + ShopMessage.prototype.surface = 0; + + /** + * ShopMessage messageVersion. + * @member {number} messageVersion + * @memberof proto.ShopMessage + * @instance + */ + ShopMessage.prototype.messageVersion = 0; + + /** + * Creates a new ShopMessage instance using the specified properties. + * @function create + * @memberof proto.ShopMessage + * @static + * @param {proto.IShopMessage=} [properties] Properties to set + * @returns {proto.ShopMessage} ShopMessage instance + */ + ShopMessage.create = function create(properties) { + return new ShopMessage(properties); + }; + + /** + * Encodes the specified ShopMessage message. Does not implicitly {@link proto.ShopMessage.verify|verify} messages. + * @function encode + * @memberof proto.ShopMessage + * @static + * @param {proto.IShopMessage} message ShopMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ShopMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); + if (message.surface != null && Object.hasOwnProperty.call(message, "surface")) + writer.uint32(/* id 2, wireType 0 =*/16).int32(message.surface); + if (message.messageVersion != null && Object.hasOwnProperty.call(message, "messageVersion")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.messageVersion); + return writer; + }; + + /** + * Encodes the specified ShopMessage message, length delimited. Does not implicitly {@link proto.ShopMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ShopMessage + * @static + * @param {proto.IShopMessage} message ShopMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ShopMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ShopMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.ShopMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ShopMessage} ShopMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ShopMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ShopMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.surface = reader.int32(); + break; + case 3: + message.messageVersion = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ShopMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ShopMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ShopMessage} ShopMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ShopMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ShopMessage message. + * @function verify + * @memberof proto.ShopMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ShopMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.surface != null && message.hasOwnProperty("surface")) + switch (message.surface) { + default: + return "surface: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) + if (!$util.isInteger(message.messageVersion)) + return "messageVersion: integer expected"; + return null; + }; + + /** + * Creates a ShopMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ShopMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.ShopMessage} ShopMessage + */ + ShopMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ShopMessage) + return object; + var message = new $root.proto.ShopMessage(); + if (object.id != null) + message.id = String(object.id); + switch (object.surface) { + case "UNKNOWN_SURFACE": + case 0: + message.surface = 0; + break; + case "FB": + case 1: + message.surface = 1; + break; + case "IG": + case 2: + message.surface = 2; + break; + case "WA": + case 3: + message.surface = 3; + break; + } + if (object.messageVersion != null) + message.messageVersion = object.messageVersion | 0; + return message; + }; + + /** + * Creates a plain object from a ShopMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ShopMessage + * @static + * @param {proto.ShopMessage} message ShopMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ShopMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.id = ""; + object.surface = options.enums === String ? "UNKNOWN_SURFACE" : 0; + object.messageVersion = 0; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.surface != null && message.hasOwnProperty("surface")) + object.surface = options.enums === String ? $root.proto.ShopMessage.ShopMessageSurface[message.surface] : message.surface; + if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) + object.messageVersion = message.messageVersion; + return object; + }; + + /** + * Converts this ShopMessage to JSON. + * @function toJSON + * @memberof proto.ShopMessage + * @instance + * @returns {Object.} JSON object + */ + ShopMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * ShopMessageSurface enum. + * @name proto.ShopMessage.ShopMessageSurface + * @enum {number} + * @property {number} UNKNOWN_SURFACE=0 UNKNOWN_SURFACE value + * @property {number} FB=1 FB value + * @property {number} IG=2 IG value + * @property {number} WA=3 WA value + */ + ShopMessage.ShopMessageSurface = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN_SURFACE"] = 0; + values[valuesById[1] = "FB"] = 1; + values[valuesById[2] = "IG"] = 2; + values[valuesById[3] = "WA"] = 3; + return values; + })(); + + return ShopMessage; + })(); + + proto.CollectionMessage = (function() { + + /** + * Properties of a CollectionMessage. + * @memberof proto + * @interface ICollectionMessage + * @property {string|null} [bizJid] CollectionMessage bizJid + * @property {string|null} [id] CollectionMessage id + * @property {number|null} [messageVersion] CollectionMessage messageVersion + */ + + /** + * Constructs a new CollectionMessage. + * @memberof proto + * @classdesc Represents a CollectionMessage. + * @implements ICollectionMessage + * @constructor + * @param {proto.ICollectionMessage=} [properties] Properties to set + */ + function CollectionMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * CollectionMessage bizJid. + * @member {string} bizJid + * @memberof proto.CollectionMessage + * @instance + */ + CollectionMessage.prototype.bizJid = ""; + + /** + * CollectionMessage id. + * @member {string} id + * @memberof proto.CollectionMessage + * @instance + */ + CollectionMessage.prototype.id = ""; + + /** + * CollectionMessage messageVersion. + * @member {number} messageVersion + * @memberof proto.CollectionMessage + * @instance + */ + CollectionMessage.prototype.messageVersion = 0; + + /** + * Creates a new CollectionMessage instance using the specified properties. + * @function create + * @memberof proto.CollectionMessage + * @static + * @param {proto.ICollectionMessage=} [properties] Properties to set + * @returns {proto.CollectionMessage} CollectionMessage instance + */ + CollectionMessage.create = function create(properties) { + return new CollectionMessage(properties); + }; + + /** + * Encodes the specified CollectionMessage message. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages. + * @function encode + * @memberof proto.CollectionMessage + * @static + * @param {proto.ICollectionMessage} message CollectionMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CollectionMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.bizJid != null && Object.hasOwnProperty.call(message, "bizJid")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.bizJid); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.id); + if (message.messageVersion != null && Object.hasOwnProperty.call(message, "messageVersion")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.messageVersion); + return writer; + }; + + /** + * Encodes the specified CollectionMessage message, length delimited. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.CollectionMessage + * @static + * @param {proto.ICollectionMessage} message CollectionMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CollectionMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a CollectionMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.CollectionMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.CollectionMessage} CollectionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CollectionMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CollectionMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.bizJid = reader.string(); + break; + case 2: + message.id = reader.string(); + break; + case 3: + message.messageVersion = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a CollectionMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.CollectionMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.CollectionMessage} CollectionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CollectionMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a CollectionMessage message. + * @function verify + * @memberof proto.CollectionMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + CollectionMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.bizJid != null && message.hasOwnProperty("bizJid")) + if (!$util.isString(message.bizJid)) + return "bizJid: string expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) + if (!$util.isInteger(message.messageVersion)) + return "messageVersion: integer expected"; + return null; + }; + + /** + * Creates a CollectionMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.CollectionMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.CollectionMessage} CollectionMessage + */ + CollectionMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.CollectionMessage) + return object; + var message = new $root.proto.CollectionMessage(); + if (object.bizJid != null) + message.bizJid = String(object.bizJid); + if (object.id != null) + message.id = String(object.id); + if (object.messageVersion != null) + message.messageVersion = object.messageVersion | 0; + return message; + }; + + /** + * Creates a plain object from a CollectionMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.CollectionMessage + * @static + * @param {proto.CollectionMessage} message CollectionMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + CollectionMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.bizJid = ""; + object.id = ""; + object.messageVersion = 0; + } + if (message.bizJid != null && message.hasOwnProperty("bizJid")) + object.bizJid = message.bizJid; + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) + object.messageVersion = message.messageVersion; + return object; + }; + + /** + * Converts this CollectionMessage to JSON. + * @function toJSON + * @memberof proto.CollectionMessage + * @instance + * @returns {Object.} JSON object + */ + CollectionMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return CollectionMessage; + })(); + + proto.NativeFlowButton = (function() { + + /** + * Properties of a NativeFlowButton. + * @memberof proto + * @interface INativeFlowButton + * @property {string|null} [name] NativeFlowButton name + * @property {string|null} [buttonParamsJson] NativeFlowButton buttonParamsJson + */ + + /** + * Constructs a new NativeFlowButton. + * @memberof proto + * @classdesc Represents a NativeFlowButton. + * @implements INativeFlowButton + * @constructor + * @param {proto.INativeFlowButton=} [properties] Properties to set + */ + function NativeFlowButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * NativeFlowButton name. + * @member {string} name + * @memberof proto.NativeFlowButton + * @instance + */ + NativeFlowButton.prototype.name = ""; + + /** + * NativeFlowButton buttonParamsJson. + * @member {string} buttonParamsJson + * @memberof proto.NativeFlowButton + * @instance + */ + NativeFlowButton.prototype.buttonParamsJson = ""; + + /** + * Creates a new NativeFlowButton instance using the specified properties. + * @function create + * @memberof proto.NativeFlowButton + * @static + * @param {proto.INativeFlowButton=} [properties] Properties to set + * @returns {proto.NativeFlowButton} NativeFlowButton instance + */ + NativeFlowButton.create = function create(properties) { + return new NativeFlowButton(properties); + }; + + /** + * Encodes the specified NativeFlowButton message. Does not implicitly {@link proto.NativeFlowButton.verify|verify} messages. + * @function encode + * @memberof proto.NativeFlowButton + * @static + * @param {proto.INativeFlowButton} message NativeFlowButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + NativeFlowButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.name); + if (message.buttonParamsJson != null && Object.hasOwnProperty.call(message, "buttonParamsJson")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.buttonParamsJson); + return writer; + }; + + /** + * Encodes the specified NativeFlowButton message, length delimited. Does not implicitly {@link proto.NativeFlowButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.NativeFlowButton + * @static + * @param {proto.INativeFlowButton} message NativeFlowButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + NativeFlowButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a NativeFlowButton message from the specified reader or buffer. + * @function decode + * @memberof proto.NativeFlowButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.NativeFlowButton} NativeFlowButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + NativeFlowButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NativeFlowButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.name = reader.string(); + break; + case 2: + message.buttonParamsJson = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a NativeFlowButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.NativeFlowButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.NativeFlowButton} NativeFlowButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + NativeFlowButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a NativeFlowButton message. + * @function verify + * @memberof proto.NativeFlowButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + NativeFlowButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + if (message.buttonParamsJson != null && message.hasOwnProperty("buttonParamsJson")) + if (!$util.isString(message.buttonParamsJson)) + return "buttonParamsJson: string expected"; + return null; + }; + + /** + * Creates a NativeFlowButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.NativeFlowButton + * @static + * @param {Object.} object Plain object + * @returns {proto.NativeFlowButton} NativeFlowButton + */ + NativeFlowButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.NativeFlowButton) + return object; + var message = new $root.proto.NativeFlowButton(); + if (object.name != null) + message.name = String(object.name); + if (object.buttonParamsJson != null) + message.buttonParamsJson = String(object.buttonParamsJson); + return message; + }; + + /** + * Creates a plain object from a NativeFlowButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.NativeFlowButton + * @static + * @param {proto.NativeFlowButton} message NativeFlowButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + NativeFlowButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.name = ""; + object.buttonParamsJson = ""; + } + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.buttonParamsJson != null && message.hasOwnProperty("buttonParamsJson")) + object.buttonParamsJson = message.buttonParamsJson; + return object; + }; + + /** + * Converts this NativeFlowButton to JSON. + * @function toJSON + * @memberof proto.NativeFlowButton + * @instance + * @returns {Object.} JSON object + */ + NativeFlowButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return NativeFlowButton; + })(); + + proto.NativeFlowMessage = (function() { + + /** + * Properties of a NativeFlowMessage. + * @memberof proto + * @interface INativeFlowMessage + * @property {Array.|null} [buttons] NativeFlowMessage buttons + * @property {string|null} [messageParamsJson] NativeFlowMessage messageParamsJson + * @property {number|null} [messageVersion] NativeFlowMessage messageVersion + */ + + /** + * Constructs a new NativeFlowMessage. + * @memberof proto + * @classdesc Represents a NativeFlowMessage. + * @implements INativeFlowMessage + * @constructor + * @param {proto.INativeFlowMessage=} [properties] Properties to set + */ + function NativeFlowMessage(properties) { + this.buttons = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * NativeFlowMessage buttons. + * @member {Array.} buttons + * @memberof proto.NativeFlowMessage + * @instance + */ + NativeFlowMessage.prototype.buttons = $util.emptyArray; + + /** + * NativeFlowMessage messageParamsJson. + * @member {string} messageParamsJson + * @memberof proto.NativeFlowMessage + * @instance + */ + NativeFlowMessage.prototype.messageParamsJson = ""; + + /** + * NativeFlowMessage messageVersion. + * @member {number} messageVersion + * @memberof proto.NativeFlowMessage + * @instance + */ + NativeFlowMessage.prototype.messageVersion = 0; + + /** + * Creates a new NativeFlowMessage instance using the specified properties. + * @function create + * @memberof proto.NativeFlowMessage + * @static + * @param {proto.INativeFlowMessage=} [properties] Properties to set + * @returns {proto.NativeFlowMessage} NativeFlowMessage instance + */ + NativeFlowMessage.create = function create(properties) { + return new NativeFlowMessage(properties); + }; + + /** + * Encodes the specified NativeFlowMessage message. Does not implicitly {@link proto.NativeFlowMessage.verify|verify} messages. + * @function encode + * @memberof proto.NativeFlowMessage + * @static + * @param {proto.INativeFlowMessage} message NativeFlowMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + NativeFlowMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.buttons != null && message.buttons.length) + for (var i = 0; i < message.buttons.length; ++i) + $root.proto.NativeFlowButton.encode(message.buttons[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.messageParamsJson != null && Object.hasOwnProperty.call(message, "messageParamsJson")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.messageParamsJson); + if (message.messageVersion != null && Object.hasOwnProperty.call(message, "messageVersion")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.messageVersion); + return writer; + }; + + /** + * Encodes the specified NativeFlowMessage message, length delimited. Does not implicitly {@link proto.NativeFlowMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.NativeFlowMessage + * @static + * @param {proto.INativeFlowMessage} message NativeFlowMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + NativeFlowMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a NativeFlowMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.NativeFlowMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.NativeFlowMessage} NativeFlowMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + NativeFlowMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NativeFlowMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.buttons && message.buttons.length)) + message.buttons = []; + message.buttons.push($root.proto.NativeFlowButton.decode(reader, reader.uint32())); + break; + case 2: + message.messageParamsJson = reader.string(); + break; + case 3: + message.messageVersion = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a NativeFlowMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.NativeFlowMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.NativeFlowMessage} NativeFlowMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + NativeFlowMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a NativeFlowMessage message. + * @function verify + * @memberof proto.NativeFlowMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + NativeFlowMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.buttons != null && message.hasOwnProperty("buttons")) { + if (!Array.isArray(message.buttons)) + return "buttons: array expected"; + for (var i = 0; i < message.buttons.length; ++i) { + var error = $root.proto.NativeFlowButton.verify(message.buttons[i]); + if (error) + return "buttons." + error; + } + } + if (message.messageParamsJson != null && message.hasOwnProperty("messageParamsJson")) + if (!$util.isString(message.messageParamsJson)) + return "messageParamsJson: string expected"; + if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) + if (!$util.isInteger(message.messageVersion)) + return "messageVersion: integer expected"; + return null; + }; + + /** + * Creates a NativeFlowMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.NativeFlowMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.NativeFlowMessage} NativeFlowMessage + */ + NativeFlowMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.NativeFlowMessage) + return object; + var message = new $root.proto.NativeFlowMessage(); + if (object.buttons) { + if (!Array.isArray(object.buttons)) + throw TypeError(".proto.NativeFlowMessage.buttons: array expected"); + message.buttons = []; + for (var i = 0; i < object.buttons.length; ++i) { + if (typeof object.buttons[i] !== "object") + throw TypeError(".proto.NativeFlowMessage.buttons: object expected"); + message.buttons[i] = $root.proto.NativeFlowButton.fromObject(object.buttons[i]); + } + } + if (object.messageParamsJson != null) + message.messageParamsJson = String(object.messageParamsJson); + if (object.messageVersion != null) + message.messageVersion = object.messageVersion | 0; + return message; + }; + + /** + * Creates a plain object from a NativeFlowMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.NativeFlowMessage + * @static + * @param {proto.NativeFlowMessage} message NativeFlowMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + NativeFlowMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.buttons = []; + if (options.defaults) { + object.messageParamsJson = ""; + object.messageVersion = 0; + } + if (message.buttons && message.buttons.length) { + object.buttons = []; + for (var j = 0; j < message.buttons.length; ++j) + object.buttons[j] = $root.proto.NativeFlowButton.toObject(message.buttons[j], options); + } + if (message.messageParamsJson != null && message.hasOwnProperty("messageParamsJson")) + object.messageParamsJson = message.messageParamsJson; + if (message.messageVersion != null && message.hasOwnProperty("messageVersion")) + object.messageVersion = message.messageVersion; + return object; + }; + + /** + * Converts this NativeFlowMessage to JSON. + * @function toJSON + * @memberof proto.NativeFlowMessage + * @instance + * @returns {Object.} JSON object + */ + NativeFlowMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return NativeFlowMessage; + })(); + + proto.InteractiveMessage = (function() { + + /** + * Properties of an InteractiveMessage. + * @memberof proto + * @interface IInteractiveMessage + * @property {proto.IHeader|null} [header] InteractiveMessage header + * @property {proto.IBody|null} [body] InteractiveMessage body + * @property {proto.IFooter|null} [footer] InteractiveMessage footer + * @property {proto.IContextInfo|null} [contextInfo] InteractiveMessage contextInfo + * @property {proto.IShopMessage|null} [shopStorefrontMessage] InteractiveMessage shopStorefrontMessage + * @property {proto.ICollectionMessage|null} [collectionMessage] InteractiveMessage collectionMessage + * @property {proto.INativeFlowMessage|null} [nativeFlowMessage] InteractiveMessage nativeFlowMessage + */ + + /** + * Constructs a new InteractiveMessage. + * @memberof proto + * @classdesc Represents an InteractiveMessage. + * @implements IInteractiveMessage + * @constructor + * @param {proto.IInteractiveMessage=} [properties] Properties to set + */ + function InteractiveMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * InteractiveMessage header. + * @member {proto.IHeader|null|undefined} header + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.header = null; + + /** + * InteractiveMessage body. + * @member {proto.IBody|null|undefined} body + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.body = null; + + /** + * InteractiveMessage footer. + * @member {proto.IFooter|null|undefined} footer + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.footer = null; + + /** + * InteractiveMessage contextInfo. + * @member {proto.IContextInfo|null|undefined} contextInfo + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.contextInfo = null; + + /** + * InteractiveMessage shopStorefrontMessage. + * @member {proto.IShopMessage|null|undefined} shopStorefrontMessage + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.shopStorefrontMessage = null; + + /** + * InteractiveMessage collectionMessage. + * @member {proto.ICollectionMessage|null|undefined} collectionMessage + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.collectionMessage = null; + + /** + * InteractiveMessage nativeFlowMessage. + * @member {proto.INativeFlowMessage|null|undefined} nativeFlowMessage + * @memberof proto.InteractiveMessage + * @instance + */ + InteractiveMessage.prototype.nativeFlowMessage = null; + + // OneOf field names bound to virtual getters and setters + var $oneOfFields; + + /** + * InteractiveMessage interactiveMessage. + * @member {"shopStorefrontMessage"|"collectionMessage"|"nativeFlowMessage"|undefined} interactiveMessage + * @memberof proto.InteractiveMessage + * @instance + */ + Object.defineProperty(InteractiveMessage.prototype, "interactiveMessage", { + get: $util.oneOfGetter($oneOfFields = ["shopStorefrontMessage", "collectionMessage", "nativeFlowMessage"]), + set: $util.oneOfSetter($oneOfFields) + }); + + /** + * Creates a new InteractiveMessage instance using the specified properties. + * @function create + * @memberof proto.InteractiveMessage + * @static + * @param {proto.IInteractiveMessage=} [properties] Properties to set + * @returns {proto.InteractiveMessage} InteractiveMessage instance + */ + InteractiveMessage.create = function create(properties) { + return new InteractiveMessage(properties); + }; + + /** + * Encodes the specified InteractiveMessage message. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages. + * @function encode + * @memberof proto.InteractiveMessage + * @static + * @param {proto.IInteractiveMessage} message InteractiveMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + InteractiveMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.header != null && Object.hasOwnProperty.call(message, "header")) + $root.proto.Header.encode(message.header, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.body != null && Object.hasOwnProperty.call(message, "body")) + $root.proto.Body.encode(message.body, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.footer != null && Object.hasOwnProperty.call(message, "footer")) + $root.proto.Footer.encode(message.footer, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.shopStorefrontMessage != null && Object.hasOwnProperty.call(message, "shopStorefrontMessage")) + $root.proto.ShopMessage.encode(message.shopStorefrontMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + if (message.collectionMessage != null && Object.hasOwnProperty.call(message, "collectionMessage")) + $root.proto.CollectionMessage.encode(message.collectionMessage, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + if (message.nativeFlowMessage != null && Object.hasOwnProperty.call(message, "nativeFlowMessage")) + $root.proto.NativeFlowMessage.encode(message.nativeFlowMessage, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo")) + $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified InteractiveMessage message, length delimited. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.InteractiveMessage + * @static + * @param {proto.IInteractiveMessage} message InteractiveMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + InteractiveMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an InteractiveMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.InteractiveMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.InteractiveMessage} InteractiveMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + InteractiveMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.InteractiveMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.header = $root.proto.Header.decode(reader, reader.uint32()); + break; + case 2: + message.body = $root.proto.Body.decode(reader, reader.uint32()); + break; + case 3: + message.footer = $root.proto.Footer.decode(reader, reader.uint32()); + break; + case 15: + message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32()); + break; + case 4: + message.shopStorefrontMessage = $root.proto.ShopMessage.decode(reader, reader.uint32()); + break; + case 5: + message.collectionMessage = $root.proto.CollectionMessage.decode(reader, reader.uint32()); + break; + case 6: + message.nativeFlowMessage = $root.proto.NativeFlowMessage.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an InteractiveMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.InteractiveMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.InteractiveMessage} InteractiveMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + InteractiveMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an InteractiveMessage message. + * @function verify + * @memberof proto.InteractiveMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + InteractiveMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var properties = {}; + if (message.header != null && message.hasOwnProperty("header")) { + var error = $root.proto.Header.verify(message.header); + if (error) + return "header." + error; + } + if (message.body != null && message.hasOwnProperty("body")) { + var error = $root.proto.Body.verify(message.body); + if (error) + return "body." + error; + } + if (message.footer != null && message.hasOwnProperty("footer")) { + var error = $root.proto.Footer.verify(message.footer); + if (error) + return "footer." + error; + } + if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) { + var error = $root.proto.ContextInfo.verify(message.contextInfo); + if (error) + return "contextInfo." + error; + } + if (message.shopStorefrontMessage != null && message.hasOwnProperty("shopStorefrontMessage")) { + properties.interactiveMessage = 1; + { + var error = $root.proto.ShopMessage.verify(message.shopStorefrontMessage); + if (error) + return "shopStorefrontMessage." + error; + } + } + if (message.collectionMessage != null && message.hasOwnProperty("collectionMessage")) { + if (properties.interactiveMessage === 1) + return "interactiveMessage: multiple values"; + properties.interactiveMessage = 1; + { + var error = $root.proto.CollectionMessage.verify(message.collectionMessage); + if (error) + return "collectionMessage." + error; + } + } + if (message.nativeFlowMessage != null && message.hasOwnProperty("nativeFlowMessage")) { + if (properties.interactiveMessage === 1) + return "interactiveMessage: multiple values"; + properties.interactiveMessage = 1; + { + var error = $root.proto.NativeFlowMessage.verify(message.nativeFlowMessage); + if (error) + return "nativeFlowMessage." + error; + } + } + return null; + }; + + /** + * Creates an InteractiveMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.InteractiveMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.InteractiveMessage} InteractiveMessage + */ + InteractiveMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.InteractiveMessage) + return object; + var message = new $root.proto.InteractiveMessage(); + if (object.header != null) { + if (typeof object.header !== "object") + throw TypeError(".proto.InteractiveMessage.header: object expected"); + message.header = $root.proto.Header.fromObject(object.header); + } + if (object.body != null) { + if (typeof object.body !== "object") + throw TypeError(".proto.InteractiveMessage.body: object expected"); + message.body = $root.proto.Body.fromObject(object.body); + } + if (object.footer != null) { + if (typeof object.footer !== "object") + throw TypeError(".proto.InteractiveMessage.footer: object expected"); + message.footer = $root.proto.Footer.fromObject(object.footer); + } + if (object.contextInfo != null) { + if (typeof object.contextInfo !== "object") + throw TypeError(".proto.InteractiveMessage.contextInfo: object expected"); + message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo); + } + if (object.shopStorefrontMessage != null) { + if (typeof object.shopStorefrontMessage !== "object") + throw TypeError(".proto.InteractiveMessage.shopStorefrontMessage: object expected"); + message.shopStorefrontMessage = $root.proto.ShopMessage.fromObject(object.shopStorefrontMessage); + } + if (object.collectionMessage != null) { + if (typeof object.collectionMessage !== "object") + throw TypeError(".proto.InteractiveMessage.collectionMessage: object expected"); + message.collectionMessage = $root.proto.CollectionMessage.fromObject(object.collectionMessage); + } + if (object.nativeFlowMessage != null) { + if (typeof object.nativeFlowMessage !== "object") + throw TypeError(".proto.InteractiveMessage.nativeFlowMessage: object expected"); + message.nativeFlowMessage = $root.proto.NativeFlowMessage.fromObject(object.nativeFlowMessage); + } + return message; + }; + + /** + * Creates a plain object from an InteractiveMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.InteractiveMessage + * @static + * @param {proto.InteractiveMessage} message InteractiveMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + InteractiveMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.header = null; + object.body = null; + object.footer = null; + object.contextInfo = null; + } + if (message.header != null && message.hasOwnProperty("header")) + object.header = $root.proto.Header.toObject(message.header, options); + if (message.body != null && message.hasOwnProperty("body")) + object.body = $root.proto.Body.toObject(message.body, options); + if (message.footer != null && message.hasOwnProperty("footer")) + object.footer = $root.proto.Footer.toObject(message.footer, options); + if (message.shopStorefrontMessage != null && message.hasOwnProperty("shopStorefrontMessage")) { + object.shopStorefrontMessage = $root.proto.ShopMessage.toObject(message.shopStorefrontMessage, options); + if (options.oneofs) + object.interactiveMessage = "shopStorefrontMessage"; + } + if (message.collectionMessage != null && message.hasOwnProperty("collectionMessage")) { + object.collectionMessage = $root.proto.CollectionMessage.toObject(message.collectionMessage, options); + if (options.oneofs) + object.interactiveMessage = "collectionMessage"; + } + if (message.nativeFlowMessage != null && message.hasOwnProperty("nativeFlowMessage")) { + object.nativeFlowMessage = $root.proto.NativeFlowMessage.toObject(message.nativeFlowMessage, options); + if (options.oneofs) + object.interactiveMessage = "nativeFlowMessage"; + } + if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) + object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options); + return object; + }; + + /** + * Converts this InteractiveMessage to JSON. + * @function toJSON + * @memberof proto.InteractiveMessage + * @instance + * @returns {Object.} JSON object + */ + InteractiveMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return InteractiveMessage; + })(); + proto.GroupInviteMessage = (function() { /** @@ -40821,6 +42442,7 @@ $root.proto = (function() { * @property {Uint8Array|null} [jpegThumbnail] GroupInviteMessage jpegThumbnail * @property {string|null} [caption] GroupInviteMessage caption * @property {proto.IContextInfo|null} [contextInfo] GroupInviteMessage contextInfo + * @property {proto.GroupInviteMessage.GroupInviteMessageGroupType|null} [groupType] GroupInviteMessage groupType */ /** @@ -40894,6 +42516,14 @@ $root.proto = (function() { */ GroupInviteMessage.prototype.contextInfo = null; + /** + * GroupInviteMessage groupType. + * @member {proto.GroupInviteMessage.GroupInviteMessageGroupType} groupType + * @memberof proto.GroupInviteMessage + * @instance + */ + GroupInviteMessage.prototype.groupType = 0; + /** * Creates a new GroupInviteMessage instance using the specified properties. * @function create @@ -40932,6 +42562,8 @@ $root.proto = (function() { writer.uint32(/* id 6, wireType 2 =*/50).string(message.caption); if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo")) $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim(); + if (message.groupType != null && Object.hasOwnProperty.call(message, "groupType")) + writer.uint32(/* id 8, wireType 0 =*/64).int32(message.groupType); return writer; }; @@ -40987,6 +42619,9 @@ $root.proto = (function() { case 7: message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32()); break; + case 8: + message.groupType = reader.int32(); + break; default: reader.skipType(tag & 7); break; @@ -41045,6 +42680,14 @@ $root.proto = (function() { if (error) return "contextInfo." + error; } + if (message.groupType != null && message.hasOwnProperty("groupType")) + switch (message.groupType) { + default: + return "groupType: enum value expected"; + case 0: + case 1: + break; + } return null; }; @@ -41087,6 +42730,16 @@ $root.proto = (function() { throw TypeError(".proto.GroupInviteMessage.contextInfo: object expected"); message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo); } + switch (object.groupType) { + case "DEFAULT": + case 0: + message.groupType = 0; + break; + case "PARENT": + case 1: + message.groupType = 1; + break; + } return message; }; @@ -41121,6 +42774,7 @@ $root.proto = (function() { } object.caption = ""; object.contextInfo = null; + object.groupType = options.enums === String ? "DEFAULT" : 0; } if (message.groupJid != null && message.hasOwnProperty("groupJid")) object.groupJid = message.groupJid; @@ -41139,6 +42793,8 @@ $root.proto = (function() { object.caption = message.caption; if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options); + if (message.groupType != null && message.hasOwnProperty("groupType")) + object.groupType = options.enums === String ? $root.proto.GroupInviteMessage.GroupInviteMessageGroupType[message.groupType] : message.groupType; return object; }; @@ -41153,6 +42809,20 @@ $root.proto = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * GroupInviteMessageGroupType enum. + * @name proto.GroupInviteMessage.GroupInviteMessageGroupType + * @enum {number} + * @property {number} DEFAULT=0 DEFAULT value + * @property {number} PARENT=1 PARENT value + */ + GroupInviteMessage.GroupInviteMessageGroupType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "DEFAULT"] = 0; + values[valuesById[1] = "PARENT"] = 1; + return values; + })(); + return GroupInviteMessage; })(); @@ -43127,6 +44797,542 @@ $root.proto = (function() { return ButtonsResponseMessage; })(); + proto.ReactionMessage = (function() { + + /** + * Properties of a ReactionMessage. + * @memberof proto + * @interface IReactionMessage + * @property {proto.IMessageKey|null} [key] ReactionMessage key + * @property {string|null} [text] ReactionMessage text + * @property {string|null} [groupingKey] ReactionMessage groupingKey + * @property {number|Long|null} [senderTimestampMs] ReactionMessage senderTimestampMs + */ + + /** + * Constructs a new ReactionMessage. + * @memberof proto + * @classdesc Represents a ReactionMessage. + * @implements IReactionMessage + * @constructor + * @param {proto.IReactionMessage=} [properties] Properties to set + */ + function ReactionMessage(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ReactionMessage key. + * @member {proto.IMessageKey|null|undefined} key + * @memberof proto.ReactionMessage + * @instance + */ + ReactionMessage.prototype.key = null; + + /** + * ReactionMessage text. + * @member {string} text + * @memberof proto.ReactionMessage + * @instance + */ + ReactionMessage.prototype.text = ""; + + /** + * ReactionMessage groupingKey. + * @member {string} groupingKey + * @memberof proto.ReactionMessage + * @instance + */ + ReactionMessage.prototype.groupingKey = ""; + + /** + * ReactionMessage senderTimestampMs. + * @member {number|Long} senderTimestampMs + * @memberof proto.ReactionMessage + * @instance + */ + ReactionMessage.prototype.senderTimestampMs = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new ReactionMessage instance using the specified properties. + * @function create + * @memberof proto.ReactionMessage + * @static + * @param {proto.IReactionMessage=} [properties] Properties to set + * @returns {proto.ReactionMessage} ReactionMessage instance + */ + ReactionMessage.create = function create(properties) { + return new ReactionMessage(properties); + }; + + /** + * Encodes the specified ReactionMessage message. Does not implicitly {@link proto.ReactionMessage.verify|verify} messages. + * @function encode + * @memberof proto.ReactionMessage + * @static + * @param {proto.IReactionMessage} message ReactionMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ReactionMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.key != null && Object.hasOwnProperty.call(message, "key")) + $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.text != null && Object.hasOwnProperty.call(message, "text")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.text); + if (message.groupingKey != null && Object.hasOwnProperty.call(message, "groupingKey")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.groupingKey); + if (message.senderTimestampMs != null && Object.hasOwnProperty.call(message, "senderTimestampMs")) + writer.uint32(/* id 4, wireType 0 =*/32).int64(message.senderTimestampMs); + return writer; + }; + + /** + * Encodes the specified ReactionMessage message, length delimited. Does not implicitly {@link proto.ReactionMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ReactionMessage + * @static + * @param {proto.IReactionMessage} message ReactionMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ReactionMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ReactionMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.ReactionMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ReactionMessage} ReactionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ReactionMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ReactionMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.key = $root.proto.MessageKey.decode(reader, reader.uint32()); + break; + case 2: + message.text = reader.string(); + break; + case 3: + message.groupingKey = reader.string(); + break; + case 4: + message.senderTimestampMs = reader.int64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ReactionMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ReactionMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ReactionMessage} ReactionMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ReactionMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ReactionMessage message. + * @function verify + * @memberof proto.ReactionMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ReactionMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.key != null && message.hasOwnProperty("key")) { + var error = $root.proto.MessageKey.verify(message.key); + if (error) + return "key." + error; + } + if (message.text != null && message.hasOwnProperty("text")) + if (!$util.isString(message.text)) + return "text: string expected"; + if (message.groupingKey != null && message.hasOwnProperty("groupingKey")) + if (!$util.isString(message.groupingKey)) + return "groupingKey: string expected"; + if (message.senderTimestampMs != null && message.hasOwnProperty("senderTimestampMs")) + if (!$util.isInteger(message.senderTimestampMs) && !(message.senderTimestampMs && $util.isInteger(message.senderTimestampMs.low) && $util.isInteger(message.senderTimestampMs.high))) + return "senderTimestampMs: integer|Long expected"; + return null; + }; + + /** + * Creates a ReactionMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ReactionMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.ReactionMessage} ReactionMessage + */ + ReactionMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ReactionMessage) + return object; + var message = new $root.proto.ReactionMessage(); + if (object.key != null) { + if (typeof object.key !== "object") + throw TypeError(".proto.ReactionMessage.key: object expected"); + message.key = $root.proto.MessageKey.fromObject(object.key); + } + if (object.text != null) + message.text = String(object.text); + if (object.groupingKey != null) + message.groupingKey = String(object.groupingKey); + if (object.senderTimestampMs != null) + if ($util.Long) + (message.senderTimestampMs = $util.Long.fromValue(object.senderTimestampMs)).unsigned = false; + else if (typeof object.senderTimestampMs === "string") + message.senderTimestampMs = parseInt(object.senderTimestampMs, 10); + else if (typeof object.senderTimestampMs === "number") + message.senderTimestampMs = object.senderTimestampMs; + else if (typeof object.senderTimestampMs === "object") + message.senderTimestampMs = new $util.LongBits(object.senderTimestampMs.low >>> 0, object.senderTimestampMs.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from a ReactionMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ReactionMessage + * @static + * @param {proto.ReactionMessage} message ReactionMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ReactionMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.key = null; + object.text = ""; + object.groupingKey = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.senderTimestampMs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.senderTimestampMs = options.longs === String ? "0" : 0; + } + if (message.key != null && message.hasOwnProperty("key")) + object.key = $root.proto.MessageKey.toObject(message.key, options); + if (message.text != null && message.hasOwnProperty("text")) + object.text = message.text; + if (message.groupingKey != null && message.hasOwnProperty("groupingKey")) + object.groupingKey = message.groupingKey; + if (message.senderTimestampMs != null && message.hasOwnProperty("senderTimestampMs")) + if (typeof message.senderTimestampMs === "number") + object.senderTimestampMs = options.longs === String ? String(message.senderTimestampMs) : message.senderTimestampMs; + else + object.senderTimestampMs = options.longs === String ? $util.Long.prototype.toString.call(message.senderTimestampMs) : options.longs === Number ? new $util.LongBits(message.senderTimestampMs.low >>> 0, message.senderTimestampMs.high >>> 0).toNumber() : message.senderTimestampMs; + return object; + }; + + /** + * Converts this ReactionMessage to JSON. + * @function toJSON + * @memberof proto.ReactionMessage + * @instance + * @returns {Object.} JSON object + */ + ReactionMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ReactionMessage; + })(); + + proto.StickerSyncRMRMessage = (function() { + + /** + * Properties of a StickerSyncRMRMessage. + * @memberof proto + * @interface IStickerSyncRMRMessage + * @property {Array.|null} [filehash] StickerSyncRMRMessage filehash + * @property {string|null} [rmrSource] StickerSyncRMRMessage rmrSource + * @property {number|Long|null} [requestTimestamp] StickerSyncRMRMessage requestTimestamp + */ + + /** + * Constructs a new StickerSyncRMRMessage. + * @memberof proto + * @classdesc Represents a StickerSyncRMRMessage. + * @implements IStickerSyncRMRMessage + * @constructor + * @param {proto.IStickerSyncRMRMessage=} [properties] Properties to set + */ + function StickerSyncRMRMessage(properties) { + this.filehash = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * StickerSyncRMRMessage filehash. + * @member {Array.} filehash + * @memberof proto.StickerSyncRMRMessage + * @instance + */ + StickerSyncRMRMessage.prototype.filehash = $util.emptyArray; + + /** + * StickerSyncRMRMessage rmrSource. + * @member {string} rmrSource + * @memberof proto.StickerSyncRMRMessage + * @instance + */ + StickerSyncRMRMessage.prototype.rmrSource = ""; + + /** + * StickerSyncRMRMessage requestTimestamp. + * @member {number|Long} requestTimestamp + * @memberof proto.StickerSyncRMRMessage + * @instance + */ + StickerSyncRMRMessage.prototype.requestTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new StickerSyncRMRMessage instance using the specified properties. + * @function create + * @memberof proto.StickerSyncRMRMessage + * @static + * @param {proto.IStickerSyncRMRMessage=} [properties] Properties to set + * @returns {proto.StickerSyncRMRMessage} StickerSyncRMRMessage instance + */ + StickerSyncRMRMessage.create = function create(properties) { + return new StickerSyncRMRMessage(properties); + }; + + /** + * Encodes the specified StickerSyncRMRMessage message. Does not implicitly {@link proto.StickerSyncRMRMessage.verify|verify} messages. + * @function encode + * @memberof proto.StickerSyncRMRMessage + * @static + * @param {proto.IStickerSyncRMRMessage} message StickerSyncRMRMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + StickerSyncRMRMessage.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.filehash != null && message.filehash.length) + for (var i = 0; i < message.filehash.length; ++i) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.filehash[i]); + if (message.rmrSource != null && Object.hasOwnProperty.call(message, "rmrSource")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.rmrSource); + if (message.requestTimestamp != null && Object.hasOwnProperty.call(message, "requestTimestamp")) + writer.uint32(/* id 3, wireType 0 =*/24).int64(message.requestTimestamp); + return writer; + }; + + /** + * Encodes the specified StickerSyncRMRMessage message, length delimited. Does not implicitly {@link proto.StickerSyncRMRMessage.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.StickerSyncRMRMessage + * @static + * @param {proto.IStickerSyncRMRMessage} message StickerSyncRMRMessage message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + StickerSyncRMRMessage.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a StickerSyncRMRMessage message from the specified reader or buffer. + * @function decode + * @memberof proto.StickerSyncRMRMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.StickerSyncRMRMessage} StickerSyncRMRMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + StickerSyncRMRMessage.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.StickerSyncRMRMessage(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.filehash && message.filehash.length)) + message.filehash = []; + message.filehash.push(reader.string()); + break; + case 2: + message.rmrSource = reader.string(); + break; + case 3: + message.requestTimestamp = reader.int64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a StickerSyncRMRMessage message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.StickerSyncRMRMessage + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.StickerSyncRMRMessage} StickerSyncRMRMessage + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + StickerSyncRMRMessage.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a StickerSyncRMRMessage message. + * @function verify + * @memberof proto.StickerSyncRMRMessage + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + StickerSyncRMRMessage.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.filehash != null && message.hasOwnProperty("filehash")) { + if (!Array.isArray(message.filehash)) + return "filehash: array expected"; + for (var i = 0; i < message.filehash.length; ++i) + if (!$util.isString(message.filehash[i])) + return "filehash: string[] expected"; + } + if (message.rmrSource != null && message.hasOwnProperty("rmrSource")) + if (!$util.isString(message.rmrSource)) + return "rmrSource: string expected"; + if (message.requestTimestamp != null && message.hasOwnProperty("requestTimestamp")) + if (!$util.isInteger(message.requestTimestamp) && !(message.requestTimestamp && $util.isInteger(message.requestTimestamp.low) && $util.isInteger(message.requestTimestamp.high))) + return "requestTimestamp: integer|Long expected"; + return null; + }; + + /** + * Creates a StickerSyncRMRMessage message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.StickerSyncRMRMessage + * @static + * @param {Object.} object Plain object + * @returns {proto.StickerSyncRMRMessage} StickerSyncRMRMessage + */ + StickerSyncRMRMessage.fromObject = function fromObject(object) { + if (object instanceof $root.proto.StickerSyncRMRMessage) + return object; + var message = new $root.proto.StickerSyncRMRMessage(); + if (object.filehash) { + if (!Array.isArray(object.filehash)) + throw TypeError(".proto.StickerSyncRMRMessage.filehash: array expected"); + message.filehash = []; + for (var i = 0; i < object.filehash.length; ++i) + message.filehash[i] = String(object.filehash[i]); + } + if (object.rmrSource != null) + message.rmrSource = String(object.rmrSource); + if (object.requestTimestamp != null) + if ($util.Long) + (message.requestTimestamp = $util.Long.fromValue(object.requestTimestamp)).unsigned = false; + else if (typeof object.requestTimestamp === "string") + message.requestTimestamp = parseInt(object.requestTimestamp, 10); + else if (typeof object.requestTimestamp === "number") + message.requestTimestamp = object.requestTimestamp; + else if (typeof object.requestTimestamp === "object") + message.requestTimestamp = new $util.LongBits(object.requestTimestamp.low >>> 0, object.requestTimestamp.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from a StickerSyncRMRMessage message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.StickerSyncRMRMessage + * @static + * @param {proto.StickerSyncRMRMessage} message StickerSyncRMRMessage + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + StickerSyncRMRMessage.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.filehash = []; + if (options.defaults) { + object.rmrSource = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.requestTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.requestTimestamp = options.longs === String ? "0" : 0; + } + if (message.filehash && message.filehash.length) { + object.filehash = []; + for (var j = 0; j < message.filehash.length; ++j) + object.filehash[j] = message.filehash[j]; + } + if (message.rmrSource != null && message.hasOwnProperty("rmrSource")) + object.rmrSource = message.rmrSource; + if (message.requestTimestamp != null && message.hasOwnProperty("requestTimestamp")) + if (typeof message.requestTimestamp === "number") + object.requestTimestamp = options.longs === String ? String(message.requestTimestamp) : message.requestTimestamp; + else + object.requestTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.requestTimestamp) : options.longs === Number ? new $util.LongBits(message.requestTimestamp.low >>> 0, message.requestTimestamp.high >>> 0).toNumber() : message.requestTimestamp; + return object; + }; + + /** + * Converts this StickerSyncRMRMessage to JSON. + * @function toJSON + * @memberof proto.StickerSyncRMRMessage + * @instance + * @returns {Object.} JSON object + */ + StickerSyncRMRMessage.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return StickerSyncRMRMessage; + })(); + proto.Message = (function() { /** @@ -43169,6 +45375,9 @@ $root.proto = (function() { * @property {proto.IButtonsMessage|null} [buttonsMessage] Message buttonsMessage * @property {proto.IButtonsResponseMessage|null} [buttonsResponseMessage] Message buttonsResponseMessage * @property {proto.IPaymentInviteMessage|null} [paymentInviteMessage] Message paymentInviteMessage + * @property {proto.IInteractiveMessage|null} [interactiveMessage] Message interactiveMessage + * @property {proto.IReactionMessage|null} [reactionMessage] Message reactionMessage + * @property {proto.IStickerSyncRMRMessage|null} [stickerSyncRmrMessage] Message stickerSyncRmrMessage */ /** @@ -43474,6 +45683,30 @@ $root.proto = (function() { */ Message.prototype.paymentInviteMessage = null; + /** + * Message interactiveMessage. + * @member {proto.IInteractiveMessage|null|undefined} interactiveMessage + * @memberof proto.Message + * @instance + */ + Message.prototype.interactiveMessage = null; + + /** + * Message reactionMessage. + * @member {proto.IReactionMessage|null|undefined} reactionMessage + * @memberof proto.Message + * @instance + */ + Message.prototype.reactionMessage = null; + + /** + * Message stickerSyncRmrMessage. + * @member {proto.IStickerSyncRMRMessage|null|undefined} stickerSyncRmrMessage + * @memberof proto.Message + * @instance + */ + Message.prototype.stickerSyncRmrMessage = null; + /** * Creates a new Message instance using the specified properties. * @function create @@ -43570,6 +45803,12 @@ $root.proto = (function() { $root.proto.ButtonsResponseMessage.encode(message.buttonsResponseMessage, writer.uint32(/* id 43, wireType 2 =*/346).fork()).ldelim(); if (message.paymentInviteMessage != null && Object.hasOwnProperty.call(message, "paymentInviteMessage")) $root.proto.PaymentInviteMessage.encode(message.paymentInviteMessage, writer.uint32(/* id 44, wireType 2 =*/354).fork()).ldelim(); + if (message.interactiveMessage != null && Object.hasOwnProperty.call(message, "interactiveMessage")) + $root.proto.InteractiveMessage.encode(message.interactiveMessage, writer.uint32(/* id 45, wireType 2 =*/362).fork()).ldelim(); + if (message.reactionMessage != null && Object.hasOwnProperty.call(message, "reactionMessage")) + $root.proto.ReactionMessage.encode(message.reactionMessage, writer.uint32(/* id 46, wireType 2 =*/370).fork()).ldelim(); + if (message.stickerSyncRmrMessage != null && Object.hasOwnProperty.call(message, "stickerSyncRmrMessage")) + $root.proto.StickerSyncRMRMessage.encode(message.stickerSyncRmrMessage, writer.uint32(/* id 47, wireType 2 =*/378).fork()).ldelim(); return writer; }; @@ -43712,6 +45951,15 @@ $root.proto = (function() { case 44: message.paymentInviteMessage = $root.proto.PaymentInviteMessage.decode(reader, reader.uint32()); break; + case 45: + message.interactiveMessage = $root.proto.InteractiveMessage.decode(reader, reader.uint32()); + break; + case 46: + message.reactionMessage = $root.proto.ReactionMessage.decode(reader, reader.uint32()); + break; + case 47: + message.stickerSyncRmrMessage = $root.proto.StickerSyncRMRMessage.decode(reader, reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -43925,6 +46173,21 @@ $root.proto = (function() { if (error) return "paymentInviteMessage." + error; } + if (message.interactiveMessage != null && message.hasOwnProperty("interactiveMessage")) { + var error = $root.proto.InteractiveMessage.verify(message.interactiveMessage); + if (error) + return "interactiveMessage." + error; + } + if (message.reactionMessage != null && message.hasOwnProperty("reactionMessage")) { + var error = $root.proto.ReactionMessage.verify(message.reactionMessage); + if (error) + return "reactionMessage." + error; + } + if (message.stickerSyncRmrMessage != null && message.hasOwnProperty("stickerSyncRmrMessage")) { + var error = $root.proto.StickerSyncRMRMessage.verify(message.stickerSyncRmrMessage); + if (error) + return "stickerSyncRmrMessage." + error; + } return null; }; @@ -44117,6 +46380,21 @@ $root.proto = (function() { throw TypeError(".proto.Message.paymentInviteMessage: object expected"); message.paymentInviteMessage = $root.proto.PaymentInviteMessage.fromObject(object.paymentInviteMessage); } + if (object.interactiveMessage != null) { + if (typeof object.interactiveMessage !== "object") + throw TypeError(".proto.Message.interactiveMessage: object expected"); + message.interactiveMessage = $root.proto.InteractiveMessage.fromObject(object.interactiveMessage); + } + if (object.reactionMessage != null) { + if (typeof object.reactionMessage !== "object") + throw TypeError(".proto.Message.reactionMessage: object expected"); + message.reactionMessage = $root.proto.ReactionMessage.fromObject(object.reactionMessage); + } + if (object.stickerSyncRmrMessage != null) { + if (typeof object.stickerSyncRmrMessage !== "object") + throw TypeError(".proto.Message.stickerSyncRmrMessage: object expected"); + message.stickerSyncRmrMessage = $root.proto.StickerSyncRMRMessage.fromObject(object.stickerSyncRmrMessage); + } return message; }; @@ -44170,6 +46448,9 @@ $root.proto = (function() { object.buttonsMessage = null; object.buttonsResponseMessage = null; object.paymentInviteMessage = null; + object.interactiveMessage = null; + object.reactionMessage = null; + object.stickerSyncRmrMessage = null; } if (message.conversation != null && message.hasOwnProperty("conversation")) object.conversation = message.conversation; @@ -44243,6 +46524,12 @@ $root.proto = (function() { object.buttonsResponseMessage = $root.proto.ButtonsResponseMessage.toObject(message.buttonsResponseMessage, options); if (message.paymentInviteMessage != null && message.hasOwnProperty("paymentInviteMessage")) object.paymentInviteMessage = $root.proto.PaymentInviteMessage.toObject(message.paymentInviteMessage, options); + if (message.interactiveMessage != null && message.hasOwnProperty("interactiveMessage")) + object.interactiveMessage = $root.proto.InteractiveMessage.toObject(message.interactiveMessage, options); + if (message.reactionMessage != null && message.hasOwnProperty("reactionMessage")) + object.reactionMessage = $root.proto.ReactionMessage.toObject(message.reactionMessage, options); + if (message.stickerSyncRmrMessage != null && message.hasOwnProperty("stickerSyncRmrMessage")) + object.stickerSyncRmrMessage = $root.proto.StickerSyncRMRMessage.toObject(message.stickerSyncRmrMessage, options); return object; }; @@ -44260,6 +46547,3807 @@ $root.proto = (function() { return Message; })(); + proto.ActionLink = (function() { + + /** + * Properties of an ActionLink. + * @memberof proto + * @interface IActionLink + * @property {string|null} [url] ActionLink url + * @property {string|null} [buttonTitle] ActionLink buttonTitle + */ + + /** + * Constructs a new ActionLink. + * @memberof proto + * @classdesc Represents an ActionLink. + * @implements IActionLink + * @constructor + * @param {proto.IActionLink=} [properties] Properties to set + */ + function ActionLink(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ActionLink url. + * @member {string} url + * @memberof proto.ActionLink + * @instance + */ + ActionLink.prototype.url = ""; + + /** + * ActionLink buttonTitle. + * @member {string} buttonTitle + * @memberof proto.ActionLink + * @instance + */ + ActionLink.prototype.buttonTitle = ""; + + /** + * Creates a new ActionLink instance using the specified properties. + * @function create + * @memberof proto.ActionLink + * @static + * @param {proto.IActionLink=} [properties] Properties to set + * @returns {proto.ActionLink} ActionLink instance + */ + ActionLink.create = function create(properties) { + return new ActionLink(properties); + }; + + /** + * Encodes the specified ActionLink message. Does not implicitly {@link proto.ActionLink.verify|verify} messages. + * @function encode + * @memberof proto.ActionLink + * @static + * @param {proto.IActionLink} message ActionLink message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ActionLink.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.url != null && Object.hasOwnProperty.call(message, "url")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.url); + if (message.buttonTitle != null && Object.hasOwnProperty.call(message, "buttonTitle")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.buttonTitle); + return writer; + }; + + /** + * Encodes the specified ActionLink message, length delimited. Does not implicitly {@link proto.ActionLink.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.ActionLink + * @static + * @param {proto.IActionLink} message ActionLink message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ActionLink.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an ActionLink message from the specified reader or buffer. + * @function decode + * @memberof proto.ActionLink + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.ActionLink} ActionLink + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ActionLink.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ActionLink(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.url = reader.string(); + break; + case 2: + message.buttonTitle = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an ActionLink message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.ActionLink + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.ActionLink} ActionLink + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ActionLink.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an ActionLink message. + * @function verify + * @memberof proto.ActionLink + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ActionLink.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.url != null && message.hasOwnProperty("url")) + if (!$util.isString(message.url)) + return "url: string expected"; + if (message.buttonTitle != null && message.hasOwnProperty("buttonTitle")) + if (!$util.isString(message.buttonTitle)) + return "buttonTitle: string expected"; + return null; + }; + + /** + * Creates an ActionLink message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.ActionLink + * @static + * @param {Object.} object Plain object + * @returns {proto.ActionLink} ActionLink + */ + ActionLink.fromObject = function fromObject(object) { + if (object instanceof $root.proto.ActionLink) + return object; + var message = new $root.proto.ActionLink(); + if (object.url != null) + message.url = String(object.url); + if (object.buttonTitle != null) + message.buttonTitle = String(object.buttonTitle); + return message; + }; + + /** + * Creates a plain object from an ActionLink message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.ActionLink + * @static + * @param {proto.ActionLink} message ActionLink + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ActionLink.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.url = ""; + object.buttonTitle = ""; + } + if (message.url != null && message.hasOwnProperty("url")) + object.url = message.url; + if (message.buttonTitle != null && message.hasOwnProperty("buttonTitle")) + object.buttonTitle = message.buttonTitle; + return object; + }; + + /** + * Converts this ActionLink to JSON. + * @function toJSON + * @memberof proto.ActionLink + * @instance + * @returns {Object.} JSON object + */ + ActionLink.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ActionLink; + })(); + + proto.DisappearingMode = (function() { + + /** + * Properties of a DisappearingMode. + * @memberof proto + * @interface IDisappearingMode + * @property {proto.DisappearingMode.DisappearingModeInitiator|null} [initiator] DisappearingMode initiator + */ + + /** + * Constructs a new DisappearingMode. + * @memberof proto + * @classdesc Represents a DisappearingMode. + * @implements IDisappearingMode + * @constructor + * @param {proto.IDisappearingMode=} [properties] Properties to set + */ + function DisappearingMode(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * DisappearingMode initiator. + * @member {proto.DisappearingMode.DisappearingModeInitiator} initiator + * @memberof proto.DisappearingMode + * @instance + */ + DisappearingMode.prototype.initiator = 0; + + /** + * Creates a new DisappearingMode instance using the specified properties. + * @function create + * @memberof proto.DisappearingMode + * @static + * @param {proto.IDisappearingMode=} [properties] Properties to set + * @returns {proto.DisappearingMode} DisappearingMode instance + */ + DisappearingMode.create = function create(properties) { + return new DisappearingMode(properties); + }; + + /** + * Encodes the specified DisappearingMode message. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages. + * @function encode + * @memberof proto.DisappearingMode + * @static + * @param {proto.IDisappearingMode} message DisappearingMode message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DisappearingMode.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.initiator != null && Object.hasOwnProperty.call(message, "initiator")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.initiator); + return writer; + }; + + /** + * Encodes the specified DisappearingMode message, length delimited. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.DisappearingMode + * @static + * @param {proto.IDisappearingMode} message DisappearingMode message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DisappearingMode.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a DisappearingMode message from the specified reader or buffer. + * @function decode + * @memberof proto.DisappearingMode + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.DisappearingMode} DisappearingMode + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DisappearingMode.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DisappearingMode(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.initiator = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a DisappearingMode message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.DisappearingMode + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.DisappearingMode} DisappearingMode + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DisappearingMode.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a DisappearingMode message. + * @function verify + * @memberof proto.DisappearingMode + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + DisappearingMode.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.initiator != null && message.hasOwnProperty("initiator")) + switch (message.initiator) { + default: + return "initiator: enum value expected"; + case 0: + case 1: + case 2: + break; + } + return null; + }; + + /** + * Creates a DisappearingMode message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.DisappearingMode + * @static + * @param {Object.} object Plain object + * @returns {proto.DisappearingMode} DisappearingMode + */ + DisappearingMode.fromObject = function fromObject(object) { + if (object instanceof $root.proto.DisappearingMode) + return object; + var message = new $root.proto.DisappearingMode(); + switch (object.initiator) { + case "CHANGED_IN_CHAT": + case 0: + message.initiator = 0; + break; + case "INITIATED_BY_ME": + case 1: + message.initiator = 1; + break; + case "INITIATED_BY_OTHER": + case 2: + message.initiator = 2; + break; + } + return message; + }; + + /** + * Creates a plain object from a DisappearingMode message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.DisappearingMode + * @static + * @param {proto.DisappearingMode} message DisappearingMode + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + DisappearingMode.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.initiator = options.enums === String ? "CHANGED_IN_CHAT" : 0; + if (message.initiator != null && message.hasOwnProperty("initiator")) + object.initiator = options.enums === String ? $root.proto.DisappearingMode.DisappearingModeInitiator[message.initiator] : message.initiator; + return object; + }; + + /** + * Converts this DisappearingMode to JSON. + * @function toJSON + * @memberof proto.DisappearingMode + * @instance + * @returns {Object.} JSON object + */ + DisappearingMode.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * DisappearingModeInitiator enum. + * @name proto.DisappearingMode.DisappearingModeInitiator + * @enum {number} + * @property {number} CHANGED_IN_CHAT=0 CHANGED_IN_CHAT value + * @property {number} INITIATED_BY_ME=1 INITIATED_BY_ME value + * @property {number} INITIATED_BY_OTHER=2 INITIATED_BY_OTHER value + */ + DisappearingMode.DisappearingModeInitiator = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "CHANGED_IN_CHAT"] = 0; + values[valuesById[1] = "INITIATED_BY_ME"] = 1; + values[valuesById[2] = "INITIATED_BY_OTHER"] = 2; + return values; + })(); + + return DisappearingMode; + })(); + + proto.MediaData = (function() { + + /** + * Properties of a MediaData. + * @memberof proto + * @interface IMediaData + * @property {Uint8Array|null} [mediaKey] MediaData mediaKey + * @property {number|Long|null} [mediaKeyTimestamp] MediaData mediaKeyTimestamp + * @property {Uint8Array|null} [fileSha256] MediaData fileSha256 + * @property {Uint8Array|null} [fileEncSha256] MediaData fileEncSha256 + * @property {string|null} [directPath] MediaData directPath + */ + + /** + * Constructs a new MediaData. + * @memberof proto + * @classdesc Represents a MediaData. + * @implements IMediaData + * @constructor + * @param {proto.IMediaData=} [properties] Properties to set + */ + function MediaData(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MediaData mediaKey. + * @member {Uint8Array} mediaKey + * @memberof proto.MediaData + * @instance + */ + MediaData.prototype.mediaKey = $util.newBuffer([]); + + /** + * MediaData mediaKeyTimestamp. + * @member {number|Long} mediaKeyTimestamp + * @memberof proto.MediaData + * @instance + */ + MediaData.prototype.mediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * MediaData fileSha256. + * @member {Uint8Array} fileSha256 + * @memberof proto.MediaData + * @instance + */ + MediaData.prototype.fileSha256 = $util.newBuffer([]); + + /** + * MediaData fileEncSha256. + * @member {Uint8Array} fileEncSha256 + * @memberof proto.MediaData + * @instance + */ + MediaData.prototype.fileEncSha256 = $util.newBuffer([]); + + /** + * MediaData directPath. + * @member {string} directPath + * @memberof proto.MediaData + * @instance + */ + MediaData.prototype.directPath = ""; + + /** + * Creates a new MediaData instance using the specified properties. + * @function create + * @memberof proto.MediaData + * @static + * @param {proto.IMediaData=} [properties] Properties to set + * @returns {proto.MediaData} MediaData instance + */ + MediaData.create = function create(properties) { + return new MediaData(properties); + }; + + /** + * Encodes the specified MediaData message. Does not implicitly {@link proto.MediaData.verify|verify} messages. + * @function encode + * @memberof proto.MediaData + * @static + * @param {proto.IMediaData} message MediaData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MediaData.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey")) + writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.mediaKey); + if (message.mediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "mediaKeyTimestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.mediaKeyTimestamp); + if (message.fileSha256 != null && Object.hasOwnProperty.call(message, "fileSha256")) + writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.fileSha256); + if (message.fileEncSha256 != null && Object.hasOwnProperty.call(message, "fileEncSha256")) + writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.fileEncSha256); + if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.directPath); + return writer; + }; + + /** + * Encodes the specified MediaData message, length delimited. Does not implicitly {@link proto.MediaData.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.MediaData + * @static + * @param {proto.IMediaData} message MediaData message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MediaData.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MediaData message from the specified reader or buffer. + * @function decode + * @memberof proto.MediaData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.MediaData} MediaData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MediaData.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MediaData(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.mediaKey = reader.bytes(); + break; + case 2: + message.mediaKeyTimestamp = reader.int64(); + break; + case 3: + message.fileSha256 = reader.bytes(); + break; + case 4: + message.fileEncSha256 = reader.bytes(); + break; + case 5: + message.directPath = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MediaData message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.MediaData + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.MediaData} MediaData + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MediaData.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MediaData message. + * @function verify + * @memberof proto.MediaData + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MediaData.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey))) + return "mediaKey: buffer expected"; + if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp")) + if (!$util.isInteger(message.mediaKeyTimestamp) && !(message.mediaKeyTimestamp && $util.isInteger(message.mediaKeyTimestamp.low) && $util.isInteger(message.mediaKeyTimestamp.high))) + return "mediaKeyTimestamp: integer|Long expected"; + if (message.fileSha256 != null && message.hasOwnProperty("fileSha256")) + if (!(message.fileSha256 && typeof message.fileSha256.length === "number" || $util.isString(message.fileSha256))) + return "fileSha256: buffer expected"; + if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256")) + if (!(message.fileEncSha256 && typeof message.fileEncSha256.length === "number" || $util.isString(message.fileEncSha256))) + return "fileEncSha256: buffer expected"; + if (message.directPath != null && message.hasOwnProperty("directPath")) + if (!$util.isString(message.directPath)) + return "directPath: string expected"; + return null; + }; + + /** + * Creates a MediaData message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.MediaData + * @static + * @param {Object.} object Plain object + * @returns {proto.MediaData} MediaData + */ + MediaData.fromObject = function fromObject(object) { + if (object instanceof $root.proto.MediaData) + return object; + var message = new $root.proto.MediaData(); + if (object.mediaKey != null) + if (typeof object.mediaKey === "string") + $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0); + else if (object.mediaKey.length) + message.mediaKey = object.mediaKey; + if (object.mediaKeyTimestamp != null) + if ($util.Long) + (message.mediaKeyTimestamp = $util.Long.fromValue(object.mediaKeyTimestamp)).unsigned = false; + else if (typeof object.mediaKeyTimestamp === "string") + message.mediaKeyTimestamp = parseInt(object.mediaKeyTimestamp, 10); + else if (typeof object.mediaKeyTimestamp === "number") + message.mediaKeyTimestamp = object.mediaKeyTimestamp; + else if (typeof object.mediaKeyTimestamp === "object") + message.mediaKeyTimestamp = new $util.LongBits(object.mediaKeyTimestamp.low >>> 0, object.mediaKeyTimestamp.high >>> 0).toNumber(); + if (object.fileSha256 != null) + if (typeof object.fileSha256 === "string") + $util.base64.decode(object.fileSha256, message.fileSha256 = $util.newBuffer($util.base64.length(object.fileSha256)), 0); + else if (object.fileSha256.length) + message.fileSha256 = object.fileSha256; + if (object.fileEncSha256 != null) + if (typeof object.fileEncSha256 === "string") + $util.base64.decode(object.fileEncSha256, message.fileEncSha256 = $util.newBuffer($util.base64.length(object.fileEncSha256)), 0); + else if (object.fileEncSha256.length) + message.fileEncSha256 = object.fileEncSha256; + if (object.directPath != null) + message.directPath = String(object.directPath); + return message; + }; + + /** + * Creates a plain object from a MediaData message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.MediaData + * @static + * @param {proto.MediaData} message MediaData + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MediaData.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if (options.bytes === String) + object.mediaKey = ""; + else { + object.mediaKey = []; + if (options.bytes !== Array) + object.mediaKey = $util.newBuffer(object.mediaKey); + } + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.mediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.mediaKeyTimestamp = options.longs === String ? "0" : 0; + if (options.bytes === String) + object.fileSha256 = ""; + else { + object.fileSha256 = []; + if (options.bytes !== Array) + object.fileSha256 = $util.newBuffer(object.fileSha256); + } + if (options.bytes === String) + object.fileEncSha256 = ""; + else { + object.fileEncSha256 = []; + if (options.bytes !== Array) + object.fileEncSha256 = $util.newBuffer(object.fileEncSha256); + } + object.directPath = ""; + } + if (message.mediaKey != null && message.hasOwnProperty("mediaKey")) + object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey; + if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp")) + if (typeof message.mediaKeyTimestamp === "number") + object.mediaKeyTimestamp = options.longs === String ? String(message.mediaKeyTimestamp) : message.mediaKeyTimestamp; + else + object.mediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.mediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.mediaKeyTimestamp.low >>> 0, message.mediaKeyTimestamp.high >>> 0).toNumber() : message.mediaKeyTimestamp; + if (message.fileSha256 != null && message.hasOwnProperty("fileSha256")) + object.fileSha256 = options.bytes === String ? $util.base64.encode(message.fileSha256, 0, message.fileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileSha256) : message.fileSha256; + if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256")) + object.fileEncSha256 = options.bytes === String ? $util.base64.encode(message.fileEncSha256, 0, message.fileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileEncSha256) : message.fileEncSha256; + if (message.directPath != null && message.hasOwnProperty("directPath")) + object.directPath = message.directPath; + return object; + }; + + /** + * Converts this MediaData to JSON. + * @function toJSON + * @memberof proto.MediaData + * @instance + * @returns {Object.} JSON object + */ + MediaData.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MediaData; + })(); + + proto.PaymentBackground = (function() { + + /** + * Properties of a PaymentBackground. + * @memberof proto + * @interface IPaymentBackground + * @property {string|null} [id] PaymentBackground id + * @property {number|Long|null} [fileLength] PaymentBackground fileLength + * @property {number|null} [width] PaymentBackground width + * @property {number|null} [height] PaymentBackground height + * @property {string|null} [mimetype] PaymentBackground mimetype + * @property {number|null} [placeholderArgb] PaymentBackground placeholderArgb + * @property {number|null} [textArgb] PaymentBackground textArgb + * @property {number|null} [subtextArgb] PaymentBackground subtextArgb + * @property {proto.IMediaData|null} [mediaData] PaymentBackground mediaData + * @property {proto.PaymentBackground.PaymentBackgroundType|null} [type] PaymentBackground type + */ + + /** + * Constructs a new PaymentBackground. + * @memberof proto + * @classdesc Represents a PaymentBackground. + * @implements IPaymentBackground + * @constructor + * @param {proto.IPaymentBackground=} [properties] Properties to set + */ + function PaymentBackground(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * PaymentBackground id. + * @member {string} id + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.id = ""; + + /** + * PaymentBackground fileLength. + * @member {number|Long} fileLength + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.fileLength = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + + /** + * PaymentBackground width. + * @member {number} width + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.width = 0; + + /** + * PaymentBackground height. + * @member {number} height + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.height = 0; + + /** + * PaymentBackground mimetype. + * @member {string} mimetype + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.mimetype = ""; + + /** + * PaymentBackground placeholderArgb. + * @member {number} placeholderArgb + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.placeholderArgb = 0; + + /** + * PaymentBackground textArgb. + * @member {number} textArgb + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.textArgb = 0; + + /** + * PaymentBackground subtextArgb. + * @member {number} subtextArgb + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.subtextArgb = 0; + + /** + * PaymentBackground mediaData. + * @member {proto.IMediaData|null|undefined} mediaData + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.mediaData = null; + + /** + * PaymentBackground type. + * @member {proto.PaymentBackground.PaymentBackgroundType} type + * @memberof proto.PaymentBackground + * @instance + */ + PaymentBackground.prototype.type = 0; + + /** + * Creates a new PaymentBackground instance using the specified properties. + * @function create + * @memberof proto.PaymentBackground + * @static + * @param {proto.IPaymentBackground=} [properties] Properties to set + * @returns {proto.PaymentBackground} PaymentBackground instance + */ + PaymentBackground.create = function create(properties) { + return new PaymentBackground(properties); + }; + + /** + * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @function encode + * @memberof proto.PaymentBackground + * @static + * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PaymentBackground.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.id); + if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength")) + writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.fileLength); + if (message.width != null && Object.hasOwnProperty.call(message, "width")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.width); + if (message.height != null && Object.hasOwnProperty.call(message, "height")) + writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.height); + if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.mimetype); + if (message.placeholderArgb != null && Object.hasOwnProperty.call(message, "placeholderArgb")) + writer.uint32(/* id 6, wireType 5 =*/53).fixed32(message.placeholderArgb); + if (message.textArgb != null && Object.hasOwnProperty.call(message, "textArgb")) + writer.uint32(/* id 7, wireType 5 =*/61).fixed32(message.textArgb); + if (message.subtextArgb != null && Object.hasOwnProperty.call(message, "subtextArgb")) + writer.uint32(/* id 8, wireType 5 =*/69).fixed32(message.subtextArgb); + if (message.mediaData != null && Object.hasOwnProperty.call(message, "mediaData")) + $root.proto.MediaData.encode(message.mediaData, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim(); + if (message.type != null && Object.hasOwnProperty.call(message, "type")) + writer.uint32(/* id 10, wireType 0 =*/80).int32(message.type); + return writer; + }; + + /** + * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.PaymentBackground + * @static + * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PaymentBackground.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a PaymentBackground message from the specified reader or buffer. + * @function decode + * @memberof proto.PaymentBackground + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.PaymentBackground} PaymentBackground + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PaymentBackground.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentBackground(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.fileLength = reader.uint64(); + break; + case 3: + message.width = reader.uint32(); + break; + case 4: + message.height = reader.uint32(); + break; + case 5: + message.mimetype = reader.string(); + break; + case 6: + message.placeholderArgb = reader.fixed32(); + break; + case 7: + message.textArgb = reader.fixed32(); + break; + case 8: + message.subtextArgb = reader.fixed32(); + break; + case 9: + message.mediaData = $root.proto.MediaData.decode(reader, reader.uint32()); + break; + case 10: + message.type = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a PaymentBackground message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.PaymentBackground + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.PaymentBackground} PaymentBackground + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PaymentBackground.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a PaymentBackground message. + * @function verify + * @memberof proto.PaymentBackground + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + PaymentBackground.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + if (message.fileLength != null && message.hasOwnProperty("fileLength")) + if (!$util.isInteger(message.fileLength) && !(message.fileLength && $util.isInteger(message.fileLength.low) && $util.isInteger(message.fileLength.high))) + return "fileLength: integer|Long expected"; + if (message.width != null && message.hasOwnProperty("width")) + if (!$util.isInteger(message.width)) + return "width: integer expected"; + if (message.height != null && message.hasOwnProperty("height")) + if (!$util.isInteger(message.height)) + return "height: integer expected"; + if (message.mimetype != null && message.hasOwnProperty("mimetype")) + if (!$util.isString(message.mimetype)) + return "mimetype: string expected"; + if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) + if (!$util.isInteger(message.placeholderArgb)) + return "placeholderArgb: integer expected"; + if (message.textArgb != null && message.hasOwnProperty("textArgb")) + if (!$util.isInteger(message.textArgb)) + return "textArgb: integer expected"; + if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) + if (!$util.isInteger(message.subtextArgb)) + return "subtextArgb: integer expected"; + if (message.mediaData != null && message.hasOwnProperty("mediaData")) { + var error = $root.proto.MediaData.verify(message.mediaData); + if (error) + return "mediaData." + error; + } + if (message.type != null && message.hasOwnProperty("type")) + switch (message.type) { + default: + return "type: enum value expected"; + case 0: + case 1: + break; + } + return null; + }; + + /** + * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.PaymentBackground + * @static + * @param {Object.} object Plain object + * @returns {proto.PaymentBackground} PaymentBackground + */ + PaymentBackground.fromObject = function fromObject(object) { + if (object instanceof $root.proto.PaymentBackground) + return object; + var message = new $root.proto.PaymentBackground(); + if (object.id != null) + message.id = String(object.id); + if (object.fileLength != null) + if ($util.Long) + (message.fileLength = $util.Long.fromValue(object.fileLength)).unsigned = true; + else if (typeof object.fileLength === "string") + message.fileLength = parseInt(object.fileLength, 10); + else if (typeof object.fileLength === "number") + message.fileLength = object.fileLength; + else if (typeof object.fileLength === "object") + message.fileLength = new $util.LongBits(object.fileLength.low >>> 0, object.fileLength.high >>> 0).toNumber(true); + if (object.width != null) + message.width = object.width >>> 0; + if (object.height != null) + message.height = object.height >>> 0; + if (object.mimetype != null) + message.mimetype = String(object.mimetype); + if (object.placeholderArgb != null) + message.placeholderArgb = object.placeholderArgb >>> 0; + if (object.textArgb != null) + message.textArgb = object.textArgb >>> 0; + if (object.subtextArgb != null) + message.subtextArgb = object.subtextArgb >>> 0; + if (object.mediaData != null) { + if (typeof object.mediaData !== "object") + throw TypeError(".proto.PaymentBackground.mediaData: object expected"); + message.mediaData = $root.proto.MediaData.fromObject(object.mediaData); + } + switch (object.type) { + case "UNKNOWN": + case 0: + message.type = 0; + break; + case "DEFAULT": + case 1: + message.type = 1; + break; + } + return message; + }; + + /** + * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.PaymentBackground + * @static + * @param {proto.PaymentBackground} message PaymentBackground + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + PaymentBackground.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.id = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.fileLength = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.fileLength = options.longs === String ? "0" : 0; + object.width = 0; + object.height = 0; + object.mimetype = ""; + object.placeholderArgb = 0; + object.textArgb = 0; + object.subtextArgb = 0; + object.mediaData = null; + object.type = options.enums === String ? "UNKNOWN" : 0; + } + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + if (message.fileLength != null && message.hasOwnProperty("fileLength")) + if (typeof message.fileLength === "number") + object.fileLength = options.longs === String ? String(message.fileLength) : message.fileLength; + else + object.fileLength = options.longs === String ? $util.Long.prototype.toString.call(message.fileLength) : options.longs === Number ? new $util.LongBits(message.fileLength.low >>> 0, message.fileLength.high >>> 0).toNumber(true) : message.fileLength; + if (message.width != null && message.hasOwnProperty("width")) + object.width = message.width; + if (message.height != null && message.hasOwnProperty("height")) + object.height = message.height; + if (message.mimetype != null && message.hasOwnProperty("mimetype")) + object.mimetype = message.mimetype; + if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb")) + object.placeholderArgb = message.placeholderArgb; + if (message.textArgb != null && message.hasOwnProperty("textArgb")) + object.textArgb = message.textArgb; + if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb")) + object.subtextArgb = message.subtextArgb; + if (message.mediaData != null && message.hasOwnProperty("mediaData")) + object.mediaData = $root.proto.MediaData.toObject(message.mediaData, options); + if (message.type != null && message.hasOwnProperty("type")) + object.type = options.enums === String ? $root.proto.PaymentBackground.PaymentBackgroundType[message.type] : message.type; + return object; + }; + + /** + * Converts this PaymentBackground to JSON. + * @function toJSON + * @memberof proto.PaymentBackground + * @instance + * @returns {Object.} JSON object + */ + PaymentBackground.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * PaymentBackgroundType enum. + * @name proto.PaymentBackground.PaymentBackgroundType + * @enum {number} + * @property {number} UNKNOWN=0 UNKNOWN value + * @property {number} DEFAULT=1 DEFAULT value + */ + PaymentBackground.PaymentBackgroundType = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN"] = 0; + values[valuesById[1] = "DEFAULT"] = 1; + return values; + })(); + + return PaymentBackground; + })(); + + proto.Money = (function() { + + /** + * Properties of a Money. + * @memberof proto + * @interface IMoney + * @property {number|Long|null} [value] Money value + * @property {number|null} [offset] Money offset + * @property {string|null} [currencyCode] Money currencyCode + */ + + /** + * Constructs a new Money. + * @memberof proto + * @classdesc Represents a Money. + * @implements IMoney + * @constructor + * @param {proto.IMoney=} [properties] Properties to set + */ + function Money(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Money value. + * @member {number|Long} value + * @memberof proto.Money + * @instance + */ + Money.prototype.value = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Money offset. + * @member {number} offset + * @memberof proto.Money + * @instance + */ + Money.prototype.offset = 0; + + /** + * Money currencyCode. + * @member {string} currencyCode + * @memberof proto.Money + * @instance + */ + Money.prototype.currencyCode = ""; + + /** + * Creates a new Money instance using the specified properties. + * @function create + * @memberof proto.Money + * @static + * @param {proto.IMoney=} [properties] Properties to set + * @returns {proto.Money} Money instance + */ + Money.create = function create(properties) { + return new Money(properties); + }; + + /** + * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages. + * @function encode + * @memberof proto.Money + * @static + * @param {proto.IMoney} message Money message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Money.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.value != null && Object.hasOwnProperty.call(message, "value")) + writer.uint32(/* id 1, wireType 0 =*/8).int64(message.value); + if (message.offset != null && Object.hasOwnProperty.call(message, "offset")) + writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.offset); + if (message.currencyCode != null && Object.hasOwnProperty.call(message, "currencyCode")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.currencyCode); + return writer; + }; + + /** + * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Money + * @static + * @param {proto.IMoney} message Money message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Money.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Money message from the specified reader or buffer. + * @function decode + * @memberof proto.Money + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Money} Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Money.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Money(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.value = reader.int64(); + break; + case 2: + message.offset = reader.uint32(); + break; + case 3: + message.currencyCode = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Money message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Money + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Money} Money + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Money.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Money message. + * @function verify + * @memberof proto.Money + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Money.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.value != null && message.hasOwnProperty("value")) + if (!$util.isInteger(message.value) && !(message.value && $util.isInteger(message.value.low) && $util.isInteger(message.value.high))) + return "value: integer|Long expected"; + if (message.offset != null && message.hasOwnProperty("offset")) + if (!$util.isInteger(message.offset)) + return "offset: integer expected"; + if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) + if (!$util.isString(message.currencyCode)) + return "currencyCode: string expected"; + return null; + }; + + /** + * Creates a Money message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Money + * @static + * @param {Object.} object Plain object + * @returns {proto.Money} Money + */ + Money.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Money) + return object; + var message = new $root.proto.Money(); + if (object.value != null) + if ($util.Long) + (message.value = $util.Long.fromValue(object.value)).unsigned = false; + else if (typeof object.value === "string") + message.value = parseInt(object.value, 10); + else if (typeof object.value === "number") + message.value = object.value; + else if (typeof object.value === "object") + message.value = new $util.LongBits(object.value.low >>> 0, object.value.high >>> 0).toNumber(); + if (object.offset != null) + message.offset = object.offset >>> 0; + if (object.currencyCode != null) + message.currencyCode = String(object.currencyCode); + return message; + }; + + /** + * Creates a plain object from a Money message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Money + * @static + * @param {proto.Money} message Money + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Money.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.value = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.value = options.longs === String ? "0" : 0; + object.offset = 0; + object.currencyCode = ""; + } + if (message.value != null && message.hasOwnProperty("value")) + if (typeof message.value === "number") + object.value = options.longs === String ? String(message.value) : message.value; + else + object.value = options.longs === String ? $util.Long.prototype.toString.call(message.value) : options.longs === Number ? new $util.LongBits(message.value.low >>> 0, message.value.high >>> 0).toNumber() : message.value; + if (message.offset != null && message.hasOwnProperty("offset")) + object.offset = message.offset; + if (message.currencyCode != null && message.hasOwnProperty("currencyCode")) + object.currencyCode = message.currencyCode; + return object; + }; + + /** + * Converts this Money to JSON. + * @function toJSON + * @memberof proto.Money + * @instance + * @returns {Object.} JSON object + */ + Money.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Money; + })(); + + proto.HydratedQuickReplyButton = (function() { + + /** + * Properties of a HydratedQuickReplyButton. + * @memberof proto + * @interface IHydratedQuickReplyButton + * @property {string|null} [displayText] HydratedQuickReplyButton displayText + * @property {string|null} [id] HydratedQuickReplyButton id + */ + + /** + * Constructs a new HydratedQuickReplyButton. + * @memberof proto + * @classdesc Represents a HydratedQuickReplyButton. + * @implements IHydratedQuickReplyButton + * @constructor + * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set + */ + function HydratedQuickReplyButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HydratedQuickReplyButton displayText. + * @member {string} displayText + * @memberof proto.HydratedQuickReplyButton + * @instance + */ + HydratedQuickReplyButton.prototype.displayText = ""; + + /** + * HydratedQuickReplyButton id. + * @member {string} id + * @memberof proto.HydratedQuickReplyButton + * @instance + */ + HydratedQuickReplyButton.prototype.id = ""; + + /** + * Creates a new HydratedQuickReplyButton instance using the specified properties. + * @function create + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set + * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton instance + */ + HydratedQuickReplyButton.create = function create(properties) { + return new HydratedQuickReplyButton(properties); + }; + + /** + * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * @function encode + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedQuickReplyButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.id); + return writer; + }; + + /** + * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedQuickReplyButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HydratedQuickReplyButton message from the specified reader or buffer. + * @function decode + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedQuickReplyButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedQuickReplyButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = reader.string(); + break; + case 2: + message.id = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedQuickReplyButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HydratedQuickReplyButton message. + * @function verify + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HydratedQuickReplyButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) + if (!$util.isString(message.displayText)) + return "displayText: string expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + return null; + }; + + /** + * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {Object.} object Plain object + * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton + */ + HydratedQuickReplyButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HydratedQuickReplyButton) + return object; + var message = new $root.proto.HydratedQuickReplyButton(); + if (object.displayText != null) + message.displayText = String(object.displayText); + if (object.id != null) + message.id = String(object.id); + return message; + }; + + /** + * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HydratedQuickReplyButton + * @static + * @param {proto.HydratedQuickReplyButton} message HydratedQuickReplyButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HydratedQuickReplyButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.displayText = ""; + object.id = ""; + } + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = message.displayText; + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + return object; + }; + + /** + * Converts this HydratedQuickReplyButton to JSON. + * @function toJSON + * @memberof proto.HydratedQuickReplyButton + * @instance + * @returns {Object.} JSON object + */ + HydratedQuickReplyButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HydratedQuickReplyButton; + })(); + + proto.HydratedURLButton = (function() { + + /** + * Properties of a HydratedURLButton. + * @memberof proto + * @interface IHydratedURLButton + * @property {string|null} [displayText] HydratedURLButton displayText + * @property {string|null} [url] HydratedURLButton url + */ + + /** + * Constructs a new HydratedURLButton. + * @memberof proto + * @classdesc Represents a HydratedURLButton. + * @implements IHydratedURLButton + * @constructor + * @param {proto.IHydratedURLButton=} [properties] Properties to set + */ + function HydratedURLButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HydratedURLButton displayText. + * @member {string} displayText + * @memberof proto.HydratedURLButton + * @instance + */ + HydratedURLButton.prototype.displayText = ""; + + /** + * HydratedURLButton url. + * @member {string} url + * @memberof proto.HydratedURLButton + * @instance + */ + HydratedURLButton.prototype.url = ""; + + /** + * Creates a new HydratedURLButton instance using the specified properties. + * @function create + * @memberof proto.HydratedURLButton + * @static + * @param {proto.IHydratedURLButton=} [properties] Properties to set + * @returns {proto.HydratedURLButton} HydratedURLButton instance + */ + HydratedURLButton.create = function create(properties) { + return new HydratedURLButton(properties); + }; + + /** + * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. + * @function encode + * @memberof proto.HydratedURLButton + * @static + * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedURLButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); + if (message.url != null && Object.hasOwnProperty.call(message, "url")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.url); + return writer; + }; + + /** + * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HydratedURLButton + * @static + * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedURLButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HydratedURLButton message from the specified reader or buffer. + * @function decode + * @memberof proto.HydratedURLButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HydratedURLButton} HydratedURLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedURLButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedURLButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = reader.string(); + break; + case 2: + message.url = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HydratedURLButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HydratedURLButton} HydratedURLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedURLButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HydratedURLButton message. + * @function verify + * @memberof proto.HydratedURLButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HydratedURLButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) + if (!$util.isString(message.displayText)) + return "displayText: string expected"; + if (message.url != null && message.hasOwnProperty("url")) + if (!$util.isString(message.url)) + return "url: string expected"; + return null; + }; + + /** + * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HydratedURLButton + * @static + * @param {Object.} object Plain object + * @returns {proto.HydratedURLButton} HydratedURLButton + */ + HydratedURLButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HydratedURLButton) + return object; + var message = new $root.proto.HydratedURLButton(); + if (object.displayText != null) + message.displayText = String(object.displayText); + if (object.url != null) + message.url = String(object.url); + return message; + }; + + /** + * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HydratedURLButton + * @static + * @param {proto.HydratedURLButton} message HydratedURLButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HydratedURLButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.displayText = ""; + object.url = ""; + } + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = message.displayText; + if (message.url != null && message.hasOwnProperty("url")) + object.url = message.url; + return object; + }; + + /** + * Converts this HydratedURLButton to JSON. + * @function toJSON + * @memberof proto.HydratedURLButton + * @instance + * @returns {Object.} JSON object + */ + HydratedURLButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HydratedURLButton; + })(); + + proto.HydratedCallButton = (function() { + + /** + * Properties of a HydratedCallButton. + * @memberof proto + * @interface IHydratedCallButton + * @property {string|null} [displayText] HydratedCallButton displayText + * @property {string|null} [phoneNumber] HydratedCallButton phoneNumber + */ + + /** + * Constructs a new HydratedCallButton. + * @memberof proto + * @classdesc Represents a HydratedCallButton. + * @implements IHydratedCallButton + * @constructor + * @param {proto.IHydratedCallButton=} [properties] Properties to set + */ + function HydratedCallButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HydratedCallButton displayText. + * @member {string} displayText + * @memberof proto.HydratedCallButton + * @instance + */ + HydratedCallButton.prototype.displayText = ""; + + /** + * HydratedCallButton phoneNumber. + * @member {string} phoneNumber + * @memberof proto.HydratedCallButton + * @instance + */ + HydratedCallButton.prototype.phoneNumber = ""; + + /** + * Creates a new HydratedCallButton instance using the specified properties. + * @function create + * @memberof proto.HydratedCallButton + * @static + * @param {proto.IHydratedCallButton=} [properties] Properties to set + * @returns {proto.HydratedCallButton} HydratedCallButton instance + */ + HydratedCallButton.create = function create(properties) { + return new HydratedCallButton(properties); + }; + + /** + * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. + * @function encode + * @memberof proto.HydratedCallButton + * @static + * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedCallButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText); + if (message.phoneNumber != null && Object.hasOwnProperty.call(message, "phoneNumber")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.phoneNumber); + return writer; + }; + + /** + * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HydratedCallButton + * @static + * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedCallButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HydratedCallButton message from the specified reader or buffer. + * @function decode + * @memberof proto.HydratedCallButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HydratedCallButton} HydratedCallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedCallButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedCallButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = reader.string(); + break; + case 2: + message.phoneNumber = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HydratedCallButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HydratedCallButton} HydratedCallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedCallButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HydratedCallButton message. + * @function verify + * @memberof proto.HydratedCallButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HydratedCallButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) + if (!$util.isString(message.displayText)) + return "displayText: string expected"; + if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) + if (!$util.isString(message.phoneNumber)) + return "phoneNumber: string expected"; + return null; + }; + + /** + * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HydratedCallButton + * @static + * @param {Object.} object Plain object + * @returns {proto.HydratedCallButton} HydratedCallButton + */ + HydratedCallButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HydratedCallButton) + return object; + var message = new $root.proto.HydratedCallButton(); + if (object.displayText != null) + message.displayText = String(object.displayText); + if (object.phoneNumber != null) + message.phoneNumber = String(object.phoneNumber); + return message; + }; + + /** + * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HydratedCallButton + * @static + * @param {proto.HydratedCallButton} message HydratedCallButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HydratedCallButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.displayText = ""; + object.phoneNumber = ""; + } + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = message.displayText; + if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) + object.phoneNumber = message.phoneNumber; + return object; + }; + + /** + * Converts this HydratedCallButton to JSON. + * @function toJSON + * @memberof proto.HydratedCallButton + * @instance + * @returns {Object.} JSON object + */ + HydratedCallButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HydratedCallButton; + })(); + + proto.HydratedTemplateButton = (function() { + + /** + * Properties of a HydratedTemplateButton. + * @memberof proto + * @interface IHydratedTemplateButton + * @property {number|null} [index] HydratedTemplateButton index + * @property {proto.IHydratedQuickReplyButton|null} [quickReplyButton] HydratedTemplateButton quickReplyButton + * @property {proto.IHydratedURLButton|null} [urlButton] HydratedTemplateButton urlButton + * @property {proto.IHydratedCallButton|null} [callButton] HydratedTemplateButton callButton + */ + + /** + * Constructs a new HydratedTemplateButton. + * @memberof proto + * @classdesc Represents a HydratedTemplateButton. + * @implements IHydratedTemplateButton + * @constructor + * @param {proto.IHydratedTemplateButton=} [properties] Properties to set + */ + function HydratedTemplateButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * HydratedTemplateButton index. + * @member {number} index + * @memberof proto.HydratedTemplateButton + * @instance + */ + HydratedTemplateButton.prototype.index = 0; + + /** + * HydratedTemplateButton quickReplyButton. + * @member {proto.IHydratedQuickReplyButton|null|undefined} quickReplyButton + * @memberof proto.HydratedTemplateButton + * @instance + */ + HydratedTemplateButton.prototype.quickReplyButton = null; + + /** + * HydratedTemplateButton urlButton. + * @member {proto.IHydratedURLButton|null|undefined} urlButton + * @memberof proto.HydratedTemplateButton + * @instance + */ + HydratedTemplateButton.prototype.urlButton = null; + + /** + * HydratedTemplateButton callButton. + * @member {proto.IHydratedCallButton|null|undefined} callButton + * @memberof proto.HydratedTemplateButton + * @instance + */ + HydratedTemplateButton.prototype.callButton = null; + + // OneOf field names bound to virtual getters and setters + var $oneOfFields; + + /** + * HydratedTemplateButton hydratedButton. + * @member {"quickReplyButton"|"urlButton"|"callButton"|undefined} hydratedButton + * @memberof proto.HydratedTemplateButton + * @instance + */ + Object.defineProperty(HydratedTemplateButton.prototype, "hydratedButton", { + get: $util.oneOfGetter($oneOfFields = ["quickReplyButton", "urlButton", "callButton"]), + set: $util.oneOfSetter($oneOfFields) + }); + + /** + * Creates a new HydratedTemplateButton instance using the specified properties. + * @function create + * @memberof proto.HydratedTemplateButton + * @static + * @param {proto.IHydratedTemplateButton=} [properties] Properties to set + * @returns {proto.HydratedTemplateButton} HydratedTemplateButton instance + */ + HydratedTemplateButton.create = function create(properties) { + return new HydratedTemplateButton(properties); + }; + + /** + * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. + * @function encode + * @memberof proto.HydratedTemplateButton + * @static + * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedTemplateButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.quickReplyButton != null && Object.hasOwnProperty.call(message, "quickReplyButton")) + $root.proto.HydratedQuickReplyButton.encode(message.quickReplyButton, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.urlButton != null && Object.hasOwnProperty.call(message, "urlButton")) + $root.proto.HydratedURLButton.encode(message.urlButton, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.callButton != null && Object.hasOwnProperty.call(message, "callButton")) + $root.proto.HydratedCallButton.encode(message.callButton, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.index != null && Object.hasOwnProperty.call(message, "index")) + writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.index); + return writer; + }; + + /** + * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.HydratedTemplateButton + * @static + * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + HydratedTemplateButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a HydratedTemplateButton message from the specified reader or buffer. + * @function decode + * @memberof proto.HydratedTemplateButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.HydratedTemplateButton} HydratedTemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedTemplateButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedTemplateButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 4: + message.index = reader.uint32(); + break; + case 1: + message.quickReplyButton = $root.proto.HydratedQuickReplyButton.decode(reader, reader.uint32()); + break; + case 2: + message.urlButton = $root.proto.HydratedURLButton.decode(reader, reader.uint32()); + break; + case 3: + message.callButton = $root.proto.HydratedCallButton.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.HydratedTemplateButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.HydratedTemplateButton} HydratedTemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + HydratedTemplateButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a HydratedTemplateButton message. + * @function verify + * @memberof proto.HydratedTemplateButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + HydratedTemplateButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var properties = {}; + if (message.index != null && message.hasOwnProperty("index")) + if (!$util.isInteger(message.index)) + return "index: integer expected"; + if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { + properties.hydratedButton = 1; + { + var error = $root.proto.HydratedQuickReplyButton.verify(message.quickReplyButton); + if (error) + return "quickReplyButton." + error; + } + } + if (message.urlButton != null && message.hasOwnProperty("urlButton")) { + if (properties.hydratedButton === 1) + return "hydratedButton: multiple values"; + properties.hydratedButton = 1; + { + var error = $root.proto.HydratedURLButton.verify(message.urlButton); + if (error) + return "urlButton." + error; + } + } + if (message.callButton != null && message.hasOwnProperty("callButton")) { + if (properties.hydratedButton === 1) + return "hydratedButton: multiple values"; + properties.hydratedButton = 1; + { + var error = $root.proto.HydratedCallButton.verify(message.callButton); + if (error) + return "callButton." + error; + } + } + return null; + }; + + /** + * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.HydratedTemplateButton + * @static + * @param {Object.} object Plain object + * @returns {proto.HydratedTemplateButton} HydratedTemplateButton + */ + HydratedTemplateButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.HydratedTemplateButton) + return object; + var message = new $root.proto.HydratedTemplateButton(); + if (object.index != null) + message.index = object.index >>> 0; + if (object.quickReplyButton != null) { + if (typeof object.quickReplyButton !== "object") + throw TypeError(".proto.HydratedTemplateButton.quickReplyButton: object expected"); + message.quickReplyButton = $root.proto.HydratedQuickReplyButton.fromObject(object.quickReplyButton); + } + if (object.urlButton != null) { + if (typeof object.urlButton !== "object") + throw TypeError(".proto.HydratedTemplateButton.urlButton: object expected"); + message.urlButton = $root.proto.HydratedURLButton.fromObject(object.urlButton); + } + if (object.callButton != null) { + if (typeof object.callButton !== "object") + throw TypeError(".proto.HydratedTemplateButton.callButton: object expected"); + message.callButton = $root.proto.HydratedCallButton.fromObject(object.callButton); + } + return message; + }; + + /** + * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.HydratedTemplateButton + * @static + * @param {proto.HydratedTemplateButton} message HydratedTemplateButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + HydratedTemplateButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.index = 0; + if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { + object.quickReplyButton = $root.proto.HydratedQuickReplyButton.toObject(message.quickReplyButton, options); + if (options.oneofs) + object.hydratedButton = "quickReplyButton"; + } + if (message.urlButton != null && message.hasOwnProperty("urlButton")) { + object.urlButton = $root.proto.HydratedURLButton.toObject(message.urlButton, options); + if (options.oneofs) + object.hydratedButton = "urlButton"; + } + if (message.callButton != null && message.hasOwnProperty("callButton")) { + object.callButton = $root.proto.HydratedCallButton.toObject(message.callButton, options); + if (options.oneofs) + object.hydratedButton = "callButton"; + } + if (message.index != null && message.hasOwnProperty("index")) + object.index = message.index; + return object; + }; + + /** + * Converts this HydratedTemplateButton to JSON. + * @function toJSON + * @memberof proto.HydratedTemplateButton + * @instance + * @returns {Object.} JSON object + */ + HydratedTemplateButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return HydratedTemplateButton; + })(); + + proto.QuickReplyButton = (function() { + + /** + * Properties of a QuickReplyButton. + * @memberof proto + * @interface IQuickReplyButton + * @property {proto.IHighlyStructuredMessage|null} [displayText] QuickReplyButton displayText + * @property {string|null} [id] QuickReplyButton id + */ + + /** + * Constructs a new QuickReplyButton. + * @memberof proto + * @classdesc Represents a QuickReplyButton. + * @implements IQuickReplyButton + * @constructor + * @param {proto.IQuickReplyButton=} [properties] Properties to set + */ + function QuickReplyButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * QuickReplyButton displayText. + * @member {proto.IHighlyStructuredMessage|null|undefined} displayText + * @memberof proto.QuickReplyButton + * @instance + */ + QuickReplyButton.prototype.displayText = null; + + /** + * QuickReplyButton id. + * @member {string} id + * @memberof proto.QuickReplyButton + * @instance + */ + QuickReplyButton.prototype.id = ""; + + /** + * Creates a new QuickReplyButton instance using the specified properties. + * @function create + * @memberof proto.QuickReplyButton + * @static + * @param {proto.IQuickReplyButton=} [properties] Properties to set + * @returns {proto.QuickReplyButton} QuickReplyButton instance + */ + QuickReplyButton.create = function create(properties) { + return new QuickReplyButton(properties); + }; + + /** + * Encodes the specified QuickReplyButton message. Does not implicitly {@link proto.QuickReplyButton.verify|verify} messages. + * @function encode + * @memberof proto.QuickReplyButton + * @static + * @param {proto.IQuickReplyButton} message QuickReplyButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + QuickReplyButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + $root.proto.HighlyStructuredMessage.encode(message.displayText, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.id); + return writer; + }; + + /** + * Encodes the specified QuickReplyButton message, length delimited. Does not implicitly {@link proto.QuickReplyButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.QuickReplyButton + * @static + * @param {proto.IQuickReplyButton} message QuickReplyButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + QuickReplyButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a QuickReplyButton message from the specified reader or buffer. + * @function decode + * @memberof proto.QuickReplyButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.QuickReplyButton} QuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + QuickReplyButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.QuickReplyButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32()); + break; + case 2: + message.id = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a QuickReplyButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.QuickReplyButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.QuickReplyButton} QuickReplyButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + QuickReplyButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a QuickReplyButton message. + * @function verify + * @memberof proto.QuickReplyButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + QuickReplyButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) { + var error = $root.proto.HighlyStructuredMessage.verify(message.displayText); + if (error) + return "displayText." + error; + } + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isString(message.id)) + return "id: string expected"; + return null; + }; + + /** + * Creates a QuickReplyButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.QuickReplyButton + * @static + * @param {Object.} object Plain object + * @returns {proto.QuickReplyButton} QuickReplyButton + */ + QuickReplyButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.QuickReplyButton) + return object; + var message = new $root.proto.QuickReplyButton(); + if (object.displayText != null) { + if (typeof object.displayText !== "object") + throw TypeError(".proto.QuickReplyButton.displayText: object expected"); + message.displayText = $root.proto.HighlyStructuredMessage.fromObject(object.displayText); + } + if (object.id != null) + message.id = String(object.id); + return message; + }; + + /** + * Creates a plain object from a QuickReplyButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.QuickReplyButton + * @static + * @param {proto.QuickReplyButton} message QuickReplyButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + QuickReplyButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.displayText = null; + object.id = ""; + } + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = $root.proto.HighlyStructuredMessage.toObject(message.displayText, options); + if (message.id != null && message.hasOwnProperty("id")) + object.id = message.id; + return object; + }; + + /** + * Converts this QuickReplyButton to JSON. + * @function toJSON + * @memberof proto.QuickReplyButton + * @instance + * @returns {Object.} JSON object + */ + QuickReplyButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return QuickReplyButton; + })(); + + proto.URLButton = (function() { + + /** + * Properties of a URLButton. + * @memberof proto + * @interface IURLButton + * @property {proto.IHighlyStructuredMessage|null} [displayText] URLButton displayText + * @property {proto.IHighlyStructuredMessage|null} [url] URLButton url + */ + + /** + * Constructs a new URLButton. + * @memberof proto + * @classdesc Represents a URLButton. + * @implements IURLButton + * @constructor + * @param {proto.IURLButton=} [properties] Properties to set + */ + function URLButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * URLButton displayText. + * @member {proto.IHighlyStructuredMessage|null|undefined} displayText + * @memberof proto.URLButton + * @instance + */ + URLButton.prototype.displayText = null; + + /** + * URLButton url. + * @member {proto.IHighlyStructuredMessage|null|undefined} url + * @memberof proto.URLButton + * @instance + */ + URLButton.prototype.url = null; + + /** + * Creates a new URLButton instance using the specified properties. + * @function create + * @memberof proto.URLButton + * @static + * @param {proto.IURLButton=} [properties] Properties to set + * @returns {proto.URLButton} URLButton instance + */ + URLButton.create = function create(properties) { + return new URLButton(properties); + }; + + /** + * Encodes the specified URLButton message. Does not implicitly {@link proto.URLButton.verify|verify} messages. + * @function encode + * @memberof proto.URLButton + * @static + * @param {proto.IURLButton} message URLButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + URLButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + $root.proto.HighlyStructuredMessage.encode(message.displayText, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.url != null && Object.hasOwnProperty.call(message, "url")) + $root.proto.HighlyStructuredMessage.encode(message.url, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified URLButton message, length delimited. Does not implicitly {@link proto.URLButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.URLButton + * @static + * @param {proto.IURLButton} message URLButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + URLButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a URLButton message from the specified reader or buffer. + * @function decode + * @memberof proto.URLButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.URLButton} URLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + URLButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.URLButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32()); + break; + case 2: + message.url = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a URLButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.URLButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.URLButton} URLButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + URLButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a URLButton message. + * @function verify + * @memberof proto.URLButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + URLButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) { + var error = $root.proto.HighlyStructuredMessage.verify(message.displayText); + if (error) + return "displayText." + error; + } + if (message.url != null && message.hasOwnProperty("url")) { + var error = $root.proto.HighlyStructuredMessage.verify(message.url); + if (error) + return "url." + error; + } + return null; + }; + + /** + * Creates a URLButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.URLButton + * @static + * @param {Object.} object Plain object + * @returns {proto.URLButton} URLButton + */ + URLButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.URLButton) + return object; + var message = new $root.proto.URLButton(); + if (object.displayText != null) { + if (typeof object.displayText !== "object") + throw TypeError(".proto.URLButton.displayText: object expected"); + message.displayText = $root.proto.HighlyStructuredMessage.fromObject(object.displayText); + } + if (object.url != null) { + if (typeof object.url !== "object") + throw TypeError(".proto.URLButton.url: object expected"); + message.url = $root.proto.HighlyStructuredMessage.fromObject(object.url); + } + return message; + }; + + /** + * Creates a plain object from a URLButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.URLButton + * @static + * @param {proto.URLButton} message URLButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + URLButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.displayText = null; + object.url = null; + } + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = $root.proto.HighlyStructuredMessage.toObject(message.displayText, options); + if (message.url != null && message.hasOwnProperty("url")) + object.url = $root.proto.HighlyStructuredMessage.toObject(message.url, options); + return object; + }; + + /** + * Converts this URLButton to JSON. + * @function toJSON + * @memberof proto.URLButton + * @instance + * @returns {Object.} JSON object + */ + URLButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return URLButton; + })(); + + proto.CallButton = (function() { + + /** + * Properties of a CallButton. + * @memberof proto + * @interface ICallButton + * @property {proto.IHighlyStructuredMessage|null} [displayText] CallButton displayText + * @property {proto.IHighlyStructuredMessage|null} [phoneNumber] CallButton phoneNumber + */ + + /** + * Constructs a new CallButton. + * @memberof proto + * @classdesc Represents a CallButton. + * @implements ICallButton + * @constructor + * @param {proto.ICallButton=} [properties] Properties to set + */ + function CallButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * CallButton displayText. + * @member {proto.IHighlyStructuredMessage|null|undefined} displayText + * @memberof proto.CallButton + * @instance + */ + CallButton.prototype.displayText = null; + + /** + * CallButton phoneNumber. + * @member {proto.IHighlyStructuredMessage|null|undefined} phoneNumber + * @memberof proto.CallButton + * @instance + */ + CallButton.prototype.phoneNumber = null; + + /** + * Creates a new CallButton instance using the specified properties. + * @function create + * @memberof proto.CallButton + * @static + * @param {proto.ICallButton=} [properties] Properties to set + * @returns {proto.CallButton} CallButton instance + */ + CallButton.create = function create(properties) { + return new CallButton(properties); + }; + + /** + * Encodes the specified CallButton message. Does not implicitly {@link proto.CallButton.verify|verify} messages. + * @function encode + * @memberof proto.CallButton + * @static + * @param {proto.ICallButton} message CallButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CallButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText")) + $root.proto.HighlyStructuredMessage.encode(message.displayText, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.phoneNumber != null && Object.hasOwnProperty.call(message, "phoneNumber")) + $root.proto.HighlyStructuredMessage.encode(message.phoneNumber, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified CallButton message, length delimited. Does not implicitly {@link proto.CallButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.CallButton + * @static + * @param {proto.ICallButton} message CallButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + CallButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a CallButton message from the specified reader or buffer. + * @function decode + * @memberof proto.CallButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.CallButton} CallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CallButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CallButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.displayText = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32()); + break; + case 2: + message.phoneNumber = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a CallButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.CallButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.CallButton} CallButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + CallButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a CallButton message. + * @function verify + * @memberof proto.CallButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + CallButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.displayText != null && message.hasOwnProperty("displayText")) { + var error = $root.proto.HighlyStructuredMessage.verify(message.displayText); + if (error) + return "displayText." + error; + } + if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) { + var error = $root.proto.HighlyStructuredMessage.verify(message.phoneNumber); + if (error) + return "phoneNumber." + error; + } + return null; + }; + + /** + * Creates a CallButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.CallButton + * @static + * @param {Object.} object Plain object + * @returns {proto.CallButton} CallButton + */ + CallButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.CallButton) + return object; + var message = new $root.proto.CallButton(); + if (object.displayText != null) { + if (typeof object.displayText !== "object") + throw TypeError(".proto.CallButton.displayText: object expected"); + message.displayText = $root.proto.HighlyStructuredMessage.fromObject(object.displayText); + } + if (object.phoneNumber != null) { + if (typeof object.phoneNumber !== "object") + throw TypeError(".proto.CallButton.phoneNumber: object expected"); + message.phoneNumber = $root.proto.HighlyStructuredMessage.fromObject(object.phoneNumber); + } + return message; + }; + + /** + * Creates a plain object from a CallButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.CallButton + * @static + * @param {proto.CallButton} message CallButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + CallButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.displayText = null; + object.phoneNumber = null; + } + if (message.displayText != null && message.hasOwnProperty("displayText")) + object.displayText = $root.proto.HighlyStructuredMessage.toObject(message.displayText, options); + if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) + object.phoneNumber = $root.proto.HighlyStructuredMessage.toObject(message.phoneNumber, options); + return object; + }; + + /** + * Converts this CallButton to JSON. + * @function toJSON + * @memberof proto.CallButton + * @instance + * @returns {Object.} JSON object + */ + CallButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return CallButton; + })(); + + proto.TemplateButton = (function() { + + /** + * Properties of a TemplateButton. + * @memberof proto + * @interface ITemplateButton + * @property {number|null} [index] TemplateButton index + * @property {proto.IQuickReplyButton|null} [quickReplyButton] TemplateButton quickReplyButton + * @property {proto.IURLButton|null} [urlButton] TemplateButton urlButton + * @property {proto.ICallButton|null} [callButton] TemplateButton callButton + */ + + /** + * Constructs a new TemplateButton. + * @memberof proto + * @classdesc Represents a TemplateButton. + * @implements ITemplateButton + * @constructor + * @param {proto.ITemplateButton=} [properties] Properties to set + */ + function TemplateButton(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * TemplateButton index. + * @member {number} index + * @memberof proto.TemplateButton + * @instance + */ + TemplateButton.prototype.index = 0; + + /** + * TemplateButton quickReplyButton. + * @member {proto.IQuickReplyButton|null|undefined} quickReplyButton + * @memberof proto.TemplateButton + * @instance + */ + TemplateButton.prototype.quickReplyButton = null; + + /** + * TemplateButton urlButton. + * @member {proto.IURLButton|null|undefined} urlButton + * @memberof proto.TemplateButton + * @instance + */ + TemplateButton.prototype.urlButton = null; + + /** + * TemplateButton callButton. + * @member {proto.ICallButton|null|undefined} callButton + * @memberof proto.TemplateButton + * @instance + */ + TemplateButton.prototype.callButton = null; + + // OneOf field names bound to virtual getters and setters + var $oneOfFields; + + /** + * TemplateButton button. + * @member {"quickReplyButton"|"urlButton"|"callButton"|undefined} button + * @memberof proto.TemplateButton + * @instance + */ + Object.defineProperty(TemplateButton.prototype, "button", { + get: $util.oneOfGetter($oneOfFields = ["quickReplyButton", "urlButton", "callButton"]), + set: $util.oneOfSetter($oneOfFields) + }); + + /** + * Creates a new TemplateButton instance using the specified properties. + * @function create + * @memberof proto.TemplateButton + * @static + * @param {proto.ITemplateButton=} [properties] Properties to set + * @returns {proto.TemplateButton} TemplateButton instance + */ + TemplateButton.create = function create(properties) { + return new TemplateButton(properties); + }; + + /** + * Encodes the specified TemplateButton message. Does not implicitly {@link proto.TemplateButton.verify|verify} messages. + * @function encode + * @memberof proto.TemplateButton + * @static + * @param {proto.ITemplateButton} message TemplateButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + TemplateButton.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.quickReplyButton != null && Object.hasOwnProperty.call(message, "quickReplyButton")) + $root.proto.QuickReplyButton.encode(message.quickReplyButton, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.urlButton != null && Object.hasOwnProperty.call(message, "urlButton")) + $root.proto.URLButton.encode(message.urlButton, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim(); + if (message.callButton != null && Object.hasOwnProperty.call(message, "callButton")) + $root.proto.CallButton.encode(message.callButton, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); + if (message.index != null && Object.hasOwnProperty.call(message, "index")) + writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.index); + return writer; + }; + + /** + * Encodes the specified TemplateButton message, length delimited. Does not implicitly {@link proto.TemplateButton.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.TemplateButton + * @static + * @param {proto.ITemplateButton} message TemplateButton message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + TemplateButton.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a TemplateButton message from the specified reader or buffer. + * @function decode + * @memberof proto.TemplateButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.TemplateButton} TemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + TemplateButton.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.TemplateButton(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 4: + message.index = reader.uint32(); + break; + case 1: + message.quickReplyButton = $root.proto.QuickReplyButton.decode(reader, reader.uint32()); + break; + case 2: + message.urlButton = $root.proto.URLButton.decode(reader, reader.uint32()); + break; + case 3: + message.callButton = $root.proto.CallButton.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a TemplateButton message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.TemplateButton + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.TemplateButton} TemplateButton + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + TemplateButton.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a TemplateButton message. + * @function verify + * @memberof proto.TemplateButton + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + TemplateButton.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var properties = {}; + if (message.index != null && message.hasOwnProperty("index")) + if (!$util.isInteger(message.index)) + return "index: integer expected"; + if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { + properties.button = 1; + { + var error = $root.proto.QuickReplyButton.verify(message.quickReplyButton); + if (error) + return "quickReplyButton." + error; + } + } + if (message.urlButton != null && message.hasOwnProperty("urlButton")) { + if (properties.button === 1) + return "button: multiple values"; + properties.button = 1; + { + var error = $root.proto.URLButton.verify(message.urlButton); + if (error) + return "urlButton." + error; + } + } + if (message.callButton != null && message.hasOwnProperty("callButton")) { + if (properties.button === 1) + return "button: multiple values"; + properties.button = 1; + { + var error = $root.proto.CallButton.verify(message.callButton); + if (error) + return "callButton." + error; + } + } + return null; + }; + + /** + * Creates a TemplateButton message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.TemplateButton + * @static + * @param {Object.} object Plain object + * @returns {proto.TemplateButton} TemplateButton + */ + TemplateButton.fromObject = function fromObject(object) { + if (object instanceof $root.proto.TemplateButton) + return object; + var message = new $root.proto.TemplateButton(); + if (object.index != null) + message.index = object.index >>> 0; + if (object.quickReplyButton != null) { + if (typeof object.quickReplyButton !== "object") + throw TypeError(".proto.TemplateButton.quickReplyButton: object expected"); + message.quickReplyButton = $root.proto.QuickReplyButton.fromObject(object.quickReplyButton); + } + if (object.urlButton != null) { + if (typeof object.urlButton !== "object") + throw TypeError(".proto.TemplateButton.urlButton: object expected"); + message.urlButton = $root.proto.URLButton.fromObject(object.urlButton); + } + if (object.callButton != null) { + if (typeof object.callButton !== "object") + throw TypeError(".proto.TemplateButton.callButton: object expected"); + message.callButton = $root.proto.CallButton.fromObject(object.callButton); + } + return message; + }; + + /** + * Creates a plain object from a TemplateButton message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.TemplateButton + * @static + * @param {proto.TemplateButton} message TemplateButton + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + TemplateButton.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.index = 0; + if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) { + object.quickReplyButton = $root.proto.QuickReplyButton.toObject(message.quickReplyButton, options); + if (options.oneofs) + object.button = "quickReplyButton"; + } + if (message.urlButton != null && message.hasOwnProperty("urlButton")) { + object.urlButton = $root.proto.URLButton.toObject(message.urlButton, options); + if (options.oneofs) + object.button = "urlButton"; + } + if (message.callButton != null && message.hasOwnProperty("callButton")) { + object.callButton = $root.proto.CallButton.toObject(message.callButton, options); + if (options.oneofs) + object.button = "callButton"; + } + if (message.index != null && message.hasOwnProperty("index")) + object.index = message.index; + return object; + }; + + /** + * Converts this TemplateButton to JSON. + * @function toJSON + * @memberof proto.TemplateButton + * @instance + * @returns {Object.} JSON object + */ + TemplateButton.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return TemplateButton; + })(); + + proto.Location = (function() { + + /** + * Properties of a Location. + * @memberof proto + * @interface ILocation + * @property {number|null} [degreesLatitude] Location degreesLatitude + * @property {number|null} [degreesLongitude] Location degreesLongitude + * @property {string|null} [name] Location name + */ + + /** + * Constructs a new Location. + * @memberof proto + * @classdesc Represents a Location. + * @implements ILocation + * @constructor + * @param {proto.ILocation=} [properties] Properties to set + */ + function Location(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Location degreesLatitude. + * @member {number} degreesLatitude + * @memberof proto.Location + * @instance + */ + Location.prototype.degreesLatitude = 0; + + /** + * Location degreesLongitude. + * @member {number} degreesLongitude + * @memberof proto.Location + * @instance + */ + Location.prototype.degreesLongitude = 0; + + /** + * Location name. + * @member {string} name + * @memberof proto.Location + * @instance + */ + Location.prototype.name = ""; + + /** + * Creates a new Location instance using the specified properties. + * @function create + * @memberof proto.Location + * @static + * @param {proto.ILocation=} [properties] Properties to set + * @returns {proto.Location} Location instance + */ + Location.create = function create(properties) { + return new Location(properties); + }; + + /** + * Encodes the specified Location message. Does not implicitly {@link proto.Location.verify|verify} messages. + * @function encode + * @memberof proto.Location + * @static + * @param {proto.ILocation} message Location message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Location.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.degreesLatitude != null && Object.hasOwnProperty.call(message, "degreesLatitude")) + writer.uint32(/* id 1, wireType 1 =*/9).double(message.degreesLatitude); + if (message.degreesLongitude != null && Object.hasOwnProperty.call(message, "degreesLongitude")) + writer.uint32(/* id 2, wireType 1 =*/17).double(message.degreesLongitude); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.name); + return writer; + }; + + /** + * Encodes the specified Location message, length delimited. Does not implicitly {@link proto.Location.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Location + * @static + * @param {proto.ILocation} message Location message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Location.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Location message from the specified reader or buffer. + * @function decode + * @memberof proto.Location + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Location} Location + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Location.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Location(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.degreesLatitude = reader.double(); + break; + case 2: + message.degreesLongitude = reader.double(); + break; + case 3: + message.name = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Location message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Location + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Location} Location + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Location.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Location message. + * @function verify + * @memberof proto.Location + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Location.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.degreesLatitude != null && message.hasOwnProperty("degreesLatitude")) + if (typeof message.degreesLatitude !== "number") + return "degreesLatitude: number expected"; + if (message.degreesLongitude != null && message.hasOwnProperty("degreesLongitude")) + if (typeof message.degreesLongitude !== "number") + return "degreesLongitude: number expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + return null; + }; + + /** + * Creates a Location message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Location + * @static + * @param {Object.} object Plain object + * @returns {proto.Location} Location + */ + Location.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Location) + return object; + var message = new $root.proto.Location(); + if (object.degreesLatitude != null) + message.degreesLatitude = Number(object.degreesLatitude); + if (object.degreesLongitude != null) + message.degreesLongitude = Number(object.degreesLongitude); + if (object.name != null) + message.name = String(object.name); + return message; + }; + + /** + * Creates a plain object from a Location message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Location + * @static + * @param {proto.Location} message Location + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Location.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.degreesLatitude = 0; + object.degreesLongitude = 0; + object.name = ""; + } + if (message.degreesLatitude != null && message.hasOwnProperty("degreesLatitude")) + object.degreesLatitude = options.json && !isFinite(message.degreesLatitude) ? String(message.degreesLatitude) : message.degreesLatitude; + if (message.degreesLongitude != null && message.hasOwnProperty("degreesLongitude")) + object.degreesLongitude = options.json && !isFinite(message.degreesLongitude) ? String(message.degreesLongitude) : message.degreesLongitude; + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + return object; + }; + + /** + * Converts this Location to JSON. + * @function toJSON + * @memberof proto.Location + * @instance + * @returns {Object.} JSON object + */ + Location.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Location; + })(); + + proto.Point = (function() { + + /** + * Properties of a Point. + * @memberof proto + * @interface IPoint + * @property {number|null} [xDeprecated] Point xDeprecated + * @property {number|null} [yDeprecated] Point yDeprecated + * @property {number|null} [x] Point x + * @property {number|null} [y] Point y + */ + + /** + * Constructs a new Point. + * @memberof proto + * @classdesc Represents a Point. + * @implements IPoint + * @constructor + * @param {proto.IPoint=} [properties] Properties to set + */ + function Point(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Point xDeprecated. + * @member {number} xDeprecated + * @memberof proto.Point + * @instance + */ + Point.prototype.xDeprecated = 0; + + /** + * Point yDeprecated. + * @member {number} yDeprecated + * @memberof proto.Point + * @instance + */ + Point.prototype.yDeprecated = 0; + + /** + * Point x. + * @member {number} x + * @memberof proto.Point + * @instance + */ + Point.prototype.x = 0; + + /** + * Point y. + * @member {number} y + * @memberof proto.Point + * @instance + */ + Point.prototype.y = 0; + + /** + * Creates a new Point instance using the specified properties. + * @function create + * @memberof proto.Point + * @static + * @param {proto.IPoint=} [properties] Properties to set + * @returns {proto.Point} Point instance + */ + Point.create = function create(properties) { + return new Point(properties); + }; + + /** + * Encodes the specified Point message. Does not implicitly {@link proto.Point.verify|verify} messages. + * @function encode + * @memberof proto.Point + * @static + * @param {proto.IPoint} message Point message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Point.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.xDeprecated != null && Object.hasOwnProperty.call(message, "xDeprecated")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.xDeprecated); + if (message.yDeprecated != null && Object.hasOwnProperty.call(message, "yDeprecated")) + writer.uint32(/* id 2, wireType 0 =*/16).int32(message.yDeprecated); + if (message.x != null && Object.hasOwnProperty.call(message, "x")) + writer.uint32(/* id 3, wireType 1 =*/25).double(message.x); + if (message.y != null && Object.hasOwnProperty.call(message, "y")) + writer.uint32(/* id 4, wireType 1 =*/33).double(message.y); + return writer; + }; + + /** + * Encodes the specified Point message, length delimited. Does not implicitly {@link proto.Point.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Point + * @static + * @param {proto.IPoint} message Point message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Point.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Point message from the specified reader or buffer. + * @function decode + * @memberof proto.Point + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Point} Point + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Point.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Point(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.xDeprecated = reader.int32(); + break; + case 2: + message.yDeprecated = reader.int32(); + break; + case 3: + message.x = reader.double(); + break; + case 4: + message.y = reader.double(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Point message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Point + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Point} Point + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Point.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Point message. + * @function verify + * @memberof proto.Point + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Point.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.xDeprecated != null && message.hasOwnProperty("xDeprecated")) + if (!$util.isInteger(message.xDeprecated)) + return "xDeprecated: integer expected"; + if (message.yDeprecated != null && message.hasOwnProperty("yDeprecated")) + if (!$util.isInteger(message.yDeprecated)) + return "yDeprecated: integer expected"; + if (message.x != null && message.hasOwnProperty("x")) + if (typeof message.x !== "number") + return "x: number expected"; + if (message.y != null && message.hasOwnProperty("y")) + if (typeof message.y !== "number") + return "y: number expected"; + return null; + }; + + /** + * Creates a Point message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Point + * @static + * @param {Object.} object Plain object + * @returns {proto.Point} Point + */ + Point.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Point) + return object; + var message = new $root.proto.Point(); + if (object.xDeprecated != null) + message.xDeprecated = object.xDeprecated | 0; + if (object.yDeprecated != null) + message.yDeprecated = object.yDeprecated | 0; + if (object.x != null) + message.x = Number(object.x); + if (object.y != null) + message.y = Number(object.y); + return message; + }; + + /** + * Creates a plain object from a Point message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Point + * @static + * @param {proto.Point} message Point + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Point.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.xDeprecated = 0; + object.yDeprecated = 0; + object.x = 0; + object.y = 0; + } + if (message.xDeprecated != null && message.hasOwnProperty("xDeprecated")) + object.xDeprecated = message.xDeprecated; + if (message.yDeprecated != null && message.hasOwnProperty("yDeprecated")) + object.yDeprecated = message.yDeprecated; + if (message.x != null && message.hasOwnProperty("x")) + object.x = options.json && !isFinite(message.x) ? String(message.x) : message.x; + if (message.y != null && message.hasOwnProperty("y")) + object.y = options.json && !isFinite(message.y) ? String(message.y) : message.y; + return object; + }; + + /** + * Converts this Point to JSON. + * @function toJSON + * @memberof proto.Point + * @instance + * @returns {Object.} JSON object + */ + Point.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Point; + })(); + proto.CompanionProps = (function() { /** @@ -46162,6 +52250,675 @@ $root.proto = (function() { return MessageKey; })(); + proto.Reaction = (function() { + + /** + * Properties of a Reaction. + * @memberof proto + * @interface IReaction + * @property {proto.IMessageKey|null} [key] Reaction key + * @property {string|null} [text] Reaction text + * @property {string|null} [groupingKey] Reaction groupingKey + * @property {number|Long|null} [senderTimestampMs] Reaction senderTimestampMs + * @property {boolean|null} [unread] Reaction unread + */ + + /** + * Constructs a new Reaction. + * @memberof proto + * @classdesc Represents a Reaction. + * @implements IReaction + * @constructor + * @param {proto.IReaction=} [properties] Properties to set + */ + function Reaction(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Reaction key. + * @member {proto.IMessageKey|null|undefined} key + * @memberof proto.Reaction + * @instance + */ + Reaction.prototype.key = null; + + /** + * Reaction text. + * @member {string} text + * @memberof proto.Reaction + * @instance + */ + Reaction.prototype.text = ""; + + /** + * Reaction groupingKey. + * @member {string} groupingKey + * @memberof proto.Reaction + * @instance + */ + Reaction.prototype.groupingKey = ""; + + /** + * Reaction senderTimestampMs. + * @member {number|Long} senderTimestampMs + * @memberof proto.Reaction + * @instance + */ + Reaction.prototype.senderTimestampMs = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Reaction unread. + * @member {boolean} unread + * @memberof proto.Reaction + * @instance + */ + Reaction.prototype.unread = false; + + /** + * Creates a new Reaction instance using the specified properties. + * @function create + * @memberof proto.Reaction + * @static + * @param {proto.IReaction=} [properties] Properties to set + * @returns {proto.Reaction} Reaction instance + */ + Reaction.create = function create(properties) { + return new Reaction(properties); + }; + + /** + * Encodes the specified Reaction message. Does not implicitly {@link proto.Reaction.verify|verify} messages. + * @function encode + * @memberof proto.Reaction + * @static + * @param {proto.IReaction} message Reaction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Reaction.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.key != null && Object.hasOwnProperty.call(message, "key")) + $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.text != null && Object.hasOwnProperty.call(message, "text")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.text); + if (message.groupingKey != null && Object.hasOwnProperty.call(message, "groupingKey")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.groupingKey); + if (message.senderTimestampMs != null && Object.hasOwnProperty.call(message, "senderTimestampMs")) + writer.uint32(/* id 4, wireType 0 =*/32).int64(message.senderTimestampMs); + if (message.unread != null && Object.hasOwnProperty.call(message, "unread")) + writer.uint32(/* id 5, wireType 0 =*/40).bool(message.unread); + return writer; + }; + + /** + * Encodes the specified Reaction message, length delimited. Does not implicitly {@link proto.Reaction.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.Reaction + * @static + * @param {proto.IReaction} message Reaction message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Reaction.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Reaction message from the specified reader or buffer. + * @function decode + * @memberof proto.Reaction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.Reaction} Reaction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Reaction.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Reaction(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.key = $root.proto.MessageKey.decode(reader, reader.uint32()); + break; + case 2: + message.text = reader.string(); + break; + case 3: + message.groupingKey = reader.string(); + break; + case 4: + message.senderTimestampMs = reader.int64(); + break; + case 5: + message.unread = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Reaction message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.Reaction + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.Reaction} Reaction + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Reaction.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Reaction message. + * @function verify + * @memberof proto.Reaction + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Reaction.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.key != null && message.hasOwnProperty("key")) { + var error = $root.proto.MessageKey.verify(message.key); + if (error) + return "key." + error; + } + if (message.text != null && message.hasOwnProperty("text")) + if (!$util.isString(message.text)) + return "text: string expected"; + if (message.groupingKey != null && message.hasOwnProperty("groupingKey")) + if (!$util.isString(message.groupingKey)) + return "groupingKey: string expected"; + if (message.senderTimestampMs != null && message.hasOwnProperty("senderTimestampMs")) + if (!$util.isInteger(message.senderTimestampMs) && !(message.senderTimestampMs && $util.isInteger(message.senderTimestampMs.low) && $util.isInteger(message.senderTimestampMs.high))) + return "senderTimestampMs: integer|Long expected"; + if (message.unread != null && message.hasOwnProperty("unread")) + if (typeof message.unread !== "boolean") + return "unread: boolean expected"; + return null; + }; + + /** + * Creates a Reaction message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.Reaction + * @static + * @param {Object.} object Plain object + * @returns {proto.Reaction} Reaction + */ + Reaction.fromObject = function fromObject(object) { + if (object instanceof $root.proto.Reaction) + return object; + var message = new $root.proto.Reaction(); + if (object.key != null) { + if (typeof object.key !== "object") + throw TypeError(".proto.Reaction.key: object expected"); + message.key = $root.proto.MessageKey.fromObject(object.key); + } + if (object.text != null) + message.text = String(object.text); + if (object.groupingKey != null) + message.groupingKey = String(object.groupingKey); + if (object.senderTimestampMs != null) + if ($util.Long) + (message.senderTimestampMs = $util.Long.fromValue(object.senderTimestampMs)).unsigned = false; + else if (typeof object.senderTimestampMs === "string") + message.senderTimestampMs = parseInt(object.senderTimestampMs, 10); + else if (typeof object.senderTimestampMs === "number") + message.senderTimestampMs = object.senderTimestampMs; + else if (typeof object.senderTimestampMs === "object") + message.senderTimestampMs = new $util.LongBits(object.senderTimestampMs.low >>> 0, object.senderTimestampMs.high >>> 0).toNumber(); + if (object.unread != null) + message.unread = Boolean(object.unread); + return message; + }; + + /** + * Creates a plain object from a Reaction message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.Reaction + * @static + * @param {proto.Reaction} message Reaction + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Reaction.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.key = null; + object.text = ""; + object.groupingKey = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.senderTimestampMs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.senderTimestampMs = options.longs === String ? "0" : 0; + object.unread = false; + } + if (message.key != null && message.hasOwnProperty("key")) + object.key = $root.proto.MessageKey.toObject(message.key, options); + if (message.text != null && message.hasOwnProperty("text")) + object.text = message.text; + if (message.groupingKey != null && message.hasOwnProperty("groupingKey")) + object.groupingKey = message.groupingKey; + if (message.senderTimestampMs != null && message.hasOwnProperty("senderTimestampMs")) + if (typeof message.senderTimestampMs === "number") + object.senderTimestampMs = options.longs === String ? String(message.senderTimestampMs) : message.senderTimestampMs; + else + object.senderTimestampMs = options.longs === String ? $util.Long.prototype.toString.call(message.senderTimestampMs) : options.longs === Number ? new $util.LongBits(message.senderTimestampMs.low >>> 0, message.senderTimestampMs.high >>> 0).toNumber() : message.senderTimestampMs; + if (message.unread != null && message.hasOwnProperty("unread")) + object.unread = message.unread; + return object; + }; + + /** + * Converts this Reaction to JSON. + * @function toJSON + * @memberof proto.Reaction + * @instance + * @returns {Object.} JSON object + */ + Reaction.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Reaction; + })(); + + proto.UserReceipt = (function() { + + /** + * Properties of a UserReceipt. + * @memberof proto + * @interface IUserReceipt + * @property {string} userJid UserReceipt userJid + * @property {number|Long|null} [receiptTimestamp] UserReceipt receiptTimestamp + * @property {number|Long|null} [readTimestamp] UserReceipt readTimestamp + * @property {number|Long|null} [playedTimestamp] UserReceipt playedTimestamp + * @property {Array.|null} [pendingDeviceJid] UserReceipt pendingDeviceJid + * @property {Array.|null} [deliveredDeviceJid] UserReceipt deliveredDeviceJid + */ + + /** + * Constructs a new UserReceipt. + * @memberof proto + * @classdesc Represents a UserReceipt. + * @implements IUserReceipt + * @constructor + * @param {proto.IUserReceipt=} [properties] Properties to set + */ + function UserReceipt(properties) { + this.pendingDeviceJid = []; + this.deliveredDeviceJid = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * UserReceipt userJid. + * @member {string} userJid + * @memberof proto.UserReceipt + * @instance + */ + UserReceipt.prototype.userJid = ""; + + /** + * UserReceipt receiptTimestamp. + * @member {number|Long} receiptTimestamp + * @memberof proto.UserReceipt + * @instance + */ + UserReceipt.prototype.receiptTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * UserReceipt readTimestamp. + * @member {number|Long} readTimestamp + * @memberof proto.UserReceipt + * @instance + */ + UserReceipt.prototype.readTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * UserReceipt playedTimestamp. + * @member {number|Long} playedTimestamp + * @memberof proto.UserReceipt + * @instance + */ + UserReceipt.prototype.playedTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * UserReceipt pendingDeviceJid. + * @member {Array.} pendingDeviceJid + * @memberof proto.UserReceipt + * @instance + */ + UserReceipt.prototype.pendingDeviceJid = $util.emptyArray; + + /** + * UserReceipt deliveredDeviceJid. + * @member {Array.} deliveredDeviceJid + * @memberof proto.UserReceipt + * @instance + */ + UserReceipt.prototype.deliveredDeviceJid = $util.emptyArray; + + /** + * Creates a new UserReceipt instance using the specified properties. + * @function create + * @memberof proto.UserReceipt + * @static + * @param {proto.IUserReceipt=} [properties] Properties to set + * @returns {proto.UserReceipt} UserReceipt instance + */ + UserReceipt.create = function create(properties) { + return new UserReceipt(properties); + }; + + /** + * Encodes the specified UserReceipt message. Does not implicitly {@link proto.UserReceipt.verify|verify} messages. + * @function encode + * @memberof proto.UserReceipt + * @static + * @param {proto.IUserReceipt} message UserReceipt message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UserReceipt.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + writer.uint32(/* id 1, wireType 2 =*/10).string(message.userJid); + if (message.receiptTimestamp != null && Object.hasOwnProperty.call(message, "receiptTimestamp")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.receiptTimestamp); + if (message.readTimestamp != null && Object.hasOwnProperty.call(message, "readTimestamp")) + writer.uint32(/* id 3, wireType 0 =*/24).int64(message.readTimestamp); + if (message.playedTimestamp != null && Object.hasOwnProperty.call(message, "playedTimestamp")) + writer.uint32(/* id 4, wireType 0 =*/32).int64(message.playedTimestamp); + if (message.pendingDeviceJid != null && message.pendingDeviceJid.length) + for (var i = 0; i < message.pendingDeviceJid.length; ++i) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.pendingDeviceJid[i]); + if (message.deliveredDeviceJid != null && message.deliveredDeviceJid.length) + for (var i = 0; i < message.deliveredDeviceJid.length; ++i) + writer.uint32(/* id 6, wireType 2 =*/50).string(message.deliveredDeviceJid[i]); + return writer; + }; + + /** + * Encodes the specified UserReceipt message, length delimited. Does not implicitly {@link proto.UserReceipt.verify|verify} messages. + * @function encodeDelimited + * @memberof proto.UserReceipt + * @static + * @param {proto.IUserReceipt} message UserReceipt message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UserReceipt.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a UserReceipt message from the specified reader or buffer. + * @function decode + * @memberof proto.UserReceipt + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {proto.UserReceipt} UserReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UserReceipt.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.UserReceipt(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.userJid = reader.string(); + break; + case 2: + message.receiptTimestamp = reader.int64(); + break; + case 3: + message.readTimestamp = reader.int64(); + break; + case 4: + message.playedTimestamp = reader.int64(); + break; + case 5: + if (!(message.pendingDeviceJid && message.pendingDeviceJid.length)) + message.pendingDeviceJid = []; + message.pendingDeviceJid.push(reader.string()); + break; + case 6: + if (!(message.deliveredDeviceJid && message.deliveredDeviceJid.length)) + message.deliveredDeviceJid = []; + message.deliveredDeviceJid.push(reader.string()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + if (!message.hasOwnProperty("userJid")) + throw $util.ProtocolError("missing required 'userJid'", { instance: message }); + return message; + }; + + /** + * Decodes a UserReceipt message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof proto.UserReceipt + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {proto.UserReceipt} UserReceipt + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UserReceipt.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a UserReceipt message. + * @function verify + * @memberof proto.UserReceipt + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + UserReceipt.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (!$util.isString(message.userJid)) + return "userJid: string expected"; + if (message.receiptTimestamp != null && message.hasOwnProperty("receiptTimestamp")) + if (!$util.isInteger(message.receiptTimestamp) && !(message.receiptTimestamp && $util.isInteger(message.receiptTimestamp.low) && $util.isInteger(message.receiptTimestamp.high))) + return "receiptTimestamp: integer|Long expected"; + if (message.readTimestamp != null && message.hasOwnProperty("readTimestamp")) + if (!$util.isInteger(message.readTimestamp) && !(message.readTimestamp && $util.isInteger(message.readTimestamp.low) && $util.isInteger(message.readTimestamp.high))) + return "readTimestamp: integer|Long expected"; + if (message.playedTimestamp != null && message.hasOwnProperty("playedTimestamp")) + if (!$util.isInteger(message.playedTimestamp) && !(message.playedTimestamp && $util.isInteger(message.playedTimestamp.low) && $util.isInteger(message.playedTimestamp.high))) + return "playedTimestamp: integer|Long expected"; + if (message.pendingDeviceJid != null && message.hasOwnProperty("pendingDeviceJid")) { + if (!Array.isArray(message.pendingDeviceJid)) + return "pendingDeviceJid: array expected"; + for (var i = 0; i < message.pendingDeviceJid.length; ++i) + if (!$util.isString(message.pendingDeviceJid[i])) + return "pendingDeviceJid: string[] expected"; + } + if (message.deliveredDeviceJid != null && message.hasOwnProperty("deliveredDeviceJid")) { + if (!Array.isArray(message.deliveredDeviceJid)) + return "deliveredDeviceJid: array expected"; + for (var i = 0; i < message.deliveredDeviceJid.length; ++i) + if (!$util.isString(message.deliveredDeviceJid[i])) + return "deliveredDeviceJid: string[] expected"; + } + return null; + }; + + /** + * Creates a UserReceipt message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof proto.UserReceipt + * @static + * @param {Object.} object Plain object + * @returns {proto.UserReceipt} UserReceipt + */ + UserReceipt.fromObject = function fromObject(object) { + if (object instanceof $root.proto.UserReceipt) + return object; + var message = new $root.proto.UserReceipt(); + if (object.userJid != null) + message.userJid = String(object.userJid); + if (object.receiptTimestamp != null) + if ($util.Long) + (message.receiptTimestamp = $util.Long.fromValue(object.receiptTimestamp)).unsigned = false; + else if (typeof object.receiptTimestamp === "string") + message.receiptTimestamp = parseInt(object.receiptTimestamp, 10); + else if (typeof object.receiptTimestamp === "number") + message.receiptTimestamp = object.receiptTimestamp; + else if (typeof object.receiptTimestamp === "object") + message.receiptTimestamp = new $util.LongBits(object.receiptTimestamp.low >>> 0, object.receiptTimestamp.high >>> 0).toNumber(); + if (object.readTimestamp != null) + if ($util.Long) + (message.readTimestamp = $util.Long.fromValue(object.readTimestamp)).unsigned = false; + else if (typeof object.readTimestamp === "string") + message.readTimestamp = parseInt(object.readTimestamp, 10); + else if (typeof object.readTimestamp === "number") + message.readTimestamp = object.readTimestamp; + else if (typeof object.readTimestamp === "object") + message.readTimestamp = new $util.LongBits(object.readTimestamp.low >>> 0, object.readTimestamp.high >>> 0).toNumber(); + if (object.playedTimestamp != null) + if ($util.Long) + (message.playedTimestamp = $util.Long.fromValue(object.playedTimestamp)).unsigned = false; + else if (typeof object.playedTimestamp === "string") + message.playedTimestamp = parseInt(object.playedTimestamp, 10); + else if (typeof object.playedTimestamp === "number") + message.playedTimestamp = object.playedTimestamp; + else if (typeof object.playedTimestamp === "object") + message.playedTimestamp = new $util.LongBits(object.playedTimestamp.low >>> 0, object.playedTimestamp.high >>> 0).toNumber(); + if (object.pendingDeviceJid) { + if (!Array.isArray(object.pendingDeviceJid)) + throw TypeError(".proto.UserReceipt.pendingDeviceJid: array expected"); + message.pendingDeviceJid = []; + for (var i = 0; i < object.pendingDeviceJid.length; ++i) + message.pendingDeviceJid[i] = String(object.pendingDeviceJid[i]); + } + if (object.deliveredDeviceJid) { + if (!Array.isArray(object.deliveredDeviceJid)) + throw TypeError(".proto.UserReceipt.deliveredDeviceJid: array expected"); + message.deliveredDeviceJid = []; + for (var i = 0; i < object.deliveredDeviceJid.length; ++i) + message.deliveredDeviceJid[i] = String(object.deliveredDeviceJid[i]); + } + return message; + }; + + /** + * Creates a plain object from a UserReceipt message. Also converts values to other types if specified. + * @function toObject + * @memberof proto.UserReceipt + * @static + * @param {proto.UserReceipt} message UserReceipt + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + UserReceipt.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.pendingDeviceJid = []; + object.deliveredDeviceJid = []; + } + if (options.defaults) { + object.userJid = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.receiptTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.receiptTimestamp = options.longs === String ? "0" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.readTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.readTimestamp = options.longs === String ? "0" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.playedTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.playedTimestamp = options.longs === String ? "0" : 0; + } + if (message.userJid != null && message.hasOwnProperty("userJid")) + object.userJid = message.userJid; + if (message.receiptTimestamp != null && message.hasOwnProperty("receiptTimestamp")) + if (typeof message.receiptTimestamp === "number") + object.receiptTimestamp = options.longs === String ? String(message.receiptTimestamp) : message.receiptTimestamp; + else + object.receiptTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.receiptTimestamp) : options.longs === Number ? new $util.LongBits(message.receiptTimestamp.low >>> 0, message.receiptTimestamp.high >>> 0).toNumber() : message.receiptTimestamp; + if (message.readTimestamp != null && message.hasOwnProperty("readTimestamp")) + if (typeof message.readTimestamp === "number") + object.readTimestamp = options.longs === String ? String(message.readTimestamp) : message.readTimestamp; + else + object.readTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.readTimestamp) : options.longs === Number ? new $util.LongBits(message.readTimestamp.low >>> 0, message.readTimestamp.high >>> 0).toNumber() : message.readTimestamp; + if (message.playedTimestamp != null && message.hasOwnProperty("playedTimestamp")) + if (typeof message.playedTimestamp === "number") + object.playedTimestamp = options.longs === String ? String(message.playedTimestamp) : message.playedTimestamp; + else + object.playedTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.playedTimestamp) : options.longs === Number ? new $util.LongBits(message.playedTimestamp.low >>> 0, message.playedTimestamp.high >>> 0).toNumber() : message.playedTimestamp; + if (message.pendingDeviceJid && message.pendingDeviceJid.length) { + object.pendingDeviceJid = []; + for (var j = 0; j < message.pendingDeviceJid.length; ++j) + object.pendingDeviceJid[j] = message.pendingDeviceJid[j]; + } + if (message.deliveredDeviceJid && message.deliveredDeviceJid.length) { + object.deliveredDeviceJid = []; + for (var j = 0; j < message.deliveredDeviceJid.length; ++j) + object.deliveredDeviceJid[j] = message.deliveredDeviceJid[j]; + } + return object; + }; + + /** + * Converts this UserReceipt to JSON. + * @function toJSON + * @memberof proto.UserReceipt + * @instance + * @returns {Object.} JSON object + */ + UserReceipt.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return UserReceipt; + })(); + proto.PhotoChange = (function() { /** @@ -46412,193 +53169,6 @@ $root.proto = (function() { return PhotoChange; })(); - proto.MediaData = (function() { - - /** - * Properties of a MediaData. - * @memberof proto - * @interface IMediaData - * @property {string|null} [localPath] MediaData localPath - */ - - /** - * Constructs a new MediaData. - * @memberof proto - * @classdesc Represents a MediaData. - * @implements IMediaData - * @constructor - * @param {proto.IMediaData=} [properties] Properties to set - */ - function MediaData(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * MediaData localPath. - * @member {string} localPath - * @memberof proto.MediaData - * @instance - */ - MediaData.prototype.localPath = ""; - - /** - * Creates a new MediaData instance using the specified properties. - * @function create - * @memberof proto.MediaData - * @static - * @param {proto.IMediaData=} [properties] Properties to set - * @returns {proto.MediaData} MediaData instance - */ - MediaData.create = function create(properties) { - return new MediaData(properties); - }; - - /** - * Encodes the specified MediaData message. Does not implicitly {@link proto.MediaData.verify|verify} messages. - * @function encode - * @memberof proto.MediaData - * @static - * @param {proto.IMediaData} message MediaData message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - MediaData.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.localPath != null && Object.hasOwnProperty.call(message, "localPath")) - writer.uint32(/* id 1, wireType 2 =*/10).string(message.localPath); - return writer; - }; - - /** - * Encodes the specified MediaData message, length delimited. Does not implicitly {@link proto.MediaData.verify|verify} messages. - * @function encodeDelimited - * @memberof proto.MediaData - * @static - * @param {proto.IMediaData} message MediaData message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - MediaData.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes a MediaData message from the specified reader or buffer. - * @function decode - * @memberof proto.MediaData - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {proto.MediaData} MediaData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - MediaData.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MediaData(); - while (reader.pos < end) { - var tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.localPath = reader.string(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes a MediaData message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof proto.MediaData - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {proto.MediaData} MediaData - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - MediaData.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies a MediaData message. - * @function verify - * @memberof proto.MediaData - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - MediaData.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.localPath != null && message.hasOwnProperty("localPath")) - if (!$util.isString(message.localPath)) - return "localPath: string expected"; - return null; - }; - - /** - * Creates a MediaData message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof proto.MediaData - * @static - * @param {Object.} object Plain object - * @returns {proto.MediaData} MediaData - */ - MediaData.fromObject = function fromObject(object) { - if (object instanceof $root.proto.MediaData) - return object; - var message = new $root.proto.MediaData(); - if (object.localPath != null) - message.localPath = String(object.localPath); - return message; - }; - - /** - * Creates a plain object from a MediaData message. Also converts values to other types if specified. - * @function toObject - * @memberof proto.MediaData - * @static - * @param {proto.MediaData} message MediaData - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - MediaData.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - object.localPath = ""; - if (message.localPath != null && message.hasOwnProperty("localPath")) - object.localPath = message.localPath; - return object; - }; - - /** - * Converts this MediaData to JSON. - * @function toJSON - * @memberof proto.MediaData - * @instance - * @returns {Object.} JSON object - */ - MediaData.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - return MediaData; - })(); - proto.WebFeatures = (function() { /** @@ -46647,6 +53217,9 @@ $root.proto = (function() { * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeralAllowGroupMembers] WebFeatures ephemeralAllowGroupMembers * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeral24HDuration] WebFeatures ephemeral24HDuration * @property {proto.WebFeatures.WebFeaturesFlag|null} [mdForceUpgrade] WebFeatures mdForceUpgrade + * @property {proto.WebFeatures.WebFeaturesFlag|null} [disappearingMode] WebFeatures disappearingMode + * @property {proto.WebFeatures.WebFeaturesFlag|null} [externalMdOptInAvailable] WebFeatures externalMdOptInAvailable + * @property {proto.WebFeatures.WebFeaturesFlag|null} [noDeleteMessageTimeLimit] WebFeatures noDeleteMessageTimeLimit */ /** @@ -47000,6 +53573,30 @@ $root.proto = (function() { */ WebFeatures.prototype.mdForceUpgrade = 0; + /** + * WebFeatures disappearingMode. + * @member {proto.WebFeatures.WebFeaturesFlag} disappearingMode + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.disappearingMode = 0; + + /** + * WebFeatures externalMdOptInAvailable. + * @member {proto.WebFeatures.WebFeaturesFlag} externalMdOptInAvailable + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.externalMdOptInAvailable = 0; + + /** + * WebFeatures noDeleteMessageTimeLimit. + * @member {proto.WebFeatures.WebFeaturesFlag} noDeleteMessageTimeLimit + * @memberof proto.WebFeatures + * @instance + */ + WebFeatures.prototype.noDeleteMessageTimeLimit = 0; + /** * Creates a new WebFeatures instance using the specified properties. * @function create @@ -47108,6 +53705,12 @@ $root.proto = (function() { writer.uint32(/* id 45, wireType 0 =*/360).int32(message.ephemeral24HDuration); if (message.mdForceUpgrade != null && Object.hasOwnProperty.call(message, "mdForceUpgrade")) writer.uint32(/* id 46, wireType 0 =*/368).int32(message.mdForceUpgrade); + if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode")) + writer.uint32(/* id 47, wireType 0 =*/376).int32(message.disappearingMode); + if (message.externalMdOptInAvailable != null && Object.hasOwnProperty.call(message, "externalMdOptInAvailable")) + writer.uint32(/* id 48, wireType 0 =*/384).int32(message.externalMdOptInAvailable); + if (message.noDeleteMessageTimeLimit != null && Object.hasOwnProperty.call(message, "noDeleteMessageTimeLimit")) + writer.uint32(/* id 49, wireType 0 =*/392).int32(message.noDeleteMessageTimeLimit); return writer; }; @@ -47268,6 +53871,15 @@ $root.proto = (function() { case 46: message.mdForceUpgrade = reader.int32(); break; + case 47: + message.disappearingMode = reader.int32(); + break; + case 48: + message.externalMdOptInAvailable = reader.int32(); + break; + case 49: + message.noDeleteMessageTimeLimit = reader.int32(); + break; default: reader.skipType(tag & 7); break; @@ -47723,6 +54335,36 @@ $root.proto = (function() { case 3: break; } + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) + switch (message.disappearingMode) { + default: + return "disappearingMode: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.externalMdOptInAvailable != null && message.hasOwnProperty("externalMdOptInAvailable")) + switch (message.externalMdOptInAvailable) { + default: + return "externalMdOptInAvailable: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } + if (message.noDeleteMessageTimeLimit != null && message.hasOwnProperty("noDeleteMessageTimeLimit")) + switch (message.noDeleteMessageTimeLimit) { + default: + return "noDeleteMessageTimeLimit: enum value expected"; + case 0: + case 1: + case 2: + case 3: + break; + } return null; }; @@ -48494,6 +55136,60 @@ $root.proto = (function() { message.mdForceUpgrade = 3; break; } + switch (object.disappearingMode) { + case "NOT_STARTED": + case 0: + message.disappearingMode = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.disappearingMode = 1; + break; + case "DEVELOPMENT": + case 2: + message.disappearingMode = 2; + break; + case "PRODUCTION": + case 3: + message.disappearingMode = 3; + break; + } + switch (object.externalMdOptInAvailable) { + case "NOT_STARTED": + case 0: + message.externalMdOptInAvailable = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.externalMdOptInAvailable = 1; + break; + case "DEVELOPMENT": + case 2: + message.externalMdOptInAvailable = 2; + break; + case "PRODUCTION": + case 3: + message.externalMdOptInAvailable = 3; + break; + } + switch (object.noDeleteMessageTimeLimit) { + case "NOT_STARTED": + case 0: + message.noDeleteMessageTimeLimit = 0; + break; + case "FORCE_UPGRADE": + case 1: + message.noDeleteMessageTimeLimit = 1; + break; + case "DEVELOPMENT": + case 2: + message.noDeleteMessageTimeLimit = 2; + break; + case "PRODUCTION": + case 3: + message.noDeleteMessageTimeLimit = 3; + break; + } return message; }; @@ -48553,6 +55249,9 @@ $root.proto = (function() { object.ephemeralAllowGroupMembers = options.enums === String ? "NOT_STARTED" : 0; object.ephemeral24HDuration = options.enums === String ? "NOT_STARTED" : 0; object.mdForceUpgrade = options.enums === String ? "NOT_STARTED" : 0; + object.disappearingMode = options.enums === String ? "NOT_STARTED" : 0; + object.externalMdOptInAvailable = options.enums === String ? "NOT_STARTED" : 0; + object.noDeleteMessageTimeLimit = options.enums === String ? "NOT_STARTED" : 0; } if (message.labelsDisplay != null && message.hasOwnProperty("labelsDisplay")) object.labelsDisplay = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.labelsDisplay] : message.labelsDisplay; @@ -48638,6 +55337,12 @@ $root.proto = (function() { object.ephemeral24HDuration = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.ephemeral24HDuration] : message.ephemeral24HDuration; if (message.mdForceUpgrade != null && message.hasOwnProperty("mdForceUpgrade")) object.mdForceUpgrade = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.mdForceUpgrade] : message.mdForceUpgrade; + if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) + object.disappearingMode = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.disappearingMode] : message.disappearingMode; + if (message.externalMdOptInAvailable != null && message.hasOwnProperty("externalMdOptInAvailable")) + object.externalMdOptInAvailable = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.externalMdOptInAvailable] : message.externalMdOptInAvailable; + if (message.noDeleteMessageTimeLimit != null && message.hasOwnProperty("noDeleteMessageTimeLimit")) + object.noDeleteMessageTimeLimit = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.noDeleteMessageTimeLimit] : message.noDeleteMessageTimeLimit; return object; }; @@ -50126,6 +56831,13 @@ $root.proto = (function() { * @property {string|null} [verifiedBizName] WebMessageInfo verifiedBizName * @property {proto.IMediaData|null} [mediaData] WebMessageInfo mediaData * @property {proto.IPhotoChange|null} [photoChange] WebMessageInfo photoChange + * @property {Array.|null} [userReceipt] WebMessageInfo userReceipt + * @property {Array.|null} [reactions] WebMessageInfo reactions + * @property {proto.IMediaData|null} [quotedStickerData] WebMessageInfo quotedStickerData + * @property {Uint8Array|null} [futureproofData] WebMessageInfo futureproofData + * @property {string|null} [statusPsaCampaignId] WebMessageInfo statusPsaCampaignId + * @property {number|null} [statusPsaCampaignDuration] WebMessageInfo statusPsaCampaignDuration + * @property {number|Long|null} [statusPsaCampaignReadTimestamp] WebMessageInfo statusPsaCampaignReadTimestamp */ /** @@ -50139,6 +56851,8 @@ $root.proto = (function() { function WebMessageInfo(properties) { this.messageStubParameters = []; this.labels = []; + this.userReceipt = []; + this.reactions = []; if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -50385,6 +57099,62 @@ $root.proto = (function() { */ WebMessageInfo.prototype.photoChange = null; + /** + * WebMessageInfo userReceipt. + * @member {Array.} userReceipt + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.userReceipt = $util.emptyArray; + + /** + * WebMessageInfo reactions. + * @member {Array.} reactions + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.reactions = $util.emptyArray; + + /** + * WebMessageInfo quotedStickerData. + * @member {proto.IMediaData|null|undefined} quotedStickerData + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.quotedStickerData = null; + + /** + * WebMessageInfo futureproofData. + * @member {Uint8Array} futureproofData + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.futureproofData = $util.newBuffer([]); + + /** + * WebMessageInfo statusPsaCampaignId. + * @member {string} statusPsaCampaignId + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.statusPsaCampaignId = ""; + + /** + * WebMessageInfo statusPsaCampaignDuration. + * @member {number} statusPsaCampaignDuration + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.statusPsaCampaignDuration = 0; + + /** + * WebMessageInfo statusPsaCampaignReadTimestamp. + * @member {number|Long} statusPsaCampaignReadTimestamp + * @memberof proto.WebMessageInfo + * @instance + */ + WebMessageInfo.prototype.statusPsaCampaignReadTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0; + /** * Creates a new WebMessageInfo instance using the specified properties. * @function create @@ -50470,6 +57240,22 @@ $root.proto = (function() { $root.proto.MediaData.encode(message.mediaData, writer.uint32(/* id 38, wireType 2 =*/306).fork()).ldelim(); if (message.photoChange != null && Object.hasOwnProperty.call(message, "photoChange")) $root.proto.PhotoChange.encode(message.photoChange, writer.uint32(/* id 39, wireType 2 =*/314).fork()).ldelim(); + if (message.userReceipt != null && message.userReceipt.length) + for (var i = 0; i < message.userReceipt.length; ++i) + $root.proto.UserReceipt.encode(message.userReceipt[i], writer.uint32(/* id 40, wireType 2 =*/322).fork()).ldelim(); + if (message.reactions != null && message.reactions.length) + for (var i = 0; i < message.reactions.length; ++i) + $root.proto.Reaction.encode(message.reactions[i], writer.uint32(/* id 41, wireType 2 =*/330).fork()).ldelim(); + if (message.quotedStickerData != null && Object.hasOwnProperty.call(message, "quotedStickerData")) + $root.proto.MediaData.encode(message.quotedStickerData, writer.uint32(/* id 42, wireType 2 =*/338).fork()).ldelim(); + if (message.futureproofData != null && Object.hasOwnProperty.call(message, "futureproofData")) + writer.uint32(/* id 43, wireType 2 =*/346).bytes(message.futureproofData); + if (message.statusPsaCampaignId != null && Object.hasOwnProperty.call(message, "statusPsaCampaignId")) + writer.uint32(/* id 44, wireType 2 =*/354).string(message.statusPsaCampaignId); + if (message.statusPsaCampaignDuration != null && Object.hasOwnProperty.call(message, "statusPsaCampaignDuration")) + writer.uint32(/* id 45, wireType 0 =*/360).uint32(message.statusPsaCampaignDuration); + if (message.statusPsaCampaignReadTimestamp != null && Object.hasOwnProperty.call(message, "statusPsaCampaignReadTimestamp")) + writer.uint32(/* id 46, wireType 0 =*/368).uint64(message.statusPsaCampaignReadTimestamp); return writer; }; @@ -50598,6 +57384,31 @@ $root.proto = (function() { case 39: message.photoChange = $root.proto.PhotoChange.decode(reader, reader.uint32()); break; + case 40: + if (!(message.userReceipt && message.userReceipt.length)) + message.userReceipt = []; + message.userReceipt.push($root.proto.UserReceipt.decode(reader, reader.uint32())); + break; + case 41: + if (!(message.reactions && message.reactions.length)) + message.reactions = []; + message.reactions.push($root.proto.Reaction.decode(reader, reader.uint32())); + break; + case 42: + message.quotedStickerData = $root.proto.MediaData.decode(reader, reader.uint32()); + break; + case 43: + message.futureproofData = reader.bytes(); + break; + case 44: + message.statusPsaCampaignId = reader.string(); + break; + case 45: + message.statusPsaCampaignDuration = reader.uint32(); + break; + case 46: + message.statusPsaCampaignReadTimestamp = reader.uint64(); + break; default: reader.skipType(tag & 7); break; @@ -50824,6 +57635,8 @@ $root.proto = (function() { case 127: case 128: case 129: + case 130: + case 131: break; } if (message.clearMedia != null && message.hasOwnProperty("clearMedia")) @@ -50896,6 +57709,41 @@ $root.proto = (function() { if (error) return "photoChange." + error; } + if (message.userReceipt != null && message.hasOwnProperty("userReceipt")) { + if (!Array.isArray(message.userReceipt)) + return "userReceipt: array expected"; + for (var i = 0; i < message.userReceipt.length; ++i) { + var error = $root.proto.UserReceipt.verify(message.userReceipt[i]); + if (error) + return "userReceipt." + error; + } + } + if (message.reactions != null && message.hasOwnProperty("reactions")) { + if (!Array.isArray(message.reactions)) + return "reactions: array expected"; + for (var i = 0; i < message.reactions.length; ++i) { + var error = $root.proto.Reaction.verify(message.reactions[i]); + if (error) + return "reactions." + error; + } + } + if (message.quotedStickerData != null && message.hasOwnProperty("quotedStickerData")) { + var error = $root.proto.MediaData.verify(message.quotedStickerData); + if (error) + return "quotedStickerData." + error; + } + if (message.futureproofData != null && message.hasOwnProperty("futureproofData")) + if (!(message.futureproofData && typeof message.futureproofData.length === "number" || $util.isString(message.futureproofData))) + return "futureproofData: buffer expected"; + if (message.statusPsaCampaignId != null && message.hasOwnProperty("statusPsaCampaignId")) + if (!$util.isString(message.statusPsaCampaignId)) + return "statusPsaCampaignId: string expected"; + if (message.statusPsaCampaignDuration != null && message.hasOwnProperty("statusPsaCampaignDuration")) + if (!$util.isInteger(message.statusPsaCampaignDuration)) + return "statusPsaCampaignDuration: integer expected"; + if (message.statusPsaCampaignReadTimestamp != null && message.hasOwnProperty("statusPsaCampaignReadTimestamp")) + if (!$util.isInteger(message.statusPsaCampaignReadTimestamp) && !(message.statusPsaCampaignReadTimestamp && $util.isInteger(message.statusPsaCampaignReadTimestamp.low) && $util.isInteger(message.statusPsaCampaignReadTimestamp.high))) + return "statusPsaCampaignReadTimestamp: integer|Long expected"; return null; }; @@ -51507,6 +58355,14 @@ $root.proto = (function() { case 129: message.messageStubType = 129; break; + case "DISAPPEARING_MODE": + case 130: + message.messageStubType = 130; + break; + case "E2E_DEVICE_FETCH_FAILED": + case 131: + message.messageStubType = 131; + break; } if (object.clearMedia != null) message.clearMedia = Boolean(object.clearMedia); @@ -51586,6 +58442,49 @@ $root.proto = (function() { throw TypeError(".proto.WebMessageInfo.photoChange: object expected"); message.photoChange = $root.proto.PhotoChange.fromObject(object.photoChange); } + if (object.userReceipt) { + if (!Array.isArray(object.userReceipt)) + throw TypeError(".proto.WebMessageInfo.userReceipt: array expected"); + message.userReceipt = []; + for (var i = 0; i < object.userReceipt.length; ++i) { + if (typeof object.userReceipt[i] !== "object") + throw TypeError(".proto.WebMessageInfo.userReceipt: object expected"); + message.userReceipt[i] = $root.proto.UserReceipt.fromObject(object.userReceipt[i]); + } + } + if (object.reactions) { + if (!Array.isArray(object.reactions)) + throw TypeError(".proto.WebMessageInfo.reactions: array expected"); + message.reactions = []; + for (var i = 0; i < object.reactions.length; ++i) { + if (typeof object.reactions[i] !== "object") + throw TypeError(".proto.WebMessageInfo.reactions: object expected"); + message.reactions[i] = $root.proto.Reaction.fromObject(object.reactions[i]); + } + } + if (object.quotedStickerData != null) { + if (typeof object.quotedStickerData !== "object") + throw TypeError(".proto.WebMessageInfo.quotedStickerData: object expected"); + message.quotedStickerData = $root.proto.MediaData.fromObject(object.quotedStickerData); + } + if (object.futureproofData != null) + if (typeof object.futureproofData === "string") + $util.base64.decode(object.futureproofData, message.futureproofData = $util.newBuffer($util.base64.length(object.futureproofData)), 0); + else if (object.futureproofData.length) + message.futureproofData = object.futureproofData; + if (object.statusPsaCampaignId != null) + message.statusPsaCampaignId = String(object.statusPsaCampaignId); + if (object.statusPsaCampaignDuration != null) + message.statusPsaCampaignDuration = object.statusPsaCampaignDuration >>> 0; + if (object.statusPsaCampaignReadTimestamp != null) + if ($util.Long) + (message.statusPsaCampaignReadTimestamp = $util.Long.fromValue(object.statusPsaCampaignReadTimestamp)).unsigned = true; + else if (typeof object.statusPsaCampaignReadTimestamp === "string") + message.statusPsaCampaignReadTimestamp = parseInt(object.statusPsaCampaignReadTimestamp, 10); + else if (typeof object.statusPsaCampaignReadTimestamp === "number") + message.statusPsaCampaignReadTimestamp = object.statusPsaCampaignReadTimestamp; + else if (typeof object.statusPsaCampaignReadTimestamp === "object") + message.statusPsaCampaignReadTimestamp = new $util.LongBits(object.statusPsaCampaignReadTimestamp.low >>> 0, object.statusPsaCampaignReadTimestamp.high >>> 0).toNumber(true); return message; }; @@ -51605,6 +58504,8 @@ $root.proto = (function() { if (options.arrays || options.defaults) { object.messageStubParameters = []; object.labels = []; + object.userReceipt = []; + object.reactions = []; } if (options.defaults) { object.key = null; @@ -51653,6 +58554,21 @@ $root.proto = (function() { object.verifiedBizName = ""; object.mediaData = null; object.photoChange = null; + object.quotedStickerData = null; + if (options.bytes === String) + object.futureproofData = ""; + else { + object.futureproofData = []; + if (options.bytes !== Array) + object.futureproofData = $util.newBuffer(object.futureproofData); + } + object.statusPsaCampaignId = ""; + object.statusPsaCampaignDuration = 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.statusPsaCampaignReadTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.statusPsaCampaignReadTimestamp = options.longs === String ? "0" : 0; } if (message.key != null && message.hasOwnProperty("key")) object.key = $root.proto.MessageKey.toObject(message.key, options); @@ -51729,6 +58645,29 @@ $root.proto = (function() { object.mediaData = $root.proto.MediaData.toObject(message.mediaData, options); if (message.photoChange != null && message.hasOwnProperty("photoChange")) object.photoChange = $root.proto.PhotoChange.toObject(message.photoChange, options); + if (message.userReceipt && message.userReceipt.length) { + object.userReceipt = []; + for (var j = 0; j < message.userReceipt.length; ++j) + object.userReceipt[j] = $root.proto.UserReceipt.toObject(message.userReceipt[j], options); + } + if (message.reactions && message.reactions.length) { + object.reactions = []; + for (var j = 0; j < message.reactions.length; ++j) + object.reactions[j] = $root.proto.Reaction.toObject(message.reactions[j], options); + } + if (message.quotedStickerData != null && message.hasOwnProperty("quotedStickerData")) + object.quotedStickerData = $root.proto.MediaData.toObject(message.quotedStickerData, options); + if (message.futureproofData != null && message.hasOwnProperty("futureproofData")) + object.futureproofData = options.bytes === String ? $util.base64.encode(message.futureproofData, 0, message.futureproofData.length) : options.bytes === Array ? Array.prototype.slice.call(message.futureproofData) : message.futureproofData; + if (message.statusPsaCampaignId != null && message.hasOwnProperty("statusPsaCampaignId")) + object.statusPsaCampaignId = message.statusPsaCampaignId; + if (message.statusPsaCampaignDuration != null && message.hasOwnProperty("statusPsaCampaignDuration")) + object.statusPsaCampaignDuration = message.statusPsaCampaignDuration; + if (message.statusPsaCampaignReadTimestamp != null && message.hasOwnProperty("statusPsaCampaignReadTimestamp")) + if (typeof message.statusPsaCampaignReadTimestamp === "number") + object.statusPsaCampaignReadTimestamp = options.longs === String ? String(message.statusPsaCampaignReadTimestamp) : message.statusPsaCampaignReadTimestamp; + else + object.statusPsaCampaignReadTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.statusPsaCampaignReadTimestamp) : options.longs === Number ? new $util.LongBits(message.statusPsaCampaignReadTimestamp.low >>> 0, message.statusPsaCampaignReadTimestamp.high >>> 0).toNumber(true) : message.statusPsaCampaignReadTimestamp; return object; }; @@ -51899,6 +58838,8 @@ $root.proto = (function() { * @property {number} BIZ_PRIVACY_MODE_INIT_BSP=127 BIZ_PRIVACY_MODE_INIT_BSP value * @property {number} BIZ_PRIVACY_MODE_TO_FB=128 BIZ_PRIVACY_MODE_TO_FB value * @property {number} BIZ_PRIVACY_MODE_TO_BSP=129 BIZ_PRIVACY_MODE_TO_BSP value + * @property {number} DISAPPEARING_MODE=130 DISAPPEARING_MODE value + * @property {number} E2E_DEVICE_FETCH_FAILED=131 E2E_DEVICE_FETCH_FAILED value */ WebMessageInfo.WebMessageInfoStubType = (function() { var valuesById = {}, values = Object.create(valuesById); @@ -52032,6 +58973,8 @@ $root.proto = (function() { values[valuesById[127] = "BIZ_PRIVACY_MODE_INIT_BSP"] = 127; values[valuesById[128] = "BIZ_PRIVACY_MODE_TO_FB"] = 128; values[valuesById[129] = "BIZ_PRIVACY_MODE_TO_BSP"] = 129; + values[valuesById[130] = "DISAPPEARING_MODE"] = 130; + values[valuesById[131] = "E2E_DEVICE_FETCH_FAILED"] = 131; return values; })(); From 7db5bb5d9a3031d7d286c1b706513b4a8a663e05 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 10 Dec 2021 11:22:06 +0530 Subject: [PATCH 205/311] chore: do not throw unhandled error on send messages again, log error --- src/Socket/messages-recv.ts | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 3db993a..86adb45 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -465,17 +465,18 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { }) const sendMessagesAgain = async(key: proto.IMessageKey, ids: string[]) => { - const participant = key.participant || key.remoteJid - await assertSession(participant, true) - - logger.debug({ key, ids }, 'recv retry request, forced new session') - + const msgs = await Promise.all( ids.map(id => ( config.getMessage({ ...key, id }) )) ) + const participant = key.participant || key.remoteJid + await assertSession(participant, true) + + logger.debug({ participant }, 'forced new session for retry recp') + for(let i = 0; i < msgs.length;i++) { if(msgs[i]) { await relayMessage(key.remoteJid, msgs[i], { @@ -489,6 +490,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } const handleReceipt = async(node: BinaryNode) => { + let shouldAck = true const { attrs, content } = node const remoteJid = attrs.recipient || attrs.from const fromMe = attrs.recipient ? false : true @@ -515,10 +517,19 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } if(attrs.type === 'retry') { - await sendMessagesAgain(key, ids) + try { + logger.debug({ attrs }, 'recv retry request') + await sendMessagesAgain(key, ids) + } catch(error) { + logger.error({ key, ids, trace: error.stack }, 'error in sending message again') + shouldAck = false + } } - await sendMessageAck(node, { class: 'receipt', type: attrs.type }) + if(shouldAck) { + await sendMessageAck(node, { class: 'receipt', type: attrs.type }) + } + } ws.on('CB:receipt', handleReceipt) From beac4d21e34c05cadae1628ea0927c3604b272b6 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 10 Dec 2021 13:15:34 +0530 Subject: [PATCH 206/311] chore: update WS --- package.json | 4 ++-- yarn.lock | 15 ++++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 2ed692d..a96edc7 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node-cache": "^5.1.2", "pino": "^6.7.0", "protobufjs": "^6.10.1", - "ws": "^7.3.1" + "ws": "^8.0.0" }, "optionalDependencies": { "qrcode-terminal": "^0.12.0" @@ -58,7 +58,7 @@ "@types/jest": "^26.0.24", "@types/node": "^14.6.2", "@types/pino": "^6.3.2", - "@types/ws": "^7.2.6", + "@types/ws": "^8.0.0", "jest": "^27.0.6", "qrcode-terminal": "^0.12.0", "ts-jest": "^27.0.3", diff --git a/yarn.lock b/yarn.lock index 902a756..4385632 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1099,10 +1099,10 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40" integrity sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg== -"@types/ws@^7.2.6": - version "7.4.6" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.6.tgz#c4320845e43d45a7129bb32905e28781c71c1fff" - integrity sha512-ijZ1vzRawI7QoWnTNL8KpHixd2b2XVb9I9HAqI3triPsh1EC0xH0Eg6w2O3TKbDCgiNNlJqfrof6j4T2I+l9vw== +"@types/ws@^8.0.0": + version "8.2.2" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.2.tgz#7c5be4decb19500ae6b3d563043cd407bf366c21" + integrity sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg== dependencies: "@types/node" "*" @@ -3816,11 +3816,16 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -ws@^7.3.1, ws@^7.4.5: +ws@^7.4.5: version "7.5.3" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== +ws@^8.0.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.3.0.tgz#7185e252c8973a60d57170175ff55fdbd116070d" + integrity sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw== + xhr@^2.0.1: version "2.6.0" resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" From b68ab8b8ac6a175b9a73c923b92f4f879e41a98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guilherme=20Fran=C3=A7a?= Date: Fri, 10 Dec 2021 15:43:03 -0300 Subject: [PATCH 207/311] refactor: change pttAudio param to ptt in send audio message as a voice note (#1002) --- src/Types/Message.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 903a5b8..b7b6380 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -77,7 +77,7 @@ export type AnyMediaMessageContent = ( } & Mentionable & Buttonable & Templatable & WithDimensions) | { audio: WAMediaUpload /** if set to true, will send as a `voice note` */ - pttAudio?: boolean + ptt?: boolean /** optionally tell the duration of the audio */ seconds?: number } | ({ From 8b1374f6ae4eef1d81f599d6b990d9abe3f177b4 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 11 Dec 2021 00:17:10 +0530 Subject: [PATCH 208/311] test: add another media test --- src/Tests/test.media-download.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Tests/test.media-download.ts b/src/Tests/test.media-download.ts index a0185a6..baa29d5 100644 --- a/src/Tests/test.media-download.ts +++ b/src/Tests/test.media-download.ts @@ -3,6 +3,8 @@ import { downloadContentFromMessage } from '../Utils' import { proto } from '../../WAProto' import { readFileSync } from 'fs' +jest.setTimeout(20_000) + type TestVector = { type: MediaType message: DownloadableMessage @@ -19,7 +21,17 @@ const TEST_VECTORS: TestVector[] = [ ) ), plaintext: readFileSync('./Media/cat.jpeg') - } + }, + { + type: 'image', + message: proto.ImageMessage.decode( + Buffer.from( + 'Ck1odHRwczovL21tZy53aGF0c2FwcC5uZXQvZC9mL0Ftb2tnWkphNWF6QWZxa3dVRzc0eUNUdTlGeWpjMmd5akpqcXNmMUFpZEU5LmVuYxIKaW1hZ2UvanBlZyIg8IS5TQzdzcuvcR7F8HMhWnXmlsV+GOo9JE1/t2k+o9Yoz6o6QiA7kDk8j5KOEQC0kDFE1qW7lBBDYhm5z06N3SirfUj3CUog/CjYF8e670D5wUJwWv2B2mKzDEo8IJLStDv76YmtPfs=', + 'base64' + ) + ), + plaintext: readFileSync('./Media/icon.png') + }, ] describe('Media Download Tests', () => { From 0ef9ce166d02d21e3e3704bd98a59f1f21fee665 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 11 Dec 2021 00:17:26 +0530 Subject: [PATCH 209/311] fix: set remote jid on quoted participant --- src/Utils/messages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index a257321..389bd10 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -324,7 +324,7 @@ export const generateWAMessageFromContent = ( // if a participant is quoted, then it must be a group // hence, remoteJid of group must also be entered - if (quoted.key.participant) { + if (quoted.key.participant || quoted.participant) { message[key].contextInfo.remoteJid = quoted.key.remoteJid } } From 2b33a5202c0001e7e5e98506bf009cfad0c92f37 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 11 Dec 2021 10:08:53 +0530 Subject: [PATCH 210/311] fix: do not retry not fromMe --- src/Socket/messages-recv.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 86adb45..3bc863f 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -517,12 +517,16 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } if(attrs.type === 'retry') { - try { - logger.debug({ attrs }, 'recv retry request') - await sendMessagesAgain(key, ids) - } catch(error) { - logger.error({ key, ids, trace: error.stack }, 'error in sending message again') - shouldAck = false + if(key.fromMe) { + try { + logger.debug({ attrs }, 'recv retry request') + await sendMessagesAgain(key, ids) + } catch(error) { + logger.error({ key, ids, trace: error.stack }, 'error in sending message again') + shouldAck = false + } + } else { + logger.info({ attrs, key }, 'recv retry for not fromMe message') } } From 792c4bf0a42dcf142d9aa23b1477dfe4691d07ef Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 11 Dec 2021 11:32:12 +0530 Subject: [PATCH 211/311] feat: add custom host names --- src/Defaults/index.ts | 1 + src/Socket/messages-send.ts | 9 +++++---- src/Types/index.ts | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 9a542e7..844449c 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -28,6 +28,7 @@ export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { printQRInTerminal: false, emitOwnEvents: true, defaultQueryTimeoutMs: 60_000, + customUploadHosts: [], getMessage: async() => undefined } diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 19befed..db63873 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -383,9 +383,10 @@ export const makeMessagesSocket = (config: SocketConfig) => { let uploadInfo = await refreshMediaConn(false) let mediaUrl: string - for (let host of uploadInfo.hosts) { + const hosts = [ ...config.customUploadHosts, ...uploadInfo.hosts.map(h => h.hostname) ] + for (let hostname of hosts) { const auth = encodeURIComponent(uploadInfo.auth) // the auth token - const url = `https://${host.hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` + const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` try { const {body: responseText} = await got.post( @@ -411,8 +412,8 @@ export const makeMessagesSocket = (config: SocketConfig) => { throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) } } catch (error) { - const isLast = host.hostname === uploadInfo.hosts[uploadInfo.hosts.length-1].hostname - logger.debug(`Error in uploading to ${host.hostname} (${error}) ${isLast ? '' : ', retrying...'}`) + const isLast = hostname === hosts[uploadInfo.hosts.length-1] + logger.debug(`Error in uploading to ${hostname} (${error}) ${isLast ? '' : ', retrying...'}`) } } if (!mediaUrl) { diff --git a/src/Types/index.ts b/src/Types/index.ts index 113a92d..680190f 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -55,6 +55,8 @@ export type SocketConfig = { mediaCache?: NodeCache /** map to store the retry counts for failed messages */ msgRetryCounterMap?: { [msgId: string]: number } + /** custom domains to push media via */ + customUploadHosts: string[] /** * fetch a message from your store * implement this so that messages failed to send (solves the "this message can take a while" issue) can be retried From 2b8256d56b234b01c5a0b9b569fe7c1239761a9a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 11 Dec 2021 17:54:38 +0530 Subject: [PATCH 212/311] feat: cleaner auth state management + store SK keys !BREAKING_CHANGE --- src/Socket/chats.ts | 25 +++-- src/Socket/messages-recv.ts | 19 ++-- src/Socket/messages-send.ts | 204 +++++++++++++++++++++--------------- src/Socket/socket.ts | 8 +- src/Types/Auth.ts | 18 +++- src/Utils/auth-utils.ts | 142 +++++++++---------------- src/Utils/chat-utils.ts | 16 +-- src/Utils/signal.ts | 79 +++++++------- 8 files changed, 264 insertions(+), 247 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index e9dbf26..73fd1f8 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -20,6 +20,11 @@ export const makeChatsSocket = (config: SocketConfig) => { const mutationMutex = makeMutex() + const getAppStateSyncKey = async(keyId: string) => { + const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId]) + return key + } + const interactiveQuery = async(userNodes: BinaryNode[], queryNode: BinaryNode) => { const result = await query({ tag: 'iq', @@ -175,7 +180,11 @@ export const makeChatsSocket = (config: SocketConfig) => { const states = { } as { [T in WAPatchName]: LTHashState } for(const name of collections) { - let state: LTHashState = fromScratch ? undefined : await authState.keys.getAppStateSyncVersion(name) + let state: LTHashState + if(!fromScratch) { + const result = await authState.keys.get('app-state-sync-version', [name]) + state = result[name] + } if(!state) state = newLTHashState() states[name] = state @@ -213,16 +222,16 @@ export const makeChatsSocket = (config: SocketConfig) => { const name = key as WAPatchName const { patches, snapshot } = decoded[name] if(snapshot) { - const newState = await decodeSyncdSnapshot(name, snapshot, authState.keys.getAppStateSyncKey) + const newState = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey) states[name] = newState logger.info(`restored state of ${name} from snapshot to v${newState.version}`) } // only process if there are syncd patches if(patches.length) { - const { newMutations, state: newState } = await decodePatches(name, patches, states[name], authState.keys.getAppStateSyncKey, true) + const { newMutations, state: newState } = await decodePatches(name, patches, states[name], getAppStateSyncKey, true) - await authState.keys.setAppStateSyncVersion(name, newState) + await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) logger.info(`synced ${name} to v${newState.version}`) if(newMutations.length) { @@ -415,12 +424,12 @@ export const makeChatsSocket = (config: SocketConfig) => { logger.debug({ patch: patchCreate }, 'applying app patch') await resyncAppState([name]) - const initial = await authState.keys.getAppStateSyncVersion(name) + const { [name]: initial } = await authState.keys.get('app-state-sync-version', [name]) const { patch, state } = await encodeSyncdPatch( patchCreate, authState.creds.myAppStateKeyId!, initial, - authState.keys, + getAppStateSyncKey, ) const node: BinaryNode = { @@ -456,10 +465,10 @@ export const makeChatsSocket = (config: SocketConfig) => { } await query(node) - await authState.keys.setAppStateSyncVersion(name, state) + await authState.keys.set({ 'app-state-sync-version': { [name]: state } }) if(config.emitOwnEvents) { - const result = await decodePatches(name, [{ ...patch, version: { version: state.version }, }], initial, authState.keys.getAppStateSyncKey) + const result = await decodePatches(name, [{ ...patch, version: { version: state.version }, }], initial, getAppStateSyncKey) processSyncActions(result.newMutations) } } diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 3bc863f..fa98b8e 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -1,12 +1,11 @@ import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata, WAMessageKey } from "../Types" import { decodeMessageStanza, encodeBigEndian, toNumber, downloadHistory, generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils" -import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser, getAllBinaryNodeChildren, BinaryNodeAttributes } from '../WABinary' +import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser, getAllBinaryNodeChildren, BinaryNodeAttributes, isJidGroup } from '../WABinary' import { proto } from "../../WAProto" import { KEY_BUNDLE_TYPE } from "../Defaults" import { makeChatsSocket } from "./chats" import { extractGroupMetadata } from "./groups" -import { Boom } from "@hapi/boom" const getStatusFromReceiptType = (type: string | undefined) => { if(type === 'read' || type === 'read-self') { @@ -25,7 +24,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { ev, authState, ws, - assertSession, + assertSessions, assertingPreKeys, sendNode, relayMessage, @@ -146,12 +145,12 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { if(keys?.length) { let newAppStateSyncKeyId = '' for(const { keyData, keyId } of keys) { - const str = Buffer.from(keyId.keyId!).toString('base64') + const strKeyId = Buffer.from(keyId.keyId!).toString('base64') - logger.info({ str }, 'injecting new app state sync key') - await authState.keys.setAppStateSyncKey(str, keyData) + logger.info({ strKeyId }, 'injecting new app state sync key') + await authState.keys.set({ 'app-state-sync-key': { [strKeyId]: keyData } }) - newAppStateSyncKeyId = str + newAppStateSyncKeyId = strKeyId } ev.emit('creds.update', { myAppStateKeyId: newAppStateSyncKeyId }) @@ -473,7 +472,11 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { ) const participant = key.participant || key.remoteJid - await assertSession(participant, true) + await assertSessions([participant], true) + + if(isJidGroup(key.remoteJid)) { + await authState.keys.set({ 'sender-key-memory': { [key.remoteJid]: null } }) + } logger.debug({ participant }, 'forced new session for retry recp') diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index db63873..c6112fb 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -2,7 +2,7 @@ import got from "got" import { Boom } from "@hapi/boom" import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions } from "../Types" -import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESession } from "../Utils" +import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESessions } from "../Utils" import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes, JidWithDevice, reduceBinaryNodeToDictionary } from '../WABinary' import { proto } from "../../WAProto" import { WA_DEFAULT_EPHEMERAL, DEFAULT_ORIGIN, MEDIA_PATH_MAP } from "../Defaults" @@ -189,15 +189,23 @@ export const makeMessagesSocket = (config: SocketConfig) => { return deviceResults } - const assertSession = async(jid: string, force: boolean) => { - const addr = jidToSignalProtocolAddress(jid).toString() - const session = await authState.keys.getSession(addr) - if(!session || force) { - logger.debug({ jid }, `fetching session`) - const identity: BinaryNode = { - tag: 'user', - attrs: { jid, reason: 'identity' }, + const assertSessions = async(jids: string[], force: boolean) => { + let jidsRequiringFetch: string[] = [] + if(force) { + jidsRequiringFetch = jids + } else { + const addrs = jids.map(jid => jidToSignalProtocolAddress(jid).toString()) + const sessions = await authState.keys.get('session', addrs) + for(const jid of jids) { + const signalId = jidToSignalProtocolAddress(jid).toString() + if(!sessions[signalId]) { + jidsRequiringFetch.push(jid) + } } + } + + if(jidsRequiringFetch.length) { + logger.debug({ jidsRequiringFetch }, `fetching sessions`) const result = await query({ tag: 'iq', attrs: { @@ -209,30 +217,41 @@ export const makeMessagesSocket = (config: SocketConfig) => { { tag: 'key', attrs: { }, - content: [ identity ] + content: jidsRequiringFetch.map( + jid => ({ + tag: 'user', + attrs: { jid, reason: 'identity' }, + }) + ) } ] }) - await parseAndInjectE2ESession(result, authState) + await parseAndInjectE2ESessions(result, authState) return true } return false } - const createParticipantNode = async(jid: string, bytes: Buffer) => { - await assertSession(jid, false) - - const { type, ciphertext } = await encryptSignalProto(jid, bytes, authState) - const node: BinaryNode = { - tag: 'to', - attrs: { jid }, - content: [{ - tag: 'enc', - attrs: { v: '2', type }, - content: ciphertext - }] - } - return node + const createParticipantNodes = async(jids: string[], bytes: Buffer) => { + await assertSessions(jids, false) + const nodes = await Promise.all( + jids.map( + async jid => { + const { type, ciphertext } = await encryptSignalProto(jid, bytes, authState) + const node: BinaryNode = { + tag: 'to', + attrs: { jid }, + content: [{ + tag: 'enc', + attrs: { v: '2', type }, + content: ciphertext + }] + } + return node + } + ) + ) + return nodes } const relayMessage = async( @@ -248,10 +267,11 @@ export const makeMessagesSocket = (config: SocketConfig) => { const encodedMsg = encodeWAMessage(message) const participants: BinaryNode[] = [] - let stanza: BinaryNode const destinationJid = jidEncode(user, isGroup ? 'g.us' : 's.whatsapp.net') + const binaryNodeContent: BinaryNode[] = [] + const devices: JidWithDevice[] = [] if(participant) { const { user, device } = jidDecode(participant) @@ -261,8 +281,17 @@ export const makeMessagesSocket = (config: SocketConfig) => { if(isGroup) { const { ciphertext, senderKeyDistributionMessageKey } = await encryptSenderKeyMsgSignalProto(destinationJid, encodedMsg, meId, authState) - let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined - if(!groupData) groupData = await groupMetadata(jid) + const [groupData, senderKeyMap] = await Promise.all([ + (async() => { + let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined + if(!groupData) groupData = await groupMetadata(jid) + return groupData + })(), + (async() => { + const result = await authState.keys.get('sender-key-memory', [jid]) + return result[jid] || { } + })() + ]) if(!participant) { const participantsList = groupData.participants.map(p => p.id) @@ -270,31 +299,31 @@ export const makeMessagesSocket = (config: SocketConfig) => { devices.push(...additionalDevices) } - const encSenderKeyMsg = encodeWAMessage({ - senderKeyDistributionMessage: { - axolotlSenderKeyDistributionMessage: senderKeyDistributionMessageKey, - groupId: destinationJid - } - }) - + const senderKeyJids: string[] = [] + // ensure a connection is established with every device for(const {user, device} of devices) { const jid = jidEncode(user, 's.whatsapp.net', device) - const participant = await createParticipantNode(jid, encSenderKeyMsg) - participants.push(participant) + if(!senderKeyMap[jid]) { + senderKeyJids.push(jid) + // store that this person has had the sender keys sent to them + senderKeyMap[jid] = true + } } + // if there are some participants with whom the session has not been established + // if there are, we re-send the senderkey + if(senderKeyJids.length) { + logger.debug({ senderKeyJids }, 'sending new sender key') - const binaryNodeContent: BinaryNode[] = [] - if( // if there are some participants with whom the session has not been established - // if there are, we overwrite the senderkey - !!participants.find((p) => ( - !!(p.content as BinaryNode[]).find(({ attrs }) => attrs.type == 'pkmsg') - )) - ) { - binaryNodeContent.push({ - tag: 'participants', - attrs: { }, - content: participants + const encSenderKeyMsg = encodeWAMessage({ + senderKeyDistributionMessage: { + axolotlSenderKeyDistributionMessage: senderKeyDistributionMessageKey, + groupId: destinationJid + } }) + + participants.push( + ...(await createParticipantNodes(senderKeyJids, encSenderKeyMsg)) + ) } binaryNodeContent.push({ @@ -303,25 +332,16 @@ export const makeMessagesSocket = (config: SocketConfig) => { content: ciphertext }) - stanza = { - tag: 'message', - attrs: { - id: msgId, - type: 'text', - to: destinationJid - }, - content: binaryNodeContent - } + await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } }) } else { const { user: meUser } = jidDecode(meId) - const messageToMyself: proto.IMessage = { + const encodedMeMsg = encodeWAMessage({ deviceSentMessage: { destinationJid, message } - } - const encodedMeMsg = encodeWAMessage(messageToMyself) + }) if(!participant) { devices.push({ user }) @@ -331,47 +351,57 @@ export const makeMessagesSocket = (config: SocketConfig) => { devices.push(...additionalDevices) } + const meJids: string[] = [] + const otherJids: string[] = [] for(const { user, device } of devices) { + const jid = jidEncode(user, 's.whatsapp.net', device) const isMe = user === meUser - participants.push( - await createParticipantNode( - jidEncode(user, 's.whatsapp.net', device), - isMe ? encodedMeMsg : encodedMsg - ) - ) + if(isMe) meJids.push(jid) + else otherJids.push(jid) } - stanza = { - tag: 'message', - attrs: { - id: msgId, - type: 'text', - to: destinationJid, - ...(additionalAttributes || {}) - }, - content: [ - { - tag: 'participants', - attrs: { }, - content: participants - }, - ] - } + const [meNodes, otherNodes] = await Promise.all([ + createParticipantNodes(meJids, encodedMeMsg), + createParticipantNodes(otherJids, encodedMsg) + ]) + participants.push(...meNodes) + participants.push(...otherNodes) } - const shouldHaveIdentity = !!participants.find((p) => ( - !!(p.content as BinaryNode[]).find(({ attrs }) => attrs.type == 'pkmsg') - )) + if(participants.length) { + binaryNodeContent.push({ + tag: 'participants', + attrs: { }, + content: participants + }) + } + + const stanza: BinaryNode = { + tag: 'message', + attrs: { + id: msgId, + type: 'text', + to: destinationJid, + ...(additionalAttributes || {}) + }, + content: binaryNodeContent + } + const shouldHaveIdentity = !!participants.find( + participant => (participant.content! as BinaryNode[]).find(n => n.attrs.type === 'pkmsg') + ) + if(shouldHaveIdentity) { (stanza.content as BinaryNode[]).push({ tag: 'device-identity', attrs: { }, content: proto.ADVSignedDeviceIdentity.encode(authState.creds.account).finish() }) + + logger.debug({ jid }, 'adding device identity') } - logger.debug({ msgId }, `sending message to ${devices.length} devices`) + logger.debug({ msgId }, `sending message to ${participants.length} devices`) await sendNode(stanza) @@ -427,7 +457,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { return { ...sock, - assertSession, + assertSessions, relayMessage, sendDeliveryReceipt, sendReadReceipt, diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 3fb7657..102cdcc 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -196,10 +196,8 @@ export const makeSocket = ({ if(!creds.serverHasPreKeys) { update.serverHasPreKeys = true } - - await Promise.all( - Object.keys(newPreKeys).map(k => authState.keys.setPreKey(+k, newPreKeys[+k])) - ) + + await authState.keys.set({ 'pre-key': newPreKeys }) const preKeys = await getPreKeys(authState.keys, preKeysRange[0], preKeysRange[0] + preKeysRange[1]) await execute(preKeys) @@ -449,7 +447,7 @@ export const makeSocket = ({ const genPairQR = () => { const ref = refs.shift() if(!ref) { - end(new Boom('QR refs attempts ended', { statusCode: DisconnectReason.restartRequired })) + end(new Boom('QR refs attempts ended', { statusCode: DisconnectReason.timedOut })) return } diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts index 7a3e749..c2cae16 100644 --- a/src/Types/Auth.ts +++ b/src/Types/Auth.ts @@ -43,9 +43,23 @@ export type AuthenticationCreds = SignalCreds & { lastAccountSyncTimestamp?: number } +export type SignalDataTypeMap = { + 'pre-key': KeyPair + 'session': any + 'sender-key': any + 'sender-key-memory': { [jid: string]: boolean } + 'app-state-sync-key': proto.IAppStateSyncKeyData + 'app-state-sync-version': LTHashState +} + +type SignalDataSet = { [T in keyof SignalDataTypeMap]?: { [id: string]: SignalDataTypeMap[T] | null } } + type Awaitable = T | Promise export type SignalKeyStore = { - getPreKey: (keyId: number) => Awaitable + get(type: T, ids: string[]): Awaitable<{ [id: string]: SignalDataTypeMap[T] }> + set(data: SignalDataSet): Awaitable + + /*getPreKey: (keyId: number) => Awaitable setPreKey: (keyId: number, pair: KeyPair | null) => Awaitable getSession: (sessionId: string) => Awaitable @@ -58,7 +72,7 @@ export type SignalKeyStore = { setAppStateSyncKey: (id: string, item: proto.IAppStateSyncKeyData | null) => Awaitable getAppStateSyncVersion: (name: WAPatchName) => Awaitable - setAppStateSyncVersion: (id: WAPatchName, item: LTHashState) => Awaitable + setAppStateSyncVersion: (id: WAPatchName, item: LTHashState) => Awaitable*/ } export type SignalAuthState = { diff --git a/src/Utils/auth-utils.ts b/src/Utils/auth-utils.ts index 16e6b4a..cf40474 100644 --- a/src/Utils/auth-utils.ts +++ b/src/Utils/auth-utils.ts @@ -1,86 +1,8 @@ import { randomBytes } from 'crypto' -import { proto } from '../../WAProto' -import type { SignalKeyStore, AuthenticationCreds, KeyPair, LTHashState, AuthenticationState } from "../Types" +import type { AuthenticationCreds, AuthenticationState, SignalDataTypeMap } from "../Types" import { Curve, signedKeyPair } from './crypto' import { generateRegistrationId, BufferJSON } from './generics' -export const initInMemoryKeyStore = ( - { preKeys, sessions, senderKeys, appStateSyncKeys, appStateVersions }: { - preKeys?: { [k: number]: KeyPair }, - sessions?: { [k: string]: any }, - senderKeys?: { [k: string]: any } - appStateSyncKeys?: { [k: string]: proto.IAppStateSyncKeyData }, - appStateVersions?: { [k: string]: LTHashState }, - } = { }, - save: (data: any) => void -) => { - - preKeys = preKeys || { } - sessions = sessions || { } - senderKeys = senderKeys || { } - appStateSyncKeys = appStateSyncKeys || { } - appStateVersions = appStateVersions || { } - - const keyData = { - preKeys, - sessions, - senderKeys, - appStateSyncKeys, - appStateVersions, - } - - return { - ...keyData, - getPreKey: keyId => preKeys[keyId], - setPreKey: (keyId, pair) => { - if(pair) preKeys[keyId] = pair - else delete preKeys[keyId] - - save(keyData) - }, - getSession: id => sessions[id], - setSession: (id, item) => { - if(item) sessions[id] = item - else delete sessions[id] - - save(keyData) - }, - getSenderKey: id => { - return senderKeys[id] - }, - setSenderKey: (id, item) => { - if(item) senderKeys[id] = item - else delete senderKeys[id] - - save(keyData) - }, - getAppStateSyncKey: id => { - const obj = appStateSyncKeys[id] - if(obj) { - return proto.AppStateSyncKeyData.fromObject(obj) - } - }, - setAppStateSyncKey: (id, item) => { - if(item) appStateSyncKeys[id] = item - else delete appStateSyncKeys[id] - - save(keyData) - }, - getAppStateSyncVersion: id => { - const obj = appStateVersions[id] - if(obj) { - return obj - } - }, - setAppStateSyncVersion: (id, item) => { - if(item) appStateVersions[id] = item - else delete appStateVersions[id] - - save(keyData) - } - } as SignalKeyStore -} - export const initAuthCreds = (): AuthenticationCreds => { const identityKey = Curve.generateKeyPair() return { @@ -95,12 +17,22 @@ export const initAuthCreds = (): AuthenticationCreds => { serverHasPreKeys: false } } + +const KEY_MAP: { [T in keyof SignalDataTypeMap]: string } = { + 'pre-key': 'preKeys', + 'session': 'sessions', + 'sender-key': 'senderKeys', + 'app-state-sync-key': 'appStateSyncKeys', + 'app-state-sync-version': 'appStateVersions', + 'sender-key-memory': 'senderKeyMemory' +} + /** stores the full authentication state in a single JSON file */ -export const useSingleFileAuthState = (filename: string) => { +export const useSingleFileAuthState = (filename: string): { state: AuthenticationState, saveState: () => void } => { // require fs here so that in case "fs" is not available -- the app does not crash const { readFileSync, writeFileSync, existsSync } = require('fs') - - let state: AuthenticationState = undefined + let creds: AuthenticationCreds + let keys: any = { } // save the authentication state to a file const saveState = () => { @@ -108,26 +40,48 @@ export const useSingleFileAuthState = (filename: string) => { writeFileSync( filename, // BufferJSON replacer utility saves buffers nicely - JSON.stringify(state, BufferJSON.replacer, 2) + JSON.stringify({ creds, keys }, BufferJSON.replacer, 2) ) } if(existsSync(filename)) { - const { creds, keys } = JSON.parse( + const result = JSON.parse( readFileSync(filename, { encoding: 'utf-8' }), BufferJSON.reviver ) - state = { - creds: creds, - // stores pre-keys, session & other keys in a JSON object - // we deserialize it here - keys: initInMemoryKeyStore(keys, saveState) - } + creds = result.creds + keys = result.keys } else { - const creds = initAuthCreds() - const keys = initInMemoryKeyStore({ }, saveState) - state = { creds: creds, keys: keys } + creds = initAuthCreds() + keys = { } } - return { state, saveState } + return { + state: { + creds, + keys: { + get: (type, ids) => { + const key = KEY_MAP[type] + return ids.reduce( + (dict, id) => { + const value = keys[key]?.[id] + if(value) { + dict[id] = value + } + return dict + }, { } + ) + }, + set: (data) => { + for(const _key in data) { + const key = KEY_MAP[_key as keyof SignalDataTypeMap] + keys[key] = keys[key] || { } + Object.assign(keys[key], data[_key]) + } + saveState() + } + } + }, + saveState + } } \ No newline at end of file diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 908f96b..7d62295 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -1,12 +1,14 @@ import { Boom } from '@hapi/boom' import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./crypto" -import { AuthenticationState, WAPatchCreate, ChatMutation, WAPatchName, LTHashState, ChatModification, SignalKeyStore } from "../Types" +import { WAPatchCreate, ChatMutation, WAPatchName, LTHashState, ChatModification, SignalKeyStore } from "../Types" import { proto } from '../../WAProto' import { LT_HASH_ANTI_TAMPERING } from './lt-hash' import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren } from '../WABinary' import { toNumber } from './generics' import { downloadContentFromMessage, } from './messages-media' +type FetchAppStateSyncKey = (keyId: string) => Promise | proto.IAppStateSyncKeyData + const mutationKeys = (keydata: Uint8Array) => { const expanded = hkdf(keydata, 160, { info: 'WhatsApp Mutation Keys' }) return { @@ -112,9 +114,9 @@ export const encodeSyncdPatch = async( { type, index, syncAction, apiVersion, operation }: WAPatchCreate, myAppStateKeyId: string, state: LTHashState, - keys: SignalKeyStore + getAppStateSyncKey: FetchAppStateSyncKey ) => { - const key = !!myAppStateKeyId ? await keys.getAppStateSyncKey(myAppStateKeyId) : undefined + const key = !!myAppStateKeyId ? await getAppStateSyncKey(myAppStateKeyId) : undefined if(!key) { throw new Boom(`myAppStateKey ("${myAppStateKeyId}") not present`, { statusCode: 404 }) } @@ -175,7 +177,7 @@ export const encodeSyncdPatch = async( export const decodeSyncdMutations = async( msgMutations: (proto.ISyncdMutation | proto.ISyncdRecord)[], initialState: LTHashState, - getAppStateSyncKey: SignalKeyStore['getAppStateSyncKey'], + getAppStateSyncKey: FetchAppStateSyncKey, validateMacs: boolean ) => { const keyCache: { [_: string]: ReturnType } = { } @@ -247,7 +249,7 @@ export const decodeSyncdPatch = async( msg: proto.ISyncdPatch, name: WAPatchName, initialState: LTHashState, - getAppStateSyncKey: SignalKeyStore['getAppStateSyncKey'], + getAppStateSyncKey: FetchAppStateSyncKey, validateMacs: boolean ) => { if(validateMacs) { @@ -334,7 +336,7 @@ export const downloadExternalPatch = async(blob: proto.IExternalBlobReference) = export const decodeSyncdSnapshot = async( name: WAPatchName, snapshot: proto.ISyncdSnapshot, - getAppStateSyncKey: SignalKeyStore['getAppStateSyncKey'], + getAppStateSyncKey: FetchAppStateSyncKey, validateMacs: boolean = true ) => { const newState = newLTHashState() @@ -370,7 +372,7 @@ export const decodePatches = async( name: WAPatchName, syncds: proto.ISyncdPatch[], initial: LTHashState, - getAppStateSyncKey: SignalKeyStore['getAppStateSyncKey'], + getAppStateSyncKey: FetchAppStateSyncKey, validateMacs: boolean = true ) => { const successfulMutations: ChatMutation[] = [] diff --git a/src/Utils/signal.ts b/src/Utils/signal.ts index 158cbf2..88533d8 100644 --- a/src/Utils/signal.ts +++ b/src/Utils/signal.ts @@ -3,7 +3,7 @@ import { encodeBigEndian } from "./generics" import { Curve } from "./crypto" import { SenderKeyDistributionMessage, GroupSessionBuilder, SenderKeyRecord, SenderKeyName, GroupCipher } from '../../WASignalGroup' import { SignalIdentity, SignalKeyStore, SignedKeyPair, KeyPair, SignalAuthState, AuthenticationCreds } from "../Types/Auth" -import { assertNodeErrorFree, BinaryNode, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildUInt, jidDecode, JidWithDevice } from "../WABinary" +import { assertNodeErrorFree, BinaryNode, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildUInt, jidDecode, JidWithDevice, getBinaryNodeChildren } from "../WABinary" import { proto } from "../../WAProto" export const generateSignalPubKey = (pubKey: Uint8Array | Buffer) => { @@ -33,13 +33,12 @@ export const createSignalIdentity = ( } } -export const getPreKeys = async({ getPreKey }: SignalKeyStore, min: number, limit: number) => { - const dict: { [id: number]: KeyPair } = { } +export const getPreKeys = async({ get }: SignalKeyStore, min: number, limit: number) => { + const idList: string[] = [] for(let id = min; id < limit;id++) { - const key = await getPreKey(id) - if(key) dict[+id] = key + idList.push(id.toString()) } - return dict + return get('pre-key', idList) } export const generateOrGetPreKeys = (creds: AuthenticationCreds, range: number) => { @@ -84,20 +83,21 @@ export const xmppPreKey = (pair: KeyPair, id: number): BinaryNode => ( ) export const signalStorage = ({ creds, keys }: SignalAuthState) => ({ - loadSession: async id => { - const sess = await keys.getSession(id) + loadSession: async (id: string) => { + const { [id]: sess } = await keys.get('session', [id]) if(sess) { return libsignal.SessionRecord.deserialize(sess) } }, storeSession: async(id, session) => { - await keys.setSession(id, session.serialize()) + await keys.set({ 'session': { [id]: session.serialize() } }) }, isTrustedIdentity: () => { return true }, - loadPreKey: async(id: number) => { - const key = await keys.getPreKey(id) + loadPreKey: async(id: number | string) => { + const keyId = id.toString() + const { [keyId]: key } = await keys.get('pre-key', [keyId]) if(key) { return { privKey: Buffer.from(key.private), @@ -105,7 +105,7 @@ export const signalStorage = ({ creds, keys }: SignalAuthState) => ({ } } }, - removePreKey: (id: number) => keys.setPreKey(id, null), + removePreKey: (id: number) => keys.set({ 'pre-key': { [id]: null } }), loadSignedPreKey: (keyId: number) => { const key = creds.signedPreKey return { @@ -113,12 +113,12 @@ export const signalStorage = ({ creds, keys }: SignalAuthState) => ({ pubKey: Buffer.from(key.keyPair.public) } }, - loadSenderKey: async(keyId) => { - const key = await keys.getSenderKey(keyId) + loadSenderKey: async(keyId: string) => { + const { [keyId]: key } = await keys.get('sender-key', [keyId]) if(key) return new SenderKeyRecord(key) }, storeSenderKey: async(keyId, key) => { - await keys.setSenderKey(keyId, key.serialize()) + await keys.set({ 'sender-key': { [keyId]: key.serialize() } }) }, getOurRegistrationId: () => ( creds.registrationId @@ -148,10 +148,10 @@ export const processSenderKeyMessage = async( const senderName = jidToSignalSenderKeyName(item.groupId, authorJid) const senderMsg = new SenderKeyDistributionMessage(null, null, null, null, item.axolotlSenderKeyDistributionMessage) - const senderKey = await auth.keys.getSenderKey(senderName) + const { [senderName]: senderKey } = await auth.keys.get('sender-key', [senderName]) if(!senderKey) { const record = new SenderKeyRecord() - await auth.keys.setSenderKey(senderName, record) + await auth.keys.set({ 'sender-key': { [senderName]: record } }) } await builder.process(senderName, senderMsg) } @@ -188,10 +188,10 @@ export const encryptSenderKeyMsgSignalProto = async(group: string, data: Uint8Ar const senderName = jidToSignalSenderKeyName(group, meId) const builder = new GroupSessionBuilder(storage) - const senderKey = await auth.keys.getSenderKey(senderName) + const { [senderName]: senderKey } = await auth.keys.get('sender-key', [senderName]) if(!senderKey) { const record = new SenderKeyRecord() - await auth.keys.setSenderKey(senderName, record) + await auth.keys.set({ 'sender-key': { [senderName]: record } }) } const senderKeyDistributionMessage = await builder.create(senderName) @@ -202,7 +202,7 @@ export const encryptSenderKeyMsgSignalProto = async(group: string, data: Uint8Ar } } -export const parseAndInjectE2ESession = async(node: BinaryNode, auth: SignalAuthState) => { +export const parseAndInjectE2ESessions = async(node: BinaryNode, auth: SignalAuthState) => { const extractKey = (key: BinaryNode) => ( key ? ({ keyId: getBinaryNodeChildUInt(key, 'id', 3), @@ -212,23 +212,30 @@ export const parseAndInjectE2ESession = async(node: BinaryNode, auth: SignalAuth signature: getBinaryNodeChildBuffer(key, 'signature'), }) : undefined ) - node = getBinaryNodeChild(getBinaryNodeChild(node, 'list'), 'user') - assertNodeErrorFree(node) - - const signedKey = getBinaryNodeChild(node, 'skey') - const key = getBinaryNodeChild(node, 'key') - const identity = getBinaryNodeChildBuffer(node, 'identity') - const jid = node.attrs.jid - const registrationId = getBinaryNodeChildUInt(node, 'registration', 4) - - const device = { - registrationId, - identityKey: generateSignalPubKey(identity), - signedPreKey: extractKey(signedKey), - preKey: extractKey(key) + const nodes = getBinaryNodeChildren(getBinaryNodeChild(node, 'list'), 'user') + for(const node of nodes) { + assertNodeErrorFree(node) } - const cipher = new libsignal.SessionBuilder(signalStorage(auth), jidToSignalProtocolAddress(jid)) - await cipher.initOutgoing(device) + await Promise.all( + nodes.map( + async node => { + const signedKey = getBinaryNodeChild(node, 'skey') + const key = getBinaryNodeChild(node, 'key') + const identity = getBinaryNodeChildBuffer(node, 'identity') + const jid = node.attrs.jid + const registrationId = getBinaryNodeChildUInt(node, 'registration', 4) + + const device = { + registrationId, + identityKey: generateSignalPubKey(identity), + signedPreKey: extractKey(signedKey), + preKey: extractKey(key) + } + const cipher = new libsignal.SessionBuilder(signalStorage(auth), jidToSignalProtocolAddress(jid)) + await cipher.initOutgoing(device) + } + ) + ) } export const extractDeviceJids = (result: BinaryNode, myJid: string, excludeZeroDevices: boolean) => { From f284217d35d8352bcf8160df3818ac5b2ab10804 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 11 Dec 2021 18:28:07 +0530 Subject: [PATCH 213/311] feat: implement transactions on auth state --- src/Socket/messages-send.ts | 260 +++++++++++++++++++----------------- src/Socket/socket.ts | 8 +- src/Types/Auth.ts | 22 +-- src/Utils/auth-utils.ts | 100 ++++++++++++-- 4 files changed, 239 insertions(+), 151 deletions(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index c6112fb..37c51d7 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -234,6 +234,14 @@ export const makeMessagesSocket = (config: SocketConfig) => { const createParticipantNodes = async(jids: string[], bytes: Buffer) => { await assertSessions(jids, false) + + if(authState.keys.isInTransaction()) { + await authState.keys.prefetch( + 'session', + jids.map(jid => jidToSignalProtocolAddress(jid).toString()) + ) + } + const nodes = await Promise.all( jids.map( async jid => { @@ -278,133 +286,137 @@ export const makeMessagesSocket = (config: SocketConfig) => { devices.push({ user, device }) } - if(isGroup) { - const { ciphertext, senderKeyDistributionMessageKey } = await encryptSenderKeyMsgSignalProto(destinationJid, encodedMsg, meId, authState) - - const [groupData, senderKeyMap] = await Promise.all([ - (async() => { - let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined - if(!groupData) groupData = await groupMetadata(jid) - return groupData - })(), - (async() => { - const result = await authState.keys.get('sender-key-memory', [jid]) - return result[jid] || { } - })() - ]) - - if(!participant) { - const participantsList = groupData.participants.map(p => p.id) - const additionalDevices = await getUSyncDevices(participantsList, false) - devices.push(...additionalDevices) - } - - const senderKeyJids: string[] = [] - // ensure a connection is established with every device - for(const {user, device} of devices) { - const jid = jidEncode(user, 's.whatsapp.net', device) - if(!senderKeyMap[jid]) { - senderKeyJids.push(jid) - // store that this person has had the sender keys sent to them - senderKeyMap[jid] = true - } - } - // if there are some participants with whom the session has not been established - // if there are, we re-send the senderkey - if(senderKeyJids.length) { - logger.debug({ senderKeyJids }, 'sending new sender key') - - const encSenderKeyMsg = encodeWAMessage({ - senderKeyDistributionMessage: { - axolotlSenderKeyDistributionMessage: senderKeyDistributionMessageKey, - groupId: destinationJid - } - }) - - participants.push( - ...(await createParticipantNodes(senderKeyJids, encSenderKeyMsg)) - ) - } - - binaryNodeContent.push({ - tag: 'enc', - attrs: { v: '2', type: 'skmsg' }, - content: ciphertext - }) - - await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } }) - } else { - const { user: meUser } = jidDecode(meId) - - const encodedMeMsg = encodeWAMessage({ - deviceSentMessage: { - destinationJid, - message - } - }) - - if(!participant) { - devices.push({ user }) - devices.push({ user: meUser }) - - const additionalDevices = await getUSyncDevices([ meId, jid ], true) - devices.push(...additionalDevices) - } - - const meJids: string[] = [] - const otherJids: string[] = [] - for(const { user, device } of devices) { - const jid = jidEncode(user, 's.whatsapp.net', device) - const isMe = user === meUser - if(isMe) meJids.push(jid) - else otherJids.push(jid) - } - - const [meNodes, otherNodes] = await Promise.all([ - createParticipantNodes(meJids, encodedMeMsg), - createParticipantNodes(otherJids, encodedMsg) - ]) - participants.push(...meNodes) - participants.push(...otherNodes) - } - - if(participants.length) { - binaryNodeContent.push({ - tag: 'participants', - attrs: { }, - content: participants - }) - } - - const stanza: BinaryNode = { - tag: 'message', - attrs: { - id: msgId, - type: 'text', - to: destinationJid, - ...(additionalAttributes || {}) - }, - content: binaryNodeContent - } + await authState.keys.transaction( + async() => { + if(isGroup) { + const { ciphertext, senderKeyDistributionMessageKey } = await encryptSenderKeyMsgSignalProto(destinationJid, encodedMsg, meId, authState) + + const [groupData, senderKeyMap] = await Promise.all([ + (async() => { + let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined + if(!groupData) groupData = await groupMetadata(jid) + return groupData + })(), + (async() => { + const result = await authState.keys.get('sender-key-memory', [jid]) + return result[jid] || { } + })() + ]) - const shouldHaveIdentity = !!participants.find( - participant => (participant.content! as BinaryNode[]).find(n => n.attrs.type === 'pkmsg') + if(!participant) { + const participantsList = groupData.participants.map(p => p.id) + const additionalDevices = await getUSyncDevices(participantsList, false) + devices.push(...additionalDevices) + } + + const senderKeyJids: string[] = [] + // ensure a connection is established with every device + for(const {user, device} of devices) { + const jid = jidEncode(user, 's.whatsapp.net', device) + if(!senderKeyMap[jid]) { + senderKeyJids.push(jid) + // store that this person has had the sender keys sent to them + senderKeyMap[jid] = true + } + } + // if there are some participants with whom the session has not been established + // if there are, we re-send the senderkey + if(senderKeyJids.length) { + logger.debug({ senderKeyJids }, 'sending new sender key') + + const encSenderKeyMsg = encodeWAMessage({ + senderKeyDistributionMessage: { + axolotlSenderKeyDistributionMessage: senderKeyDistributionMessageKey, + groupId: destinationJid + } + }) + + participants.push( + ...(await createParticipantNodes(senderKeyJids, encSenderKeyMsg)) + ) + } + + binaryNodeContent.push({ + tag: 'enc', + attrs: { v: '2', type: 'skmsg' }, + content: ciphertext + }) + + await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } }) + } else { + const { user: meUser } = jidDecode(meId) + + const encodedMeMsg = encodeWAMessage({ + deviceSentMessage: { + destinationJid, + message + } + }) + + if(!participant) { + devices.push({ user }) + devices.push({ user: meUser }) + + const additionalDevices = await getUSyncDevices([ meId, jid ], true) + devices.push(...additionalDevices) + } + + const meJids: string[] = [] + const otherJids: string[] = [] + for(const { user, device } of devices) { + const jid = jidEncode(user, 's.whatsapp.net', device) + const isMe = user === meUser + if(isMe) meJids.push(jid) + else otherJids.push(jid) + } + + const [meNodes, otherNodes] = await Promise.all([ + createParticipantNodes(meJids, encodedMeMsg), + createParticipantNodes(otherJids, encodedMsg) + ]) + participants.push(...meNodes) + participants.push(...otherNodes) + } + + if(participants.length) { + binaryNodeContent.push({ + tag: 'participants', + attrs: { }, + content: participants + }) + } + + const stanza: BinaryNode = { + tag: 'message', + attrs: { + id: msgId, + type: 'text', + to: destinationJid, + ...(additionalAttributes || {}) + }, + content: binaryNodeContent + } + + const shouldHaveIdentity = !!participants.find( + participant => (participant.content! as BinaryNode[]).find(n => n.attrs.type === 'pkmsg') + ) + + if(shouldHaveIdentity) { + (stanza.content as BinaryNode[]).push({ + tag: 'device-identity', + attrs: { }, + content: proto.ADVSignedDeviceIdentity.encode(authState.creds.account).finish() + }) + + logger.debug({ jid }, 'adding device identity') + } + + logger.debug({ msgId }, `sending message to ${participants.length} devices`) + + await sendNode(stanza) + } ) - if(shouldHaveIdentity) { - (stanza.content as BinaryNode[]).push({ - tag: 'device-identity', - attrs: { }, - content: proto.ADVSignedDeviceIdentity.encode(authState.creds.account).finish() - }) - - logger.debug({ jid }, 'adding device identity') - } - - logger.debug({ msgId }, `sending message to ${participants.length} devices`) - - await sendNode(stanza) - return msgId } diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 102cdcc..c09459e 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -5,7 +5,7 @@ import WebSocket from "ws" import { randomBytes } from 'crypto' import { proto } from '../../WAProto' import { DisconnectReason, SocketConfig, BaileysEventEmitter, ConnectionState, AuthenticationCreds } from "../Types" -import { Curve, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout, generateOrGetPreKeys, xmppSignedPreKey, xmppPreKey, getPreKeys, makeNoiseHandler, useSingleFileAuthState } from "../Utils" +import { Curve, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout, generateOrGetPreKeys, xmppSignedPreKey, xmppPreKey, getPreKeys, makeNoiseHandler, useSingleFileAuthState, addTransactionCapability } from "../Utils" import { DEFAULT_ORIGIN, DEF_TAG_PREFIX, DEF_CALLBACK_PREFIX, KEY_BUNDLE_TYPE } from "../Defaults" import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, S_WHATSAPP_NET, getBinaryNodeChild } from '../WABinary' @@ -539,7 +539,11 @@ export const makeSocket = ({ return { ws, ev, - authState, + authState: { + creds, + // add capability + keys: addTransactionCapability(authState.keys, logger) + }, get user () { return authState.creds.me }, diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts index c2cae16..1e9eedd 100644 --- a/src/Types/Auth.ts +++ b/src/Types/Auth.ts @@ -52,27 +52,19 @@ export type SignalDataTypeMap = { 'app-state-sync-version': LTHashState } -type SignalDataSet = { [T in keyof SignalDataTypeMap]?: { [id: string]: SignalDataTypeMap[T] | null } } +export type SignalDataSet = { [T in keyof SignalDataTypeMap]?: { [id: string]: SignalDataTypeMap[T] | null } } type Awaitable = T | Promise + export type SignalKeyStore = { get(type: T, ids: string[]): Awaitable<{ [id: string]: SignalDataTypeMap[T] }> set(data: SignalDataSet): Awaitable +} - /*getPreKey: (keyId: number) => Awaitable - setPreKey: (keyId: number, pair: KeyPair | null) => Awaitable - - getSession: (sessionId: string) => Awaitable - setSession: (sessionId: string, item: any | null) => Awaitable - - getSenderKey: (id: string) => Awaitable - setSenderKey: (id: string, item: any | null) => Awaitable - - getAppStateSyncKey: (id: string) => Awaitable - setAppStateSyncKey: (id: string, item: proto.IAppStateSyncKeyData | null) => Awaitable - - getAppStateSyncVersion: (name: WAPatchName) => Awaitable - setAppStateSyncVersion: (id: WAPatchName, item: LTHashState) => Awaitable*/ +export type SignalKeyStoreWithTransaction = SignalKeyStore & { + isInTransaction: () => boolean + transaction(exec: () => Promise): Promise + prefetch(type: T, ids: string[]): Promise } export type SignalAuthState = { diff --git a/src/Utils/auth-utils.ts b/src/Utils/auth-utils.ts index cf40474..39ea354 100644 --- a/src/Utils/auth-utils.ts +++ b/src/Utils/auth-utils.ts @@ -1,8 +1,97 @@ +import { Boom } from '@hapi/boom' import { randomBytes } from 'crypto' -import type { AuthenticationCreds, AuthenticationState, SignalDataTypeMap } from "../Types" +import type { Logger } from 'pino' +import type { AuthenticationCreds, AuthenticationState, SignalDataTypeMap, SignalDataSet, SignalKeyStore, SignalKeyStoreWithTransaction } from "../Types" import { Curve, signedKeyPair } from './crypto' import { generateRegistrationId, BufferJSON } from './generics' +const KEY_MAP: { [T in keyof SignalDataTypeMap]: string } = { + 'pre-key': 'preKeys', + 'session': 'sessions', + 'sender-key': 'senderKeys', + 'app-state-sync-key': 'appStateSyncKeys', + 'app-state-sync-version': 'appStateVersions', + 'sender-key-memory': 'senderKeyMemory' +} + +export const addTransactionCapability = (state: SignalKeyStore, logger: Logger): SignalKeyStoreWithTransaction => { + let inTransaction = false + let transactionCache: SignalDataSet = { } + let mutations: SignalDataSet = { } + + const prefetch = async(type: keyof SignalDataTypeMap, ids: string[]) => { + if(!inTransaction) { + throw new Boom('Cannot prefetch without transaction') + } + + const dict = transactionCache[type] + const idsRequiringFetch = ids.filter(item => !dict?.[item]) + const result = await state.get(type, idsRequiringFetch) + + transactionCache[type] = transactionCache[type] || { } + Object.assign(transactionCache[type], result) + } + + return { + get: async(type, ids) => { + if(inTransaction) { + await prefetch(type, ids) + return ids.reduce( + (dict, id) => { + const value = transactionCache[type]?.[id] + if(value) { + dict[id] = value + } + return dict + }, { } + ) + } else { + return state.get(type, ids) + } + }, + set: data => { + if(inTransaction) { + logger.trace({ types: Object.keys(data) }, `caching in transaction`) + for(const key in data) { + transactionCache[key] = transactionCache[key] || { } + Object.assign(transactionCache[key], data[key]) + + mutations[key] = mutations[key] || { } + Object.assign(mutations[key], data[key]) + } + } else { + return state.set(data) + } + }, + isInTransaction: () => inTransaction, + prefetch: (type, ids) => { + logger.trace({ type, ids }, `prefetching`) + return prefetch(type, ids) + }, + transaction: async(work) => { + if(inTransaction) { + await work() + } else { + logger.debug('entering transaction') + inTransaction = true + try { + await work() + if(Object.keys(mutations).length) { + logger.debug('committing transaction') + await state.set(mutations) + } else { + logger.debug('no mutations in transaction') + } + } finally { + inTransaction = false + transactionCache = { } + mutations = { } + } + } + } + } +} + export const initAuthCreds = (): AuthenticationCreds => { const identityKey = Curve.generateKeyPair() return { @@ -18,15 +107,6 @@ export const initAuthCreds = (): AuthenticationCreds => { } } -const KEY_MAP: { [T in keyof SignalDataTypeMap]: string } = { - 'pre-key': 'preKeys', - 'session': 'sessions', - 'sender-key': 'senderKeys', - 'app-state-sync-key': 'appStateSyncKeys', - 'app-state-sync-version': 'appStateVersions', - 'sender-key-memory': 'senderKeyMemory' -} - /** stores the full authentication state in a single JSON file */ export const useSingleFileAuthState = (filename: string): { state: AuthenticationState, saveState: () => void } => { // require fs here so that in case "fs" is not available -- the app does not crash From 0650c10c736a6b386700b29c7ab664b4203cd3d4 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 12 Dec 2021 11:18:04 +0530 Subject: [PATCH 214/311] fix: decode app state key correctly --- src/Utils/auth-utils.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Utils/auth-utils.ts b/src/Utils/auth-utils.ts index 39ea354..3ad7e1a 100644 --- a/src/Utils/auth-utils.ts +++ b/src/Utils/auth-utils.ts @@ -1,6 +1,7 @@ import { Boom } from '@hapi/boom' import { randomBytes } from 'crypto' import type { Logger } from 'pino' +import { proto } from '../../WAProto' import type { AuthenticationCreds, AuthenticationState, SignalDataTypeMap, SignalDataSet, SignalKeyStore, SignalKeyStoreWithTransaction } from "../Types" import { Curve, signedKeyPair } from './crypto' import { generateRegistrationId, BufferJSON } from './generics' @@ -144,8 +145,11 @@ export const useSingleFileAuthState = (filename: string): { state: Authenticatio const key = KEY_MAP[type] return ids.reduce( (dict, id) => { - const value = keys[key]?.[id] + let value = keys[key]?.[id] if(value) { + if(type === 'app-state-sync-key') { + value = proto.AppStateSyncKeyData.fromObject(value) + } dict[id] = value } return dict From 5624ecf96c8a638ce8821d5755892232acfceff1 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 12 Dec 2021 11:18:21 +0530 Subject: [PATCH 215/311] fix: throw connection closed instead of WS error --- src/Socket/socket.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index c09459e..428b103 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -68,9 +68,12 @@ export const makeSocket = ({ const sendPromise = promisify(ws.send) /** send a raw buffer */ - const sendRawMessage = (data: Buffer | Uint8Array) => { + const sendRawMessage = async(data: Buffer | Uint8Array) => { + if(ws.readyState !== ws.OPEN) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } const bytes = noise.encodeFrame(data) - return sendPromise.call(ws, bytes) as Promise + await sendPromise.call(ws, bytes) as Promise } /** send a binary node */ const sendNode = (node: BinaryNode) => { From a21e3b0bacfdb9e5c53e13d029789b754c40da61 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 12 Dec 2021 11:26:19 +0530 Subject: [PATCH 216/311] perf: put main app state sync in transaction --- src/Socket/chats.ts | 119 +++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 57 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 73fd1f8..f7d3dd9 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -178,69 +178,74 @@ export const makeChatsSocket = (config: SocketConfig) => { const resyncAppStateInternal = async(collections: WAPatchName[], fromScratch: boolean = false, returnSnapshot: boolean = false) => { if(fromScratch) returnSnapshot = true - const states = { } as { [T in WAPatchName]: LTHashState } - for(const name of collections) { - let state: LTHashState - if(!fromScratch) { - const result = await authState.keys.get('app-state-sync-version', [name]) - state = result[name] - } - if(!state) state = newLTHashState() - - states[name] = state - - logger.info(`resyncing ${name} from v${state.version}`) - } - const result = await query({ - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - xmlns: 'w:sync:app:state', - type: 'set' - }, - content: [ - { - tag: 'sync', - attrs: { }, - content: collections.map( - (name) => ({ - tag: 'collection', - attrs: { - name, - version: states[name].version.toString(), - return_snapshot: returnSnapshot ? 'true' : 'false' - } - }) - ) - } - ] - }) - - const decoded = await extractSyncdPatches(result) // extract from binary node const totalMutations: ChatMutation[] = [] - for(const key in decoded) { - const name = key as WAPatchName - const { patches, snapshot } = decoded[name] - if(snapshot) { - const newState = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey) - states[name] = newState + + await authState.keys.transaction( + async() => { + const states = { } as { [T in WAPatchName]: LTHashState } + for(const name of collections) { + let state: LTHashState + if(!fromScratch) { + const result = await authState.keys.get('app-state-sync-version', [name]) + state = result[name] + } + if(!state) state = newLTHashState() - logger.info(`restored state of ${name} from snapshot to v${newState.version}`) - } - // only process if there are syncd patches - if(patches.length) { - const { newMutations, state: newState } = await decodePatches(name, patches, states[name], getAppStateSyncKey, true) + states[name] = state - await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) - - logger.info(`synced ${name} to v${newState.version}`) - if(newMutations.length) { - logger.trace({ newMutations, name }, 'recv new mutations') + logger.info(`resyncing ${name} from v${state.version}`) } + const result = await query({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + xmlns: 'w:sync:app:state', + type: 'set' + }, + content: [ + { + tag: 'sync', + attrs: { }, + content: collections.map( + (name) => ({ + tag: 'collection', + attrs: { + name, + version: states[name].version.toString(), + return_snapshot: returnSnapshot ? 'true' : 'false' + } + }) + ) + } + ] + }) + + const decoded = await extractSyncdPatches(result) // extract from binary node + for(const key in decoded) { + const name = key as WAPatchName + const { patches, snapshot } = decoded[name] + if(snapshot) { + const newState = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey) + states[name] = newState - totalMutations.push(...newMutations) + logger.info(`restored state of ${name} from snapshot to v${newState.version}`) + } + // only process if there are syncd patches + if(patches.length) { + const { newMutations, state: newState } = await decodePatches(name, patches, states[name], getAppStateSyncKey, true) + + await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) + + logger.info(`synced ${name} to v${newState.version}`) + if(newMutations.length) { + logger.trace({ newMutations, name }, 'recv new mutations') + } + + totalMutations.push(...newMutations) + } + } } - } + ) processSyncActions(totalMutations) From 13b49e658dd1ea75873fbde463e68593749080c9 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 12 Dec 2021 12:25:03 +0530 Subject: [PATCH 217/311] fix: do not fetch empty ID list on transaction --- src/Utils/auth-utils.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Utils/auth-utils.ts b/src/Utils/auth-utils.ts index 3ad7e1a..3a5dc5f 100644 --- a/src/Utils/auth-utils.ts +++ b/src/Utils/auth-utils.ts @@ -27,10 +27,13 @@ export const addTransactionCapability = (state: SignalKeyStore, logger: Logger): const dict = transactionCache[type] const idsRequiringFetch = ids.filter(item => !dict?.[item]) - const result = await state.get(type, idsRequiringFetch) + // only fetch if there are any items to fetch + if(idsRequiringFetch.length) { + const result = await state.get(type, idsRequiringFetch) - transactionCache[type] = transactionCache[type] || { } - Object.assign(transactionCache[type], result) + transactionCache[type] = transactionCache[type] || { } + Object.assign(transactionCache[type], result) + } } return { From ea077e9feaa891f270fe9c8af83a28c5a1d7fe43 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 13 Dec 2021 13:50:39 +0530 Subject: [PATCH 218/311] refactor: use abstraction for tmpdir --- src/Utils/messages-media.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index e20b847..c8d3bdb 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -15,6 +15,8 @@ import { generateMessageID } from './generics' import { hkdf } from './crypto' import { DEFAULT_ORIGIN } from '../Defaults' +const getTmpFilesDirectory = () => tmpdir() + export const hkdfInfoKey = (type: MediaType) => { let str: string = type if(type === 'sticker') str = 'image' @@ -135,7 +137,7 @@ export async function generateThumbnail( const buff = await compressImage(file) thumbnail = buff.toString('base64') } else if(mediaType === 'video') { - const imgFilename = join(tmpdir(), generateMessageID() + '.jpg') + const imgFilename = join(getTmpFilesDirectory(), generateMessageID() + '.jpg') try { await extractVideoThumb(file, imgFilename, '00:00:00', { width: 32, height: 32 }) const buff = await fs.readFile(imgFilename) @@ -173,7 +175,7 @@ export const encryptedStream = async(media: WAMediaUpload, mediaType: MediaType, const mediaKey = Crypto.randomBytes(32) const {cipherKey, iv, macKey} = getMediaKeys(mediaKey, mediaType) // random name - const encBodyPath = join(tmpdir(), mediaType + generateMessageID() + '.enc') + const encBodyPath = join(getTmpFilesDirectory(), mediaType + generateMessageID() + '.enc') const encWriteStream = createWriteStream(encBodyPath) let bodyPath: string let writeStream: WriteStream @@ -181,7 +183,7 @@ export const encryptedStream = async(media: WAMediaUpload, mediaType: MediaType, if(type === 'file') { bodyPath = (media as any).url } else if(saveOriginalFileIfRequired) { - bodyPath = join(tmpdir(), mediaType + generateMessageID()) + bodyPath = join(getTmpFilesDirectory(), mediaType + generateMessageID()) writeStream = createWriteStream(bodyPath) didSaveToTmpPath = true } From d15dd6e1d2a65add35027d1690b413e2bcb20f83 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 13 Dec 2021 17:31:20 +0530 Subject: [PATCH 219/311] feat: add "direct_path" to media messages --- src/Socket/messages-send.ts | 16 ++++++++++------ src/Types/Message.ts | 2 +- src/Utils/messages.ts | 5 +++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 37c51d7..12288df 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -424,7 +424,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { // send a query JSON to obtain the url & auth token to upload our media let uploadInfo = await refreshMediaConn(false) - let mediaUrl: string + let urls: { mediaUrl: string, directPath: string } const hosts = [ ...config.customUploadHosts, ...uploadInfo.hosts.map(h => h.hostname) ] for (let hostname of hosts) { const auth = encodeURIComponent(uploadInfo.auth) // the auth token @@ -446,10 +446,14 @@ export const makeMessagesSocket = (config: SocketConfig) => { } ) const result = JSON.parse(responseText) - mediaUrl = result?.url - if (mediaUrl) break - else { + if(result?.url || result?.directPath) { + urls = { + mediaUrl: result.url, + directPath: result.direct_path + } + break + } else { uploadInfo = await refreshMediaConn(true) throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) } @@ -458,13 +462,13 @@ export const makeMessagesSocket = (config: SocketConfig) => { logger.debug(`Error in uploading to ${hostname} (${error}) ${isLast ? '' : ', retrying...'}`) } } - if (!mediaUrl) { + if (!urls) { throw new Boom( 'Media upload failed on all hosts', { statusCode: 500 } ) } - return { mediaUrl } + return urls } return { diff --git a/src/Types/Message.ts b/src/Types/Message.ts index b7b6380..8ae9454 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -140,7 +140,7 @@ export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & userJid: string } -export type WAMediaUploadFunction = (readStream: ReadStream, opts: { fileEncSha256B64: string, mediaType: MediaType, timeoutMs?: number }) => Promise<{ mediaUrl: string }> +export type WAMediaUploadFunction = (readStream: ReadStream, opts: { fileEncSha256B64: string, mediaType: MediaType, timeoutMs?: number }) => Promise<{ mediaUrl: string, directPath: string }> export type MediaGenerationOptions = { logger?: Logger diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 389bd10..1b352df 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -118,7 +118,7 @@ export const prepareWAMessageMedia = async( } catch (error) { options.logger?.info({ trace: error.stack }, 'failed to obtain extra info') } - const {mediaUrl} = await options.upload( + const {mediaUrl, directPath} = await options.upload( createReadStream(encBodyPath), { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs } ) @@ -136,11 +136,12 @@ export const prepareWAMessageMedia = async( [`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject( { url: mediaUrl, + directPath, mediaKey, fileEncSha256, fileSha256, fileLength, - + mediaKeyTimestamp: unixTimestampSeconds(), ...uploadData } ) From ef1b01b6df0e3c10f139c57aa842cbc5aec245e7 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 14 Dec 2021 00:31:29 +0530 Subject: [PATCH 220/311] fix: correctly handle retry from own devices --- src/Socket/messages-recv.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index fa98b8e..51cac7b 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -494,9 +494,11 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const handleReceipt = async(node: BinaryNode) => { let shouldAck = true + const { attrs, content } = node + const isNodeFromMe = areJidsSameUser(attrs.from, authState.creds.me?.id) const remoteJid = attrs.recipient || attrs.from - const fromMe = attrs.recipient ? false : true + const fromMe = isNodeFromMe || (attrs.recipient ? false : true) const ids = [attrs.id] if(Array.isArray(content)) { @@ -512,7 +514,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } const status = getStatusFromReceiptType(attrs.type) - if(typeof status !== 'undefined' && !areJidsSameUser(attrs.from, authState.creds.me?.id)) { + if(typeof status !== 'undefined' && !isNodeFromMe) { ev.emit('messages.update', ids.map(id => ({ key: { ...key, id }, update: { status } @@ -520,6 +522,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } if(attrs.type === 'retry') { + // correctly set who is asking for the retry + key.participant = key.participant || attrs.from if(key.fromMe) { try { logger.debug({ attrs }, 'recv retry request') From 9474017930d8e594928c9daa4df369ed09f45ac3 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 16 Dec 2021 00:38:53 +0530 Subject: [PATCH 221/311] feat: async import got wherever required --- src/Socket/messages-send.ts | 4 ++-- src/Utils/messages-media.ts | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 12288df..7ee514b 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -1,5 +1,4 @@ -import got from "got" import { Boom } from "@hapi/boom" import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions } from "../Types" import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESessions } from "../Utils" @@ -421,7 +420,8 @@ export const makeMessagesSocket = (config: SocketConfig) => { } const waUploadToServer: WAMediaUploadFunction = async(stream, { mediaType, fileEncSha256B64, timeoutMs }) => { - // send a query JSON to obtain the url & auth token to upload our media + const { default: got } = await import('got') + // send a query JSON to obtain the url & auth token to upload our media let uploadInfo = await refreshMediaConn(false) let urls: { mediaUrl: string, directPath: string } diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index c8d3bdb..50285f3 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -1,5 +1,6 @@ import type { Logger } from 'pino' import type { IAudioMetadata } from 'music-metadata' +import type { Options, Response } from 'got' import { Boom } from '@hapi/boom' import * as Crypto from 'crypto' import { Readable, Transform } from 'stream' @@ -9,7 +10,6 @@ import { tmpdir } from 'os' import { URL } from 'url' import { join } from 'path' import { once } from 'events' -import got, { Options, Response } from 'got' import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType, DownloadableMessage } from '../Types' import { generateMessageID } from './generics' import { hkdf } from './crypto' @@ -152,7 +152,8 @@ export async function generateThumbnail( return thumbnail } export const getGotStream = async(url: string | URL, options: Options & { isStream?: true } = {}) => { - const fetched = got.stream(url, { ...options, isStream: true }) + const { default: { stream: gotStream }} = await import('got') + const fetched = gotStream(url, { ...options, isStream: true }) await new Promise((resolve, reject) => { fetched.once('error', reject) fetched.once('response', ({ statusCode }: Response) => { From 6c4a9c7354a6da393e9b4fbe9bc3104e14a5dfca Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 16 Dec 2021 23:20:27 +0530 Subject: [PATCH 222/311] fix: sending list of contacts --- src/Utils/messages.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 1b352df..0d115f3 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -223,6 +223,8 @@ export const generateWAMessageContent = async( } if(contactLen === 1) { m.contactMessage = WAProto.ContactMessage.fromObject(message.contacts.contacts[0]) + } else { + m.contactsArrayMessage = WAProto.ContactsArrayMessage.fromObject(message.contacts) } } else if('location' in message) { m.locationMessage = WAProto.LocationMessage.fromObject(message.location) From 4f674d3e2666ca2a49607b6bf05ee89ea9b6a10e Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 16 Dec 2021 23:22:03 +0530 Subject: [PATCH 223/311] fix: sending multiple contacts --- src/Utils/messages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 0d115f3..9238159 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -224,7 +224,7 @@ export const generateWAMessageContent = async( if(contactLen === 1) { m.contactMessage = WAProto.ContactMessage.fromObject(message.contacts.contacts[0]) } else { - m.contactsArrayMessage = WAProto.ContactsArrayMessage.fromObject(message.contacts) + m.contactsArrayMessage = WAProto.ContactsArrayMessage.fromObject({ contacts: message.contacts }) } } else if('location' in message) { m.locationMessage = WAProto.LocationMessage.fromObject(message.location) From ca12da6269c6e7ce79bf0ffc25454738355d5eda Mon Sep 17 00:00:00 2001 From: LyFE <76509367+lyfe00011@users.noreply.github.com> Date: Thu, 16 Dec 2021 23:49:48 +0530 Subject: [PATCH 224/311] fix updateBlockStatus,fetchPrivacySettings (#1034) * fix updateBlockStatus * fix fetchPrivacySettings * Update chats.ts --- src/Socket/chats.ts | 3 ++- src/Socket/messages-send.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index f7d3dd9..e5781d6 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -138,6 +138,7 @@ export const makeChatsSocket = (config: SocketConfig) => { await query({ tag: 'iq', attrs: { + xmlns: 'blocklist', to: S_WHATSAPP_NET, type: 'set' }, @@ -598,4 +599,4 @@ export const makeChatsSocket = (config: SocketConfig) => { chatModify, resyncMainAppState, } -} \ No newline at end of file +} diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 7ee514b..51d3357 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -29,7 +29,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { const fetchPrivacySettings = async(force: boolean = false) => { if(!privacySettings || force) { - const result = await query({ + const { content } = await query({ tag: 'iq', attrs: { xmlns: 'privacy', @@ -40,7 +40,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { { tag: 'privacy', attrs: { } } ] }) - privacySettings = reduceBinaryNodeToDictionary(result, 'category') + privacySettings = reduceBinaryNodeToDictionary(content[0], 'category') } return privacySettings } From ed30e368ad048edbb977098e672bf962e6aa934c Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 17 Dec 2021 11:16:49 +0530 Subject: [PATCH 225/311] fix: tsc error --- src/Socket/messages-send.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 51d3357..811d1e7 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -40,7 +40,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { { tag: 'privacy', attrs: { } } ] }) - privacySettings = reduceBinaryNodeToDictionary(content[0], 'category') + privacySettings = reduceBinaryNodeToDictionary(content[0] as BinaryNode, 'category') } return privacySettings } From e51bbc489367d882caed06f92b712a3817bf814f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 17 Dec 2021 11:44:04 +0530 Subject: [PATCH 226/311] feat: add support for "sharp" for image generation --- README.md | 10 +- package.json | 8 +- src/Utils/messages-media.ts | 89 ++++++-- yarn.lock | 405 ++++++++++++++++++++++++++++++++++-- 4 files changed, 458 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index b97efdf..26b46a7 100644 --- a/README.md +++ b/README.md @@ -304,14 +304,6 @@ await sock.sendMessage( gifPlayback: true } ) -await sock.sendMessage( - id, - { - video: "./Media/ma_gif.mp4", - caption: "hello!", - gifPlayback: true - } -) await sock.sendMessage( id, @@ -369,7 +361,7 @@ const sendMsg = await sock.sendMessage(id, templateMessage) - It must be in the format ```[country code][phone number]@s.whatsapp.net```, for example ```+19999999999@s.whatsapp.net``` for people. For groups, it must be in the format ``` 123456789-123345@g.us ```. - For broadcast lists it's `[timestamp of creation]@broadcast`. - For stories, the ID is `status@broadcast`. -- For media messages, the thumbnail can be generated automatically for images & stickers. Thumbnails for videos can also be generated automatically, though, you need to have `ffmpeg` installed on your system. +- For media messages, the thumbnail can be generated automatically for images & stickers provided you add `jimp` or `sharp` as a dependency in your project using `yarn add jimp` or `yarn add sharp`. Thumbnails for videos can also be generated automatically, though, you need to have `ffmpeg` installed on your system. - **MiscGenerationOptions**: some extra info about the message. It can have the following __optional__ values: ``` ts const info: MessageOptions = { diff --git a/package.json b/package.json index a96edc7..ec31289 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "@hapi/boom": "^9.1.3", "curve25519-js": "^0.0.4", "got": "^11.8.1", - "jimp": "^0.16.1", "libsignal": "git+https://github.com/adiwajshing/libsignal-node", "music-metadata": "^7.4.1", "node-cache": "^5.1.2", @@ -45,7 +44,9 @@ "ws": "^8.0.0" }, "optionalDependencies": { - "qrcode-terminal": "^0.12.0" + "qrcode-terminal": "^0.12.0", + "jimp": "^0.16.1", + "sharp": "^0.29.3" }, "files": [ "lib/*", @@ -58,9 +59,12 @@ "@types/jest": "^26.0.24", "@types/node": "^14.6.2", "@types/pino": "^6.3.2", + "@types/sharp": "^0.29.4", "@types/ws": "^8.0.0", "jest": "^27.0.6", + "jimp": "^0.16.1", "qrcode-terminal": "^0.12.0", + "sharp": "^0.29.3", "ts-jest": "^27.0.3", "ts-node": "^10.0.0", "typedoc": "^0.20.0-beta.27", diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 50285f3..af6b227 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -17,6 +17,29 @@ import { DEFAULT_ORIGIN } from '../Defaults' const getTmpFilesDirectory = () => tmpdir() +const getImageProcessingLibrary = async() => { + const [jimp, sharp] = await Promise.all([ + (async() => { + const jimp = await ( + import('jimp') + .catch(() => { }) + ) + return jimp + })(), + (async() => { + const sharp = await ( + import('sharp') + .catch(() => { }) + ) + return sharp + })() + ]) + if(sharp) return { sharp } + if(jimp) return { jimp } + + throw new Boom('No image processing library available') +} + export const hkdfInfoKey = (type: MediaType) => { let str: string = type if(type === 'sticker') str = 'image' @@ -53,17 +76,27 @@ const extractVideoThumb = async ( }) }) as Promise -export const compressImage = async (bufferOrFilePath: Readable | Buffer | string) => { +export const extractImageThumb = async (bufferOrFilePath: Readable | Buffer | string) => { if(bufferOrFilePath instanceof Readable) { bufferOrFilePath = await toBuffer(bufferOrFilePath) } - const { read, MIME_JPEG, RESIZE_BILINEAR } = await import('jimp') - const jimp = await read(bufferOrFilePath as any) - const result = await jimp - .quality(50) - .resize(32, 32, RESIZE_BILINEAR) - .getBufferAsync(MIME_JPEG) - return result + const lib = await getImageProcessingLibrary() + if('sharp' in lib) { + const result = await lib.sharp!.default(bufferOrFilePath) + .resize(32, 32) + .jpeg({ quality: 50 }) + .toBuffer() + return result + } else { + const { read, MIME_JPEG, RESIZE_BILINEAR } = lib.jimp + + const jimp = await read(bufferOrFilePath as any) + const result = await jimp + .quality(50) + .resize(32, 32, RESIZE_BILINEAR) + .getBufferAsync(MIME_JPEG) + return result + } } export const generateProfilePicture = async (mediaUpload: WAMediaUpload) => { let bufferOrFilePath: Buffer | string @@ -74,16 +107,30 @@ export const generateProfilePicture = async (mediaUpload: WAMediaUpload) => { } else { bufferOrFilePath = await toBuffer(mediaUpload.stream) } - - const { read, MIME_JPEG, RESIZE_BILINEAR } = await import('jimp') - const jimp = await read(bufferOrFilePath as any) - const min = Math.min(jimp.getWidth (), jimp.getHeight ()) - const cropped = jimp.crop (0, 0, min, min) - return { - img: await cropped + + const lib = await getImageProcessingLibrary() + let img: Promise + if('sharp' in lib) { + img = lib.sharp!.default(bufferOrFilePath) + .resize(640, 640) + .jpeg({ + quality: 50, + }) + .toBuffer() + } else { + const { read, MIME_JPEG, RESIZE_BILINEAR } = lib.jimp + const jimp = await read(bufferOrFilePath as any) + const min = Math.min(jimp.getWidth(), jimp.getHeight()) + const cropped = jimp.crop(0, 0, min, min) + + img = cropped .quality(50) .resize(640, 640, RESIZE_BILINEAR) - .getBufferAsync(MIME_JPEG), + .getBufferAsync(MIME_JPEG) + } + + return { + img: await img, } } /** gets the SHA256 of the given media message */ @@ -91,15 +138,17 @@ export const mediaMessageSHA256B64 = (message: WAMessageContent) => { const media = Object.values(message)[0] as WAGenericMediaMessage return media?.fileSha256 && Buffer.from(media.fileSha256).toString ('base64') } -export async function getAudioDuration (buffer: Buffer | string) { - const musicMetadata = await import ('music-metadata') +export async function getAudioDuration (buffer: Buffer | string | Readable) { + const musicMetadata = await import('music-metadata') let metadata: IAudioMetadata if(Buffer.isBuffer(buffer)) { metadata = await musicMetadata.parseBuffer(buffer, null, { duration: true }) - } else { + } else if(typeof buffer === 'string') { const rStream = createReadStream(buffer) metadata = await musicMetadata.parseStream(rStream, null, { duration: true }) rStream.close() + } else { + metadata = await musicMetadata.parseStream(buffer, null, { duration: true }) } return metadata.format.duration; } @@ -134,7 +183,7 @@ export async function generateThumbnail( ) { let thumbnail: string if(mediaType === 'image') { - const buff = await compressImage(file) + const buff = await extractImageThumb(file) thumbnail = buff.toString('base64') } else if(mediaType === 'video') { const imgFilename = join(getTmpFilesDirectory(), generateMessageID() + '.jpg') diff --git a/yarn.lock b/yarn.lock index 4385632..b054002 100644 --- a/yarn.lock +++ b/yarn.lock @@ -266,9 +266,9 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/runtime@^7.7.2": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" - integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== + version "7.16.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a" + integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA== dependencies: regenerator-runtime "^0.13.4" @@ -1082,6 +1082,13 @@ dependencies: "@types/node" "*" +"@types/sharp@^0.29.4": + version "0.29.4" + resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.29.4.tgz#e47d8677befc9944d4b9d76ed837452814166de0" + integrity sha512-asrPef2LYenr76zBzyy+Fw40yGzq/q/CY77mUP5n43DnuWjQoOB+8vxnzFcqccz+LF+A7mbnknGCfpVWSG82Bw== + dependencies: + "@types/node" "*" + "@types/sonic-boom@*": version "0.7.0" resolved "https://registry.yarnpkg.com/@types/sonic-boom/-/sonic-boom-0.7.0.tgz#38337036293992a1df65dd3161abddf8fb9b7176" @@ -1177,11 +1184,21 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.21.3" +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + ansi-regex@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1214,6 +1231,19 @@ anymatch@^3.0.3: normalize-path "^3.0.0" picomatch "^2.0.4" +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.7" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" + integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" @@ -1312,6 +1342,15 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + bmp-js@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" @@ -1377,7 +1416,7 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@^5.2.0: +buffer@^5.2.0, buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -1445,6 +1484,11 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + ci-info@^3.1.1: version "3.2.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6" @@ -1481,6 +1525,11 @@ co@^4.6.0: resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" @@ -1505,11 +1554,27 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-string@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.0.tgz#63b6ebd1bec11999d1df3a79a7569451ac2be8aa" + integrity sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/color/-/color-4.1.0.tgz#9502e6a2dcacb26adf4c60910a27628d010b3de3" + integrity sha512-o2rkkxyLGgYoeUy1OodXpbPAQNmlNBrirQ8ODO8QutzDiDMNdezSOZLNnusQ6pUpCQJUsaJIo9DZJKqa2HgH7A== + dependencies: + color-convert "^2.0.1" + color-string "^1.9.0" + colorette@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" @@ -1532,6 +1597,11 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + content-type@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" @@ -1544,6 +1614,11 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -1613,6 +1688,11 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -1633,6 +1713,16 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -1680,7 +1770,7 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -end-of-stream@^1.1.0: +end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -1754,6 +1844,11 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + expect@^27.0.6: version "27.0.6" resolved "https://registry.yarnpkg.com/expect/-/expect-27.0.6.tgz#a4d74fbe27222c718fff68ef49d78e26a8fd4c05" @@ -1845,6 +1940,11 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -1870,6 +1970,20 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -1905,6 +2019,11 @@ gifwrap@^0.9.2: image-q "^1.1.1" omggif "^1.0.10" +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" @@ -1974,6 +2093,11 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -2066,16 +2190,26 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3: +inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + interpret@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + is-ci@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994" @@ -2090,6 +2224,13 @@ is-core-module@^2.2.0: dependencies: has "^1.0.3" +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -2125,6 +2266,11 @@ is-typedarray@^1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2858,11 +3004,16 @@ minimatch@^3.0.0, minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.5: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + mkdirp@1.x: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" @@ -2892,6 +3043,11 @@ music-metadata@^7.4.1: strtok3 "^6.0.8" token-types "^2.1.1" +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -2902,6 +3058,18 @@ neo-async@^2.6.0: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +node-abi@^3.3.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.5.0.tgz#26e8b7b251c3260a5ac5ba5aef3b4345a0229248" + integrity sha512-LtHvNIBgOy5mO8mPEUtkCW/YCRWYEKshIvqhe1GHHyXEHEB5mgICyYnAcl4qan3uFeRROErKGzatFHPf6kDxWw== + dependencies: + semver "^7.3.5" + +node-addon-api@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.2.0.tgz#117cbb5a959dff0992e1c586ae0393573e4d2a87" + integrity sha512-eazsqzwG2lskuzBqCGPi7Ac2UgOoMz8JVOXVhTvvPDYhthvNpefx8jWD8Np7Gv+2Sz0FlPWZk0nJV0z598Wn8Q== + node-cache@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-5.1.2.tgz#f264dc2ccad0a780e76253a694e9fd0ed19c398d" @@ -2941,11 +3109,31 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npmlog@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== +object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + omggif@^1.0.10, omggif@^1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" @@ -3037,9 +3225,9 @@ parse-bmfont-xml@^1.1.4: xml2js "^0.4.5" parse-headers@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" - integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA== + version "2.0.4" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.4.tgz#9eaf2d02bed2d1eff494331ce3df36d7924760bf" + integrity sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw== parse5@6.0.1: version "6.0.1" @@ -3124,6 +3312,25 @@ pngjs@^3.0.0, pngjs@^3.3.3: resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== +prebuild-install@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.0.tgz#3c5ce3902f1cb9d6de5ae94ca53575e4af0c1574" + integrity sha512-IvSenf33K7JcgddNz2D5w521EgO+4aMMjFt73Uk9FRzQ7P+QZPKrp7qPsDydsSwjGt3T5xRNnM1bj1zMTD5fTA== + dependencies: + detect-libc "^1.0.3" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -3149,6 +3356,11 @@ pretty-format@^27.0.6: ansi-styles "^5.0.0" react-is "^17.0.1" +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" @@ -3238,12 +3450,35 @@ quick-lru@^5.1.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -readable-stream@^3.6.0: +readable-stream@^2.0.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -3267,9 +3502,9 @@ rechoir@^0.6.2: resolve "^1.1.6" regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== require-directory@^2.1.1: version "2.1.1" @@ -3315,16 +3550,16 @@ rimraf@^3.0.0: dependencies: glob "^7.1.3" -safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -3342,7 +3577,7 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" -semver@7.x, semver@^7.3.2: +semver@7.x, semver@^7.3.2, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -3354,6 +3589,25 @@ semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +sharp@^0.29.3: + version "0.29.3" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.29.3.tgz#0da183d626094c974516a48fab9b3e4ba92eb5c2" + integrity sha512-fKWUuOw77E4nhpyzCCJR1ayrttHoFHBT2U/kR/qEMRhvPEcluG4BKj324+SCO1e84+knXHwhJ1HHJGnUt4ElGA== + dependencies: + color "^4.0.1" + detect-libc "^1.0.3" + node-addon-api "^4.2.0" + prebuild-install "^7.0.0" + semver "^7.3.5" + simple-get "^4.0.0" + tar-fs "^2.1.1" + tunnel-agent "^0.6.0" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -3384,11 +3638,37 @@ shiki@^0.9.3: onigasm "^2.2.5" vscode-textmate "5.2.0" +signal-exit@^3.0.0: + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.0.tgz#73fa628278d21de83dadd5512d2cc1f4872bd675" + integrity sha512-ZalZGexYr3TA0SwySsr5HlgOOinS4Jsa8YB2GJ6lUNAazyAu4KG/VmzMTwAt2YVXzzVj8QmefmAonZIK2BSGcQ== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -3450,6 +3730,24 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2 || 3 || 4": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^4.1.0, string-width@^4.2.0: version "4.2.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" @@ -3466,6 +3764,20 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" @@ -3473,6 +3785,13 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-bom@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" @@ -3483,6 +3802,11 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + strtok3@^6.0.3, strtok3@^6.0.8: version "6.2.0" resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.2.0.tgz#7c24e74a9a24c7f2b976e4469654d459e6795d91" @@ -3524,6 +3848,27 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +tar-fs@^2.0.0, tar-fs@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" @@ -3631,6 +3976,13 @@ ts-node@^10.0.0: make-error "^1.1.1" yn "3.1.1" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -3704,7 +4056,7 @@ utif@^2.0.1: dependencies: pako "^1.0.5" -util-deprecate@^1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -3782,6 +4134,13 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" From 38a44be006d4d43c9a283bae026c21746fca5ee6 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 17 Dec 2021 18:27:03 +0530 Subject: [PATCH 227/311] perf: experimental do not use fs for enc stream --- src/Types/Message.ts | 2 +- src/Utils/messages-media.ts | 80 +++++++++++++++++++++++-------------- src/Utils/messages.ts | 49 +++++++++++++---------- 3 files changed, 78 insertions(+), 53 deletions(-) diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 8ae9454..2162545 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -140,7 +140,7 @@ export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions & userJid: string } -export type WAMediaUploadFunction = (readStream: ReadStream, opts: { fileEncSha256B64: string, mediaType: MediaType, timeoutMs?: number }) => Promise<{ mediaUrl: string, directPath: string }> +export type WAMediaUploadFunction = (readStream: Readable, opts: { fileEncSha256B64: string, mediaType: MediaType, timeoutMs?: number }) => Promise<{ mediaUrl: string, directPath: string }> export type MediaGenerationOptions = { logger?: Logger diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index af6b227..ee3ed5c 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -4,7 +4,7 @@ import type { Options, Response } from 'got' import { Boom } from '@hapi/boom' import * as Crypto from 'crypto' import { Readable, Transform } from 'stream' -import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs' +import { createReadStream, createWriteStream, promises as fs, ReadStream, WriteStream } from 'fs' import { exec } from 'child_process' import { tmpdir } from 'os' import { URL } from 'url' @@ -219,14 +219,20 @@ export const getGotStream = async(url: string | URL, options: Options & { isStre }) return fetched } -export const encryptedStream = async(media: WAMediaUpload, mediaType: MediaType, saveOriginalFileIfRequired = true) => { +export const encryptedStream = async( + media: WAMediaUpload, + mediaType: MediaType, + saveOriginalFileIfRequired = true +) => { const { stream, type } = await getStream(media) const mediaKey = Crypto.randomBytes(32) const {cipherKey, iv, macKey} = getMediaKeys(mediaKey, mediaType) // random name - const encBodyPath = join(getTmpFilesDirectory(), mediaType + generateMessageID() + '.enc') - const encWriteStream = createWriteStream(encBodyPath) + //const encBodyPath = join(getTmpFilesDirectory(), mediaType + generateMessageID() + '.enc') + // const encWriteStream = createWriteStream(encBodyPath) + const encWriteStream = new Readable({ read: () => {} }) + let bodyPath: string let writeStream: WriteStream let didSaveToTmpPath = false @@ -247,38 +253,50 @@ export const encryptedStream = async(media: WAMediaUpload, mediaType: MediaType, const onChunk = (buff: Buffer) => { sha256Enc = sha256Enc.update(buff) hmac = hmac.update(buff) - encWriteStream.write(buff) + encWriteStream.push(buff) } - for await(const data of stream) { - fileLength += data.length - sha256Plain = sha256Plain.update(data) - if(writeStream) { - if(!writeStream.write(data)) await once(writeStream, 'drain') + + try { + for await(const data of stream) { + fileLength += data.length + sha256Plain = sha256Plain.update(data) + if(writeStream) { + if(!writeStream.write(data)) await once(writeStream, 'drain') + } + onChunk(aes.update(data)) } - onChunk(aes.update(data)) - } - onChunk(aes.final()) - - const mac = hmac.digest().slice(0, 10) - sha256Enc = sha256Enc.update(mac) + onChunk(aes.final()) - const fileSha256 = sha256Plain.digest() - const fileEncSha256 = sha256Enc.digest() + const mac = hmac.digest().slice(0, 10) + sha256Enc = sha256Enc.update(mac) + + const fileSha256 = sha256Plain.digest() + const fileEncSha256 = sha256Enc.digest() + + encWriteStream.push(mac) + encWriteStream.push(null) - encWriteStream.write(mac) - encWriteStream.end() + writeStream && writeStream.end() + + return { + mediaKey, + encWriteStream, + bodyPath, + mac, + fileEncSha256, + fileSha256, + fileLength, + didSaveToTmpPath + } + } catch(error) { + encWriteStream.destroy(error) + writeStream.destroy(error) + aes.destroy(error) + hmac.destroy(error) + sha256Plain.destroy(error) + sha256Enc.destroy(error) - writeStream && writeStream.end() - - return { - mediaKey, - encBodyPath, - bodyPath, - mac, - fileEncSha256, - fileSha256, - fileLength, - didSaveToTmpPath + throw error } } diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 9238159..47ab76a 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -94,7 +94,7 @@ export const prepareWAMessageMedia = async( const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation const { mediaKey, - encBodyPath, + encWriteStream, bodyPath, fileEncSha256, fileSha256, @@ -108,28 +108,35 @@ export const prepareWAMessageMedia = async( .replace(/\//g, '_') .replace(/\=+$/, '') ) - try { - if(requiresThumbnailComputation) { - uploadData.jpegThumbnail = await generateThumbnail(bodyPath, mediaType as any, options) + + const [{ mediaUrl, directPath }] = await Promise.all([ + (() => { + return options.upload( + encWriteStream, + { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs } + ) + })(), + (async() => { + try { + if(requiresThumbnailComputation) { + uploadData.jpegThumbnail = await generateThumbnail(bodyPath, mediaType as any, options) + } + if (requiresDurationComputation) { + uploadData.seconds = await getAudioDuration(bodyPath) + } + } catch (error) { + options.logger?.info({ trace: error.stack }, 'failed to obtain extra info') + } + })(), + ]) + .finally( + async() => { + encWriteStream.destroy() + // remove tmp files + didSaveToTmpPath && bodyPath && await fs.unlink(bodyPath) } - if (requiresDurationComputation) { - uploadData.seconds = await getAudioDuration(bodyPath) - } - } catch (error) { - options.logger?.info({ trace: error.stack }, 'failed to obtain extra info') - } - const {mediaUrl, directPath} = await options.upload( - createReadStream(encBodyPath), - { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs } - ) - // remove tmp files - await Promise.all( - [ - fs.unlink(encBodyPath), - didSaveToTmpPath && bodyPath && fs.unlink(bodyPath) - ] - .filter(Boolean) ) + delete uploadData.media const obj = WAProto.Message.fromObject({ From 19a99804921df46b19825b085ccc92c9f97c5de6 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 17 Dec 2021 19:27:04 +0530 Subject: [PATCH 228/311] feat: add legacy connection --- src/Defaults/index.ts | 25 +- src/LegacySocket/auth.ts | 269 ++++++++++++++++++ src/LegacySocket/chats.ts | 503 ++++++++++++++++++++++++++++++++ src/LegacySocket/groups.ts | 238 ++++++++++++++++ src/LegacySocket/index.ts | 14 + src/LegacySocket/messages.ts | 535 +++++++++++++++++++++++++++++++++++ src/LegacySocket/socket.ts | 393 +++++++++++++++++++++++++ src/Socket/chats.ts | 8 +- src/Socket/messages-send.ts | 51 +--- src/Socket/socket.ts | 2 +- src/Types/Auth.ts | 1 - src/Types/Chat.ts | 2 +- src/Types/Events.ts | 56 ++++ src/Types/Legacy.ts | 83 ++++++ src/Types/Message.ts | 2 +- src/Types/Socket.ts | 39 +++ src/Types/State.ts | 10 +- src/Types/index.ts | 61 ++-- src/Utils/chat-utils.ts | 2 +- src/Utils/index.ts | 3 +- src/Utils/legacy-msgs.ts | 142 ++++++++++ src/Utils/messages-media.ts | 53 +++- src/WABinary/index.ts | 13 + 23 files changed, 2402 insertions(+), 103 deletions(-) create mode 100644 src/LegacySocket/auth.ts create mode 100644 src/LegacySocket/chats.ts create mode 100644 src/LegacySocket/groups.ts create mode 100644 src/LegacySocket/index.ts create mode 100644 src/LegacySocket/messages.ts create mode 100644 src/LegacySocket/socket.ts create mode 100644 src/Types/Events.ts create mode 100644 src/Types/Legacy.ts create mode 100644 src/Types/Socket.ts create mode 100644 src/Utils/legacy-msgs.ts diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 844449c..6cb9c8c 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -1,5 +1,5 @@ import P from "pino" -import type { MediaType, SocketConfig } from "../Types" +import type { MediaType, SocketConfig, LegacySocketConfig, CommonSocketConfig } from "../Types" import { Browsers } from "../Utils" export const UNAUTHORIZED_CODES = [401, 403, 419] @@ -17,7 +17,26 @@ export const NOISE_WA_HEADER = new Uint8Array([87, 65, 5, 2]) // last is "DICT_V /** from: https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url */ export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi +const BASE_CONNECTION_CONFIG: CommonSocketConfig = { + version: [2, 2146, 9], + browser: Browsers.baileys('Chrome'), + + waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', + connectTimeoutMs: 20_000, + keepAliveIntervalMs: 25_000, + logger: P().child({ class: 'baileys' }), + printQRInTerminal: false, + emitOwnEvents: true, + defaultQueryTimeoutMs: 60_000, + customUploadHosts: [], +} + export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { + ...BASE_CONNECTION_CONFIG, + getMessage: async() => undefined +} + +export const DEFAULT_LEGACY_CONNECTION_CONFIG: LegacySocketConfig = { version: [2, 2146, 9], browser: Browsers.baileys('Chrome'), @@ -29,7 +48,9 @@ export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { emitOwnEvents: true, defaultQueryTimeoutMs: 60_000, customUploadHosts: [], - getMessage: async() => undefined + phoneResponseTimeMs: 20_000, + expectResponseTimeout: 60_000, + pendingRequestTimeoutMs: 60_000 } export const MEDIA_PATH_MAP: { [T in MediaType]: string } = { diff --git a/src/LegacySocket/auth.ts b/src/LegacySocket/auth.ts new file mode 100644 index 0000000..21b06a5 --- /dev/null +++ b/src/LegacySocket/auth.ts @@ -0,0 +1,269 @@ +import { Boom } from '@hapi/boom' +import EventEmitter from "events" +import { LegacyBaileysEventEmitter, BaileysEventMap, LegacySocketConfig, CurveKeyPair, WAInitResponse, ConnectionState, DisconnectReason, LegacyAuthenticationCreds } from "../Types" +import { newLegacyAuthCreds, promiseTimeout, computeChallengeResponse, validateNewConnection, Curve } from "../Utils" +import { makeSocket } from "./socket" + +const makeAuthSocket = (config: LegacySocketConfig) => { + const { + logger, + version, + browser, + connectTimeoutMs, + pendingRequestTimeoutMs, + printQRInTerminal, + auth: initialAuthInfo + } = config + const ev = new EventEmitter() as LegacyBaileysEventEmitter + + let authInfo = initialAuthInfo || newLegacyAuthCreds() + + const state: ConnectionState = { + legacy: { + phoneConnected: false, + }, + connection: 'connecting', + } + + const socket = makeSocket(config) + const { ws } = socket + let curveKeys: CurveKeyPair + let initTimeout: NodeJS.Timeout + + ws.on('phone-connection', ({ value: phoneConnected }) => { + if(phoneConnected !== state.legacy.phoneConnected) { + updateState({ legacy: { ...state.legacy, phoneConnected } }) + } + }) + // add close listener + ws.on('ws-close', (error: Boom | Error) => { + logger.info({ error }, 'Closed connection to WhatsApp') + initTimeout && clearTimeout(initTimeout) + // if no reconnects occur + // send close event + updateState({ + connection: 'close', + qr: undefined, + lastDisconnect: { + error, + date: new Date() + } + }) + }) + /** Can you login to WA without scanning the QR */ + const canLogin = () => !!authInfo?.encKey && !!authInfo?.macKey + + const updateState = (update: Partial) => { + Object.assign(state, update) + ev.emit('connection.update', update) + } + + /** + * Logs you out from WA + * If connected, invalidates the credentials with the server + */ + const logout = async() => { + if(state.connection === 'open') { + await socket.sendMessage({ + json: ['admin', 'Conn', 'disconnect'], + tag: 'goodbye' + }) + } + // will call state update to close connection + socket?.end( + new Boom('Logged Out', { statusCode: DisconnectReason.loggedOut }) + ) + authInfo = undefined + } + /** Waits for the connection to WA to open up */ + const waitForConnection = async(waitInfinitely: boolean = false) => { + if(state.connection === 'open') return + + let listener: (item: BaileysEventMap['connection.update']) => void + const timeout = waitInfinitely ? undefined : pendingRequestTimeoutMs + if(timeout < 0) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } + + await ( + promiseTimeout( + timeout, + (resolve, reject) => { + listener = ({ connection, lastDisconnect }) => { + if(connection === 'open') resolve() + else if(connection == 'close') { + reject(lastDisconnect.error || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) + } + } + ev.on('connection.update', listener) + } + ) + .finally(() => ( + ev.off('connection.update', listener) + )) + ) + } + + const updateEncKeys = () => { + // update the keys so we can decrypt traffic + socket.updateKeys({ encKey: authInfo!.encKey, macKey: authInfo!.macKey }) + } + + const generateKeysForAuth = async(ref: string, ttl?: number) => { + curveKeys = Curve.generateKeyPair() + const publicKey = Buffer.from(curveKeys.public).toString('base64') + let qrGens = 0 + + const qrLoop = ttl => { + const qr = [ref, publicKey, authInfo.clientID].join(',') + updateState({ qr }) + + initTimeout = setTimeout(async () => { + if(state.connection !== 'connecting') return + + logger.debug('regenerating QR') + try { + // request new QR + const {ref: newRef, ttl: newTTL} = await socket.query({ + json: ['admin', 'Conn', 'reref'], + expect200: true, + longTag: true, + requiresPhoneConnection: false + }) + ttl = newTTL + ref = newRef + } catch (error) { + logger.error({ error }, `error in QR gen`) + if (error.output?.statusCode === 429) { // too many QR requests + socket.end(error) + return + } + } + qrGens += 1 + qrLoop(ttl) + }, ttl || 20_000) // default is 20s, on the off-chance ttl is not present + } + qrLoop(ttl) + } + const onOpen = async() => { + const canDoLogin = canLogin() + const initQuery = (async () => { + const {ref, ttl} = await socket.query({ + json: ['admin', 'init', version, browser, authInfo.clientID, true], + expect200: true, + longTag: true, + requiresPhoneConnection: false + }) as WAInitResponse + + if (!canDoLogin) { + generateKeysForAuth(ref, ttl) + } + })(); + let loginTag: string + if(canDoLogin) { + updateEncKeys() + // if we have the info to restore a closed session + const json = [ + 'admin', + 'login', + authInfo.clientToken, + authInfo.serverToken, + authInfo.clientID, + 'takeover' + ] + loginTag = socket.generateMessageTag(true) + // send login every 10s + const sendLoginReq = () => { + if(state.connection === 'open') { + logger.warn('Received login timeout req when state=open, ignoring...') + return + } + logger.info('sending login request') + socket.sendMessage({ + json, + tag: loginTag + }) + initTimeout = setTimeout(sendLoginReq, 10_000) + } + sendLoginReq() + } + await initQuery + + // wait for response with tag "s1" + let response = await Promise.race( + [ + socket.waitForMessage('s1', false, undefined).promise, + ...(loginTag ? [socket.waitForMessage(loginTag, false, connectTimeoutMs).promise] : []) + ] + ) + initTimeout && clearTimeout(initTimeout) + initTimeout = undefined + + if(response.status && response.status !== 200) { + throw new Boom(`Unexpected error in login`, { data: response, statusCode: response.status }) + } + // if its a challenge request (we get it when logging in) + if(response[1]?.challenge) { + const json = computeChallengeResponse(response[1].challenge, authInfo) + logger.info('resolving login challenge') + + await socket.query({ json, expect200: true, timeoutMs: connectTimeoutMs }) + + response = await socket.waitForMessage('s2', true).promise + } + if(!response || !response[1]) { + throw new Boom('Received unexpected login response', { data: response }) + } + if(response[1].type === 'upgrade_md_prod') { + throw new Boom('Require multi-device edition', { statusCode: DisconnectReason.multideviceMismatch }) + } + // validate the new connection + const {user, auth} = validateNewConnection(response[1], authInfo, curveKeys)// validate the connection + const isNewLogin = user.id !== state.legacy!.user?.id + + authInfo = auth + updateEncKeys() + + logger.info({ user }, 'logged in') + + updateState({ + connection: 'open', + legacy: { + phoneConnected: true, + user, + }, + isNewLogin, + qr: undefined + }) + ev.emit('creds.update', auth) + } + ws.once('open', async() => { + try { + await onOpen() + } catch(error) { + socket.end(error) + } + }) + + if(printQRInTerminal) { + ev.on('connection.update', async({ qr }) => { + if(qr) { + const QR = await import('qrcode-terminal').catch(err => { + logger.error('QR code terminal not added as dependency') + }) + QR?.generate(qr, { small: true }) + } + }) + } + + return { + ...socket, + ev, + getState: () => state, + getAuthInfo: () => authInfo, + waitForConnection, + canLogin, + logout + } +} +export default makeAuthSocket \ No newline at end of file diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts new file mode 100644 index 0000000..ea67f99 --- /dev/null +++ b/src/LegacySocket/chats.ts @@ -0,0 +1,503 @@ +import { BinaryNode, jidNormalizedUser } from "../WABinary"; +import { Chat, Contact, WAPresence, PresenceData, LegacySocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessageUpdate, BaileysEventMap } from "../Types"; +import { debouncedTimeout, unixTimestampSeconds } from "../Utils/generics"; +import makeAuthSocket from "./auth"; + +const makeChatsSocket = (config: LegacySocketConfig) => { + const { logger } = config + const sock = makeAuthSocket(config) + const { + ev, + ws: socketEvents, + currentEpoch, + setQuery, + query, + sendMessage, + getState + } = sock + + const chatsDebounceTimeout = debouncedTimeout(10_000, () => sendChatsQuery(1)) + + const sendChatsQuery = (epoch: number) => ( + sendMessage({ + json: { + tag: 'query', + attrs: {type: 'chat', epoch: epoch.toString()} + }, + binaryTag: [ WAMetric.queryChat, WAFlag.ignore ] + }) + ) + + const fetchImageUrl = async(jid: string) => { + const response = await query({ + json: ['query', 'ProfilePicThumb', jid], + expect200: false, + requiresPhoneConnection: false + }) + return response.eurl as string | undefined + } + + const executeChatModification = (node: BinaryNode) => { + const { attrs: attributes } = node + const updateType = attributes.type + const jid = jidNormalizedUser(attributes?.jid) + + switch(updateType) { + case 'delete': + ev.emit('chats.delete', [jid]) + break + case 'clear': + if(node.content) { + const ids = (node.content as BinaryNode[]).map( + ({ attrs }) => attrs.index + ) + ev.emit('messages.delete', { keys: ids.map(id => ({ id, remoteJid: jid })) }) + } else { + ev.emit('messages.delete', { jid, all: true }) + } + break + case 'archive': + ev.emit('chats.update', [ { id: jid, archive: true } ]) + break + case 'unarchive': + ev.emit('chats.update', [ { id: jid, archive: false } ]) + break + case 'pin': + ev.emit('chats.update', [ { id: jid, pin: +attributes.pin } ]) + break + case 'star': + case 'unstar': + const starred = updateType === 'star' + const updates: WAMessageUpdate[] = (node.content as BinaryNode[]).map( + ({ attrs }) => ({ + key: { + remoteJid: jid, + id: attrs.index, + fromMe: attrs.owner === 'true' + }, + update: { starred } + }) + ) + ev.emit('messages.update', updates) + break + case 'mute': + if(attributes.mute === '0') { + ev.emit('chats.update', [{ id: jid, mute: null }]) + } else { + ev.emit('chats.update', [{ id: jid, mute: +attributes.mute }]) + } + break + default: + logger.warn({ node }, `received unrecognized chat update`) + break + } + } + + const applyingPresenceUpdate = (update: BinaryNode['attrs']): BaileysEventMap['presence.update'] => { + const id = jidNormalizedUser(update.id) + const participant = jidNormalizedUser(update.participant || update.id) + + const presence: PresenceData = { + lastSeen: update.t ? +update.t : undefined, + lastKnownPresence: update.type as WAPresence + } + return { id, presences: { [participant]: presence } } + } + + ev.on('connection.update', async({ connection }) => { + if(connection !== 'open') return + try { + await Promise.all([ + sendMessage({ + json: { tag: 'query', attrs: {type: 'contacts', epoch: '1'} }, + binaryTag: [ WAMetric.queryContact, WAFlag.ignore ] + }), + sendMessage({ + json: { tag: 'query', attrs: {type: 'status', epoch: '1'} }, + binaryTag: [ WAMetric.queryStatus, WAFlag.ignore ] + }), + sendMessage({ + json: { tag: 'query', attrs: {type: 'quick_reply', epoch: '1'} }, + binaryTag: [ WAMetric.queryQuickReply, WAFlag.ignore ] + }), + sendMessage({ + json: { tag: 'query', attrs: {type: 'label', epoch: '1'} }, + binaryTag: [ WAMetric.queryLabel, WAFlag.ignore ] + }), + sendMessage({ + json: { tag: 'query', attrs: {type: 'emoji', epoch: '1'} }, + binaryTag: [ WAMetric.queryEmoji, WAFlag.ignore ] + }), + sendMessage({ + json: { + tag: 'action', + attrs: { type: 'set', epoch: '1' }, + content: [ + { tag: 'presence', attrs: {type: 'available'} } + ] + }, + binaryTag: [ WAMetric.presence, WAFlag.available ] + }) + ]) + chatsDebounceTimeout.start() + + logger.debug('sent init queries') + } catch(error) { + logger.error(`error in sending init queries: ${error}`) + } + }) + socketEvents.on('CB:response,type:chat', async ({ content: data }: BinaryNode) => { + chatsDebounceTimeout.cancel() + if(Array.isArray(data)) { + const chats = data.map(({ attrs }): Chat => { + return { + id: jidNormalizedUser(attrs.jid), + conversationTimestamp: +attrs.t, + unreadCount: +attrs.count, + archive: attrs.archive === 'true' ? true : undefined, + pin: attrs.pin ? +attrs.pin : undefined, + mute: attrs.mute ? +attrs.mute : undefined, + notSpam: !(attrs.spam === 'true'), + name: attrs.name, + ephemeralExpiration: attrs.ephemeral ? +attrs.ephemeral : undefined, + ephemeralSettingTimestamp: attrs.eph_setting_ts ? +attrs.eph_setting_ts : undefined, + readOnly: attrs.read_only === 'true' ? true : undefined, + } + }) + + logger.info(`got ${chats.length} chats`) + ev.emit('chats.set', { chats, messages: [] }) + } + }) + // got all contacts from phone + socketEvents.on('CB:response,type:contacts', async ({ content: data }: BinaryNode) => { + if(Array.isArray(data)) { + const contacts = data.map(({ attrs }): Contact => { + return { + id: jidNormalizedUser(attrs.jid), + name: attrs.name, + notify: attrs.notify, + verifiedName: attrs.vname + } + }) + + logger.info(`got ${contacts.length} contacts`) + ev.emit('contacts.upsert', contacts) + } + }) + // status updates + socketEvents.on('CB:Status,status', json => { + const id = jidNormalizedUser(json[1].id) + ev.emit('contacts.update', [ { id, status: json[1].status } ]) + }) + // User Profile Name Updates + socketEvents.on('CB:Conn,pushname', json => { + const { legacy: { user }, connection } = getState() + if(connection === 'open' && json[1].pushname !== user.name) { + user.name = json[1].pushname + ev.emit('connection.update', { legacy: { ...getState().legacy, user } }) + } + }) + // read updates + socketEvents.on ('CB:action,,read', async ({ content }: BinaryNode) => { + if(Array.isArray(content)) { + const { attrs } = content[0] + + const update: Partial = { + id: jidNormalizedUser(attrs.jid) + } + if (attrs.type === 'false') update.unreadCount = -1 + else update.unreadCount = 0 + + ev.emit('chats.update', [update]) + } + }) + + socketEvents.on('CB:Cmd,type:picture', async json => { + json = json[1] + const id = jidNormalizedUser(json.jid) + const imgUrl = await fetchImageUrl(id).catch(() => '') + + ev.emit('contacts.update', [ { id, imgUrl } ]) + }) + + // chat archive, pin etc. + socketEvents.on('CB:action,,chat', ({ content }: BinaryNode) => { + if(Array.isArray(content)) { + const [node] = content + executeChatModification(node) + } + }) + + socketEvents.on('CB:action,,user', (json: BinaryNode) => { + if(Array.isArray(json.content)) { + const user = json.content[0].attrs + user.id = jidNormalizedUser(user.id) + + //ev.emit('contacts.upsert', [user]) + } + }) + + // presence updates + socketEvents.on('CB:Presence', json => { + const update = applyingPresenceUpdate(json[1]) + ev.emit('presence.update', update) + }) + + // blocklist updates + socketEvents.on('CB:Blocklist', json => { + json = json[1] + const blocklist = json.blocklist + ev.emit('blocklist.set', { blocklist }) + }) + + return { + ...sock, + sendChatsQuery, + fetchImageUrl, + chatRead: async(fromMessage: WAMessageKey, count: number) => { + await setQuery ( + [ + { tag: 'read', + attrs: { + jid: fromMessage.remoteJid, + count: count.toString(), + index: fromMessage.id, + owner: fromMessage.fromMe ? 'true' : 'false' + } + } + ], + [ WAMetric.read, WAFlag.ignore ] + ) + if(config.emitOwnEvents) { + ev.emit ('chats.update', [{ id: fromMessage.remoteJid, unreadCount: count < 0 ? -1 : 0 }]) + } + }, + /** + * Modify a given chat (archive, pin etc.) + * @param jid the ID of the person/group you are modifiying + */ + modifyChat: async(jid: string, modification: ChatModification, chatInfo: Pick, index?: WAMessageKey) => { + let chatAttrs: BinaryNode['attrs'] = { jid: jid } + let data: BinaryNode[] | undefined = undefined + const stamp = unixTimestampSeconds() + + if('archive' in modification) { + chatAttrs.type = modification.archive ? 'archive' : 'unarchive' + } else if('pin' in modification) { + chatAttrs.type = 'pin' + if(modification.pin) { + chatAttrs.pin = stamp.toString() + } else { + chatAttrs.previous = chatInfo.pin!.toString() + } + } else if('mute' in modification) { + chatAttrs.type = 'mute' + if(modification.mute) { + chatAttrs.mute = (stamp + modification.mute).toString() + } else { + chatAttrs.previous = chatInfo.mute!.toString() + } + } else if('clear' in modification) { + chatAttrs.type = 'clear' + chatAttrs.modify_tag = Math.round(Math.random ()*1000000).toString() + if(modification.clear !== 'all') { + data = modification.clear.messages.map(({ id, fromMe }) => ( + { + tag: 'item', + attrs: { owner: (!!fromMe).toString(), index: id } + } + )) + } + } else if('star' in modification) { + chatAttrs.type = modification.star.star ? 'star' : 'unstar' + data = modification.star.messages.map(({ id, fromMe }) => ( + { + tag: 'item', + attrs: { owner: (!!fromMe).toString(), index: id } + } + )) + } + + if(index) { + chatAttrs.index = index.id + chatAttrs.owner = index.fromMe ? 'true' : 'false' + } + + const node = { tag: 'chat', attrs: chatAttrs, content: data } + const response = await setQuery([node], [ WAMetric.chat, WAFlag.ignore ]) + // apply it and emit events + executeChatModification(node) + return response + }, + /** + * Query whether a given number is registered on WhatsApp + * @param str phone number/jid you want to check for + * @returns undefined if the number doesn't exists, otherwise the correctly formatted jid + */ + isOnWhatsApp: async (str: string) => { + const { status, jid, biz } = await query({ + json: ['query', 'exist', str], + requiresPhoneConnection: false + }) + if (status === 200) { + return { + exists: true, + jid: jidNormalizedUser(jid), + isBusiness: biz as boolean + } + } + }, + /** + * Tell someone about your presence -- online, typing, offline etc. + * @param jid the ID of the person/group who you are updating + * @param type your presence + */ + updatePresence: (jid: string | undefined, type: WAPresence) => ( + sendMessage({ + binaryTag: [WAMetric.presence, WAFlag[type]], // weird stuff WA does + json: { + tag: 'action', + attrs: { epoch: currentEpoch().toString(), type: 'set' }, + content: [ + { + tag: 'presence', + attrs: { type: type, to: jid } + } + ] + } + }) + ), + /** + * Request updates on the presence of a user + * this returns nothing, you'll receive updates in chats.update event + * */ + requestPresenceUpdate: async (jid: string) => ( + sendMessage({ json: ['action', 'presence', 'subscribe', jid] }) + ), + /** Query the status of the person (see groupMetadata() for groups) */ + getStatus: async(jid: string) => { + const status: { status: string } = await query({ json: ['query', 'Status', jid], requiresPhoneConnection: false }) + return status + }, + setStatus: async(status: string) => { + const response = await setQuery( + [ + { + tag: 'status', + attrs: {}, + content: Buffer.from (status, 'utf-8') + } + ] + ) + ev.emit('contacts.update', [{ id: getState().legacy!.user!.id, status }]) + return response + }, + /** Updates business profile. */ + updateBusinessProfile: async(profile: WABusinessProfile) => { + if (profile.business_hours?.config) { + profile.business_hours.business_config = profile.business_hours.config + delete profile.business_hours.config + } + const json = ['action', "editBusinessProfile", {...profile, v: 2}] + await query({ json, expect200: true, requiresPhoneConnection: true }) + }, + updateProfileName: async(name: string) => { + const response = (await setQuery( + [ + { + tag: 'profile', + attrs: { name } + } + ] + )) as any as {status: number, pushname: string} + + if(config.emitOwnEvents) { + const user = { ...getState().legacy!.user!, name } + ev.emit('connection.update', { legacy: { + ...getState().legacy, user + } }) + ev.emit('contacts.update', [{ id: user.id, name }]) + } + return response + }, + /** + * Update the profile picture + * @param jid + * @param img + */ + async updateProfilePicture (jid: string, img: Buffer) { + jid = jidNormalizedUser (jid) + const data = { img: Buffer.from([]), preview: Buffer.from([]) } //await generateProfilePicture(img) TODO + const tag = this.generateMessageTag () + const query: BinaryNode = { + tag: 'picture', + attrs: { jid: jid, id: tag, type: 'set' }, + content: [ + { tag: 'image', attrs: {}, content: data.img }, + { tag: 'preview', attrs: {}, content: data.preview } + ] + } + + const user = getState().legacy?.user + const { eurl } = await this.setQuery ([query], [WAMetric.picture, 136], tag) as { eurl: string, status: number } + + if(config.emitOwnEvents) { + if(jid === user.id) { + user.imgUrl = eurl + ev.emit('connection.update', { + legacy: { + ...getState().legacy, + user + } + }) + } + ev.emit('contacts.update', [ { id: jid, imgUrl: eurl } ]) + } + }, + /** + * Add or remove user from blocklist + * @param jid the ID of the person who you are blocking/unblocking + * @param type type of operation + */ + blockUser: async(jid: string, type: 'add' | 'remove' = 'add') => { + const json = { + tag: 'block', + attrs: { type }, + content: [ { tag: 'user', attrs: { jid } } ] + } + await setQuery([json], [WAMetric.block, WAFlag.ignore]) + if(config.emitOwnEvents) { + ev.emit('blocklist.update', { blocklist: [jid], type }) + } + }, + /** + * Query Business Profile (Useful for VCards) + * @param jid Business Jid + * @returns profile object or undefined if not business account + */ + getBusinessProfile: async(jid: string) => { + jid = jidNormalizedUser(jid) + const { + profiles: [{ + profile, + wid + }] + } = await query({ + json: [ + "query", "businessProfile", + [ { "wid": jid.replace('@s.whatsapp.net', '@c.us') } ], + 84 + ], + expect200: true, + requiresPhoneConnection: false, + }) + + return { + ...profile, + wid: jidNormalizedUser(wid) + } as WABusinessProfile + } + } +} +export default makeChatsSocket \ No newline at end of file diff --git a/src/LegacySocket/groups.ts b/src/LegacySocket/groups.ts new file mode 100644 index 0000000..b4bba8b --- /dev/null +++ b/src/LegacySocket/groups.ts @@ -0,0 +1,238 @@ +import { BinaryNode, jidNormalizedUser } from "../WABinary"; +import { LegacySocketConfig, GroupModificationResponse, ParticipantAction, GroupMetadata, WAFlag, WAMetric, WAGroupCreateResponse, GroupParticipant } from "../Types"; +import { generateMessageID, unixTimestampSeconds } from "../Utils/generics"; +import makeMessagesSocket from "./messages"; + +const makeGroupsSocket = (config: LegacySocketConfig) => { + const { logger } = config + const sock = makeMessagesSocket(config) + const { + ev, + ws: socketEvents, + query, + generateMessageTag, + currentEpoch, + setQuery, + getState + } = sock + + /** Generic function for group queries */ + const groupQuery = async(type: string, jid?: string, subject?: string, participants?: string[], additionalNodes?: BinaryNode[]) => { + const tag = generateMessageTag() + const result = await setQuery ([ + { + tag: 'group', + attrs: { + author: getState().legacy?.user?.id, + id: tag, + type: type, + jid: jid, + subject: subject, + }, + content: participants ? + participants.map(jid => ( + { tag: 'participant', attrs: { jid } } + )) : + additionalNodes + } + ], [WAMetric.group, 136], tag) + return result + } + + /** Get the metadata of the group from WA */ + const groupMetadataFull = async (jid: string) => { + const metadata = await query({ + json: ['query', 'GroupMetadata', jid], + expect200: true + }) + metadata.participants = metadata.participants.map(p => ( + { ...p, id: undefined, jid: jidNormalizedUser(p.id) } + )) + metadata.owner = jidNormalizedUser(metadata.owner) + return metadata as GroupMetadata + } + /** Get the metadata (works after you've left the group also) */ + const groupMetadataMinimal = async (jid: string) => { + const { attrs, content }:BinaryNode = await query({ + json: { + tag: 'query', + attrs: {type: 'group', jid: jid, epoch: currentEpoch().toString()} + }, + binaryTag: [WAMetric.group, WAFlag.ignore], + expect200: true + }) + const participants: GroupParticipant[] = [] + let desc: string | undefined + if(Array.isArray(content) && Array.isArray(content[0].content)) { + const nodes = content[0].content + for(const item of nodes) { + if(item.tag === 'participant') { + participants.push({ + id: item.attrs.jid, + isAdmin: item.attrs.type === 'admin', + isSuperAdmin: false + }) + } else if(item.tag === 'description') { + desc = (item.content as Buffer).toString('utf-8') + } + } + } + const meta: GroupMetadata = { + id: jid, + owner: attrs?.creator, + creation: +attrs?.create, + subject: null, + desc, + participants + } + return meta + } + + socketEvents.on('CB:Chat,cmd:action', (json: BinaryNode) => { + /*const data = json[1].data + if (data) { + const emitGroupParticipantsUpdate = (action: WAParticipantAction) => this.emitParticipantsUpdate + (json[1].id, data[2].participants.map(whatsappID), action) + const emitGroupUpdate = (data: Partial) => this.emitGroupUpdate(json[1].id, data) + + switch (data[0]) { + case "promote": + emitGroupParticipantsUpdate('promote') + break + case "demote": + emitGroupParticipantsUpdate('demote') + break + case "desc_add": + emitGroupUpdate({ ...data[2], descOwner: data[1] }) + break + default: + this.logger.debug({ unhandled: true }, json) + break + } + }*/ + }) + + return { + ...sock, + groupMetadata: async(jid: string, minimal: boolean) => { + let result: GroupMetadata + + if(minimal) result = await groupMetadataMinimal(jid) + else result = await groupMetadataFull(jid) + + return result + }, + /** + * Create a group + * @param title like, the title of the group + * @param participants people to include in the group + */ + groupCreate: async (title: string, participants: string[]) => { + const response = await groupQuery('create', null, title, participants) as WAGroupCreateResponse + const gid = response.gid + let metadata: GroupMetadata + try { + metadata = await groupMetadataFull(gid) + } catch (error) { + logger.warn (`error in group creation: ${error}, switching gid & checking`) + // if metadata is not available + const comps = gid.replace ('@g.us', '').split ('-') + response.gid = `${comps[0]}-${+comps[1] + 1}@g.us` + + metadata = await groupMetadataFull(gid) + logger.warn (`group ID switched from ${gid} to ${response.gid}`) + } + ev.emit('chats.upsert', [ + { + id: response.gid!, + name: title, + conversationTimestamp: unixTimestampSeconds(), + unreadCount: 0 + } + ]) + return metadata + }, + /** + * Leave a group + * @param jid the ID of the group + */ + groupLeave: async (id: string) => { + await groupQuery('leave', id) + ev.emit('chats.update', [ { id, readOnly: true } ]) + }, + /** + * Update the subject of the group + * @param {string} jid the ID of the group + * @param {string} title the new title of the group + */ + groupUpdateSubject: async (id: string, title: string) => { + await groupQuery('subject', id, title) + ev.emit('chats.update', [ { id, name: title } ]) + ev.emit('contacts.update', [ { id, name: title } ]) + ev.emit('groups.update', [ { id: id, subject: title } ]) + }, + /** + * Update the group description + * @param {string} jid the ID of the group + * @param {string} title the new title of the group + */ + groupUpdateDescription: async (jid: string, description: string) => { + const metadata = await groupMetadataFull(jid) + const node: BinaryNode = { + tag: 'description', + attrs: {id: generateMessageID(), prev: metadata?.descId}, + content: Buffer.from(description, 'utf-8') + } + + const response = await groupQuery ('description', jid, null, null, [node]) + ev.emit('groups.update', [ { id: jid, desc: description } ]) + return response + }, + /** + * Update participants in the group + * @param jid the ID of the group + * @param participants the people to add + */ + groupParticipantsUpdate: async(id: string, participants: string[], action: ParticipantAction) => { + const result: GroupModificationResponse = await groupQuery(action, id, null, participants) + const jids = Object.keys(result.participants || {}) + ev.emit('group-participants.update', { id, participants: jids, action }) + return jids + }, + /** Query broadcast list info */ + getBroadcastListInfo: async(jid: string) => { + interface WABroadcastListInfo { + status: number + name: string + recipients?: {id: string}[] + } + + const result = await query({ + json: ['query', 'contact', jid], + expect200: true, + requiresPhoneConnection: true + }) as WABroadcastListInfo + + const metadata: GroupMetadata = { + subject: result.name, + id: jid, + creation: undefined, + owner: getState().legacy?.user?.id, + participants: result.recipients!.map(({ id }) => ( + { id: jidNormalizedUser(id), isAdmin: false, isSuperAdmin: false } + )) + } + return metadata + }, + inviteCode: async(jid: string) => { + const response = await sock.query({ + json: ['query', 'inviteCode', jid], + expect200: true, + requiresPhoneConnection: false + }) + return response.code as string + } + } + +} +export default makeGroupsSocket \ No newline at end of file diff --git a/src/LegacySocket/index.ts b/src/LegacySocket/index.ts new file mode 100644 index 0000000..60cd4d4 --- /dev/null +++ b/src/LegacySocket/index.ts @@ -0,0 +1,14 @@ +import { LegacySocketConfig } from '../Types' +import { DEFAULT_LEGACY_CONNECTION_CONFIG } from '../Defaults' +import _makeConnection from './groups' +// export the last socket layer +const makeConnection = (config: Partial) => ( + _makeConnection({ + ...DEFAULT_LEGACY_CONNECTION_CONFIG, + ...config + }) +) + +export type Connection = ReturnType + +export default makeConnection \ No newline at end of file diff --git a/src/LegacySocket/messages.ts b/src/LegacySocket/messages.ts new file mode 100644 index 0000000..026bbc6 --- /dev/null +++ b/src/LegacySocket/messages.ts @@ -0,0 +1,535 @@ +import { BinaryNode, getBinaryNodeMessages, isJidGroup, jidNormalizedUser, areJidsSameUser } from "../WABinary"; +import { Boom } from '@hapi/boom' +import { Chat, WAPresence, WAMessageCursor, WAMessage, LegacySocketConfig, WAMessageKey, ParticipantAction, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo, MessageInfoUpdate, WAMediaUploadFunction, MediaType, WAMessageUpdate } from "../Types"; +import { toNumber, generateWAMessage, decryptMediaMessageBuffer, extractMessageContent, getWAUploadToServer } from "../Utils"; +import makeChatsSocket from "./chats"; +import { DEFAULT_ORIGIN, MEDIA_PATH_MAP, WA_DEFAULT_EPHEMERAL } from "../Defaults"; +import got from "got"; +import { proto } from "../../WAProto"; + +const STATUS_MAP = { + read: WAMessageStatus.READ, + message: WAMessageStatus.DELIVERY_ACK, + error: WAMessageStatus.ERROR +} as { [_: string]: WAMessageStatus } + +const makeMessagesSocket = (config: LegacySocketConfig) => { + const { logger } = config + const sock = makeChatsSocket(config) + const { + ev, + ws: socketEvents, + query, + generateMessageTag, + currentEpoch, + setQuery, + getState + } = sock + + let mediaConn: Promise + const refreshMediaConn = async(forceGet = false) => { + let media = await mediaConn + if (!media || forceGet || (new Date().getTime()-media.fetchDate.getTime()) > media.ttl*1000) { + mediaConn = (async() => { + const {media_conn} = await query({ + json: ['query', 'mediaConn'], + requiresPhoneConnection: false + }) + media_conn.fetchDate = new Date() + return media_conn as MediaConnInfo + })() + } + return mediaConn + } + + const fetchMessagesFromWA = async( + jid: string, + count: number, + cursor?: WAMessageCursor + ) => { + let key: WAMessageKey + if(cursor) { + key = 'before' in cursor ? cursor.before : cursor.after + } + const { content }:BinaryNode = await query({ + json: { + tag: 'query', + attrs: { + epoch: currentEpoch().toString(), + type: 'message', + jid: jid, + kind: !cursor || 'before' in cursor ? 'before' : 'after', + count: count.toString(), + index: key?.id, + owner: key?.fromMe === false ? 'false' : 'true', + } + }, + binaryTag: [WAMetric.queryMessages, WAFlag.ignore], + expect200: false, + requiresPhoneConnection: true + }) + if(Array.isArray(content)) { + return content.map(data => proto.WebMessageInfo.decode(data.content as Buffer)) + } + return [] + } + + const updateMediaMessage = async(message: WAMessage) => { + const content = message.message?.audioMessage || message.message?.videoMessage || message.message?.imageMessage || message.message?.stickerMessage || message.message?.documentMessage + if (!content) throw new Boom( + `given message ${message.key.id} is not a media message`, + { statusCode: 400, data: message } + ) + + const response: BinaryNode = await query ({ + json: { + tag: 'query', + attrs: { + type: 'media', + index: message.key.id, + owner: message.key.fromMe ? 'true' : 'false', + jid: message.key.remoteJid, + epoch: currentEpoch().toString() + } + }, + binaryTag: [WAMetric.queryMedia, WAFlag.ignore], + expect200: true, + requiresPhoneConnection: true + }) + const attrs = response.attrs + Object.assign(content, attrs) // update message + + ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]) + + return response + } + + const onMessage = (message: WAMessage, type: MessageUpdateType | 'update') => { + const jid = message.key.remoteJid! + // store chat updates in this + const chatUpdate: Partial = { + id: jid, + } + + const emitGroupUpdate = (update: Partial) => { + ev.emit('groups.update', [ { id: jid, ...update } ]) + } + + if(message.message) { + chatUpdate.conversationTimestamp = +toNumber(message.messageTimestamp) + // add to count if the message isn't from me & there exists a message + if(!message.key.fromMe) { + chatUpdate.unreadCount = 1 + const participant = jidNormalizedUser(message.participant || jid) + + ev.emit( + 'presence.update', + { + id: jid, + presences: { [participant]: { lastKnownPresence: 'available' } } + } + ) + } + } + + const ephemeralProtocolMsg = message.message?.ephemeralMessage?.message?.protocolMessage + if ( + ephemeralProtocolMsg && + ephemeralProtocolMsg.type === proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING + ) { + chatUpdate.ephemeralSettingTimestamp = message.messageTimestamp + chatUpdate.ephemeralExpiration = ephemeralProtocolMsg.ephemeralExpiration + + if(isJidGroup(jid)) { + emitGroupUpdate({ ephemeralDuration: ephemeralProtocolMsg.ephemeralExpiration || null }) + } + } + const protocolMessage = message.message?.protocolMessage + // if it's a message to delete another message + if (protocolMessage) { + switch (protocolMessage.type) { + case proto.ProtocolMessage.ProtocolMessageType.REVOKE: + const key = protocolMessage.key + const messageStubType = WAMessageStubType.REVOKE + ev.emit('messages.update', [ + { + // the key of the deleted message is updated + update: { message: null, key: message.key, messageStubType }, + key + } + ]) + return + default: + break + } + } + + // check if the message is an action + if (message.messageStubType) { + const { user } = getState().legacy! + //let actor = jidNormalizedUser (message.participant) + let participants: string[] + const emitParticipantsUpdate = (action: ParticipantAction) => ( + ev.emit('group-participants.update', { id: jid, participants, action }) + ) + + switch (message.messageStubType) { + case WAMessageStubType.CHANGE_EPHEMERAL_SETTING: + chatUpdate.ephemeralSettingTimestamp = message.messageTimestamp + chatUpdate.ephemeralExpiration = +message.messageStubParameters[0] + if(isJidGroup(jid)) { + emitGroupUpdate({ ephemeralDuration: +message.messageStubParameters[0] || null }) + } + break + case WAMessageStubType.GROUP_PARTICIPANT_LEAVE: + case WAMessageStubType.GROUP_PARTICIPANT_REMOVE: + participants = message.messageStubParameters.map (jidNormalizedUser) + emitParticipantsUpdate('remove') + // mark the chat read only if you left the group + if (participants.includes(user.id)) { + chatUpdate.readOnly = true + } + break + case WAMessageStubType.GROUP_PARTICIPANT_ADD: + case WAMessageStubType.GROUP_PARTICIPANT_INVITE: + case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN: + participants = message.messageStubParameters.map (jidNormalizedUser) + if (participants.includes(user.id)) { + chatUpdate.readOnly = null + } + emitParticipantsUpdate('add') + break + case WAMessageStubType.GROUP_CHANGE_ANNOUNCE: + const announce = message.messageStubParameters[0] === 'on' + emitGroupUpdate({ announce }) + break + case WAMessageStubType.GROUP_CHANGE_RESTRICT: + const restrict = message.messageStubParameters[0] === 'on' + emitGroupUpdate({ restrict }) + break + case WAMessageStubType.GROUP_CHANGE_SUBJECT: + case WAMessageStubType.GROUP_CREATE: + chatUpdate.name = message.messageStubParameters[0] + emitGroupUpdate({ subject: chatUpdate.name }) + break + } + } + + if(Object.keys(chatUpdate).length > 1) { + ev.emit('chats.update', [chatUpdate]) + } + if(type === 'update') { + ev.emit('messages.update', [ { update: message, key: message.key } ]) + } else { + ev.emit('messages.upsert', { messages: [message], type }) + } + } + + const waUploadToServer = getWAUploadToServer(config, refreshMediaConn) + + /** Query a string to check if it has a url, if it does, return WAUrlInfo */ + const generateUrlInfo = async(text: string) => { + const response: BinaryNode = await query({ + json: { + tag: 'query', + attrs: { + type: 'url', + url: text, + epoch: currentEpoch().toString() + } + }, + binaryTag: [26, WAFlag.ignore], + expect200: true, + requiresPhoneConnection: false + }) + const urlInfo = { ...response.attrs } as any as WAUrlInfo + if(response && response.content) { + urlInfo.jpegThumbnail = response.content as Buffer + } + return urlInfo + } + + /** Relay (send) a WAMessage; more advanced functionality to send a built WA Message, you may want to stick with sendMessage() */ + const relayWAMessage = async(message: WAMessage, { waitForAck } = { waitForAck: true }) => { + const json: BinaryNode = { + tag: 'action', + attrs: { epoch: currentEpoch().toString(), type: 'relay' }, + content: [ + { + tag: 'message', + attrs: {}, + content: proto.WebMessageInfo.encode(message).finish() + } + ] + } + const isMsgToMe = areJidsSameUser(message.key.remoteJid, getState().legacy.user?.id || '') + const flag = isMsgToMe ? WAFlag.acknowledge : WAFlag.ignore // acknowledge when sending message to oneself + const mID = message.key.id + const finalState = isMsgToMe ? WAMessageStatus.READ : WAMessageStatus.SERVER_ACK + + message.status = WAMessageStatus.PENDING + const promise = query({ + json, + binaryTag: [WAMetric.message, flag], + tag: mID, + expect200: true, + requiresPhoneConnection: true + }) + + if(waitForAck) { + await promise + message.status = finalState + } else { + const emitUpdate = (status: WAMessageStatus) => { + message.status = status + ev.emit('messages.update', [ { key: message.key, update: { status } } ]) + } + promise + .then(() => emitUpdate(finalState)) + .catch(() => emitUpdate(WAMessageStatus.ERROR)) + } + + onMessage(message, 'append') + } + + // messages received + const messagesUpdate = (node: BinaryNode, type: 'prepend' | 'last') => { + const messages = getBinaryNodeMessages(node) + messages.reverse() + ev.emit('messages.upsert', { messages, type }) + } + + socketEvents.on('CB:action,add:last', json => messagesUpdate(json, 'last')) + socketEvents.on('CB:action,add:unread', json => messagesUpdate(json, 'prepend')) + socketEvents.on('CB:action,add:before', json => messagesUpdate(json, 'prepend')) + + // new messages + socketEvents.on('CB:action,add:relay,message', (node: BinaryNode) => { + const msgs = getBinaryNodeMessages(node) + for(const msg of msgs) { + onMessage(msg, 'notify') + } + }) + // If a message has been updated (usually called when a video message gets its upload url, or live locations) + socketEvents.on ('CB:action,add:update,message', (node: BinaryNode) => { + const msgs = getBinaryNodeMessages(node) + for(const msg of msgs) { + onMessage(msg, 'update') + } + }) + // message status updates + const onMessageStatusUpdate = ({ content }: BinaryNode) => { + if(Array.isArray(content)) { + const updates: WAMessageUpdate[] = [] + for(const { attrs: json } of content) { + const key: WAMessageKey = { + remoteJid: jidNormalizedUser(json.jid), + id: json.index, + fromMe: json.owner === 'true' + } + const status = STATUS_MAP[json.type] + + if(status) { + updates.push({ key, update: { status } }) + } else { + logger.warn({ content, key }, 'got unknown status update for message') + } + } + ev.emit('messages.update', updates) + } + } + const onMessageInfoUpdate = ([,attributes]: [string,{[_: string]: any}]) => { + let ids = attributes.id as string[] | string + if(typeof ids === 'string') { + ids = [ids] + } + let updateKey: keyof MessageInfoUpdate['update'] + switch(attributes.ack.toString()) { + case '2': + updateKey = 'deliveries' + break + case '3': + updateKey = 'reads' + break + default: + logger.warn({ attributes }, `received unknown message info update`) + return + } + const keyPartial = { + remoteJid: jidNormalizedUser(attributes.to), + fromMe: areJidsSameUser(attributes.from, getState().legacy?.user?.id || ''), + } + const updates = ids.map(id => ({ + key: { ...keyPartial, id }, + update: { + [updateKey]: { [jidNormalizedUser(attributes.participant)]: new Date(+attributes.t) } + } + })) + ev.emit('message-info.update', updates) + // for individual messages + // it means the message is marked read/delivered + if(!isJidGroup(keyPartial.remoteJid)) { + ev.emit('messages.update', ids.map(id => ( + { + key: { ...keyPartial, id }, + update: { + status: updateKey === 'deliveries' ? WAMessageStatus.DELIVERY_ACK : WAMessageStatus.READ + } + } + ))) + } + } + + socketEvents.on('CB:action,add:relay,received', onMessageStatusUpdate) + socketEvents.on('CB:action,,received', onMessageStatusUpdate) + + socketEvents.on('CB:Msg', onMessageInfoUpdate) + socketEvents.on('CB:MsgInfo', onMessageInfoUpdate) + + return { + ...sock, + relayWAMessage, + generateUrlInfo, + messageInfo: async(jid: string, messageID: string) => { + const { content }: BinaryNode = await query({ + json: { + tag: 'query', + attrs: {type: 'message_info', index: messageID, jid: jid, epoch: currentEpoch().toString()} + }, + binaryTag: [WAMetric.queryRead, WAFlag.ignore], + expect200: true, + requiresPhoneConnection: true + }) + const info: MessageInfo = { reads: {}, deliveries: {} } + if(Array.isArray(content)) { + for(const { tag, content: innerData } of content) { + const [{ attrs }] = (innerData as BinaryNode[]) + const jid = jidNormalizedUser(attrs.jid) + const date = new Date(+attrs.t * 1000) + switch(tag) { + case 'read': + info.reads[jid] = date + break + case 'delivery': + info.deliveries[jid] = date + break + } + } + } + return info + }, + downloadMediaMessage: async(message: WAMessage, type: 'buffer' | 'stream' = 'buffer') => { + + const downloadMediaMessage = async () => { + let mContent = extractMessageContent(message.message) + if (!mContent) throw new Boom('No message present', { statusCode: 400, data: message }) + + const stream = await decryptMediaMessageBuffer(mContent) + if(type === 'buffer') { + let buffer = Buffer.from([]) + for await(const chunk of stream) { + buffer = Buffer.concat([buffer, chunk]) + } + return buffer + } + return stream + } + + try { + const result = await downloadMediaMessage() + return result + } catch (error) { + if(error.message.includes('404')) { // media needs to be updated + logger.info (`updating media of message: ${message.key.id}`) + + await updateMediaMessage(message) + + const result = await downloadMediaMessage() + return result + } + throw error + } + }, + updateMediaMessage, + fetchMessagesFromWA, + /** Load a single message specified by the ID */ + loadMessageFromWA: async(jid: string, id: string) => { + let message: WAMessage + + // load the message before the given message + let messages = (await fetchMessagesFromWA(jid, 1, { before: {id, fromMe: true} })) + if(!messages[0]) messages = (await fetchMessagesFromWA(jid, 1, { before: {id, fromMe: false} })) + // the message after the loaded message is the message required + const [actual] = await fetchMessagesFromWA(jid, 1, { after: messages[0] && messages[0].key }) + message = actual + return message + }, + searchMessages: async(txt: string, inJid: string | null, count: number, page: number) => { + const node: BinaryNode = await query({ + json: { + tag: 'query', + attrs: { + epoch: currentEpoch().toString(), + type: 'search', + search: txt, + count: count.toString(), + page: page.toString(), + jid: inJid + } + }, + binaryTag: [24, WAFlag.ignore], + expect200: true + }) // encrypt and send off + + return { + last: node.attrs?.last === 'true', + messages: getBinaryNodeMessages(node) + } + }, + sendWAMessage: async( + jid: string, + content: AnyMessageContent, + options: MiscMessageGenerationOptions & { waitForAck?: boolean } + ) => { + const userJid = getState().legacy.user?.id + if( + typeof content === 'object' && + 'disappearingMessagesInChat' in content && + typeof content['disappearingMessagesInChat'] !== 'undefined' && + isJidGroup(jid) + ) { + const { disappearingMessagesInChat } = content + const value = typeof disappearingMessagesInChat === 'boolean' ? + (disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : + disappearingMessagesInChat + const tag = generateMessageTag(true) + await setQuery([ + { + tag: 'group', + attrs: { id: tag, jid, type: 'prop', author: userJid }, + content: [ + { tag: 'ephemeral', attrs: { value: value.toString() } } + ] + } + ]) + } else { + const msg = await generateWAMessage( + jid, + content, + { + ...options, + logger, + userJid: userJid, + getUrlInfo: generateUrlInfo, + upload: waUploadToServer + } + ) + + await relayWAMessage(msg, { waitForAck: options.waitForAck }) + return msg + } + } + } +} + +export default makeMessagesSocket \ No newline at end of file diff --git a/src/LegacySocket/socket.ts b/src/LegacySocket/socket.ts new file mode 100644 index 0000000..c80fa4e --- /dev/null +++ b/src/LegacySocket/socket.ts @@ -0,0 +1,393 @@ +import { Boom } from '@hapi/boom' +import { STATUS_CODES } from "http" +import { promisify } from "util" +import WebSocket from "ws" +import { BinaryNode, encodeBinaryNode } from "../WABinary" +import { DisconnectReason, LegacySocketConfig, SocketQueryOptions, SocketSendMessageOptions, WAFlag, WAMetric, WATag } from "../Types" +import { aesEncrypt, hmacSign, promiseTimeout, unixTimestampSeconds, decodeWAMessage } from "../Utils" +import { DEFAULT_ORIGIN, DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, PHONE_CONNECTION_CB } from "../Defaults" + +/** + * Connects to WA servers and performs: + * - simple queries (no retry mechanism, wait for connection establishment) + * - listen to messages and emit events + * - query phone connection + */ +export const makeSocket = ({ + waWebSocketUrl, + connectTimeoutMs, + phoneResponseTimeMs, + logger, + agent, + keepAliveIntervalMs, + expectResponseTimeout, +}: LegacySocketConfig) => { + // for generating tags + const referenceDateSeconds = unixTimestampSeconds(new Date()) + const ws = new WebSocket(waWebSocketUrl, undefined, { + origin: DEFAULT_ORIGIN, + timeout: connectTimeoutMs, + agent, + headers: { + 'Accept-Encoding': 'gzip, deflate, br', + 'Accept-Language': 'en-US,en;q=0.9', + 'Cache-Control': 'no-cache', + 'Host': 'web.whatsapp.com', + 'Pragma': 'no-cache', + 'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits', + } + }) + ws.setMaxListeners(0) + let lastDateRecv: Date + let epoch = 0 + let authInfo: { encKey: Buffer, macKey: Buffer } + let keepAliveReq: NodeJS.Timeout + + let phoneCheckInterval: NodeJS.Timeout + let phoneCheckListeners = 0 + + const phoneConnectionChanged = (value: boolean) => { + ws.emit('phone-connection', { value }) + } + + const sendPromise = promisify(ws.send) + /** generate message tag and increment epoch */ + const generateMessageTag = (longTag: boolean = false) => { + const tag = `${longTag ? referenceDateSeconds : (referenceDateSeconds%1000)}.--${epoch}` + epoch += 1 // increment message count, it makes the 'epoch' field when sending binary messages + return tag + } + const sendRawMessage = (data: Buffer | string) => sendPromise.call(ws, data) as Promise + /** + * Send a message to the WA servers + * @returns the tag attached in the message + * */ + const sendMessage = async( + { json, binaryTag, tag, longTag }: SocketSendMessageOptions + ) => { + tag = tag || generateMessageTag(longTag) + let data: Buffer | string + if(logger.level === 'trace') { + logger.trace({ tag, fromMe: true, json, binaryTag }, 'communication') + } + + if(binaryTag) { + if(Array.isArray(json)) { + throw new Boom('Expected BinaryNode with binary code', { statusCode: 400 }) + } + if(!authInfo) { + throw new Boom('No encryption/mac keys to encrypt node with', { statusCode: 400 }) + } + const binary = encodeBinaryNode(json) // encode the JSON to the WhatsApp binary format + + const buff = aesEncrypt(binary, authInfo.encKey) // encrypt it using AES and our encKey + const sign = hmacSign(buff, authInfo.macKey) // sign the message using HMAC and our macKey + + data = Buffer.concat([ + Buffer.from(tag + ','), // generate & prefix the message tag + Buffer.from(binaryTag), // prefix some bytes that tell whatsapp what the message is about + sign, // the HMAC sign of the message + buff, // the actual encrypted buffer + ]) + } else { + data = `${tag},${JSON.stringify(json)}` + } + await sendRawMessage(data) + return tag + } + const end = (error: Error | undefined) => { + logger.debug({ error }, 'connection closed') + + ws.removeAllListeners('close') + ws.removeAllListeners('error') + ws.removeAllListeners('open') + ws.removeAllListeners('message') + + phoneCheckListeners = 0 + clearInterval(keepAliveReq) + clearPhoneCheckInterval() + + if(ws.readyState !== ws.CLOSED && ws.readyState !== ws.CLOSING) { + try { ws.close() } catch { } + } + + ws.emit('ws-close', error) + ws.removeAllListeners('ws-close') + } + const onMessageRecieved = (message: string | Buffer) => { + if(message[0] === '!') { + // when the first character in the message is an '!', the server is sending a pong frame + const timestamp = message.slice(1, message.length).toString ('utf-8') + lastDateRecv = new Date(parseInt(timestamp)) + ws.emit('received-pong') + } else { + let messageTag: string + let json: any + try { + const dec = decodeWAMessage(message, authInfo) + messageTag = dec[0] + json = dec[1] + if (!json) return + } catch (error) { + end(error) + return + } + //if (this.shouldLogMessages) this.messageLog.push ({ tag: messageTag, json: JSON.stringify(json), fromMe: false }) + + if (logger.level === 'trace') { + logger.trace({ tag: messageTag, fromMe: false, json }, 'communication') + } + + let anyTriggered = false + /* Check if this is a response to a message we sent */ + anyTriggered = ws.emit(`${DEF_TAG_PREFIX}${messageTag}`, json) + /* Check if this is a response to a message we are expecting */ + const l0 = json.header || json[0] || '' + const l1 = json?.attributes || json?.[1] || { } + const l2 = json?.data?.[0]?.header || json[2]?.[0] || '' + + Object.keys(l1).forEach(key => { + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, json) || anyTriggered + }) + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0}`, json) || anyTriggered + + if (!anyTriggered && logger.level === 'debug') { + logger.debug({ unhandled: true, tag: messageTag, fromMe: false, json }, 'communication recv') + } + } + } + + /** Exits a query if the phone connection is active and no response is still found */ + const exitQueryIfResponseNotExpected = (tag: string, cancel: (error: Boom) => void) => { + let timeout: NodeJS.Timeout + const listener = ([, connected]) => { + if(connected) { + timeout = setTimeout(() => { + logger.info({ tag }, `cancelling wait for message as a response is no longer expected from the phone`) + cancel(new Boom('Not expecting a response', { statusCode: 422 })) + }, expectResponseTimeout) + ws.off(PHONE_CONNECTION_CB, listener) + } + } + ws.on(PHONE_CONNECTION_CB, listener) + return () => { + ws.off(PHONE_CONNECTION_CB, listener) + timeout && clearTimeout(timeout) + } + } + /** interval is started when a query takes too long to respond */ + const startPhoneCheckInterval = () => { + phoneCheckListeners += 1 + if (!phoneCheckInterval) { + // if its been a long time and we haven't heard back from WA, send a ping + phoneCheckInterval = setInterval(() => { + if(phoneCheckListeners <= 0) { + logger.warn('phone check called without listeners') + return + } + logger.info('checking phone connection...') + sendAdminTest() + + phoneConnectionChanged(false) + }, phoneResponseTimeMs) + } + } + const clearPhoneCheckInterval = () => { + phoneCheckListeners -= 1 + if (phoneCheckListeners <= 0) { + clearInterval(phoneCheckInterval) + phoneCheckInterval = undefined + phoneCheckListeners = 0 + } + } + /** checks for phone connection */ + const sendAdminTest = () => sendMessage({ json: ['admin', 'test'] }) + /** + * Wait for a message with a certain tag to be received + * @param tag the message tag to await + * @param json query that was sent + * @param timeoutMs timeout after which the promise will reject + */ + const waitForMessage = (tag: string, requiresPhoneConnection: boolean, timeoutMs?: number) => { + if(ws.readyState !== ws.OPEN) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } + + let cancelToken = () => { } + + return { + promise: (async() => { + let onRecv: (json) => void + let onErr: (err) => void + let cancelPhoneChecker: () => void + try { + const result = await promiseTimeout(timeoutMs, + (resolve, reject) => { + onRecv = resolve + onErr = err => { + reject(err || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) + } + cancelToken = () => onErr(new Boom('Cancelled', { statusCode: 500 })) + + if(requiresPhoneConnection) { + startPhoneCheckInterval() + cancelPhoneChecker = exitQueryIfResponseNotExpected(tag, onErr) + } + + ws.on(`TAG:${tag}`, onRecv) + ws.on('ws-close', onErr) // if the socket closes, you'll never receive the message + }, + ) + return result as any + } finally { + requiresPhoneConnection && clearPhoneCheckInterval() + cancelPhoneChecker && cancelPhoneChecker() + + ws.off(`TAG:${tag}`, onRecv) + ws.off('ws-close', onErr) // if the socket closes, you'll never receive the message + } + })(), + cancelToken: () => { cancelToken() } + } + } + /** + * Query something from the WhatsApp servers + * @param json the query itself + * @param binaryTags the tags to attach if the query is supposed to be sent encoded in binary + * @param timeoutMs timeout after which the query will be failed (set to null to disable a timeout) + * @param tag the tag to attach to the message + */ + const query = async( + { json, timeoutMs, expect200, tag, longTag, binaryTag, requiresPhoneConnection }: SocketQueryOptions + ) => { + tag = tag || generateMessageTag(longTag) + const { promise, cancelToken } = waitForMessage(tag, requiresPhoneConnection, timeoutMs) + try { + await sendMessage({ json, tag, binaryTag }) + } catch(error) { + cancelToken() + // swallow error + await promise.catch(() => { }) + // throw back the error + throw error + } + + const response = await promise + const responseStatusCode = +(response.status ? response.status : 200) // default status + // read here: http://getstatuscode.com/599 + if(responseStatusCode === 599) { // the connection has gone bad + end(new Boom('WA server overloaded', { statusCode: 599, data: { query: json, response } })) + } + if(expect200 && Math.floor(responseStatusCode/100) !== 2) { + const message = STATUS_CODES[responseStatusCode] || 'unknown' + throw new Boom( + `Unexpected status in '${Array.isArray(json) ? json[0] : (json?.tag || 'query')}': ${message}(${responseStatusCode})`, + { data: { query: json, message }, statusCode: response.status } + ) + } + return response + } + const startKeepAliveRequest = () => ( + keepAliveReq = setInterval(() => { + if (!lastDateRecv) lastDateRecv = new Date() + const diff = Date.now() - lastDateRecv.getTime() + /* + check if it's been a suspicious amount of time since the server responded with our last seen + it could be that the network is down + */ + if (diff > keepAliveIntervalMs+5000) { + end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost })) + } else if(ws.readyState === ws.OPEN) { + sendRawMessage('?,,') // if its all good, send a keep alive request + } else { + logger.warn('keep alive called when WS not open') + } + }, keepAliveIntervalMs) + ) + + const waitForSocketOpen = async() => { + if(ws.readyState === ws.OPEN) return + if(ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } + let onOpen: () => void + let onClose: (err: Error) => void + await new Promise((resolve, reject) => { + onOpen = () => resolve(undefined) + onClose = reject + ws.on('open', onOpen) + ws.on('close', onClose) + ws.on('error', onClose) + }) + .finally(() => { + ws.off('open', onOpen) + ws.off('close', onClose) + ws.off('error', onClose) + }) + } + + ws.on('message', onMessageRecieved) + ws.on('open', () => { + startKeepAliveRequest() + logger.info('Opened WS connection to WhatsApp Web') + }) + ws.on('error', end) + ws.on('close', () => end(new Boom('Connection Terminated', { statusCode: DisconnectReason.connectionLost }))) + + ws.on(PHONE_CONNECTION_CB, json => { + if (!json[1]) { + end(new Boom('Connection terminated by phone', { statusCode: DisconnectReason.connectionLost })) + logger.info('Connection terminated by phone, closing...') + } else { + phoneConnectionChanged(true) + } + }) + ws.on('CB:Cmd,type:disconnect', json => { + const {kind} = json[1] + let reason: DisconnectReason + switch(kind) { + case 'replaced': + reason = DisconnectReason.connectionReplaced + break + default: + reason = DisconnectReason.connectionLost + break + } + end(new Boom( + `Connection terminated by server: "${kind || 'unknown'}"`, + { statusCode: reason } + )) + }) + + return { + ws, + updateKeys: (info: { encKey: Buffer, macKey: Buffer }) => authInfo = info, + waitForSocketOpen, + sendRawMessage, + sendMessage, + generateMessageTag, + waitForMessage, + query, + /** Generic function for action, set queries */ + setQuery: async(nodes: BinaryNode[], binaryTag: WATag = [WAMetric.group, WAFlag.ignore], tag?: string) => { + const json: BinaryNode = { + tag: 'action', + attrs: { epoch: epoch.toString(), type: 'set' }, + content: nodes + } + + return query({ + json, + binaryTag, + tag, + expect200: true, + requiresPhoneConnection: true + }) as Promise<{ status: number }> + }, + currentEpoch: () => epoch, + end + } +} \ No newline at end of file diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index f7d3dd9..0dbf200 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -4,6 +4,7 @@ import { proto } from '../../WAProto' import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch, decodeSyncdSnapshot, newLTHashState } from "../Utils"; import { makeMessagesSocket } from "./messages-send"; import makeMutex from "../Utils/make-mutex"; +import { Boom } from "@hapi/boom"; export const makeChatsSocket = (config: SocketConfig) => { const { logger } = config @@ -424,6 +425,11 @@ export const makeChatsSocket = (config: SocketConfig) => { const appPatch = async(patchCreate: WAPatchCreate) => { const name = patchCreate.type + const myAppStateKeyId = authState.creds.myAppStateKeyId + if(!myAppStateKeyId) { + throw new Boom(`App state key not present!`, { statusCode: 400 }) + } + await mutationMutex.mutex( async() => { logger.debug({ patch: patchCreate }, 'applying app patch') @@ -432,7 +438,7 @@ export const makeChatsSocket = (config: SocketConfig) => { const { [name]: initial } = await authState.keys.get('app-state-sync-version', [name]) const { patch, state } = await encodeSyncdPatch( patchCreate, - authState.creds.myAppStateKeyId!, + myAppStateKeyId, initial, getAppStateSyncKey, ) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 37c51d7..129590b 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -2,7 +2,7 @@ import got from "got" import { Boom } from "@hapi/boom" import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions } from "../Types" -import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESessions } from "../Utils" +import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESessions, getWAUploadToServer } from "../Utils" import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes, JidWithDevice, reduceBinaryNodeToDictionary } from '../WABinary' import { proto } from "../../WAProto" import { WA_DEFAULT_EPHEMERAL, DEFAULT_ORIGIN, MEDIA_PATH_MAP } from "../Defaults" @@ -420,53 +420,8 @@ export const makeMessagesSocket = (config: SocketConfig) => { return msgId } - const waUploadToServer: WAMediaUploadFunction = async(stream, { mediaType, fileEncSha256B64, timeoutMs }) => { - // send a query JSON to obtain the url & auth token to upload our media - let uploadInfo = await refreshMediaConn(false) - - let mediaUrl: string - const hosts = [ ...config.customUploadHosts, ...uploadInfo.hosts.map(h => h.hostname) ] - for (let hostname of hosts) { - const auth = encodeURIComponent(uploadInfo.auth) // the auth token - const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` - - try { - const {body: responseText} = await got.post( - url, - { - headers: { - 'Content-Type': 'application/octet-stream', - 'Origin': DEFAULT_ORIGIN - }, - agent: { - https: config.agent - }, - body: stream, - timeout: timeoutMs - } - ) - const result = JSON.parse(responseText) - mediaUrl = result?.url - - if (mediaUrl) break - else { - uploadInfo = await refreshMediaConn(true) - throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) - } - } catch (error) { - const isLast = hostname === hosts[uploadInfo.hosts.length-1] - logger.debug(`Error in uploading to ${hostname} (${error}) ${isLast ? '' : ', retrying...'}`) - } - } - if (!mediaUrl) { - throw new Boom( - 'Media upload failed on all hosts', - { statusCode: 500 } - ) - } - return { mediaUrl } - } - + const waUploadToServer = getWAUploadToServer(config, refreshMediaConn) + return { ...sock, assertSessions, diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 428b103..3aa0073 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -530,7 +530,7 @@ export const makeSocket = ({ }) ws.on('CB:ib,,downgrade_webclient', () => { - end(new Boom('Multi-device beta not joined', { statusCode: DisconnectReason.notJoinedBeta })) + end(new Boom('Multi-device beta not joined', { statusCode: DisconnectReason.multideviceMismatch })) }) process.nextTick(() => { diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts index 1e9eedd..cd88192 100644 --- a/src/Types/Auth.ts +++ b/src/Types/Auth.ts @@ -1,6 +1,5 @@ import type { Contact } from "./Contact" import type { proto } from "../../WAProto" -import type { WAPatchName } from "./Chat" export type KeyPair = { public: Uint8Array, private: Uint8Array } export type SignedKeyPair = { keyPair: KeyPair, signature: Uint8Array, keyId: number } diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index e5656cb..a959c91 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -38,7 +38,7 @@ export type ChatModification = mute: number | null } | { - clear: 'all' | { message: {id: string, fromMe?: boolean} } + clear: 'all' | { messages: {id: string, fromMe?: boolean}[] } } | { star: { diff --git a/src/Types/Events.ts b/src/Types/Events.ts new file mode 100644 index 0000000..33889a7 --- /dev/null +++ b/src/Types/Events.ts @@ -0,0 +1,56 @@ +import type EventEmitter from "events" + +import { AuthenticationCreds } from './Auth' +import { Chat, PresenceData } from './Chat' +import { Contact } from './Contact' +import { ConnectionState } from './State' + +import { GroupMetadata, ParticipantAction } from './GroupMetadata' +import { MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageUpdate, WAMessageKey } from './Message' + +export type BaileysEventMap = { + /** connection state has been updated -- WS closed, opened, connecting etc. */ + 'connection.update': Partial + /** credentials updated -- some metadata, keys or something */ + 'creds.update': Partial + /** set chats (history sync), messages are reverse chronologically sorted */ + 'chats.set': { chats: Chat[], messages: WAMessage[] } + /** upsert chats */ + 'chats.upsert': Chat[] + /** update the given chats */ + 'chats.update': Partial[] + /** delete chats with given ID */ + 'chats.delete': string[] + /** presence of contact in a chat updated */ + 'presence.update': { id: string, presences: { [participant: string]: PresenceData } } + + 'contacts.upsert': Contact[] + 'contacts.update': Partial[] + + 'messages.delete': { keys: WAMessageKey[] } | { jid: string, all: true } + 'messages.update': WAMessageUpdate[] + /** + * add/update the given messages. If they were received while the connection was online, + * the update will have type: "notify" + * */ + 'messages.upsert': { messages: WAMessage[], type: MessageUpdateType } + + 'message-info.update': MessageInfoUpdate[] + + 'groups.upsert': GroupMetadata[] + 'groups.update': Partial[] + /** apply an action to participants in a group */ + 'group-participants.update': { id: string, participants: string[], action: ParticipantAction } + + 'blocklist.set': { blocklist: string[] } + 'blocklist.update': { blocklist: string[], type: 'add' | 'remove' } +} + +export interface CommonBaileysEventEmitter extends EventEmitter { + on>(event: T, listener: (arg: BaileysEventMap[T]) => void): this + off>(event: T, listener: (arg: BaileysEventMap[T]) => void): this + removeAllListeners>(event: T): this + emit>(event: T, arg: BaileysEventMap[T]): boolean +} + +export type BaileysEventEmitter = CommonBaileysEventEmitter \ No newline at end of file diff --git a/src/Types/Legacy.ts b/src/Types/Legacy.ts new file mode 100644 index 0000000..688c122 --- /dev/null +++ b/src/Types/Legacy.ts @@ -0,0 +1,83 @@ +import { CommonSocketConfig } from "./Socket" +import { CommonBaileysEventEmitter } from "./Events" +import { BinaryNode } from "../WABinary" + +export interface LegacyAuthenticationCreds { + clientID: string + serverToken: string + clientToken: string + encKey: Buffer + macKey: Buffer +} + +/** used for binary messages */ +export enum WAMetric { + debugLog = 1, + queryResume = 2, + liveLocation = 3, + queryMedia = 4, + queryChat = 5, + queryContact = 6, + queryMessages = 7, + presence = 8, + presenceSubscribe = 9, + group = 10, + read = 11, + chat = 12, + received = 13, + picture = 14, + status = 15, + message = 16, + queryActions = 17, + block = 18, + queryGroup = 19, + queryPreview = 20, + queryEmoji = 21, + queryRead = 22, + queryVCard = 29, + queryStatus = 30, + queryStatusUpdate = 31, + queryLiveLocation = 33, + queryLabel = 36, + queryQuickReply = 39 +} + +/** used for binary messages */ +export enum WAFlag { + available = 160, + other = 136, // don't know this one + ignore = 1 << 7, + acknowledge = 1 << 6, + unavailable = 1 << 4, + expires = 1 << 3, + composing = 1 << 2, + recording = 1 << 2, + paused = 1 << 2 +} + +/** Tag used with binary queries */ +export type WATag = [WAMetric, WAFlag] + +export type SocketSendMessageOptions = { + json: BinaryNode | any[] + binaryTag?: WATag + tag?: string + longTag?: boolean +} + +export type SocketQueryOptions = SocketSendMessageOptions & { + timeoutMs?: number + expect200?: boolean + requiresPhoneConnection?: boolean +} + +export type LegacySocketConfig = CommonSocketConfig & { + /** max time for the phone to respond to a connectivity test */ + phoneResponseTimeMs: number + /** max time for WA server to respond before error with 422 */ + expectResponseTimeout: number + + pendingRequestTimeoutMs: number +} + +export type LegacyBaileysEventEmitter = CommonBaileysEventEmitter \ No newline at end of file diff --git a/src/Types/Message.ts b/src/Types/Message.ts index b7b6380..0906901 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -155,7 +155,7 @@ export type MessageContentGenerationOptions = MediaGenerationOptions & { } export type MessageGenerationOptions = MessageContentGenerationOptions & MessageGenerationOptionsFromContent -export type MessageUpdateType = 'append' | 'notify' | 'prepend' +export type MessageUpdateType = 'append' | 'notify' | 'prepend' | 'last' export type MessageInfoEventMap = { [jid: string]: Date } export interface MessageInfo { diff --git a/src/Types/Socket.ts b/src/Types/Socket.ts new file mode 100644 index 0000000..b9d8f42 --- /dev/null +++ b/src/Types/Socket.ts @@ -0,0 +1,39 @@ + +import type { Agent } from "https" +import type { Logger } from "pino" +import type { URL } from "url" +import type NodeCache from 'node-cache' + +export type WAVersion = [number, number, number] +export type WABrowserDescription = [string, string, string] + +export type CommonSocketConfig = { + /** provide an auth state object to maintain the auth state */ + auth?: T + /** the WS url to connect to WA */ + waWebSocketUrl: string | URL + /** Fails the connection if the socket times out in this interval */ + connectTimeoutMs: number + /** Default timeout for queries, undefined for no timeout */ + defaultQueryTimeoutMs: number | undefined + /** ping-pong interval for WS connection */ + keepAliveIntervalMs: number + /** proxy agent */ + agent?: Agent + /** pino logger */ + logger: Logger + /** version to connect with */ + version: WAVersion + /** override browser config */ + browser: WABrowserDescription + /** agent used for fetch requests -- uploading/downloading media */ + fetchAgent?: Agent + /** should the QR be printed in the terminal */ + printQRInTerminal: boolean + /** should events be emitted for actions done by this socket connection */ + emitOwnEvents: boolean + /** provide a cache to store media, so does not have to be re-uploaded */ + mediaCache?: NodeCache + + customUploadHosts: string[] +} diff --git a/src/Types/State.ts b/src/Types/State.ts index 754ff32..e7f0cec 100644 --- a/src/Types/State.ts +++ b/src/Types/State.ts @@ -1,3 +1,5 @@ +import { Contact } from "./Contact" + export type WAConnectionState = 'open' | 'connecting' | 'close' export type ConnectionState = { @@ -13,5 +15,11 @@ export type ConnectionState = { /** the current QR code */ qr?: string /** has the device received all pending notifications while it was offline */ - receivedPendingNotifications?: boolean + receivedPendingNotifications?: boolean + /** legacy connection options */ + legacy?: { + phoneConnected: boolean + user?: Contact + } + } \ No newline at end of file diff --git a/src/Types/index.ts b/src/Types/index.ts index 680190f..641bedb 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -4,11 +4,11 @@ export * from './Chat' export * from './Contact' export * from './State' export * from './Message' +export * from './Legacy' +export * from './Socket' +export * from './Events' import type EventEmitter from "events" -import type { Agent } from "https" -import type { Logger } from "pino" -import type { URL } from "url" import type NodeCache from 'node-cache' import { AuthenticationState, AuthenticationCreds } from './Auth' @@ -19,40 +19,11 @@ import { ConnectionState } from './State' import { GroupMetadata, ParticipantAction } from './GroupMetadata' import { MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageUpdate, WAMessageKey } from './Message' import { proto } from '../../WAProto' +import { CommonSocketConfig } from './Socket' -export type WAVersion = [number, number, number] -export type WABrowserDescription = [string, string, string] -export type ReconnectMode = 'no-reconnects' | 'on-any-error' | 'on-connection-error' - -export type SocketConfig = { - /** provide an auth state object to maintain the auth state */ - auth?: AuthenticationState - /** the WS url to connect to WA */ - waWebSocketUrl: string | URL - /** Fails the connection if the socket times out in this interval */ - connectTimeoutMs: number - /** Default timeout for queries, undefined for no timeout */ - defaultQueryTimeoutMs: number | undefined - /** ping-pong interval for WS connection */ - keepAliveIntervalMs: number - /** proxy agent */ - agent?: Agent - /** pino logger */ - logger: Logger - /** version to connect with */ - version: WAVersion - /** override browser config */ - browser: WABrowserDescription - /** agent used for fetch requests -- uploading/downloading media */ - fetchAgent?: Agent - /** should the QR be printed in the terminal */ - printQRInTerminal: boolean - /** should events be emitted for actions done by this socket connection */ - emitOwnEvents: boolean +export type SocketConfig = CommonSocketConfig & { /** provide a cache to store a user's device list */ userDevicesCache?: NodeCache - /** provide a cache to store media, so does not have to be re-uploaded */ - mediaCache?: NodeCache /** map to store the retry counts for failed messages */ msgRetryCounterMap?: { [msgId: string]: number } /** custom domains to push media via */ @@ -67,11 +38,12 @@ export type SocketConfig = { export enum DisconnectReason { connectionClosed = 428, connectionLost = 408, + connectionReplaced = 440, timedOut = 408, loggedOut = 401, badSession = 500, restartRequired = 410, - notJoinedBeta = 403 + multideviceMismatch = 403 } export type WAInitResponse = { @@ -104,11 +76,11 @@ export type WABusinessProfile = { export type CurveKeyPair = { private: Uint8Array; public: Uint8Array } -export type BaileysEventMap = { +export type BaileysEventMap = { /** connection state has been updated -- WS closed, opened, connecting etc. */ 'connection.update': Partial /** credentials updated -- some metadata, keys or something */ - 'creds.update': Partial + 'creds.update': Partial /** set chats (history sync), messages are reverse chronologically sorted */ 'chats.set': { chats: Chat[], messages: WAMessage[] } /** upsert chats */ @@ -141,9 +113,12 @@ export type BaileysEventMap = { 'blocklist.set': { blocklist: string[] } 'blocklist.update': { blocklist: string[], type: 'add' | 'remove' } } -export interface BaileysEventEmitter extends EventEmitter { - on(event: T, listener: (arg: BaileysEventMap[T]) => void): this - off(event: T, listener: (arg: BaileysEventMap[T]) => void): this - removeAllListeners(event: T): this - emit(event: T, arg: BaileysEventMap[T]): boolean -} \ No newline at end of file + +export interface CommonBaileysEventEmitter extends EventEmitter { + on>(event: T, listener: (arg: BaileysEventMap[T]) => void): this + off>(event: T, listener: (arg: BaileysEventMap[T]) => void): this + removeAllListeners>(event: T): this + emit>(event: T, arg: BaileysEventMap[T]): boolean +} + +export type BaileysEventEmitter = CommonBaileysEventEmitter \ No newline at end of file diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 7d62295..1d324ee 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -480,7 +480,7 @@ export const chatModificationToAppPatch = ( if(mod.clear === 'all') { throw new Boom('not supported') } else { - const key = mod.clear.message + const key = mod.clear.messages[0] patch = { syncAction: { deleteMessageForMeAction: { diff --git a/src/Utils/index.ts b/src/Utils/index.ts index a4c41fe..76448aa 100644 --- a/src/Utils/index.ts +++ b/src/Utils/index.ts @@ -9,4 +9,5 @@ export * from './noise-handler' export * from './history' export * from './chat-utils' export * from './lt-hash' -export * from './auth-utils' \ No newline at end of file +export * from './auth-utils' +export * from './legacy-msgs' \ No newline at end of file diff --git a/src/Utils/legacy-msgs.ts b/src/Utils/legacy-msgs.ts new file mode 100644 index 0000000..1da5b82 --- /dev/null +++ b/src/Utils/legacy-msgs.ts @@ -0,0 +1,142 @@ +import { Boom } from '@hapi/boom' +import { randomBytes } from 'crypto' +import { decodeBinaryNode, jidNormalizedUser } from "../WABinary" +import { aesDecrypt, hmacSign, hkdf, Curve } from "./crypto" +import { DisconnectReason, WATag, LegacyAuthenticationCreds, CurveKeyPair, Contact } from "../Types" + +export const newLegacyAuthCreds = () => ({ + clientID: randomBytes(16).toString('base64') +}) as LegacyAuthenticationCreds + +export const decodeWAMessage = ( + message: string | Buffer, + auth: { macKey: Buffer, encKey: Buffer }, + fromMe: boolean=false +) => { + + let commaIndex = message.indexOf(',') // all whatsapp messages have a tag and a comma, followed by the actual message + if (commaIndex < 0) throw new Boom('invalid message', { data: message }) // if there was no comma, then this message must be not be valid + + if (message[commaIndex+1] === ',') commaIndex += 1 + let data = message.slice(commaIndex+1, message.length) + + // get the message tag. + // If a query was done, the server will respond with the same message tag we sent the query with + const messageTag: string = message.slice(0, commaIndex).toString() + let json: any + let tags: WATag + if (data.length > 0) { + if (typeof data === 'string') { + json = JSON.parse(data) // parse the JSON + } else { + const { macKey, encKey } = auth || {} + if (!macKey || !encKey) { + throw new Boom('recieved encrypted buffer when auth creds unavailable', { data: message, statusCode: DisconnectReason.badSession }) + } + /* + If the data recieved was not a JSON, then it must be an encrypted message. + Such a message can only be decrypted if we're connected successfully to the servers & have encryption keys + */ + if (fromMe) { + tags = [data[0], data[1]] + data = data.slice(2, data.length) + } + + const checksum = data.slice(0, 32) // the first 32 bytes of the buffer are the HMAC sign of the message + data = data.slice(32, data.length) // the actual message + const computedChecksum = hmacSign(data, macKey) // compute the sign of the message we recieved using our macKey + + if (checksum.equals(computedChecksum)) { + // the checksum the server sent, must match the one we computed for the message to be valid + const decrypted = aesDecrypt(data, encKey) // decrypt using AES + json = decodeBinaryNode(decrypted) // decode the binary message into a JSON array + } else { + throw new Boom('Bad checksum', { + data: { + received: checksum.toString('hex'), + computed: computedChecksum.toString('hex'), + data: data.slice(0, 80).toString(), + tag: messageTag, + message: message.slice(0, 80).toString() + }, + statusCode: DisconnectReason.badSession + }) + } + } + } + return [messageTag, json, tags] as const +} + +/** +* Once the QR code is scanned and we can validate our connection, or we resolved the challenge when logging back in +* @private +* @param json +*/ +export const validateNewConnection = ( + json: { [_: string]: any }, + auth: LegacyAuthenticationCreds, + curveKeys: CurveKeyPair +) => { + // set metadata: one's WhatsApp ID [cc][number]@s.whatsapp.net, name on WhatsApp, info about the phone + const onValidationSuccess = () => { + const user: Contact = { + id: jidNormalizedUser(json.wid), + name: json.pushname + } + return { user, auth, phone: json.phone } + } + if (!json.secret) { + // if we didn't get a secret, we don't need it, we're validated + if (json.clientToken && json.clientToken !== auth.clientToken) { + auth = { ...auth, clientToken: json.clientToken } + } + if (json.serverToken && json.serverToken !== auth.serverToken) { + auth = { ...auth, serverToken: json.serverToken } + } + return onValidationSuccess() + } + const secret = Buffer.from(json.secret, 'base64') + if (secret.length !== 144) { + throw new Error ('incorrect secret length received: ' + secret.length) + } + + // generate shared key from our private key & the secret shared by the server + const sharedKey = Curve.sharedKey(curveKeys.private, secret.slice(0, 32)) + // expand the key to 80 bytes using HKDF + const expandedKey = hkdf(sharedKey as Buffer, 80, { }) + + // perform HMAC validation. + const hmacValidationKey = expandedKey.slice(32, 64) + const hmacValidationMessage = Buffer.concat([secret.slice(0, 32), secret.slice(64, secret.length)]) + + const hmac = hmacSign(hmacValidationMessage, hmacValidationKey) + + if (!hmac.equals(secret.slice(32, 64))) { + // if the checksums didn't match + throw new Boom('HMAC validation failed', { statusCode: 400 }) + } + + // computed HMAC should equal secret[32:64] + // expandedKey[64:] + secret[64:] are the keys, encrypted using AES, that are used to encrypt/decrypt the messages recieved from WhatsApp + // they are encrypted using key: expandedKey[0:32] + const encryptedAESKeys = Buffer.concat([ + expandedKey.slice(64, expandedKey.length), + secret.slice(64, secret.length), + ]) + const decryptedKeys = aesDecrypt(encryptedAESKeys, expandedKey.slice(0, 32)) + // set the credentials + auth = { + encKey: decryptedKeys.slice(0, 32), // first 32 bytes form the key to encrypt/decrypt messages + macKey: decryptedKeys.slice(32, 64), // last 32 bytes from the key to sign messages + clientToken: json.clientToken, + serverToken: json.serverToken, + clientID: auth.clientID, + } + return onValidationSuccess() +} + +export const computeChallengeResponse = (challenge: string, auth: LegacyAuthenticationCreds) => { + const bytes = Buffer.from(challenge, 'base64') // decode the base64 encoded challenge string + const signed = hmacSign(bytes, auth.macKey).toString('base64') // sign the challenge string with our macKey + return[ 'admin', 'challenge', signed, auth.serverToken, auth.clientID] // prepare to send this signed string with the serverToken & clientID +} \ No newline at end of file diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index e20b847..86c50c9 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -10,10 +10,10 @@ import { URL } from 'url' import { join } from 'path' import { once } from 'events' import got, { Options, Response } from 'got' -import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType, DownloadableMessage } from '../Types' +import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType, DownloadableMessage, WAMediaUploadFunction, MediaConnInfo, CommonSocketConfig } from '../Types' import { generateMessageID } from './generics' import { hkdf } from './crypto' -import { DEFAULT_ORIGIN } from '../Defaults' +import { DEFAULT_ORIGIN, MEDIA_PATH_MAP } from '../Defaults' export const hkdfInfoKey = (type: MediaType) => { let str: string = type @@ -389,4 +389,53 @@ export function extensionForMediaMessage(message: WAMessageContent) { extension = getExtension (messageContent.mimetype) } return extension +} + +export const getWAUploadToServer = ({ customUploadHosts, agent, logger }: CommonSocketConfig, refreshMediaConn: (force: boolean) => Promise): WAMediaUploadFunction => { + return async(stream, { mediaType, fileEncSha256B64, timeoutMs }) => { + // send a query JSON to obtain the url & auth token to upload our media + let uploadInfo = await refreshMediaConn(false) + + let mediaUrl: string + const hosts = [ ...customUploadHosts, ...uploadInfo.hosts.map(h => h.hostname) ] + for (let hostname of hosts) { + const auth = encodeURIComponent(uploadInfo.auth) // the auth token + const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` + + try { + const {body: responseText} = await got.post( + url, + { + headers: { + 'Content-Type': 'application/octet-stream', + 'Origin': DEFAULT_ORIGIN + }, + agent: { + https: agent + }, + body: stream, + timeout: timeoutMs + } + ) + const result = JSON.parse(responseText) + mediaUrl = result?.url + + if (mediaUrl) break + else { + uploadInfo = await refreshMediaConn(true) + throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) + } + } catch (error) { + const isLast = hostname === hosts[uploadInfo.hosts.length-1] + logger.debug(`Error in uploading to ${hostname} (${error}) ${isLast ? '' : ', retrying...'}`) + } + } + if (!mediaUrl) { + throw new Boom( + 'Media upload failed on all hosts', + { statusCode: 500 } + ) + } + return { mediaUrl } + } } \ No newline at end of file diff --git a/src/WABinary/index.ts b/src/WABinary/index.ts index 644a870..1423573 100644 --- a/src/WABinary/index.ts +++ b/src/WABinary/index.ts @@ -2,6 +2,7 @@ import { DICTIONARIES_MAP, SINGLE_BYTE_TOKEN, SINGLE_BYTE_TOKEN_MAP, DICTIONARIE import { jidDecode, jidEncode } from './jid-utils'; import { Binary, numUtf8Bytes } from '../../WABinary/Binary'; import { Boom } from '@hapi/boom'; +import { proto } from '../../WAProto'; const LIST1 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '.', '�', '�', '�', '�']; const LIST2 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']; @@ -319,5 +320,17 @@ export const reduceBinaryNodeToDictionary = (node: BinaryNode, tag: string) => { return dict } +export const getBinaryNodeMessages = ({ content }: BinaryNode) => { + const msgs: proto.WebMessageInfo[] = [] + if(Array.isArray(content)) { + for(const item of content) { + if(item.tag === 'message') { + msgs.push(proto.WebMessageInfo.decode(item.content as Buffer)) + } + } + } + return msgs +} + export * from './jid-utils' export { Binary } from '../../WABinary/Binary' \ No newline at end of file From d8b415a075079d05e93f617dcc58c6293e178b96 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 17 Dec 2021 19:30:10 +0530 Subject: [PATCH 229/311] fix: merge conflict errors --- src/Utils/messages-media.ts | 91 +++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index e63838b..8a1f077 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -4,13 +4,13 @@ import type { Options, Response } from 'got' import { Boom } from '@hapi/boom' import * as Crypto from 'crypto' import { Readable, Transform } from 'stream' -import { createReadStream, createWriteStream, promises as fs, ReadStream, WriteStream } from 'fs' +import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs' import { exec } from 'child_process' import { tmpdir } from 'os' import { URL } from 'url' import { join } from 'path' import { once } from 'events' -import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType, DownloadableMessage } from '../Types' +import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType, DownloadableMessage, CommonSocketConfig, WAMediaUploadFunction, MediaConnInfo } from '../Types' import { generateMessageID } from './generics' import { hkdf } from './crypto' import { DEFAULT_ORIGIN, MEDIA_PATH_MAP } from '../Defaults' @@ -463,49 +463,54 @@ export function extensionForMediaMessage(message: WAMessageContent) { export const getWAUploadToServer = ({ customUploadHosts, agent, logger }: CommonSocketConfig, refreshMediaConn: (force: boolean) => Promise): WAMediaUploadFunction => { return async(stream, { mediaType, fileEncSha256B64, timeoutMs }) => { + const { default: got } = await import('got') // send a query JSON to obtain the url & auth token to upload our media - let uploadInfo = await refreshMediaConn(false) - - let mediaUrl: string + let uploadInfo = await refreshMediaConn(false) + + let urls: { mediaUrl: string, directPath: string } const hosts = [ ...customUploadHosts, ...uploadInfo.hosts.map(h => h.hostname) ] - for (let hostname of hosts) { - const auth = encodeURIComponent(uploadInfo.auth) // the auth token - const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` - - try { - const {body: responseText} = await got.post( - url, - { - headers: { - 'Content-Type': 'application/octet-stream', - 'Origin': DEFAULT_ORIGIN - }, - agent: { - https: agent - }, - body: stream, + for (let hostname of hosts) { + const auth = encodeURIComponent(uploadInfo.auth) // the auth token + const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` + + try { + const {body: responseText} = await got.post( + url, + { + headers: { + 'Content-Type': 'application/octet-stream', + 'Origin': DEFAULT_ORIGIN + }, + agent: { + https: agent + }, + body: stream, timeout: timeoutMs + } + ) + const result = JSON.parse(responseText) + + if(result?.url || result?.directPath) { + urls = { + mediaUrl: result.url, + directPath: result.direct_path } - ) - const result = JSON.parse(responseText) - mediaUrl = result?.url - - if (mediaUrl) break - else { - uploadInfo = await refreshMediaConn(true) - throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) - } - } catch (error) { - const isLast = hostname === hosts[uploadInfo.hosts.length-1] - logger.debug(`Error in uploading to ${hostname} (${error}) ${isLast ? '' : ', retrying...'}`) - } - } - if (!mediaUrl) { - throw new Boom( - 'Media upload failed on all hosts', - { statusCode: 500 } - ) - } - return { mediaUrl } - } + break + } else { + uploadInfo = await refreshMediaConn(true) + throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) + } + } catch (error) { + const isLast = hostname === hosts[uploadInfo.hosts.length-1] + logger.debug(`Error in uploading to ${hostname} (${error}) ${isLast ? '' : ', retrying...'}`) + } + } + if (!urls) { + throw new Boom( + 'Media upload failed on all hosts', + { statusCode: 500 } + ) + } + return urls + } } \ No newline at end of file From c803e22e8a143f118477f1dc3802e9bb0ba90496 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 17 Dec 2021 20:58:33 +0530 Subject: [PATCH 230/311] feat: functional legacy socket --- Example/example-legacy.ts | 64 ++++++ package.json | 1 + src/Defaults/index.ts | 18 +- src/LegacySocket/auth.ts | 8 +- src/LegacySocket/chats.ts | 6 +- src/LegacySocket/index.ts | 10 +- src/LegacySocket/messages.ts | 17 +- src/LegacySocket/socket.ts | 14 +- src/Socket/messages-send.ts | 3 +- src/Utils/legacy-msgs.ts | 47 ++++- src/WABinary/Legacy/constants.ts | 198 ++++++++++++++++++ src/WABinary/Legacy/index.ts | 337 +++++++++++++++++++++++++++++++ src/WABinary/index.ts | 19 +- src/WABinary/types.ts | 14 ++ src/index.ts | 5 + 15 files changed, 695 insertions(+), 66 deletions(-) create mode 100644 Example/example-legacy.ts create mode 100644 src/WABinary/Legacy/constants.ts create mode 100644 src/WABinary/Legacy/index.ts create mode 100644 src/WABinary/types.ts diff --git a/Example/example-legacy.ts b/Example/example-legacy.ts new file mode 100644 index 0000000..06c6fd0 --- /dev/null +++ b/Example/example-legacy.ts @@ -0,0 +1,64 @@ +import P from "pino" +import { Boom } from "@hapi/boom" +import { makeWALegacySocket, DisconnectReason, AnyMessageContent, delay, useSingleFileLegacyAuthState } from '../src' + +const { state, saveState } = useSingleFileLegacyAuthState('./auth_info.json') + +// start a connection +const startSock = () => { + + const sock = makeWALegacySocket({ + logger: P({ level: 'debug' }), + printQRInTerminal: true, + auth: state + }) + + const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { + await sock.presenceSubscribe(jid) + await delay(500) + + await sock.sendPresenceUpdate('composing', jid) + await delay(2000) + + await sock.sendPresenceUpdate('paused', jid) + + await sock.sendWAMessage(jid, msg) + } + + sock.ev.on('messages.upsert', async m => { + console.log(JSON.stringify(m, undefined, 2)) + + const msg = m.messages[0] + if(!msg.key.fromMe && m.type === 'notify') { + console.log('replying to', m.messages[0].key.remoteJid) + await sock!.chatRead(msg.key, 1) + await sendMessageWTyping({ text: 'Hello there!' }, msg.key.remoteJid) + } + + }) + + sock.ev.on('messages.update', m => console.log(m)) + sock.ev.on('presence.update', m => console.log(m)) + sock.ev.on('chats.update', m => console.log(m)) + sock.ev.on('contacts.update', m => console.log(m)) + + sock.ev.on('connection.update', (update) => { + const { connection, lastDisconnect } = update + if(connection === 'close') { + // reconnect if not logged out + if((lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut) { + startSock() + } else { + console.log('connection closed') + } + } + + console.log('connection update', update) + }) + // listen for when the auth credentials is updated + sock.ev.on('creds.update', saveState) + + return sock +} + +startSock() \ No newline at end of file diff --git a/package.json b/package.json index ec31289..05b3875 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "build:docs": "typedoc", "build:tsc": "tsc", "example": "node --inspect -r ts-node/register Example/example.ts", + "example:legacy": "node --inspect -r ts-node/register Example/example-legacy.ts", "gen-protobuf": "bash src/BinaryNode/GenerateStatics.sh", "browser-decode": "yarn ts-node src/BrowserMessageDecoding.ts" }, diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 6cb9c8c..dba9ff9 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -18,10 +18,10 @@ export const NOISE_WA_HEADER = new Uint8Array([87, 65, 5, 2]) // last is "DICT_V export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi const BASE_CONNECTION_CONFIG: CommonSocketConfig = { - version: [2, 2146, 9], + version: [2, 2147, 16], browser: Browsers.baileys('Chrome'), - waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', + waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', connectTimeoutMs: 20_000, keepAliveIntervalMs: 25_000, logger: P().child({ class: 'baileys' }), @@ -33,21 +33,13 @@ const BASE_CONNECTION_CONFIG: CommonSocketConfig = { export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { ...BASE_CONNECTION_CONFIG, + waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', getMessage: async() => undefined } export const DEFAULT_LEGACY_CONNECTION_CONFIG: LegacySocketConfig = { - version: [2, 2146, 9], - browser: Browsers.baileys('Chrome'), - - waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', - connectTimeoutMs: 20_000, - keepAliveIntervalMs: 25_000, - logger: P().child({ class: 'baileys' }), - printQRInTerminal: false, - emitOwnEvents: true, - defaultQueryTimeoutMs: 60_000, - customUploadHosts: [], + ...BASE_CONNECTION_CONFIG, + waWebSocketUrl: 'wss://web.whatsapp.com/ws', phoneResponseTimeMs: 20_000, expectResponseTimeout: 60_000, pendingRequestTimeoutMs: 60_000 diff --git a/src/LegacySocket/auth.ts b/src/LegacySocket/auth.ts index 21b06a5..fbae0b4 100644 --- a/src/LegacySocket/auth.ts +++ b/src/LegacySocket/auth.ts @@ -16,7 +16,7 @@ const makeAuthSocket = (config: LegacySocketConfig) => { } = config const ev = new EventEmitter() as LegacyBaileysEventEmitter - let authInfo = initialAuthInfo || newLegacyAuthCreds() + const authInfo = initialAuthInfo || newLegacyAuthCreds() const state: ConnectionState = { legacy: { @@ -73,7 +73,6 @@ const makeAuthSocket = (config: LegacySocketConfig) => { socket?.end( new Boom('Logged Out', { statusCode: DisconnectReason.loggedOut }) ) - authInfo = undefined } /** Waits for the connection to WA to open up */ const waitForConnection = async(waitInfinitely: boolean = false) => { @@ -221,11 +220,13 @@ const makeAuthSocket = (config: LegacySocketConfig) => { const {user, auth} = validateNewConnection(response[1], authInfo, curveKeys)// validate the connection const isNewLogin = user.id !== state.legacy!.user?.id - authInfo = auth + Object.assign(authInfo, auth) updateEncKeys() logger.info({ user }, 'logged in') + ev.emit('creds.update', auth) + updateState({ connection: 'open', legacy: { @@ -235,7 +236,6 @@ const makeAuthSocket = (config: LegacySocketConfig) => { isNewLogin, qr: undefined }) - ev.emit('creds.update', auth) } ws.once('open', async() => { try { diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index ea67f99..67d8c00 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -152,7 +152,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { const chats = data.map(({ attrs }): Chat => { return { id: jidNormalizedUser(attrs.jid), - conversationTimestamp: +attrs.t, + conversationTimestamp: attrs.t ? +attrs.t : undefined, unreadCount: +attrs.count, archive: attrs.archive === 'true' ? true : undefined, pin: attrs.pin ? +attrs.pin : undefined, @@ -353,7 +353,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { * @param jid the ID of the person/group who you are updating * @param type your presence */ - updatePresence: (jid: string | undefined, type: WAPresence) => ( + sendPresenceUpdate: ( type: WAPresence, jid: string | undefined) => ( sendMessage({ binaryTag: [WAMetric.presence, WAFlag[type]], // weird stuff WA does json: { @@ -372,7 +372,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { * Request updates on the presence of a user * this returns nothing, you'll receive updates in chats.update event * */ - requestPresenceUpdate: async (jid: string) => ( + presenceSubscribe: async (jid: string) => ( sendMessage({ json: ['action', 'presence', 'subscribe', jid] }) ), /** Query the status of the person (see groupMetadata() for groups) */ diff --git a/src/LegacySocket/index.ts b/src/LegacySocket/index.ts index 60cd4d4..3f1f7bf 100644 --- a/src/LegacySocket/index.ts +++ b/src/LegacySocket/index.ts @@ -1,14 +1,12 @@ import { LegacySocketConfig } from '../Types' import { DEFAULT_LEGACY_CONNECTION_CONFIG } from '../Defaults' -import _makeConnection from './groups' +import _makeLegacySocket from './groups' // export the last socket layer -const makeConnection = (config: Partial) => ( - _makeConnection({ +const makeLegacySocket = (config: Partial) => ( + _makeLegacySocket({ ...DEFAULT_LEGACY_CONNECTION_CONFIG, ...config }) ) -export type Connection = ReturnType - -export default makeConnection \ No newline at end of file +export default makeLegacySocket \ No newline at end of file diff --git a/src/LegacySocket/messages.ts b/src/LegacySocket/messages.ts index 026bbc6..83d6f58 100644 --- a/src/LegacySocket/messages.ts +++ b/src/LegacySocket/messages.ts @@ -1,10 +1,9 @@ import { BinaryNode, getBinaryNodeMessages, isJidGroup, jidNormalizedUser, areJidsSameUser } from "../WABinary"; import { Boom } from '@hapi/boom' -import { Chat, WAPresence, WAMessageCursor, WAMessage, LegacySocketConfig, WAMessageKey, ParticipantAction, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo, MessageInfoUpdate, WAMediaUploadFunction, MediaType, WAMessageUpdate } from "../Types"; +import { Chat, WAMessageCursor, WAMessage, LegacySocketConfig, WAMessageKey, ParticipantAction, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo, MessageInfoUpdate, WAMessageUpdate } from "../Types"; import { toNumber, generateWAMessage, decryptMediaMessageBuffer, extractMessageContent, getWAUploadToServer } from "../Utils"; import makeChatsSocket from "./chats"; -import { DEFAULT_ORIGIN, MEDIA_PATH_MAP, WA_DEFAULT_EPHEMERAL } from "../Defaults"; -import got from "got"; +import { WA_DEFAULT_EPHEMERAL } from "../Defaults"; import { proto } from "../../WAProto"; const STATUS_MAP = { @@ -288,8 +287,9 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { .then(() => emitUpdate(finalState)) .catch(() => emitUpdate(WAMessageStatus.ERROR)) } - - onMessage(message, 'append') + if(config.emitOwnEvents) { + onMessage(message, 'append') + } } // messages received @@ -362,7 +362,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { const updates = ids.map(id => ({ key: { ...keyPartial, id }, update: { - [updateKey]: { [jidNormalizedUser(attributes.participant)]: new Date(+attributes.t) } + [updateKey]: { [jidNormalizedUser(attributes.participant || attributes.to)]: new Date(+attributes.t) } } })) ev.emit('message-info.update', updates) @@ -489,7 +489,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { sendWAMessage: async( jid: string, content: AnyMessageContent, - options: MiscMessageGenerationOptions & { waitForAck?: boolean } + options: MiscMessageGenerationOptions & { waitForAck?: boolean } = { waitForAck: true } ) => { const userJid = getState().legacy.user?.id if( @@ -521,7 +521,8 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { logger, userJid: userJid, getUrlInfo: generateUrlInfo, - upload: waUploadToServer + upload: waUploadToServer, + mediaCache: config.mediaCache } ) diff --git a/src/LegacySocket/socket.ts b/src/LegacySocket/socket.ts index c80fa4e..5f7c3bf 100644 --- a/src/LegacySocket/socket.ts +++ b/src/LegacySocket/socket.ts @@ -2,7 +2,7 @@ import { Boom } from '@hapi/boom' import { STATUS_CODES } from "http" import { promisify } from "util" import WebSocket from "ws" -import { BinaryNode, encodeBinaryNode } from "../WABinary" +import { BinaryNode, encodeBinaryNodeLegacy } from "../WABinary" import { DisconnectReason, LegacySocketConfig, SocketQueryOptions, SocketSendMessageOptions, WAFlag, WAMetric, WATag } from "../Types" import { aesEncrypt, hmacSign, promiseTimeout, unixTimestampSeconds, decodeWAMessage } from "../Utils" import { DEFAULT_ORIGIN, DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, PHONE_CONNECTION_CB } from "../Defaults" @@ -78,7 +78,7 @@ export const makeSocket = ({ if(!authInfo) { throw new Boom('No encryption/mac keys to encrypt node with', { statusCode: 400 }) } - const binary = encodeBinaryNode(json) // encode the JSON to the WhatsApp binary format + const binary = encodeBinaryNodeLegacy(json) // encode the JSON to the WhatsApp binary format const buff = aesEncrypt(binary, authInfo.encKey) // encrypt it using AES and our encKey const sign = hmacSign(buff, authInfo.macKey) // sign the message using HMAC and our macKey @@ -115,9 +115,9 @@ export const makeSocket = ({ ws.removeAllListeners('ws-close') } const onMessageRecieved = (message: string | Buffer) => { - if(message[0] === '!') { + if(message[0] === '!' || message[0] === '!'.charCodeAt(0)) { // when the first character in the message is an '!', the server is sending a pong frame - const timestamp = message.slice(1, message.length).toString ('utf-8') + const timestamp = message.slice(1, message.length).toString() lastDateRecv = new Date(parseInt(timestamp)) ws.emit('received-pong') } else { @@ -142,9 +142,9 @@ export const makeSocket = ({ /* Check if this is a response to a message we sent */ anyTriggered = ws.emit(`${DEF_TAG_PREFIX}${messageTag}`, json) /* Check if this is a response to a message we are expecting */ - const l0 = json.header || json[0] || '' - const l1 = json?.attributes || json?.[1] || { } - const l2 = json?.data?.[0]?.header || json[2]?.[0] || '' + const l0 = json.tag || json[0] || '' + const l1 = json?.attrs || json?.[1] || { } + const l2 = json?.content?.[0]?.tag || json[2]?.[0] || '' Object.keys(l1).forEach(key => { anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, json) || anyTriggered diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index c703773..dcc8a2f 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -1,10 +1,9 @@ -import { Boom } from "@hapi/boom" import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions } from "../Types" import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESessions, getWAUploadToServer } from "../Utils" import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes, JidWithDevice, reduceBinaryNodeToDictionary } from '../WABinary' import { proto } from "../../WAProto" -import { WA_DEFAULT_EPHEMERAL, DEFAULT_ORIGIN, MEDIA_PATH_MAP } from "../Defaults" +import { WA_DEFAULT_EPHEMERAL } from "../Defaults" import { makeGroupsSocket } from "./groups" import NodeCache from "node-cache" diff --git a/src/Utils/legacy-msgs.ts b/src/Utils/legacy-msgs.ts index 1da5b82..ba60d2b 100644 --- a/src/Utils/legacy-msgs.ts +++ b/src/Utils/legacy-msgs.ts @@ -1,7 +1,8 @@ import { Boom } from '@hapi/boom' import { randomBytes } from 'crypto' -import { decodeBinaryNode, jidNormalizedUser } from "../WABinary" +import { decodeBinaryNodeLegacy, jidNormalizedUser } from "../WABinary" import { aesDecrypt, hmacSign, hkdf, Curve } from "./crypto" +import { BufferJSON } from './generics' import { DisconnectReason, WATag, LegacyAuthenticationCreds, CurveKeyPair, Contact } from "../Types" export const newLegacyAuthCreds = () => ({ @@ -9,11 +10,10 @@ export const newLegacyAuthCreds = () => ({ }) as LegacyAuthenticationCreds export const decodeWAMessage = ( - message: string | Buffer, + message: Buffer | string, auth: { macKey: Buffer, encKey: Buffer }, fromMe: boolean=false ) => { - let commaIndex = message.indexOf(',') // all whatsapp messages have a tag and a comma, followed by the actual message if (commaIndex < 0) throw new Boom('invalid message', { data: message }) // if there was no comma, then this message must be not be valid @@ -25,10 +25,12 @@ export const decodeWAMessage = ( const messageTag: string = message.slice(0, commaIndex).toString() let json: any let tags: WATag - if (data.length > 0) { - if (typeof data === 'string') { - json = JSON.parse(data) // parse the JSON + if(data.length) { + const possiblyEnc = (data.length > 32 && data.length % 16 === 0) + if(typeof data === 'string' || !possiblyEnc) { + json = JSON.parse(data.toString()) // parse the JSON } else { + const { macKey, encKey } = auth || {} if (!macKey || !encKey) { throw new Boom('recieved encrypted buffer when auth creds unavailable', { data: message, statusCode: DisconnectReason.badSession }) @@ -49,7 +51,7 @@ export const decodeWAMessage = ( if (checksum.equals(computedChecksum)) { // the checksum the server sent, must match the one we computed for the message to be valid const decrypted = aesDecrypt(data, encKey) // decrypt using AES - json = decodeBinaryNode(decrypted) // decode the binary message into a JSON array + json = decodeBinaryNodeLegacy(decrypted, { index: 0 }) // decode the binary message into a JSON array } else { throw new Boom('Bad checksum', { data: { @@ -138,5 +140,34 @@ export const validateNewConnection = ( export const computeChallengeResponse = (challenge: string, auth: LegacyAuthenticationCreds) => { const bytes = Buffer.from(challenge, 'base64') // decode the base64 encoded challenge string const signed = hmacSign(bytes, auth.macKey).toString('base64') // sign the challenge string with our macKey - return[ 'admin', 'challenge', signed, auth.serverToken, auth.clientID] // prepare to send this signed string with the serverToken & clientID + return['admin', 'challenge', signed, auth.serverToken, auth.clientID] // prepare to send this signed string with the serverToken & clientID +} + +export const useSingleFileLegacyAuthState = (file: string) => { + // require fs here so that in case "fs" is not available -- the app does not crash + const { readFileSync, writeFileSync, existsSync } = require('fs') + let state: LegacyAuthenticationCreds + + if(existsSync(file)) { + state = JSON.parse( + readFileSync(file, { encoding: 'utf-8' }), + BufferJSON.reviver + ) + if(typeof state.encKey === 'string') { + state.encKey = Buffer.from(state.encKey, 'base64') + } + if(typeof state.macKey === 'string') { + state.macKey = Buffer.from(state.macKey, 'base64') + } + } else { + state = newLegacyAuthCreds() + } + + return { + state, + saveState: () => { + const str = JSON.stringify(state, BufferJSON.replacer, 2) + writeFileSync(file, str) + } + } } \ No newline at end of file diff --git a/src/WABinary/Legacy/constants.ts b/src/WABinary/Legacy/constants.ts new file mode 100644 index 0000000..a9be6d6 --- /dev/null +++ b/src/WABinary/Legacy/constants.ts @@ -0,0 +1,198 @@ + +export const Tags = { + LIST_EMPTY: 0, + STREAM_END: 2, + DICTIONARY_0: 236, + DICTIONARY_1: 237, + DICTIONARY_2: 238, + DICTIONARY_3: 239, + LIST_8: 248, + LIST_16: 249, + JID_PAIR: 250, + HEX_8: 251, + BINARY_8: 252, + BINARY_20: 253, + BINARY_32: 254, + NIBBLE_8: 255, + SINGLE_BYTE_MAX: 256, + PACKED_MAX: 254, +} +export const DoubleByteTokens = [] +export const SingleByteTokens = [ + null, + null, + null, + '200', + '400', + '404', + '500', + '501', + '502', + 'action', + 'add', + 'after', + 'archive', + 'author', + 'available', + 'battery', + 'before', + 'body', + 'broadcast', + 'chat', + 'clear', + 'code', + 'composing', + 'contacts', + 'count', + 'create', + 'debug', + 'delete', + 'demote', + 'duplicate', + 'encoding', + 'error', + 'false', + 'filehash', + 'from', + 'g.us', + 'group', + 'groups_v2', + 'height', + 'id', + 'image', + 'in', + 'index', + 'invis', + 'item', + 'jid', + 'kind', + 'last', + 'leave', + 'live', + 'log', + 'media', + 'message', + 'mimetype', + 'missing', + 'modify', + 'name', + 'notification', + 'notify', + 'out', + 'owner', + 'participant', + 'paused', + 'picture', + 'played', + 'presence', + 'preview', + 'promote', + 'query', + 'raw', + 'read', + 'receipt', + 'received', + 'recipient', + 'recording', + 'relay', + 'remove', + 'response', + 'resume', + 'retry', + 's.whatsapp.net', + 'seconds', + 'set', + 'size', + 'status', + 'subject', + 'subscribe', + 't', + 'text', + 'to', + 'true', + 'type', + 'unarchive', + 'unavailable', + 'url', + 'user', + 'value', + 'web', + 'width', + 'mute', + 'read_only', + 'admin', + 'creator', + 'short', + 'update', + 'powersave', + 'checksum', + 'epoch', + 'block', + 'previous', + '409', + 'replaced', + 'reason', + 'spam', + 'modify_tag', + 'message_info', + 'delivery', + 'emoji', + 'title', + 'description', + 'canonical-url', + 'matched-text', + 'star', + 'unstar', + 'media_key', + 'filename', + 'identity', + 'unread', + 'page', + 'page_count', + 'search', + 'media_message', + 'security', + 'call_log', + 'profile', + 'ciphertext', + 'invite', + 'gif', + 'vcard', + 'frequent', + 'privacy', + 'blacklist', + 'whitelist', + 'verify', + 'location', + 'document', + 'elapsed', + 'revoke_invite', + 'expiration', + 'unsubscribe', + 'disable', + 'vname', + 'old_jid', + 'new_jid', + 'announcement', + 'locked', + 'prop', + 'label', + 'color', + 'call', + 'offer', + 'call-id', + 'quick_reply', + 'sticker', + 'pay_t', + 'accept', + 'reject', + 'sticker_pack', + 'invalid', + 'canceled', + 'missed', + 'connected', + 'result', + 'audio', + 'video', + 'recent', +] \ No newline at end of file diff --git a/src/WABinary/Legacy/index.ts b/src/WABinary/Legacy/index.ts new file mode 100644 index 0000000..945eed0 --- /dev/null +++ b/src/WABinary/Legacy/index.ts @@ -0,0 +1,337 @@ + +import { BinaryNode } from '../types' +import { DoubleByteTokens, SingleByteTokens, Tags } from './constants' + +export const isLegacyBinaryNode = (buffer: Buffer) => { + switch(buffer[0]) { + case Tags.LIST_EMPTY: + case Tags.LIST_8: + case Tags.LIST_16: + return true + default: + return false + } +} + +function decode(buffer: Buffer, indexRef: { index: number }): BinaryNode { + + const checkEOS = (length: number) => { + if (indexRef.index + length > buffer.length) { + throw new Error('end of stream') + } + } + const next = () => { + const value = buffer[indexRef.index] + indexRef.index += 1 + return value + } + const readByte = () => { + checkEOS(1) + return next() + } + const readStringFromChars = (length: number) => { + checkEOS(length) + const value = buffer.slice(indexRef.index, indexRef.index + length) + + indexRef.index += length + return value.toString('utf-8') + } + const readBytes = (n: number) => { + checkEOS(n) + const value = buffer.slice(indexRef.index, indexRef.index + n) + indexRef.index += n + return value + } + const readInt = (n: number, littleEndian = false) => { + checkEOS(n) + let val = 0 + for (let i = 0; i < n; i++) { + const shift = littleEndian ? i : n - 1 - i + val |= next() << (shift * 8) + } + return val + } + const readInt20 = () => { + checkEOS(3) + return ((next() & 15) << 16) + (next() << 8) + next() + } + const unpackHex = (value: number) => { + if (value >= 0 && value < 16) { + return value < 10 ? '0'.charCodeAt(0) + value : 'A'.charCodeAt(0) + value - 10 + } + throw new Error('invalid hex: ' + value) + } + const unpackNibble = (value: number) => { + if (value >= 0 && value <= 9) { + return '0'.charCodeAt(0) + value + } + switch (value) { + case 10: + return '-'.charCodeAt(0) + case 11: + return '.'.charCodeAt(0) + case 15: + return '\0'.charCodeAt(0) + default: + throw new Error('invalid nibble: ' + value) + } + } + const unpackByte = (tag: number, value: number) => { + if (tag === Tags.NIBBLE_8) { + return unpackNibble(value) + } else if (tag === Tags.HEX_8) { + return unpackHex(value) + } else { + throw new Error('unknown tag: ' + tag) + } + } + const readPacked8 = (tag: number) => { + const startByte = readByte() + let value = '' + + for (let i = 0; i < (startByte & 127); i++) { + const curByte = readByte() + value += String.fromCharCode(unpackByte(tag, (curByte & 0xf0) >> 4)) + value += String.fromCharCode(unpackByte(tag, curByte & 0x0f)) + } + if (startByte >> 7 !== 0) { + value = value.slice(0, -1) + } + return value + } + const isListTag = (tag: number) => { + return tag === Tags.LIST_EMPTY || tag === Tags.LIST_8 || tag === Tags.LIST_16 + } + const readListSize = (tag: number) => { + switch (tag) { + case Tags.LIST_EMPTY: + return 0 + case Tags.LIST_8: + return readByte() + case Tags.LIST_16: + return readInt(2) + default: + throw new Error('invalid tag for list size: ' + tag) + } + } + const getToken = (index: number) => { + if (index < 3 || index >= SingleByteTokens.length) { + throw new Error('invalid token index: ' + index) + } + return SingleByteTokens[index] + } + const readString = (tag: number) => { + if (tag >= 3 && tag <= 235) { + const token = getToken(tag) + return token// === 's.whatsapp.net' ? 'c.us' : token + } + + switch (tag) { + case Tags.DICTIONARY_0: + case Tags.DICTIONARY_1: + case Tags.DICTIONARY_2: + case Tags.DICTIONARY_3: + return getTokenDouble(tag - Tags.DICTIONARY_0, readByte()) + case Tags.LIST_EMPTY: + return null + case Tags.BINARY_8: + return readStringFromChars(readByte()) + case Tags.BINARY_20: + return readStringFromChars(readInt20()) + case Tags.BINARY_32: + return readStringFromChars(readInt(4)) + case Tags.JID_PAIR: + const i = readString(readByte()) + const j = readString(readByte()) + if (typeof i === 'string' && j) { + return i + '@' + j + } + throw new Error('invalid jid pair: ' + i + ', ' + j) + case Tags.HEX_8: + case Tags.NIBBLE_8: + return readPacked8(tag) + default: + throw new Error('invalid string with tag: ' + tag) + } + } + const readList = (tag: number) => ( + [...new Array(readListSize(tag))].map(() => decode(buffer, indexRef)) + ) + const getTokenDouble = (index1: number, index2: number) => { + const n = 256 * index1 + index2 + if (n < 0 || n > DoubleByteTokens.length) { + throw new Error('invalid double token index: ' + n) + } + return DoubleByteTokens[n] + } + + const listSize = readListSize(readByte()) + const descrTag = readByte() + if (descrTag === Tags.STREAM_END) { + throw new Error('unexpected stream end') + } + const header = readString(descrTag) + const attrs: BinaryNode['attrs'] = { } + let data: BinaryNode['content'] + if (listSize === 0 || !header) { + throw new Error('invalid node') + } + // read the attributes in + + const attributesLength = (listSize - 1) >> 1 + for (let i = 0; i < attributesLength; i++) { + const key = readString(readByte()) + const b = readByte() + + attrs[key] = readString(b) + } + + if (listSize % 2 === 0) { + const tag = readByte() + if (isListTag(tag)) { + data = readList(tag) + } else { + let decoded: Buffer | string + switch (tag) { + case Tags.BINARY_8: + decoded = readBytes(readByte()) + break + case Tags.BINARY_20: + decoded = readBytes(readInt20()) + break + case Tags.BINARY_32: + decoded = readBytes(readInt(4)) + break + default: + decoded = readString(tag) + break + } + data = decoded + } + } + + return { + tag: header, + attrs, + content: data + } +} + +const encode = ({ tag, attrs, content }: BinaryNode, buffer: number[] = []) => { + + const pushByte = (value: number) => buffer.push(value & 0xff) + + const pushInt = (value: number, n: number, littleEndian=false) => { + for (let i = 0; i < n; i++) { + const curShift = littleEndian ? i : n - 1 - i + buffer.push((value >> (curShift * 8)) & 0xff) + } + } + const pushBytes = (bytes: Uint8Array | Buffer | number[]) => ( + bytes.forEach (b => buffer.push(b)) + ) + const pushInt20 = (value: number) => ( + pushBytes([(value >> 16) & 0x0f, (value >> 8) & 0xff, value & 0xff]) + ) + const writeByteLength = (length: number) => { + if (length >= 4294967296) throw new Error('string too large to encode: ' + length) + + if (length >= 1 << 20) { + pushByte(Tags.BINARY_32) + pushInt(length, 4) // 32 bit integer + } else if (length >= 256) { + pushByte(Tags.BINARY_20) + pushInt20(length) + } else { + pushByte(Tags.BINARY_8) + pushByte(length) + } + } + const writeStringRaw = (str: string) => { + const bytes = Buffer.from (str, 'utf-8') + writeByteLength(bytes.length) + pushBytes(bytes) + } + const writeToken = (token: number) => { + if (token < 245) { + pushByte(token) + } else if (token <= 500) { + throw new Error('invalid token') + } + } + const writeString = (token: string, i?: boolean) => { + if (token === 'c.us') token = 's.whatsapp.net' + + const tokenIndex = SingleByteTokens.indexOf(token) + if (!i && token === 's.whatsapp.net') { + writeToken(tokenIndex) + } else if (tokenIndex >= 0) { + if (tokenIndex < Tags.SINGLE_BYTE_MAX) { + writeToken(tokenIndex) + } else { + const overflow = tokenIndex - Tags.SINGLE_BYTE_MAX + const dictionaryIndex = overflow >> 8 + if (dictionaryIndex < 0 || dictionaryIndex > 3) { + throw new Error('double byte dict token out of range: ' + token + ', ' + tokenIndex) + } + writeToken(Tags.DICTIONARY_0 + dictionaryIndex) + writeToken(overflow % 256) + } + } else if (token) { + const jidSepIndex = token.indexOf('@') + if (jidSepIndex <= 0) { + writeStringRaw(token) + } else { + writeJid(token.slice(0, jidSepIndex), token.slice(jidSepIndex + 1, token.length)) + } + } + } + const writeJid = (left: string, right: string) => { + pushByte(Tags.JID_PAIR) + left && left.length > 0 ? writeString(left) : writeToken(Tags.LIST_EMPTY) + writeString(right) + } + const writeListStart = (listSize: number) => { + if (listSize === 0) { + pushByte(Tags.LIST_EMPTY) + } else if (listSize < 256) { + pushBytes([Tags.LIST_8, listSize]) + } else { + pushBytes([Tags.LIST_16, listSize]) + } + } + const validAttributes = Object.keys(attrs).filter(k => ( + typeof attrs[k] !== 'undefined' && attrs[k] !== null + )) + + writeListStart(2*validAttributes.length + 1 + (typeof content !== 'undefined' && content !== null ? 1 : 0)) + writeString(tag) + + validAttributes.forEach((key) => { + if(typeof attrs[key] === 'string') { + writeString(key) + writeString(attrs[key]) + } + }) + + if (typeof content === 'string') { + writeString(content, true) + } else if (Buffer.isBuffer(content)) { + writeByteLength(content.length) + pushBytes(content) + } else if (Array.isArray(content)) { + writeListStart(content.length) + for(const item of content) { + if(item) encode(item, buffer) + } + } else if(typeof content === 'undefined' || content === null) { + + } else { + throw new Error(`invalid children for header "${tag}": ${content} (${typeof content})`) + } + + return Buffer.from(buffer) +} + +export const encodeBinaryNodeLegacy = encode +export const decodeBinaryNodeLegacy = decode diff --git a/src/WABinary/index.ts b/src/WABinary/index.ts index 1423573..0633c4f 100644 --- a/src/WABinary/index.ts +++ b/src/WABinary/index.ts @@ -3,6 +3,7 @@ import { jidDecode, jidEncode } from './jid-utils'; import { Binary, numUtf8Bytes } from '../../WABinary/Binary'; import { Boom } from '@hapi/boom'; import { proto } from '../../WAProto'; +import { BinaryNode } from './types'; const LIST1 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '.', '�', '�', '�', '�']; const LIST2 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']; @@ -210,20 +211,6 @@ function bufferToUInt(e: Uint8Array | Buffer, t: number) { for (let i = 0; i < t; i++) a = 256 * a + e[i] return a } -/** - * the binary node WA uses internally for communication - * - * this is manipulated soley as an object and it does not have any functions. - * This is done for easy serialization, to prevent running into issues with prototypes & - * to maintain functional code structure - * */ -export type BinaryNode = { - tag: string - attrs: { [key: string]: string } - content?: BinaryNode[] | string | Uint8Array -} -export type BinaryNodeAttributes = BinaryNode['attrs'] -export type BinaryNodeData = BinaryNode['content'] export const decodeBinaryNode = (data: Binary): BinaryNode => { //U @@ -333,4 +320,6 @@ export const getBinaryNodeMessages = ({ content }: BinaryNode) => { } export * from './jid-utils' -export { Binary } from '../../WABinary/Binary' \ No newline at end of file +export { Binary } from '../../WABinary/Binary' +export * from './types' +export * from './Legacy' \ No newline at end of file diff --git a/src/WABinary/types.ts b/src/WABinary/types.ts new file mode 100644 index 0000000..96e35d4 --- /dev/null +++ b/src/WABinary/types.ts @@ -0,0 +1,14 @@ +/** + * the binary node WA uses internally for communication + * + * this is manipulated soley as an object and it does not have any functions. + * This is done for easy serialization, to prevent running into issues with prototypes & + * to maintain functional code structure + * */ + export type BinaryNode = { + tag: string + attrs: { [key: string]: string } + content?: BinaryNode[] | string | Uint8Array +} +export type BinaryNodeAttributes = BinaryNode['attrs'] +export type BinaryNodeData = BinaryNode['content'] \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index fe1c58f..d445a48 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import makeWASocket from './Socket' +import makeWALegacySocket from './LegacySocket' export * from '../WAProto' export * from './Utils' @@ -7,6 +8,10 @@ export * from './Types' export * from './Defaults' export * from './WABinary' +export type WALegacySocket = ReturnType + +export { makeWALegacySocket } + export type WASocket = ReturnType export default makeWASocket \ No newline at end of file From d386f2db8be1118e9e35df77b3c6f5eb44377f9c Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 17 Dec 2021 20:59:43 +0530 Subject: [PATCH 231/311] Implement Legacy Socket Capability in MD Code (#1041) * feat: add legacy connection * fix: merge conflict errors * feat: functional legacy socket --- Example/example-legacy.ts | 64 ++++ package.json | 1 + src/Defaults/index.ts | 21 +- src/LegacySocket/auth.ts | 269 ++++++++++++++++ src/LegacySocket/chats.ts | 503 +++++++++++++++++++++++++++++ src/LegacySocket/groups.ts | 238 ++++++++++++++ src/LegacySocket/index.ts | 12 + src/LegacySocket/messages.ts | 536 +++++++++++++++++++++++++++++++ src/LegacySocket/socket.ts | 393 ++++++++++++++++++++++ src/Socket/chats.ts | 8 +- src/Socket/messages-send.ts | 59 +--- src/Socket/socket.ts | 2 +- src/Types/Auth.ts | 1 - src/Types/Chat.ts | 2 +- src/Types/Events.ts | 56 ++++ src/Types/Legacy.ts | 83 +++++ src/Types/Message.ts | 2 +- src/Types/Socket.ts | 39 +++ src/Types/State.ts | 10 +- src/Types/index.ts | 61 ++-- src/Utils/chat-utils.ts | 2 +- src/Utils/index.ts | 3 +- src/Utils/legacy-msgs.ts | 173 ++++++++++ src/Utils/messages-media.ts | 60 +++- src/WABinary/Legacy/constants.ts | 198 ++++++++++++ src/WABinary/Legacy/index.ts | 337 +++++++++++++++++++ src/WABinary/index.ts | 32 +- src/WABinary/types.ts | 14 + src/index.ts | 5 + 29 files changed, 3056 insertions(+), 128 deletions(-) create mode 100644 Example/example-legacy.ts create mode 100644 src/LegacySocket/auth.ts create mode 100644 src/LegacySocket/chats.ts create mode 100644 src/LegacySocket/groups.ts create mode 100644 src/LegacySocket/index.ts create mode 100644 src/LegacySocket/messages.ts create mode 100644 src/LegacySocket/socket.ts create mode 100644 src/Types/Events.ts create mode 100644 src/Types/Legacy.ts create mode 100644 src/Types/Socket.ts create mode 100644 src/Utils/legacy-msgs.ts create mode 100644 src/WABinary/Legacy/constants.ts create mode 100644 src/WABinary/Legacy/index.ts create mode 100644 src/WABinary/types.ts diff --git a/Example/example-legacy.ts b/Example/example-legacy.ts new file mode 100644 index 0000000..06c6fd0 --- /dev/null +++ b/Example/example-legacy.ts @@ -0,0 +1,64 @@ +import P from "pino" +import { Boom } from "@hapi/boom" +import { makeWALegacySocket, DisconnectReason, AnyMessageContent, delay, useSingleFileLegacyAuthState } from '../src' + +const { state, saveState } = useSingleFileLegacyAuthState('./auth_info.json') + +// start a connection +const startSock = () => { + + const sock = makeWALegacySocket({ + logger: P({ level: 'debug' }), + printQRInTerminal: true, + auth: state + }) + + const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { + await sock.presenceSubscribe(jid) + await delay(500) + + await sock.sendPresenceUpdate('composing', jid) + await delay(2000) + + await sock.sendPresenceUpdate('paused', jid) + + await sock.sendWAMessage(jid, msg) + } + + sock.ev.on('messages.upsert', async m => { + console.log(JSON.stringify(m, undefined, 2)) + + const msg = m.messages[0] + if(!msg.key.fromMe && m.type === 'notify') { + console.log('replying to', m.messages[0].key.remoteJid) + await sock!.chatRead(msg.key, 1) + await sendMessageWTyping({ text: 'Hello there!' }, msg.key.remoteJid) + } + + }) + + sock.ev.on('messages.update', m => console.log(m)) + sock.ev.on('presence.update', m => console.log(m)) + sock.ev.on('chats.update', m => console.log(m)) + sock.ev.on('contacts.update', m => console.log(m)) + + sock.ev.on('connection.update', (update) => { + const { connection, lastDisconnect } = update + if(connection === 'close') { + // reconnect if not logged out + if((lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut) { + startSock() + } else { + console.log('connection closed') + } + } + + console.log('connection update', update) + }) + // listen for when the auth credentials is updated + sock.ev.on('creds.update', saveState) + + return sock +} + +startSock() \ No newline at end of file diff --git a/package.json b/package.json index ec31289..05b3875 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "build:docs": "typedoc", "build:tsc": "tsc", "example": "node --inspect -r ts-node/register Example/example.ts", + "example:legacy": "node --inspect -r ts-node/register Example/example-legacy.ts", "gen-protobuf": "bash src/BinaryNode/GenerateStatics.sh", "browser-decode": "yarn ts-node src/BrowserMessageDecoding.ts" }, diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 844449c..dba9ff9 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -1,5 +1,5 @@ import P from "pino" -import type { MediaType, SocketConfig } from "../Types" +import type { MediaType, SocketConfig, LegacySocketConfig, CommonSocketConfig } from "../Types" import { Browsers } from "../Utils" export const UNAUTHORIZED_CODES = [401, 403, 419] @@ -17,11 +17,11 @@ export const NOISE_WA_HEADER = new Uint8Array([87, 65, 5, 2]) // last is "DICT_V /** from: https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url */ export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi -export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { - version: [2, 2146, 9], +const BASE_CONNECTION_CONFIG: CommonSocketConfig = { + version: [2, 2147, 16], browser: Browsers.baileys('Chrome'), - waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', + waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', connectTimeoutMs: 20_000, keepAliveIntervalMs: 25_000, logger: P().child({ class: 'baileys' }), @@ -29,9 +29,22 @@ export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { emitOwnEvents: true, defaultQueryTimeoutMs: 60_000, customUploadHosts: [], +} + +export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { + ...BASE_CONNECTION_CONFIG, + waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', getMessage: async() => undefined } +export const DEFAULT_LEGACY_CONNECTION_CONFIG: LegacySocketConfig = { + ...BASE_CONNECTION_CONFIG, + waWebSocketUrl: 'wss://web.whatsapp.com/ws', + phoneResponseTimeMs: 20_000, + expectResponseTimeout: 60_000, + pendingRequestTimeoutMs: 60_000 +} + export const MEDIA_PATH_MAP: { [T in MediaType]: string } = { image: '/mms/image', video: '/mms/video', diff --git a/src/LegacySocket/auth.ts b/src/LegacySocket/auth.ts new file mode 100644 index 0000000..fbae0b4 --- /dev/null +++ b/src/LegacySocket/auth.ts @@ -0,0 +1,269 @@ +import { Boom } from '@hapi/boom' +import EventEmitter from "events" +import { LegacyBaileysEventEmitter, BaileysEventMap, LegacySocketConfig, CurveKeyPair, WAInitResponse, ConnectionState, DisconnectReason, LegacyAuthenticationCreds } from "../Types" +import { newLegacyAuthCreds, promiseTimeout, computeChallengeResponse, validateNewConnection, Curve } from "../Utils" +import { makeSocket } from "./socket" + +const makeAuthSocket = (config: LegacySocketConfig) => { + const { + logger, + version, + browser, + connectTimeoutMs, + pendingRequestTimeoutMs, + printQRInTerminal, + auth: initialAuthInfo + } = config + const ev = new EventEmitter() as LegacyBaileysEventEmitter + + const authInfo = initialAuthInfo || newLegacyAuthCreds() + + const state: ConnectionState = { + legacy: { + phoneConnected: false, + }, + connection: 'connecting', + } + + const socket = makeSocket(config) + const { ws } = socket + let curveKeys: CurveKeyPair + let initTimeout: NodeJS.Timeout + + ws.on('phone-connection', ({ value: phoneConnected }) => { + if(phoneConnected !== state.legacy.phoneConnected) { + updateState({ legacy: { ...state.legacy, phoneConnected } }) + } + }) + // add close listener + ws.on('ws-close', (error: Boom | Error) => { + logger.info({ error }, 'Closed connection to WhatsApp') + initTimeout && clearTimeout(initTimeout) + // if no reconnects occur + // send close event + updateState({ + connection: 'close', + qr: undefined, + lastDisconnect: { + error, + date: new Date() + } + }) + }) + /** Can you login to WA without scanning the QR */ + const canLogin = () => !!authInfo?.encKey && !!authInfo?.macKey + + const updateState = (update: Partial) => { + Object.assign(state, update) + ev.emit('connection.update', update) + } + + /** + * Logs you out from WA + * If connected, invalidates the credentials with the server + */ + const logout = async() => { + if(state.connection === 'open') { + await socket.sendMessage({ + json: ['admin', 'Conn', 'disconnect'], + tag: 'goodbye' + }) + } + // will call state update to close connection + socket?.end( + new Boom('Logged Out', { statusCode: DisconnectReason.loggedOut }) + ) + } + /** Waits for the connection to WA to open up */ + const waitForConnection = async(waitInfinitely: boolean = false) => { + if(state.connection === 'open') return + + let listener: (item: BaileysEventMap['connection.update']) => void + const timeout = waitInfinitely ? undefined : pendingRequestTimeoutMs + if(timeout < 0) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } + + await ( + promiseTimeout( + timeout, + (resolve, reject) => { + listener = ({ connection, lastDisconnect }) => { + if(connection === 'open') resolve() + else if(connection == 'close') { + reject(lastDisconnect.error || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) + } + } + ev.on('connection.update', listener) + } + ) + .finally(() => ( + ev.off('connection.update', listener) + )) + ) + } + + const updateEncKeys = () => { + // update the keys so we can decrypt traffic + socket.updateKeys({ encKey: authInfo!.encKey, macKey: authInfo!.macKey }) + } + + const generateKeysForAuth = async(ref: string, ttl?: number) => { + curveKeys = Curve.generateKeyPair() + const publicKey = Buffer.from(curveKeys.public).toString('base64') + let qrGens = 0 + + const qrLoop = ttl => { + const qr = [ref, publicKey, authInfo.clientID].join(',') + updateState({ qr }) + + initTimeout = setTimeout(async () => { + if(state.connection !== 'connecting') return + + logger.debug('regenerating QR') + try { + // request new QR + const {ref: newRef, ttl: newTTL} = await socket.query({ + json: ['admin', 'Conn', 'reref'], + expect200: true, + longTag: true, + requiresPhoneConnection: false + }) + ttl = newTTL + ref = newRef + } catch (error) { + logger.error({ error }, `error in QR gen`) + if (error.output?.statusCode === 429) { // too many QR requests + socket.end(error) + return + } + } + qrGens += 1 + qrLoop(ttl) + }, ttl || 20_000) // default is 20s, on the off-chance ttl is not present + } + qrLoop(ttl) + } + const onOpen = async() => { + const canDoLogin = canLogin() + const initQuery = (async () => { + const {ref, ttl} = await socket.query({ + json: ['admin', 'init', version, browser, authInfo.clientID, true], + expect200: true, + longTag: true, + requiresPhoneConnection: false + }) as WAInitResponse + + if (!canDoLogin) { + generateKeysForAuth(ref, ttl) + } + })(); + let loginTag: string + if(canDoLogin) { + updateEncKeys() + // if we have the info to restore a closed session + const json = [ + 'admin', + 'login', + authInfo.clientToken, + authInfo.serverToken, + authInfo.clientID, + 'takeover' + ] + loginTag = socket.generateMessageTag(true) + // send login every 10s + const sendLoginReq = () => { + if(state.connection === 'open') { + logger.warn('Received login timeout req when state=open, ignoring...') + return + } + logger.info('sending login request') + socket.sendMessage({ + json, + tag: loginTag + }) + initTimeout = setTimeout(sendLoginReq, 10_000) + } + sendLoginReq() + } + await initQuery + + // wait for response with tag "s1" + let response = await Promise.race( + [ + socket.waitForMessage('s1', false, undefined).promise, + ...(loginTag ? [socket.waitForMessage(loginTag, false, connectTimeoutMs).promise] : []) + ] + ) + initTimeout && clearTimeout(initTimeout) + initTimeout = undefined + + if(response.status && response.status !== 200) { + throw new Boom(`Unexpected error in login`, { data: response, statusCode: response.status }) + } + // if its a challenge request (we get it when logging in) + if(response[1]?.challenge) { + const json = computeChallengeResponse(response[1].challenge, authInfo) + logger.info('resolving login challenge') + + await socket.query({ json, expect200: true, timeoutMs: connectTimeoutMs }) + + response = await socket.waitForMessage('s2', true).promise + } + if(!response || !response[1]) { + throw new Boom('Received unexpected login response', { data: response }) + } + if(response[1].type === 'upgrade_md_prod') { + throw new Boom('Require multi-device edition', { statusCode: DisconnectReason.multideviceMismatch }) + } + // validate the new connection + const {user, auth} = validateNewConnection(response[1], authInfo, curveKeys)// validate the connection + const isNewLogin = user.id !== state.legacy!.user?.id + + Object.assign(authInfo, auth) + updateEncKeys() + + logger.info({ user }, 'logged in') + + ev.emit('creds.update', auth) + + updateState({ + connection: 'open', + legacy: { + phoneConnected: true, + user, + }, + isNewLogin, + qr: undefined + }) + } + ws.once('open', async() => { + try { + await onOpen() + } catch(error) { + socket.end(error) + } + }) + + if(printQRInTerminal) { + ev.on('connection.update', async({ qr }) => { + if(qr) { + const QR = await import('qrcode-terminal').catch(err => { + logger.error('QR code terminal not added as dependency') + }) + QR?.generate(qr, { small: true }) + } + }) + } + + return { + ...socket, + ev, + getState: () => state, + getAuthInfo: () => authInfo, + waitForConnection, + canLogin, + logout + } +} +export default makeAuthSocket \ No newline at end of file diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts new file mode 100644 index 0000000..67d8c00 --- /dev/null +++ b/src/LegacySocket/chats.ts @@ -0,0 +1,503 @@ +import { BinaryNode, jidNormalizedUser } from "../WABinary"; +import { Chat, Contact, WAPresence, PresenceData, LegacySocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessageUpdate, BaileysEventMap } from "../Types"; +import { debouncedTimeout, unixTimestampSeconds } from "../Utils/generics"; +import makeAuthSocket from "./auth"; + +const makeChatsSocket = (config: LegacySocketConfig) => { + const { logger } = config + const sock = makeAuthSocket(config) + const { + ev, + ws: socketEvents, + currentEpoch, + setQuery, + query, + sendMessage, + getState + } = sock + + const chatsDebounceTimeout = debouncedTimeout(10_000, () => sendChatsQuery(1)) + + const sendChatsQuery = (epoch: number) => ( + sendMessage({ + json: { + tag: 'query', + attrs: {type: 'chat', epoch: epoch.toString()} + }, + binaryTag: [ WAMetric.queryChat, WAFlag.ignore ] + }) + ) + + const fetchImageUrl = async(jid: string) => { + const response = await query({ + json: ['query', 'ProfilePicThumb', jid], + expect200: false, + requiresPhoneConnection: false + }) + return response.eurl as string | undefined + } + + const executeChatModification = (node: BinaryNode) => { + const { attrs: attributes } = node + const updateType = attributes.type + const jid = jidNormalizedUser(attributes?.jid) + + switch(updateType) { + case 'delete': + ev.emit('chats.delete', [jid]) + break + case 'clear': + if(node.content) { + const ids = (node.content as BinaryNode[]).map( + ({ attrs }) => attrs.index + ) + ev.emit('messages.delete', { keys: ids.map(id => ({ id, remoteJid: jid })) }) + } else { + ev.emit('messages.delete', { jid, all: true }) + } + break + case 'archive': + ev.emit('chats.update', [ { id: jid, archive: true } ]) + break + case 'unarchive': + ev.emit('chats.update', [ { id: jid, archive: false } ]) + break + case 'pin': + ev.emit('chats.update', [ { id: jid, pin: +attributes.pin } ]) + break + case 'star': + case 'unstar': + const starred = updateType === 'star' + const updates: WAMessageUpdate[] = (node.content as BinaryNode[]).map( + ({ attrs }) => ({ + key: { + remoteJid: jid, + id: attrs.index, + fromMe: attrs.owner === 'true' + }, + update: { starred } + }) + ) + ev.emit('messages.update', updates) + break + case 'mute': + if(attributes.mute === '0') { + ev.emit('chats.update', [{ id: jid, mute: null }]) + } else { + ev.emit('chats.update', [{ id: jid, mute: +attributes.mute }]) + } + break + default: + logger.warn({ node }, `received unrecognized chat update`) + break + } + } + + const applyingPresenceUpdate = (update: BinaryNode['attrs']): BaileysEventMap['presence.update'] => { + const id = jidNormalizedUser(update.id) + const participant = jidNormalizedUser(update.participant || update.id) + + const presence: PresenceData = { + lastSeen: update.t ? +update.t : undefined, + lastKnownPresence: update.type as WAPresence + } + return { id, presences: { [participant]: presence } } + } + + ev.on('connection.update', async({ connection }) => { + if(connection !== 'open') return + try { + await Promise.all([ + sendMessage({ + json: { tag: 'query', attrs: {type: 'contacts', epoch: '1'} }, + binaryTag: [ WAMetric.queryContact, WAFlag.ignore ] + }), + sendMessage({ + json: { tag: 'query', attrs: {type: 'status', epoch: '1'} }, + binaryTag: [ WAMetric.queryStatus, WAFlag.ignore ] + }), + sendMessage({ + json: { tag: 'query', attrs: {type: 'quick_reply', epoch: '1'} }, + binaryTag: [ WAMetric.queryQuickReply, WAFlag.ignore ] + }), + sendMessage({ + json: { tag: 'query', attrs: {type: 'label', epoch: '1'} }, + binaryTag: [ WAMetric.queryLabel, WAFlag.ignore ] + }), + sendMessage({ + json: { tag: 'query', attrs: {type: 'emoji', epoch: '1'} }, + binaryTag: [ WAMetric.queryEmoji, WAFlag.ignore ] + }), + sendMessage({ + json: { + tag: 'action', + attrs: { type: 'set', epoch: '1' }, + content: [ + { tag: 'presence', attrs: {type: 'available'} } + ] + }, + binaryTag: [ WAMetric.presence, WAFlag.available ] + }) + ]) + chatsDebounceTimeout.start() + + logger.debug('sent init queries') + } catch(error) { + logger.error(`error in sending init queries: ${error}`) + } + }) + socketEvents.on('CB:response,type:chat', async ({ content: data }: BinaryNode) => { + chatsDebounceTimeout.cancel() + if(Array.isArray(data)) { + const chats = data.map(({ attrs }): Chat => { + return { + id: jidNormalizedUser(attrs.jid), + conversationTimestamp: attrs.t ? +attrs.t : undefined, + unreadCount: +attrs.count, + archive: attrs.archive === 'true' ? true : undefined, + pin: attrs.pin ? +attrs.pin : undefined, + mute: attrs.mute ? +attrs.mute : undefined, + notSpam: !(attrs.spam === 'true'), + name: attrs.name, + ephemeralExpiration: attrs.ephemeral ? +attrs.ephemeral : undefined, + ephemeralSettingTimestamp: attrs.eph_setting_ts ? +attrs.eph_setting_ts : undefined, + readOnly: attrs.read_only === 'true' ? true : undefined, + } + }) + + logger.info(`got ${chats.length} chats`) + ev.emit('chats.set', { chats, messages: [] }) + } + }) + // got all contacts from phone + socketEvents.on('CB:response,type:contacts', async ({ content: data }: BinaryNode) => { + if(Array.isArray(data)) { + const contacts = data.map(({ attrs }): Contact => { + return { + id: jidNormalizedUser(attrs.jid), + name: attrs.name, + notify: attrs.notify, + verifiedName: attrs.vname + } + }) + + logger.info(`got ${contacts.length} contacts`) + ev.emit('contacts.upsert', contacts) + } + }) + // status updates + socketEvents.on('CB:Status,status', json => { + const id = jidNormalizedUser(json[1].id) + ev.emit('contacts.update', [ { id, status: json[1].status } ]) + }) + // User Profile Name Updates + socketEvents.on('CB:Conn,pushname', json => { + const { legacy: { user }, connection } = getState() + if(connection === 'open' && json[1].pushname !== user.name) { + user.name = json[1].pushname + ev.emit('connection.update', { legacy: { ...getState().legacy, user } }) + } + }) + // read updates + socketEvents.on ('CB:action,,read', async ({ content }: BinaryNode) => { + if(Array.isArray(content)) { + const { attrs } = content[0] + + const update: Partial = { + id: jidNormalizedUser(attrs.jid) + } + if (attrs.type === 'false') update.unreadCount = -1 + else update.unreadCount = 0 + + ev.emit('chats.update', [update]) + } + }) + + socketEvents.on('CB:Cmd,type:picture', async json => { + json = json[1] + const id = jidNormalizedUser(json.jid) + const imgUrl = await fetchImageUrl(id).catch(() => '') + + ev.emit('contacts.update', [ { id, imgUrl } ]) + }) + + // chat archive, pin etc. + socketEvents.on('CB:action,,chat', ({ content }: BinaryNode) => { + if(Array.isArray(content)) { + const [node] = content + executeChatModification(node) + } + }) + + socketEvents.on('CB:action,,user', (json: BinaryNode) => { + if(Array.isArray(json.content)) { + const user = json.content[0].attrs + user.id = jidNormalizedUser(user.id) + + //ev.emit('contacts.upsert', [user]) + } + }) + + // presence updates + socketEvents.on('CB:Presence', json => { + const update = applyingPresenceUpdate(json[1]) + ev.emit('presence.update', update) + }) + + // blocklist updates + socketEvents.on('CB:Blocklist', json => { + json = json[1] + const blocklist = json.blocklist + ev.emit('blocklist.set', { blocklist }) + }) + + return { + ...sock, + sendChatsQuery, + fetchImageUrl, + chatRead: async(fromMessage: WAMessageKey, count: number) => { + await setQuery ( + [ + { tag: 'read', + attrs: { + jid: fromMessage.remoteJid, + count: count.toString(), + index: fromMessage.id, + owner: fromMessage.fromMe ? 'true' : 'false' + } + } + ], + [ WAMetric.read, WAFlag.ignore ] + ) + if(config.emitOwnEvents) { + ev.emit ('chats.update', [{ id: fromMessage.remoteJid, unreadCount: count < 0 ? -1 : 0 }]) + } + }, + /** + * Modify a given chat (archive, pin etc.) + * @param jid the ID of the person/group you are modifiying + */ + modifyChat: async(jid: string, modification: ChatModification, chatInfo: Pick, index?: WAMessageKey) => { + let chatAttrs: BinaryNode['attrs'] = { jid: jid } + let data: BinaryNode[] | undefined = undefined + const stamp = unixTimestampSeconds() + + if('archive' in modification) { + chatAttrs.type = modification.archive ? 'archive' : 'unarchive' + } else if('pin' in modification) { + chatAttrs.type = 'pin' + if(modification.pin) { + chatAttrs.pin = stamp.toString() + } else { + chatAttrs.previous = chatInfo.pin!.toString() + } + } else if('mute' in modification) { + chatAttrs.type = 'mute' + if(modification.mute) { + chatAttrs.mute = (stamp + modification.mute).toString() + } else { + chatAttrs.previous = chatInfo.mute!.toString() + } + } else if('clear' in modification) { + chatAttrs.type = 'clear' + chatAttrs.modify_tag = Math.round(Math.random ()*1000000).toString() + if(modification.clear !== 'all') { + data = modification.clear.messages.map(({ id, fromMe }) => ( + { + tag: 'item', + attrs: { owner: (!!fromMe).toString(), index: id } + } + )) + } + } else if('star' in modification) { + chatAttrs.type = modification.star.star ? 'star' : 'unstar' + data = modification.star.messages.map(({ id, fromMe }) => ( + { + tag: 'item', + attrs: { owner: (!!fromMe).toString(), index: id } + } + )) + } + + if(index) { + chatAttrs.index = index.id + chatAttrs.owner = index.fromMe ? 'true' : 'false' + } + + const node = { tag: 'chat', attrs: chatAttrs, content: data } + const response = await setQuery([node], [ WAMetric.chat, WAFlag.ignore ]) + // apply it and emit events + executeChatModification(node) + return response + }, + /** + * Query whether a given number is registered on WhatsApp + * @param str phone number/jid you want to check for + * @returns undefined if the number doesn't exists, otherwise the correctly formatted jid + */ + isOnWhatsApp: async (str: string) => { + const { status, jid, biz } = await query({ + json: ['query', 'exist', str], + requiresPhoneConnection: false + }) + if (status === 200) { + return { + exists: true, + jid: jidNormalizedUser(jid), + isBusiness: biz as boolean + } + } + }, + /** + * Tell someone about your presence -- online, typing, offline etc. + * @param jid the ID of the person/group who you are updating + * @param type your presence + */ + sendPresenceUpdate: ( type: WAPresence, jid: string | undefined) => ( + sendMessage({ + binaryTag: [WAMetric.presence, WAFlag[type]], // weird stuff WA does + json: { + tag: 'action', + attrs: { epoch: currentEpoch().toString(), type: 'set' }, + content: [ + { + tag: 'presence', + attrs: { type: type, to: jid } + } + ] + } + }) + ), + /** + * Request updates on the presence of a user + * this returns nothing, you'll receive updates in chats.update event + * */ + presenceSubscribe: async (jid: string) => ( + sendMessage({ json: ['action', 'presence', 'subscribe', jid] }) + ), + /** Query the status of the person (see groupMetadata() for groups) */ + getStatus: async(jid: string) => { + const status: { status: string } = await query({ json: ['query', 'Status', jid], requiresPhoneConnection: false }) + return status + }, + setStatus: async(status: string) => { + const response = await setQuery( + [ + { + tag: 'status', + attrs: {}, + content: Buffer.from (status, 'utf-8') + } + ] + ) + ev.emit('contacts.update', [{ id: getState().legacy!.user!.id, status }]) + return response + }, + /** Updates business profile. */ + updateBusinessProfile: async(profile: WABusinessProfile) => { + if (profile.business_hours?.config) { + profile.business_hours.business_config = profile.business_hours.config + delete profile.business_hours.config + } + const json = ['action', "editBusinessProfile", {...profile, v: 2}] + await query({ json, expect200: true, requiresPhoneConnection: true }) + }, + updateProfileName: async(name: string) => { + const response = (await setQuery( + [ + { + tag: 'profile', + attrs: { name } + } + ] + )) as any as {status: number, pushname: string} + + if(config.emitOwnEvents) { + const user = { ...getState().legacy!.user!, name } + ev.emit('connection.update', { legacy: { + ...getState().legacy, user + } }) + ev.emit('contacts.update', [{ id: user.id, name }]) + } + return response + }, + /** + * Update the profile picture + * @param jid + * @param img + */ + async updateProfilePicture (jid: string, img: Buffer) { + jid = jidNormalizedUser (jid) + const data = { img: Buffer.from([]), preview: Buffer.from([]) } //await generateProfilePicture(img) TODO + const tag = this.generateMessageTag () + const query: BinaryNode = { + tag: 'picture', + attrs: { jid: jid, id: tag, type: 'set' }, + content: [ + { tag: 'image', attrs: {}, content: data.img }, + { tag: 'preview', attrs: {}, content: data.preview } + ] + } + + const user = getState().legacy?.user + const { eurl } = await this.setQuery ([query], [WAMetric.picture, 136], tag) as { eurl: string, status: number } + + if(config.emitOwnEvents) { + if(jid === user.id) { + user.imgUrl = eurl + ev.emit('connection.update', { + legacy: { + ...getState().legacy, + user + } + }) + } + ev.emit('contacts.update', [ { id: jid, imgUrl: eurl } ]) + } + }, + /** + * Add or remove user from blocklist + * @param jid the ID of the person who you are blocking/unblocking + * @param type type of operation + */ + blockUser: async(jid: string, type: 'add' | 'remove' = 'add') => { + const json = { + tag: 'block', + attrs: { type }, + content: [ { tag: 'user', attrs: { jid } } ] + } + await setQuery([json], [WAMetric.block, WAFlag.ignore]) + if(config.emitOwnEvents) { + ev.emit('blocklist.update', { blocklist: [jid], type }) + } + }, + /** + * Query Business Profile (Useful for VCards) + * @param jid Business Jid + * @returns profile object or undefined if not business account + */ + getBusinessProfile: async(jid: string) => { + jid = jidNormalizedUser(jid) + const { + profiles: [{ + profile, + wid + }] + } = await query({ + json: [ + "query", "businessProfile", + [ { "wid": jid.replace('@s.whatsapp.net', '@c.us') } ], + 84 + ], + expect200: true, + requiresPhoneConnection: false, + }) + + return { + ...profile, + wid: jidNormalizedUser(wid) + } as WABusinessProfile + } + } +} +export default makeChatsSocket \ No newline at end of file diff --git a/src/LegacySocket/groups.ts b/src/LegacySocket/groups.ts new file mode 100644 index 0000000..b4bba8b --- /dev/null +++ b/src/LegacySocket/groups.ts @@ -0,0 +1,238 @@ +import { BinaryNode, jidNormalizedUser } from "../WABinary"; +import { LegacySocketConfig, GroupModificationResponse, ParticipantAction, GroupMetadata, WAFlag, WAMetric, WAGroupCreateResponse, GroupParticipant } from "../Types"; +import { generateMessageID, unixTimestampSeconds } from "../Utils/generics"; +import makeMessagesSocket from "./messages"; + +const makeGroupsSocket = (config: LegacySocketConfig) => { + const { logger } = config + const sock = makeMessagesSocket(config) + const { + ev, + ws: socketEvents, + query, + generateMessageTag, + currentEpoch, + setQuery, + getState + } = sock + + /** Generic function for group queries */ + const groupQuery = async(type: string, jid?: string, subject?: string, participants?: string[], additionalNodes?: BinaryNode[]) => { + const tag = generateMessageTag() + const result = await setQuery ([ + { + tag: 'group', + attrs: { + author: getState().legacy?.user?.id, + id: tag, + type: type, + jid: jid, + subject: subject, + }, + content: participants ? + participants.map(jid => ( + { tag: 'participant', attrs: { jid } } + )) : + additionalNodes + } + ], [WAMetric.group, 136], tag) + return result + } + + /** Get the metadata of the group from WA */ + const groupMetadataFull = async (jid: string) => { + const metadata = await query({ + json: ['query', 'GroupMetadata', jid], + expect200: true + }) + metadata.participants = metadata.participants.map(p => ( + { ...p, id: undefined, jid: jidNormalizedUser(p.id) } + )) + metadata.owner = jidNormalizedUser(metadata.owner) + return metadata as GroupMetadata + } + /** Get the metadata (works after you've left the group also) */ + const groupMetadataMinimal = async (jid: string) => { + const { attrs, content }:BinaryNode = await query({ + json: { + tag: 'query', + attrs: {type: 'group', jid: jid, epoch: currentEpoch().toString()} + }, + binaryTag: [WAMetric.group, WAFlag.ignore], + expect200: true + }) + const participants: GroupParticipant[] = [] + let desc: string | undefined + if(Array.isArray(content) && Array.isArray(content[0].content)) { + const nodes = content[0].content + for(const item of nodes) { + if(item.tag === 'participant') { + participants.push({ + id: item.attrs.jid, + isAdmin: item.attrs.type === 'admin', + isSuperAdmin: false + }) + } else if(item.tag === 'description') { + desc = (item.content as Buffer).toString('utf-8') + } + } + } + const meta: GroupMetadata = { + id: jid, + owner: attrs?.creator, + creation: +attrs?.create, + subject: null, + desc, + participants + } + return meta + } + + socketEvents.on('CB:Chat,cmd:action', (json: BinaryNode) => { + /*const data = json[1].data + if (data) { + const emitGroupParticipantsUpdate = (action: WAParticipantAction) => this.emitParticipantsUpdate + (json[1].id, data[2].participants.map(whatsappID), action) + const emitGroupUpdate = (data: Partial) => this.emitGroupUpdate(json[1].id, data) + + switch (data[0]) { + case "promote": + emitGroupParticipantsUpdate('promote') + break + case "demote": + emitGroupParticipantsUpdate('demote') + break + case "desc_add": + emitGroupUpdate({ ...data[2], descOwner: data[1] }) + break + default: + this.logger.debug({ unhandled: true }, json) + break + } + }*/ + }) + + return { + ...sock, + groupMetadata: async(jid: string, minimal: boolean) => { + let result: GroupMetadata + + if(minimal) result = await groupMetadataMinimal(jid) + else result = await groupMetadataFull(jid) + + return result + }, + /** + * Create a group + * @param title like, the title of the group + * @param participants people to include in the group + */ + groupCreate: async (title: string, participants: string[]) => { + const response = await groupQuery('create', null, title, participants) as WAGroupCreateResponse + const gid = response.gid + let metadata: GroupMetadata + try { + metadata = await groupMetadataFull(gid) + } catch (error) { + logger.warn (`error in group creation: ${error}, switching gid & checking`) + // if metadata is not available + const comps = gid.replace ('@g.us', '').split ('-') + response.gid = `${comps[0]}-${+comps[1] + 1}@g.us` + + metadata = await groupMetadataFull(gid) + logger.warn (`group ID switched from ${gid} to ${response.gid}`) + } + ev.emit('chats.upsert', [ + { + id: response.gid!, + name: title, + conversationTimestamp: unixTimestampSeconds(), + unreadCount: 0 + } + ]) + return metadata + }, + /** + * Leave a group + * @param jid the ID of the group + */ + groupLeave: async (id: string) => { + await groupQuery('leave', id) + ev.emit('chats.update', [ { id, readOnly: true } ]) + }, + /** + * Update the subject of the group + * @param {string} jid the ID of the group + * @param {string} title the new title of the group + */ + groupUpdateSubject: async (id: string, title: string) => { + await groupQuery('subject', id, title) + ev.emit('chats.update', [ { id, name: title } ]) + ev.emit('contacts.update', [ { id, name: title } ]) + ev.emit('groups.update', [ { id: id, subject: title } ]) + }, + /** + * Update the group description + * @param {string} jid the ID of the group + * @param {string} title the new title of the group + */ + groupUpdateDescription: async (jid: string, description: string) => { + const metadata = await groupMetadataFull(jid) + const node: BinaryNode = { + tag: 'description', + attrs: {id: generateMessageID(), prev: metadata?.descId}, + content: Buffer.from(description, 'utf-8') + } + + const response = await groupQuery ('description', jid, null, null, [node]) + ev.emit('groups.update', [ { id: jid, desc: description } ]) + return response + }, + /** + * Update participants in the group + * @param jid the ID of the group + * @param participants the people to add + */ + groupParticipantsUpdate: async(id: string, participants: string[], action: ParticipantAction) => { + const result: GroupModificationResponse = await groupQuery(action, id, null, participants) + const jids = Object.keys(result.participants || {}) + ev.emit('group-participants.update', { id, participants: jids, action }) + return jids + }, + /** Query broadcast list info */ + getBroadcastListInfo: async(jid: string) => { + interface WABroadcastListInfo { + status: number + name: string + recipients?: {id: string}[] + } + + const result = await query({ + json: ['query', 'contact', jid], + expect200: true, + requiresPhoneConnection: true + }) as WABroadcastListInfo + + const metadata: GroupMetadata = { + subject: result.name, + id: jid, + creation: undefined, + owner: getState().legacy?.user?.id, + participants: result.recipients!.map(({ id }) => ( + { id: jidNormalizedUser(id), isAdmin: false, isSuperAdmin: false } + )) + } + return metadata + }, + inviteCode: async(jid: string) => { + const response = await sock.query({ + json: ['query', 'inviteCode', jid], + expect200: true, + requiresPhoneConnection: false + }) + return response.code as string + } + } + +} +export default makeGroupsSocket \ No newline at end of file diff --git a/src/LegacySocket/index.ts b/src/LegacySocket/index.ts new file mode 100644 index 0000000..3f1f7bf --- /dev/null +++ b/src/LegacySocket/index.ts @@ -0,0 +1,12 @@ +import { LegacySocketConfig } from '../Types' +import { DEFAULT_LEGACY_CONNECTION_CONFIG } from '../Defaults' +import _makeLegacySocket from './groups' +// export the last socket layer +const makeLegacySocket = (config: Partial) => ( + _makeLegacySocket({ + ...DEFAULT_LEGACY_CONNECTION_CONFIG, + ...config + }) +) + +export default makeLegacySocket \ No newline at end of file diff --git a/src/LegacySocket/messages.ts b/src/LegacySocket/messages.ts new file mode 100644 index 0000000..83d6f58 --- /dev/null +++ b/src/LegacySocket/messages.ts @@ -0,0 +1,536 @@ +import { BinaryNode, getBinaryNodeMessages, isJidGroup, jidNormalizedUser, areJidsSameUser } from "../WABinary"; +import { Boom } from '@hapi/boom' +import { Chat, WAMessageCursor, WAMessage, LegacySocketConfig, WAMessageKey, ParticipantAction, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo, MessageInfoUpdate, WAMessageUpdate } from "../Types"; +import { toNumber, generateWAMessage, decryptMediaMessageBuffer, extractMessageContent, getWAUploadToServer } from "../Utils"; +import makeChatsSocket from "./chats"; +import { WA_DEFAULT_EPHEMERAL } from "../Defaults"; +import { proto } from "../../WAProto"; + +const STATUS_MAP = { + read: WAMessageStatus.READ, + message: WAMessageStatus.DELIVERY_ACK, + error: WAMessageStatus.ERROR +} as { [_: string]: WAMessageStatus } + +const makeMessagesSocket = (config: LegacySocketConfig) => { + const { logger } = config + const sock = makeChatsSocket(config) + const { + ev, + ws: socketEvents, + query, + generateMessageTag, + currentEpoch, + setQuery, + getState + } = sock + + let mediaConn: Promise + const refreshMediaConn = async(forceGet = false) => { + let media = await mediaConn + if (!media || forceGet || (new Date().getTime()-media.fetchDate.getTime()) > media.ttl*1000) { + mediaConn = (async() => { + const {media_conn} = await query({ + json: ['query', 'mediaConn'], + requiresPhoneConnection: false + }) + media_conn.fetchDate = new Date() + return media_conn as MediaConnInfo + })() + } + return mediaConn + } + + const fetchMessagesFromWA = async( + jid: string, + count: number, + cursor?: WAMessageCursor + ) => { + let key: WAMessageKey + if(cursor) { + key = 'before' in cursor ? cursor.before : cursor.after + } + const { content }:BinaryNode = await query({ + json: { + tag: 'query', + attrs: { + epoch: currentEpoch().toString(), + type: 'message', + jid: jid, + kind: !cursor || 'before' in cursor ? 'before' : 'after', + count: count.toString(), + index: key?.id, + owner: key?.fromMe === false ? 'false' : 'true', + } + }, + binaryTag: [WAMetric.queryMessages, WAFlag.ignore], + expect200: false, + requiresPhoneConnection: true + }) + if(Array.isArray(content)) { + return content.map(data => proto.WebMessageInfo.decode(data.content as Buffer)) + } + return [] + } + + const updateMediaMessage = async(message: WAMessage) => { + const content = message.message?.audioMessage || message.message?.videoMessage || message.message?.imageMessage || message.message?.stickerMessage || message.message?.documentMessage + if (!content) throw new Boom( + `given message ${message.key.id} is not a media message`, + { statusCode: 400, data: message } + ) + + const response: BinaryNode = await query ({ + json: { + tag: 'query', + attrs: { + type: 'media', + index: message.key.id, + owner: message.key.fromMe ? 'true' : 'false', + jid: message.key.remoteJid, + epoch: currentEpoch().toString() + } + }, + binaryTag: [WAMetric.queryMedia, WAFlag.ignore], + expect200: true, + requiresPhoneConnection: true + }) + const attrs = response.attrs + Object.assign(content, attrs) // update message + + ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]) + + return response + } + + const onMessage = (message: WAMessage, type: MessageUpdateType | 'update') => { + const jid = message.key.remoteJid! + // store chat updates in this + const chatUpdate: Partial = { + id: jid, + } + + const emitGroupUpdate = (update: Partial) => { + ev.emit('groups.update', [ { id: jid, ...update } ]) + } + + if(message.message) { + chatUpdate.conversationTimestamp = +toNumber(message.messageTimestamp) + // add to count if the message isn't from me & there exists a message + if(!message.key.fromMe) { + chatUpdate.unreadCount = 1 + const participant = jidNormalizedUser(message.participant || jid) + + ev.emit( + 'presence.update', + { + id: jid, + presences: { [participant]: { lastKnownPresence: 'available' } } + } + ) + } + } + + const ephemeralProtocolMsg = message.message?.ephemeralMessage?.message?.protocolMessage + if ( + ephemeralProtocolMsg && + ephemeralProtocolMsg.type === proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING + ) { + chatUpdate.ephemeralSettingTimestamp = message.messageTimestamp + chatUpdate.ephemeralExpiration = ephemeralProtocolMsg.ephemeralExpiration + + if(isJidGroup(jid)) { + emitGroupUpdate({ ephemeralDuration: ephemeralProtocolMsg.ephemeralExpiration || null }) + } + } + const protocolMessage = message.message?.protocolMessage + // if it's a message to delete another message + if (protocolMessage) { + switch (protocolMessage.type) { + case proto.ProtocolMessage.ProtocolMessageType.REVOKE: + const key = protocolMessage.key + const messageStubType = WAMessageStubType.REVOKE + ev.emit('messages.update', [ + { + // the key of the deleted message is updated + update: { message: null, key: message.key, messageStubType }, + key + } + ]) + return + default: + break + } + } + + // check if the message is an action + if (message.messageStubType) { + const { user } = getState().legacy! + //let actor = jidNormalizedUser (message.participant) + let participants: string[] + const emitParticipantsUpdate = (action: ParticipantAction) => ( + ev.emit('group-participants.update', { id: jid, participants, action }) + ) + + switch (message.messageStubType) { + case WAMessageStubType.CHANGE_EPHEMERAL_SETTING: + chatUpdate.ephemeralSettingTimestamp = message.messageTimestamp + chatUpdate.ephemeralExpiration = +message.messageStubParameters[0] + if(isJidGroup(jid)) { + emitGroupUpdate({ ephemeralDuration: +message.messageStubParameters[0] || null }) + } + break + case WAMessageStubType.GROUP_PARTICIPANT_LEAVE: + case WAMessageStubType.GROUP_PARTICIPANT_REMOVE: + participants = message.messageStubParameters.map (jidNormalizedUser) + emitParticipantsUpdate('remove') + // mark the chat read only if you left the group + if (participants.includes(user.id)) { + chatUpdate.readOnly = true + } + break + case WAMessageStubType.GROUP_PARTICIPANT_ADD: + case WAMessageStubType.GROUP_PARTICIPANT_INVITE: + case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN: + participants = message.messageStubParameters.map (jidNormalizedUser) + if (participants.includes(user.id)) { + chatUpdate.readOnly = null + } + emitParticipantsUpdate('add') + break + case WAMessageStubType.GROUP_CHANGE_ANNOUNCE: + const announce = message.messageStubParameters[0] === 'on' + emitGroupUpdate({ announce }) + break + case WAMessageStubType.GROUP_CHANGE_RESTRICT: + const restrict = message.messageStubParameters[0] === 'on' + emitGroupUpdate({ restrict }) + break + case WAMessageStubType.GROUP_CHANGE_SUBJECT: + case WAMessageStubType.GROUP_CREATE: + chatUpdate.name = message.messageStubParameters[0] + emitGroupUpdate({ subject: chatUpdate.name }) + break + } + } + + if(Object.keys(chatUpdate).length > 1) { + ev.emit('chats.update', [chatUpdate]) + } + if(type === 'update') { + ev.emit('messages.update', [ { update: message, key: message.key } ]) + } else { + ev.emit('messages.upsert', { messages: [message], type }) + } + } + + const waUploadToServer = getWAUploadToServer(config, refreshMediaConn) + + /** Query a string to check if it has a url, if it does, return WAUrlInfo */ + const generateUrlInfo = async(text: string) => { + const response: BinaryNode = await query({ + json: { + tag: 'query', + attrs: { + type: 'url', + url: text, + epoch: currentEpoch().toString() + } + }, + binaryTag: [26, WAFlag.ignore], + expect200: true, + requiresPhoneConnection: false + }) + const urlInfo = { ...response.attrs } as any as WAUrlInfo + if(response && response.content) { + urlInfo.jpegThumbnail = response.content as Buffer + } + return urlInfo + } + + /** Relay (send) a WAMessage; more advanced functionality to send a built WA Message, you may want to stick with sendMessage() */ + const relayWAMessage = async(message: WAMessage, { waitForAck } = { waitForAck: true }) => { + const json: BinaryNode = { + tag: 'action', + attrs: { epoch: currentEpoch().toString(), type: 'relay' }, + content: [ + { + tag: 'message', + attrs: {}, + content: proto.WebMessageInfo.encode(message).finish() + } + ] + } + const isMsgToMe = areJidsSameUser(message.key.remoteJid, getState().legacy.user?.id || '') + const flag = isMsgToMe ? WAFlag.acknowledge : WAFlag.ignore // acknowledge when sending message to oneself + const mID = message.key.id + const finalState = isMsgToMe ? WAMessageStatus.READ : WAMessageStatus.SERVER_ACK + + message.status = WAMessageStatus.PENDING + const promise = query({ + json, + binaryTag: [WAMetric.message, flag], + tag: mID, + expect200: true, + requiresPhoneConnection: true + }) + + if(waitForAck) { + await promise + message.status = finalState + } else { + const emitUpdate = (status: WAMessageStatus) => { + message.status = status + ev.emit('messages.update', [ { key: message.key, update: { status } } ]) + } + promise + .then(() => emitUpdate(finalState)) + .catch(() => emitUpdate(WAMessageStatus.ERROR)) + } + if(config.emitOwnEvents) { + onMessage(message, 'append') + } + } + + // messages received + const messagesUpdate = (node: BinaryNode, type: 'prepend' | 'last') => { + const messages = getBinaryNodeMessages(node) + messages.reverse() + ev.emit('messages.upsert', { messages, type }) + } + + socketEvents.on('CB:action,add:last', json => messagesUpdate(json, 'last')) + socketEvents.on('CB:action,add:unread', json => messagesUpdate(json, 'prepend')) + socketEvents.on('CB:action,add:before', json => messagesUpdate(json, 'prepend')) + + // new messages + socketEvents.on('CB:action,add:relay,message', (node: BinaryNode) => { + const msgs = getBinaryNodeMessages(node) + for(const msg of msgs) { + onMessage(msg, 'notify') + } + }) + // If a message has been updated (usually called when a video message gets its upload url, or live locations) + socketEvents.on ('CB:action,add:update,message', (node: BinaryNode) => { + const msgs = getBinaryNodeMessages(node) + for(const msg of msgs) { + onMessage(msg, 'update') + } + }) + // message status updates + const onMessageStatusUpdate = ({ content }: BinaryNode) => { + if(Array.isArray(content)) { + const updates: WAMessageUpdate[] = [] + for(const { attrs: json } of content) { + const key: WAMessageKey = { + remoteJid: jidNormalizedUser(json.jid), + id: json.index, + fromMe: json.owner === 'true' + } + const status = STATUS_MAP[json.type] + + if(status) { + updates.push({ key, update: { status } }) + } else { + logger.warn({ content, key }, 'got unknown status update for message') + } + } + ev.emit('messages.update', updates) + } + } + const onMessageInfoUpdate = ([,attributes]: [string,{[_: string]: any}]) => { + let ids = attributes.id as string[] | string + if(typeof ids === 'string') { + ids = [ids] + } + let updateKey: keyof MessageInfoUpdate['update'] + switch(attributes.ack.toString()) { + case '2': + updateKey = 'deliveries' + break + case '3': + updateKey = 'reads' + break + default: + logger.warn({ attributes }, `received unknown message info update`) + return + } + const keyPartial = { + remoteJid: jidNormalizedUser(attributes.to), + fromMe: areJidsSameUser(attributes.from, getState().legacy?.user?.id || ''), + } + const updates = ids.map(id => ({ + key: { ...keyPartial, id }, + update: { + [updateKey]: { [jidNormalizedUser(attributes.participant || attributes.to)]: new Date(+attributes.t) } + } + })) + ev.emit('message-info.update', updates) + // for individual messages + // it means the message is marked read/delivered + if(!isJidGroup(keyPartial.remoteJid)) { + ev.emit('messages.update', ids.map(id => ( + { + key: { ...keyPartial, id }, + update: { + status: updateKey === 'deliveries' ? WAMessageStatus.DELIVERY_ACK : WAMessageStatus.READ + } + } + ))) + } + } + + socketEvents.on('CB:action,add:relay,received', onMessageStatusUpdate) + socketEvents.on('CB:action,,received', onMessageStatusUpdate) + + socketEvents.on('CB:Msg', onMessageInfoUpdate) + socketEvents.on('CB:MsgInfo', onMessageInfoUpdate) + + return { + ...sock, + relayWAMessage, + generateUrlInfo, + messageInfo: async(jid: string, messageID: string) => { + const { content }: BinaryNode = await query({ + json: { + tag: 'query', + attrs: {type: 'message_info', index: messageID, jid: jid, epoch: currentEpoch().toString()} + }, + binaryTag: [WAMetric.queryRead, WAFlag.ignore], + expect200: true, + requiresPhoneConnection: true + }) + const info: MessageInfo = { reads: {}, deliveries: {} } + if(Array.isArray(content)) { + for(const { tag, content: innerData } of content) { + const [{ attrs }] = (innerData as BinaryNode[]) + const jid = jidNormalizedUser(attrs.jid) + const date = new Date(+attrs.t * 1000) + switch(tag) { + case 'read': + info.reads[jid] = date + break + case 'delivery': + info.deliveries[jid] = date + break + } + } + } + return info + }, + downloadMediaMessage: async(message: WAMessage, type: 'buffer' | 'stream' = 'buffer') => { + + const downloadMediaMessage = async () => { + let mContent = extractMessageContent(message.message) + if (!mContent) throw new Boom('No message present', { statusCode: 400, data: message }) + + const stream = await decryptMediaMessageBuffer(mContent) + if(type === 'buffer') { + let buffer = Buffer.from([]) + for await(const chunk of stream) { + buffer = Buffer.concat([buffer, chunk]) + } + return buffer + } + return stream + } + + try { + const result = await downloadMediaMessage() + return result + } catch (error) { + if(error.message.includes('404')) { // media needs to be updated + logger.info (`updating media of message: ${message.key.id}`) + + await updateMediaMessage(message) + + const result = await downloadMediaMessage() + return result + } + throw error + } + }, + updateMediaMessage, + fetchMessagesFromWA, + /** Load a single message specified by the ID */ + loadMessageFromWA: async(jid: string, id: string) => { + let message: WAMessage + + // load the message before the given message + let messages = (await fetchMessagesFromWA(jid, 1, { before: {id, fromMe: true} })) + if(!messages[0]) messages = (await fetchMessagesFromWA(jid, 1, { before: {id, fromMe: false} })) + // the message after the loaded message is the message required + const [actual] = await fetchMessagesFromWA(jid, 1, { after: messages[0] && messages[0].key }) + message = actual + return message + }, + searchMessages: async(txt: string, inJid: string | null, count: number, page: number) => { + const node: BinaryNode = await query({ + json: { + tag: 'query', + attrs: { + epoch: currentEpoch().toString(), + type: 'search', + search: txt, + count: count.toString(), + page: page.toString(), + jid: inJid + } + }, + binaryTag: [24, WAFlag.ignore], + expect200: true + }) // encrypt and send off + + return { + last: node.attrs?.last === 'true', + messages: getBinaryNodeMessages(node) + } + }, + sendWAMessage: async( + jid: string, + content: AnyMessageContent, + options: MiscMessageGenerationOptions & { waitForAck?: boolean } = { waitForAck: true } + ) => { + const userJid = getState().legacy.user?.id + if( + typeof content === 'object' && + 'disappearingMessagesInChat' in content && + typeof content['disappearingMessagesInChat'] !== 'undefined' && + isJidGroup(jid) + ) { + const { disappearingMessagesInChat } = content + const value = typeof disappearingMessagesInChat === 'boolean' ? + (disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : + disappearingMessagesInChat + const tag = generateMessageTag(true) + await setQuery([ + { + tag: 'group', + attrs: { id: tag, jid, type: 'prop', author: userJid }, + content: [ + { tag: 'ephemeral', attrs: { value: value.toString() } } + ] + } + ]) + } else { + const msg = await generateWAMessage( + jid, + content, + { + ...options, + logger, + userJid: userJid, + getUrlInfo: generateUrlInfo, + upload: waUploadToServer, + mediaCache: config.mediaCache + } + ) + + await relayWAMessage(msg, { waitForAck: options.waitForAck }) + return msg + } + } + } +} + +export default makeMessagesSocket \ No newline at end of file diff --git a/src/LegacySocket/socket.ts b/src/LegacySocket/socket.ts new file mode 100644 index 0000000..5f7c3bf --- /dev/null +++ b/src/LegacySocket/socket.ts @@ -0,0 +1,393 @@ +import { Boom } from '@hapi/boom' +import { STATUS_CODES } from "http" +import { promisify } from "util" +import WebSocket from "ws" +import { BinaryNode, encodeBinaryNodeLegacy } from "../WABinary" +import { DisconnectReason, LegacySocketConfig, SocketQueryOptions, SocketSendMessageOptions, WAFlag, WAMetric, WATag } from "../Types" +import { aesEncrypt, hmacSign, promiseTimeout, unixTimestampSeconds, decodeWAMessage } from "../Utils" +import { DEFAULT_ORIGIN, DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, PHONE_CONNECTION_CB } from "../Defaults" + +/** + * Connects to WA servers and performs: + * - simple queries (no retry mechanism, wait for connection establishment) + * - listen to messages and emit events + * - query phone connection + */ +export const makeSocket = ({ + waWebSocketUrl, + connectTimeoutMs, + phoneResponseTimeMs, + logger, + agent, + keepAliveIntervalMs, + expectResponseTimeout, +}: LegacySocketConfig) => { + // for generating tags + const referenceDateSeconds = unixTimestampSeconds(new Date()) + const ws = new WebSocket(waWebSocketUrl, undefined, { + origin: DEFAULT_ORIGIN, + timeout: connectTimeoutMs, + agent, + headers: { + 'Accept-Encoding': 'gzip, deflate, br', + 'Accept-Language': 'en-US,en;q=0.9', + 'Cache-Control': 'no-cache', + 'Host': 'web.whatsapp.com', + 'Pragma': 'no-cache', + 'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits', + } + }) + ws.setMaxListeners(0) + let lastDateRecv: Date + let epoch = 0 + let authInfo: { encKey: Buffer, macKey: Buffer } + let keepAliveReq: NodeJS.Timeout + + let phoneCheckInterval: NodeJS.Timeout + let phoneCheckListeners = 0 + + const phoneConnectionChanged = (value: boolean) => { + ws.emit('phone-connection', { value }) + } + + const sendPromise = promisify(ws.send) + /** generate message tag and increment epoch */ + const generateMessageTag = (longTag: boolean = false) => { + const tag = `${longTag ? referenceDateSeconds : (referenceDateSeconds%1000)}.--${epoch}` + epoch += 1 // increment message count, it makes the 'epoch' field when sending binary messages + return tag + } + const sendRawMessage = (data: Buffer | string) => sendPromise.call(ws, data) as Promise + /** + * Send a message to the WA servers + * @returns the tag attached in the message + * */ + const sendMessage = async( + { json, binaryTag, tag, longTag }: SocketSendMessageOptions + ) => { + tag = tag || generateMessageTag(longTag) + let data: Buffer | string + if(logger.level === 'trace') { + logger.trace({ tag, fromMe: true, json, binaryTag }, 'communication') + } + + if(binaryTag) { + if(Array.isArray(json)) { + throw new Boom('Expected BinaryNode with binary code', { statusCode: 400 }) + } + if(!authInfo) { + throw new Boom('No encryption/mac keys to encrypt node with', { statusCode: 400 }) + } + const binary = encodeBinaryNodeLegacy(json) // encode the JSON to the WhatsApp binary format + + const buff = aesEncrypt(binary, authInfo.encKey) // encrypt it using AES and our encKey + const sign = hmacSign(buff, authInfo.macKey) // sign the message using HMAC and our macKey + + data = Buffer.concat([ + Buffer.from(tag + ','), // generate & prefix the message tag + Buffer.from(binaryTag), // prefix some bytes that tell whatsapp what the message is about + sign, // the HMAC sign of the message + buff, // the actual encrypted buffer + ]) + } else { + data = `${tag},${JSON.stringify(json)}` + } + await sendRawMessage(data) + return tag + } + const end = (error: Error | undefined) => { + logger.debug({ error }, 'connection closed') + + ws.removeAllListeners('close') + ws.removeAllListeners('error') + ws.removeAllListeners('open') + ws.removeAllListeners('message') + + phoneCheckListeners = 0 + clearInterval(keepAliveReq) + clearPhoneCheckInterval() + + if(ws.readyState !== ws.CLOSED && ws.readyState !== ws.CLOSING) { + try { ws.close() } catch { } + } + + ws.emit('ws-close', error) + ws.removeAllListeners('ws-close') + } + const onMessageRecieved = (message: string | Buffer) => { + if(message[0] === '!' || message[0] === '!'.charCodeAt(0)) { + // when the first character in the message is an '!', the server is sending a pong frame + const timestamp = message.slice(1, message.length).toString() + lastDateRecv = new Date(parseInt(timestamp)) + ws.emit('received-pong') + } else { + let messageTag: string + let json: any + try { + const dec = decodeWAMessage(message, authInfo) + messageTag = dec[0] + json = dec[1] + if (!json) return + } catch (error) { + end(error) + return + } + //if (this.shouldLogMessages) this.messageLog.push ({ tag: messageTag, json: JSON.stringify(json), fromMe: false }) + + if (logger.level === 'trace') { + logger.trace({ tag: messageTag, fromMe: false, json }, 'communication') + } + + let anyTriggered = false + /* Check if this is a response to a message we sent */ + anyTriggered = ws.emit(`${DEF_TAG_PREFIX}${messageTag}`, json) + /* Check if this is a response to a message we are expecting */ + const l0 = json.tag || json[0] || '' + const l1 = json?.attrs || json?.[1] || { } + const l2 = json?.content?.[0]?.tag || json[2]?.[0] || '' + + Object.keys(l1).forEach(key => { + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, json) || anyTriggered + }) + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0}`, json) || anyTriggered + + if (!anyTriggered && logger.level === 'debug') { + logger.debug({ unhandled: true, tag: messageTag, fromMe: false, json }, 'communication recv') + } + } + } + + /** Exits a query if the phone connection is active and no response is still found */ + const exitQueryIfResponseNotExpected = (tag: string, cancel: (error: Boom) => void) => { + let timeout: NodeJS.Timeout + const listener = ([, connected]) => { + if(connected) { + timeout = setTimeout(() => { + logger.info({ tag }, `cancelling wait for message as a response is no longer expected from the phone`) + cancel(new Boom('Not expecting a response', { statusCode: 422 })) + }, expectResponseTimeout) + ws.off(PHONE_CONNECTION_CB, listener) + } + } + ws.on(PHONE_CONNECTION_CB, listener) + return () => { + ws.off(PHONE_CONNECTION_CB, listener) + timeout && clearTimeout(timeout) + } + } + /** interval is started when a query takes too long to respond */ + const startPhoneCheckInterval = () => { + phoneCheckListeners += 1 + if (!phoneCheckInterval) { + // if its been a long time and we haven't heard back from WA, send a ping + phoneCheckInterval = setInterval(() => { + if(phoneCheckListeners <= 0) { + logger.warn('phone check called without listeners') + return + } + logger.info('checking phone connection...') + sendAdminTest() + + phoneConnectionChanged(false) + }, phoneResponseTimeMs) + } + } + const clearPhoneCheckInterval = () => { + phoneCheckListeners -= 1 + if (phoneCheckListeners <= 0) { + clearInterval(phoneCheckInterval) + phoneCheckInterval = undefined + phoneCheckListeners = 0 + } + } + /** checks for phone connection */ + const sendAdminTest = () => sendMessage({ json: ['admin', 'test'] }) + /** + * Wait for a message with a certain tag to be received + * @param tag the message tag to await + * @param json query that was sent + * @param timeoutMs timeout after which the promise will reject + */ + const waitForMessage = (tag: string, requiresPhoneConnection: boolean, timeoutMs?: number) => { + if(ws.readyState !== ws.OPEN) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } + + let cancelToken = () => { } + + return { + promise: (async() => { + let onRecv: (json) => void + let onErr: (err) => void + let cancelPhoneChecker: () => void + try { + const result = await promiseTimeout(timeoutMs, + (resolve, reject) => { + onRecv = resolve + onErr = err => { + reject(err || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) + } + cancelToken = () => onErr(new Boom('Cancelled', { statusCode: 500 })) + + if(requiresPhoneConnection) { + startPhoneCheckInterval() + cancelPhoneChecker = exitQueryIfResponseNotExpected(tag, onErr) + } + + ws.on(`TAG:${tag}`, onRecv) + ws.on('ws-close', onErr) // if the socket closes, you'll never receive the message + }, + ) + return result as any + } finally { + requiresPhoneConnection && clearPhoneCheckInterval() + cancelPhoneChecker && cancelPhoneChecker() + + ws.off(`TAG:${tag}`, onRecv) + ws.off('ws-close', onErr) // if the socket closes, you'll never receive the message + } + })(), + cancelToken: () => { cancelToken() } + } + } + /** + * Query something from the WhatsApp servers + * @param json the query itself + * @param binaryTags the tags to attach if the query is supposed to be sent encoded in binary + * @param timeoutMs timeout after which the query will be failed (set to null to disable a timeout) + * @param tag the tag to attach to the message + */ + const query = async( + { json, timeoutMs, expect200, tag, longTag, binaryTag, requiresPhoneConnection }: SocketQueryOptions + ) => { + tag = tag || generateMessageTag(longTag) + const { promise, cancelToken } = waitForMessage(tag, requiresPhoneConnection, timeoutMs) + try { + await sendMessage({ json, tag, binaryTag }) + } catch(error) { + cancelToken() + // swallow error + await promise.catch(() => { }) + // throw back the error + throw error + } + + const response = await promise + const responseStatusCode = +(response.status ? response.status : 200) // default status + // read here: http://getstatuscode.com/599 + if(responseStatusCode === 599) { // the connection has gone bad + end(new Boom('WA server overloaded', { statusCode: 599, data: { query: json, response } })) + } + if(expect200 && Math.floor(responseStatusCode/100) !== 2) { + const message = STATUS_CODES[responseStatusCode] || 'unknown' + throw new Boom( + `Unexpected status in '${Array.isArray(json) ? json[0] : (json?.tag || 'query')}': ${message}(${responseStatusCode})`, + { data: { query: json, message }, statusCode: response.status } + ) + } + return response + } + const startKeepAliveRequest = () => ( + keepAliveReq = setInterval(() => { + if (!lastDateRecv) lastDateRecv = new Date() + const diff = Date.now() - lastDateRecv.getTime() + /* + check if it's been a suspicious amount of time since the server responded with our last seen + it could be that the network is down + */ + if (diff > keepAliveIntervalMs+5000) { + end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost })) + } else if(ws.readyState === ws.OPEN) { + sendRawMessage('?,,') // if its all good, send a keep alive request + } else { + logger.warn('keep alive called when WS not open') + } + }, keepAliveIntervalMs) + ) + + const waitForSocketOpen = async() => { + if(ws.readyState === ws.OPEN) return + if(ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } + let onOpen: () => void + let onClose: (err: Error) => void + await new Promise((resolve, reject) => { + onOpen = () => resolve(undefined) + onClose = reject + ws.on('open', onOpen) + ws.on('close', onClose) + ws.on('error', onClose) + }) + .finally(() => { + ws.off('open', onOpen) + ws.off('close', onClose) + ws.off('error', onClose) + }) + } + + ws.on('message', onMessageRecieved) + ws.on('open', () => { + startKeepAliveRequest() + logger.info('Opened WS connection to WhatsApp Web') + }) + ws.on('error', end) + ws.on('close', () => end(new Boom('Connection Terminated', { statusCode: DisconnectReason.connectionLost }))) + + ws.on(PHONE_CONNECTION_CB, json => { + if (!json[1]) { + end(new Boom('Connection terminated by phone', { statusCode: DisconnectReason.connectionLost })) + logger.info('Connection terminated by phone, closing...') + } else { + phoneConnectionChanged(true) + } + }) + ws.on('CB:Cmd,type:disconnect', json => { + const {kind} = json[1] + let reason: DisconnectReason + switch(kind) { + case 'replaced': + reason = DisconnectReason.connectionReplaced + break + default: + reason = DisconnectReason.connectionLost + break + } + end(new Boom( + `Connection terminated by server: "${kind || 'unknown'}"`, + { statusCode: reason } + )) + }) + + return { + ws, + updateKeys: (info: { encKey: Buffer, macKey: Buffer }) => authInfo = info, + waitForSocketOpen, + sendRawMessage, + sendMessage, + generateMessageTag, + waitForMessage, + query, + /** Generic function for action, set queries */ + setQuery: async(nodes: BinaryNode[], binaryTag: WATag = [WAMetric.group, WAFlag.ignore], tag?: string) => { + const json: BinaryNode = { + tag: 'action', + attrs: { epoch: epoch.toString(), type: 'set' }, + content: nodes + } + + return query({ + json, + binaryTag, + tag, + expect200: true, + requiresPhoneConnection: true + }) as Promise<{ status: number }> + }, + currentEpoch: () => epoch, + end + } +} \ No newline at end of file diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index e5781d6..49448e0 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -4,6 +4,7 @@ import { proto } from '../../WAProto' import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch, decodeSyncdSnapshot, newLTHashState } from "../Utils"; import { makeMessagesSocket } from "./messages-send"; import makeMutex from "../Utils/make-mutex"; +import { Boom } from "@hapi/boom"; export const makeChatsSocket = (config: SocketConfig) => { const { logger } = config @@ -425,6 +426,11 @@ export const makeChatsSocket = (config: SocketConfig) => { const appPatch = async(patchCreate: WAPatchCreate) => { const name = patchCreate.type + const myAppStateKeyId = authState.creds.myAppStateKeyId + if(!myAppStateKeyId) { + throw new Boom(`App state key not present!`, { statusCode: 400 }) + } + await mutationMutex.mutex( async() => { logger.debug({ patch: patchCreate }, 'applying app patch') @@ -433,7 +439,7 @@ export const makeChatsSocket = (config: SocketConfig) => { const { [name]: initial } = await authState.keys.get('app-state-sync-version', [name]) const { patch, state } = await encodeSyncdPatch( patchCreate, - authState.creds.myAppStateKeyId!, + myAppStateKeyId, initial, getAppStateSyncKey, ) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 811d1e7..dcc8a2f 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -1,10 +1,9 @@ -import { Boom } from "@hapi/boom" import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions } from "../Types" -import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESessions } from "../Utils" +import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESessions, getWAUploadToServer } from "../Utils" import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes, JidWithDevice, reduceBinaryNodeToDictionary } from '../WABinary' import { proto } from "../../WAProto" -import { WA_DEFAULT_EPHEMERAL, DEFAULT_ORIGIN, MEDIA_PATH_MAP } from "../Defaults" +import { WA_DEFAULT_EPHEMERAL } from "../Defaults" import { makeGroupsSocket } from "./groups" import NodeCache from "node-cache" @@ -419,58 +418,8 @@ export const makeMessagesSocket = (config: SocketConfig) => { return msgId } - const waUploadToServer: WAMediaUploadFunction = async(stream, { mediaType, fileEncSha256B64, timeoutMs }) => { - const { default: got } = await import('got') - // send a query JSON to obtain the url & auth token to upload our media - let uploadInfo = await refreshMediaConn(false) - - let urls: { mediaUrl: string, directPath: string } - const hosts = [ ...config.customUploadHosts, ...uploadInfo.hosts.map(h => h.hostname) ] - for (let hostname of hosts) { - const auth = encodeURIComponent(uploadInfo.auth) // the auth token - const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` - - try { - const {body: responseText} = await got.post( - url, - { - headers: { - 'Content-Type': 'application/octet-stream', - 'Origin': DEFAULT_ORIGIN - }, - agent: { - https: config.agent - }, - body: stream, - timeout: timeoutMs - } - ) - const result = JSON.parse(responseText) - - if(result?.url || result?.directPath) { - urls = { - mediaUrl: result.url, - directPath: result.direct_path - } - break - } else { - uploadInfo = await refreshMediaConn(true) - throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) - } - } catch (error) { - const isLast = hostname === hosts[uploadInfo.hosts.length-1] - logger.debug(`Error in uploading to ${hostname} (${error}) ${isLast ? '' : ', retrying...'}`) - } - } - if (!urls) { - throw new Boom( - 'Media upload failed on all hosts', - { statusCode: 500 } - ) - } - return urls - } - + const waUploadToServer = getWAUploadToServer(config, refreshMediaConn) + return { ...sock, assertSessions, diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 428b103..3aa0073 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -530,7 +530,7 @@ export const makeSocket = ({ }) ws.on('CB:ib,,downgrade_webclient', () => { - end(new Boom('Multi-device beta not joined', { statusCode: DisconnectReason.notJoinedBeta })) + end(new Boom('Multi-device beta not joined', { statusCode: DisconnectReason.multideviceMismatch })) }) process.nextTick(() => { diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts index 1e9eedd..cd88192 100644 --- a/src/Types/Auth.ts +++ b/src/Types/Auth.ts @@ -1,6 +1,5 @@ import type { Contact } from "./Contact" import type { proto } from "../../WAProto" -import type { WAPatchName } from "./Chat" export type KeyPair = { public: Uint8Array, private: Uint8Array } export type SignedKeyPair = { keyPair: KeyPair, signature: Uint8Array, keyId: number } diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index e5656cb..a959c91 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -38,7 +38,7 @@ export type ChatModification = mute: number | null } | { - clear: 'all' | { message: {id: string, fromMe?: boolean} } + clear: 'all' | { messages: {id: string, fromMe?: boolean}[] } } | { star: { diff --git a/src/Types/Events.ts b/src/Types/Events.ts new file mode 100644 index 0000000..33889a7 --- /dev/null +++ b/src/Types/Events.ts @@ -0,0 +1,56 @@ +import type EventEmitter from "events" + +import { AuthenticationCreds } from './Auth' +import { Chat, PresenceData } from './Chat' +import { Contact } from './Contact' +import { ConnectionState } from './State' + +import { GroupMetadata, ParticipantAction } from './GroupMetadata' +import { MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageUpdate, WAMessageKey } from './Message' + +export type BaileysEventMap = { + /** connection state has been updated -- WS closed, opened, connecting etc. */ + 'connection.update': Partial + /** credentials updated -- some metadata, keys or something */ + 'creds.update': Partial + /** set chats (history sync), messages are reverse chronologically sorted */ + 'chats.set': { chats: Chat[], messages: WAMessage[] } + /** upsert chats */ + 'chats.upsert': Chat[] + /** update the given chats */ + 'chats.update': Partial[] + /** delete chats with given ID */ + 'chats.delete': string[] + /** presence of contact in a chat updated */ + 'presence.update': { id: string, presences: { [participant: string]: PresenceData } } + + 'contacts.upsert': Contact[] + 'contacts.update': Partial[] + + 'messages.delete': { keys: WAMessageKey[] } | { jid: string, all: true } + 'messages.update': WAMessageUpdate[] + /** + * add/update the given messages. If they were received while the connection was online, + * the update will have type: "notify" + * */ + 'messages.upsert': { messages: WAMessage[], type: MessageUpdateType } + + 'message-info.update': MessageInfoUpdate[] + + 'groups.upsert': GroupMetadata[] + 'groups.update': Partial[] + /** apply an action to participants in a group */ + 'group-participants.update': { id: string, participants: string[], action: ParticipantAction } + + 'blocklist.set': { blocklist: string[] } + 'blocklist.update': { blocklist: string[], type: 'add' | 'remove' } +} + +export interface CommonBaileysEventEmitter extends EventEmitter { + on>(event: T, listener: (arg: BaileysEventMap[T]) => void): this + off>(event: T, listener: (arg: BaileysEventMap[T]) => void): this + removeAllListeners>(event: T): this + emit>(event: T, arg: BaileysEventMap[T]): boolean +} + +export type BaileysEventEmitter = CommonBaileysEventEmitter \ No newline at end of file diff --git a/src/Types/Legacy.ts b/src/Types/Legacy.ts new file mode 100644 index 0000000..688c122 --- /dev/null +++ b/src/Types/Legacy.ts @@ -0,0 +1,83 @@ +import { CommonSocketConfig } from "./Socket" +import { CommonBaileysEventEmitter } from "./Events" +import { BinaryNode } from "../WABinary" + +export interface LegacyAuthenticationCreds { + clientID: string + serverToken: string + clientToken: string + encKey: Buffer + macKey: Buffer +} + +/** used for binary messages */ +export enum WAMetric { + debugLog = 1, + queryResume = 2, + liveLocation = 3, + queryMedia = 4, + queryChat = 5, + queryContact = 6, + queryMessages = 7, + presence = 8, + presenceSubscribe = 9, + group = 10, + read = 11, + chat = 12, + received = 13, + picture = 14, + status = 15, + message = 16, + queryActions = 17, + block = 18, + queryGroup = 19, + queryPreview = 20, + queryEmoji = 21, + queryRead = 22, + queryVCard = 29, + queryStatus = 30, + queryStatusUpdate = 31, + queryLiveLocation = 33, + queryLabel = 36, + queryQuickReply = 39 +} + +/** used for binary messages */ +export enum WAFlag { + available = 160, + other = 136, // don't know this one + ignore = 1 << 7, + acknowledge = 1 << 6, + unavailable = 1 << 4, + expires = 1 << 3, + composing = 1 << 2, + recording = 1 << 2, + paused = 1 << 2 +} + +/** Tag used with binary queries */ +export type WATag = [WAMetric, WAFlag] + +export type SocketSendMessageOptions = { + json: BinaryNode | any[] + binaryTag?: WATag + tag?: string + longTag?: boolean +} + +export type SocketQueryOptions = SocketSendMessageOptions & { + timeoutMs?: number + expect200?: boolean + requiresPhoneConnection?: boolean +} + +export type LegacySocketConfig = CommonSocketConfig & { + /** max time for the phone to respond to a connectivity test */ + phoneResponseTimeMs: number + /** max time for WA server to respond before error with 422 */ + expectResponseTimeout: number + + pendingRequestTimeoutMs: number +} + +export type LegacyBaileysEventEmitter = CommonBaileysEventEmitter \ No newline at end of file diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 2162545..c06d029 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -155,7 +155,7 @@ export type MessageContentGenerationOptions = MediaGenerationOptions & { } export type MessageGenerationOptions = MessageContentGenerationOptions & MessageGenerationOptionsFromContent -export type MessageUpdateType = 'append' | 'notify' | 'prepend' +export type MessageUpdateType = 'append' | 'notify' | 'prepend' | 'last' export type MessageInfoEventMap = { [jid: string]: Date } export interface MessageInfo { diff --git a/src/Types/Socket.ts b/src/Types/Socket.ts new file mode 100644 index 0000000..b9d8f42 --- /dev/null +++ b/src/Types/Socket.ts @@ -0,0 +1,39 @@ + +import type { Agent } from "https" +import type { Logger } from "pino" +import type { URL } from "url" +import type NodeCache from 'node-cache' + +export type WAVersion = [number, number, number] +export type WABrowserDescription = [string, string, string] + +export type CommonSocketConfig = { + /** provide an auth state object to maintain the auth state */ + auth?: T + /** the WS url to connect to WA */ + waWebSocketUrl: string | URL + /** Fails the connection if the socket times out in this interval */ + connectTimeoutMs: number + /** Default timeout for queries, undefined for no timeout */ + defaultQueryTimeoutMs: number | undefined + /** ping-pong interval for WS connection */ + keepAliveIntervalMs: number + /** proxy agent */ + agent?: Agent + /** pino logger */ + logger: Logger + /** version to connect with */ + version: WAVersion + /** override browser config */ + browser: WABrowserDescription + /** agent used for fetch requests -- uploading/downloading media */ + fetchAgent?: Agent + /** should the QR be printed in the terminal */ + printQRInTerminal: boolean + /** should events be emitted for actions done by this socket connection */ + emitOwnEvents: boolean + /** provide a cache to store media, so does not have to be re-uploaded */ + mediaCache?: NodeCache + + customUploadHosts: string[] +} diff --git a/src/Types/State.ts b/src/Types/State.ts index 754ff32..e7f0cec 100644 --- a/src/Types/State.ts +++ b/src/Types/State.ts @@ -1,3 +1,5 @@ +import { Contact } from "./Contact" + export type WAConnectionState = 'open' | 'connecting' | 'close' export type ConnectionState = { @@ -13,5 +15,11 @@ export type ConnectionState = { /** the current QR code */ qr?: string /** has the device received all pending notifications while it was offline */ - receivedPendingNotifications?: boolean + receivedPendingNotifications?: boolean + /** legacy connection options */ + legacy?: { + phoneConnected: boolean + user?: Contact + } + } \ No newline at end of file diff --git a/src/Types/index.ts b/src/Types/index.ts index 680190f..641bedb 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -4,11 +4,11 @@ export * from './Chat' export * from './Contact' export * from './State' export * from './Message' +export * from './Legacy' +export * from './Socket' +export * from './Events' import type EventEmitter from "events" -import type { Agent } from "https" -import type { Logger } from "pino" -import type { URL } from "url" import type NodeCache from 'node-cache' import { AuthenticationState, AuthenticationCreds } from './Auth' @@ -19,40 +19,11 @@ import { ConnectionState } from './State' import { GroupMetadata, ParticipantAction } from './GroupMetadata' import { MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageUpdate, WAMessageKey } from './Message' import { proto } from '../../WAProto' +import { CommonSocketConfig } from './Socket' -export type WAVersion = [number, number, number] -export type WABrowserDescription = [string, string, string] -export type ReconnectMode = 'no-reconnects' | 'on-any-error' | 'on-connection-error' - -export type SocketConfig = { - /** provide an auth state object to maintain the auth state */ - auth?: AuthenticationState - /** the WS url to connect to WA */ - waWebSocketUrl: string | URL - /** Fails the connection if the socket times out in this interval */ - connectTimeoutMs: number - /** Default timeout for queries, undefined for no timeout */ - defaultQueryTimeoutMs: number | undefined - /** ping-pong interval for WS connection */ - keepAliveIntervalMs: number - /** proxy agent */ - agent?: Agent - /** pino logger */ - logger: Logger - /** version to connect with */ - version: WAVersion - /** override browser config */ - browser: WABrowserDescription - /** agent used for fetch requests -- uploading/downloading media */ - fetchAgent?: Agent - /** should the QR be printed in the terminal */ - printQRInTerminal: boolean - /** should events be emitted for actions done by this socket connection */ - emitOwnEvents: boolean +export type SocketConfig = CommonSocketConfig & { /** provide a cache to store a user's device list */ userDevicesCache?: NodeCache - /** provide a cache to store media, so does not have to be re-uploaded */ - mediaCache?: NodeCache /** map to store the retry counts for failed messages */ msgRetryCounterMap?: { [msgId: string]: number } /** custom domains to push media via */ @@ -67,11 +38,12 @@ export type SocketConfig = { export enum DisconnectReason { connectionClosed = 428, connectionLost = 408, + connectionReplaced = 440, timedOut = 408, loggedOut = 401, badSession = 500, restartRequired = 410, - notJoinedBeta = 403 + multideviceMismatch = 403 } export type WAInitResponse = { @@ -104,11 +76,11 @@ export type WABusinessProfile = { export type CurveKeyPair = { private: Uint8Array; public: Uint8Array } -export type BaileysEventMap = { +export type BaileysEventMap = { /** connection state has been updated -- WS closed, opened, connecting etc. */ 'connection.update': Partial /** credentials updated -- some metadata, keys or something */ - 'creds.update': Partial + 'creds.update': Partial /** set chats (history sync), messages are reverse chronologically sorted */ 'chats.set': { chats: Chat[], messages: WAMessage[] } /** upsert chats */ @@ -141,9 +113,12 @@ export type BaileysEventMap = { 'blocklist.set': { blocklist: string[] } 'blocklist.update': { blocklist: string[], type: 'add' | 'remove' } } -export interface BaileysEventEmitter extends EventEmitter { - on(event: T, listener: (arg: BaileysEventMap[T]) => void): this - off(event: T, listener: (arg: BaileysEventMap[T]) => void): this - removeAllListeners(event: T): this - emit(event: T, arg: BaileysEventMap[T]): boolean -} \ No newline at end of file + +export interface CommonBaileysEventEmitter extends EventEmitter { + on>(event: T, listener: (arg: BaileysEventMap[T]) => void): this + off>(event: T, listener: (arg: BaileysEventMap[T]) => void): this + removeAllListeners>(event: T): this + emit>(event: T, arg: BaileysEventMap[T]): boolean +} + +export type BaileysEventEmitter = CommonBaileysEventEmitter \ No newline at end of file diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 7d62295..1d324ee 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -480,7 +480,7 @@ export const chatModificationToAppPatch = ( if(mod.clear === 'all') { throw new Boom('not supported') } else { - const key = mod.clear.message + const key = mod.clear.messages[0] patch = { syncAction: { deleteMessageForMeAction: { diff --git a/src/Utils/index.ts b/src/Utils/index.ts index a4c41fe..76448aa 100644 --- a/src/Utils/index.ts +++ b/src/Utils/index.ts @@ -9,4 +9,5 @@ export * from './noise-handler' export * from './history' export * from './chat-utils' export * from './lt-hash' -export * from './auth-utils' \ No newline at end of file +export * from './auth-utils' +export * from './legacy-msgs' \ No newline at end of file diff --git a/src/Utils/legacy-msgs.ts b/src/Utils/legacy-msgs.ts new file mode 100644 index 0000000..ba60d2b --- /dev/null +++ b/src/Utils/legacy-msgs.ts @@ -0,0 +1,173 @@ +import { Boom } from '@hapi/boom' +import { randomBytes } from 'crypto' +import { decodeBinaryNodeLegacy, jidNormalizedUser } from "../WABinary" +import { aesDecrypt, hmacSign, hkdf, Curve } from "./crypto" +import { BufferJSON } from './generics' +import { DisconnectReason, WATag, LegacyAuthenticationCreds, CurveKeyPair, Contact } from "../Types" + +export const newLegacyAuthCreds = () => ({ + clientID: randomBytes(16).toString('base64') +}) as LegacyAuthenticationCreds + +export const decodeWAMessage = ( + message: Buffer | string, + auth: { macKey: Buffer, encKey: Buffer }, + fromMe: boolean=false +) => { + let commaIndex = message.indexOf(',') // all whatsapp messages have a tag and a comma, followed by the actual message + if (commaIndex < 0) throw new Boom('invalid message', { data: message }) // if there was no comma, then this message must be not be valid + + if (message[commaIndex+1] === ',') commaIndex += 1 + let data = message.slice(commaIndex+1, message.length) + + // get the message tag. + // If a query was done, the server will respond with the same message tag we sent the query with + const messageTag: string = message.slice(0, commaIndex).toString() + let json: any + let tags: WATag + if(data.length) { + const possiblyEnc = (data.length > 32 && data.length % 16 === 0) + if(typeof data === 'string' || !possiblyEnc) { + json = JSON.parse(data.toString()) // parse the JSON + } else { + + const { macKey, encKey } = auth || {} + if (!macKey || !encKey) { + throw new Boom('recieved encrypted buffer when auth creds unavailable', { data: message, statusCode: DisconnectReason.badSession }) + } + /* + If the data recieved was not a JSON, then it must be an encrypted message. + Such a message can only be decrypted if we're connected successfully to the servers & have encryption keys + */ + if (fromMe) { + tags = [data[0], data[1]] + data = data.slice(2, data.length) + } + + const checksum = data.slice(0, 32) // the first 32 bytes of the buffer are the HMAC sign of the message + data = data.slice(32, data.length) // the actual message + const computedChecksum = hmacSign(data, macKey) // compute the sign of the message we recieved using our macKey + + if (checksum.equals(computedChecksum)) { + // the checksum the server sent, must match the one we computed for the message to be valid + const decrypted = aesDecrypt(data, encKey) // decrypt using AES + json = decodeBinaryNodeLegacy(decrypted, { index: 0 }) // decode the binary message into a JSON array + } else { + throw new Boom('Bad checksum', { + data: { + received: checksum.toString('hex'), + computed: computedChecksum.toString('hex'), + data: data.slice(0, 80).toString(), + tag: messageTag, + message: message.slice(0, 80).toString() + }, + statusCode: DisconnectReason.badSession + }) + } + } + } + return [messageTag, json, tags] as const +} + +/** +* Once the QR code is scanned and we can validate our connection, or we resolved the challenge when logging back in +* @private +* @param json +*/ +export const validateNewConnection = ( + json: { [_: string]: any }, + auth: LegacyAuthenticationCreds, + curveKeys: CurveKeyPair +) => { + // set metadata: one's WhatsApp ID [cc][number]@s.whatsapp.net, name on WhatsApp, info about the phone + const onValidationSuccess = () => { + const user: Contact = { + id: jidNormalizedUser(json.wid), + name: json.pushname + } + return { user, auth, phone: json.phone } + } + if (!json.secret) { + // if we didn't get a secret, we don't need it, we're validated + if (json.clientToken && json.clientToken !== auth.clientToken) { + auth = { ...auth, clientToken: json.clientToken } + } + if (json.serverToken && json.serverToken !== auth.serverToken) { + auth = { ...auth, serverToken: json.serverToken } + } + return onValidationSuccess() + } + const secret = Buffer.from(json.secret, 'base64') + if (secret.length !== 144) { + throw new Error ('incorrect secret length received: ' + secret.length) + } + + // generate shared key from our private key & the secret shared by the server + const sharedKey = Curve.sharedKey(curveKeys.private, secret.slice(0, 32)) + // expand the key to 80 bytes using HKDF + const expandedKey = hkdf(sharedKey as Buffer, 80, { }) + + // perform HMAC validation. + const hmacValidationKey = expandedKey.slice(32, 64) + const hmacValidationMessage = Buffer.concat([secret.slice(0, 32), secret.slice(64, secret.length)]) + + const hmac = hmacSign(hmacValidationMessage, hmacValidationKey) + + if (!hmac.equals(secret.slice(32, 64))) { + // if the checksums didn't match + throw new Boom('HMAC validation failed', { statusCode: 400 }) + } + + // computed HMAC should equal secret[32:64] + // expandedKey[64:] + secret[64:] are the keys, encrypted using AES, that are used to encrypt/decrypt the messages recieved from WhatsApp + // they are encrypted using key: expandedKey[0:32] + const encryptedAESKeys = Buffer.concat([ + expandedKey.slice(64, expandedKey.length), + secret.slice(64, secret.length), + ]) + const decryptedKeys = aesDecrypt(encryptedAESKeys, expandedKey.slice(0, 32)) + // set the credentials + auth = { + encKey: decryptedKeys.slice(0, 32), // first 32 bytes form the key to encrypt/decrypt messages + macKey: decryptedKeys.slice(32, 64), // last 32 bytes from the key to sign messages + clientToken: json.clientToken, + serverToken: json.serverToken, + clientID: auth.clientID, + } + return onValidationSuccess() +} + +export const computeChallengeResponse = (challenge: string, auth: LegacyAuthenticationCreds) => { + const bytes = Buffer.from(challenge, 'base64') // decode the base64 encoded challenge string + const signed = hmacSign(bytes, auth.macKey).toString('base64') // sign the challenge string with our macKey + return['admin', 'challenge', signed, auth.serverToken, auth.clientID] // prepare to send this signed string with the serverToken & clientID +} + +export const useSingleFileLegacyAuthState = (file: string) => { + // require fs here so that in case "fs" is not available -- the app does not crash + const { readFileSync, writeFileSync, existsSync } = require('fs') + let state: LegacyAuthenticationCreds + + if(existsSync(file)) { + state = JSON.parse( + readFileSync(file, { encoding: 'utf-8' }), + BufferJSON.reviver + ) + if(typeof state.encKey === 'string') { + state.encKey = Buffer.from(state.encKey, 'base64') + } + if(typeof state.macKey === 'string') { + state.macKey = Buffer.from(state.macKey, 'base64') + } + } else { + state = newLegacyAuthCreds() + } + + return { + state, + saveState: () => { + const str = JSON.stringify(state, BufferJSON.replacer, 2) + writeFileSync(file, str) + } + } +} \ No newline at end of file diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index ee3ed5c..8a1f077 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -4,16 +4,16 @@ import type { Options, Response } from 'got' import { Boom } from '@hapi/boom' import * as Crypto from 'crypto' import { Readable, Transform } from 'stream' -import { createReadStream, createWriteStream, promises as fs, ReadStream, WriteStream } from 'fs' +import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs' import { exec } from 'child_process' import { tmpdir } from 'os' import { URL } from 'url' import { join } from 'path' import { once } from 'events' -import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType, DownloadableMessage } from '../Types' +import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType, DownloadableMessage, CommonSocketConfig, WAMediaUploadFunction, MediaConnInfo } from '../Types' import { generateMessageID } from './generics' import { hkdf } from './crypto' -import { DEFAULT_ORIGIN } from '../Defaults' +import { DEFAULT_ORIGIN, MEDIA_PATH_MAP } from '../Defaults' const getTmpFilesDirectory = () => tmpdir() @@ -459,4 +459,58 @@ export function extensionForMediaMessage(message: WAMessageContent) { extension = getExtension (messageContent.mimetype) } return extension +} + +export const getWAUploadToServer = ({ customUploadHosts, agent, logger }: CommonSocketConfig, refreshMediaConn: (force: boolean) => Promise): WAMediaUploadFunction => { + return async(stream, { mediaType, fileEncSha256B64, timeoutMs }) => { + const { default: got } = await import('got') + // send a query JSON to obtain the url & auth token to upload our media + let uploadInfo = await refreshMediaConn(false) + + let urls: { mediaUrl: string, directPath: string } + const hosts = [ ...customUploadHosts, ...uploadInfo.hosts.map(h => h.hostname) ] + for (let hostname of hosts) { + const auth = encodeURIComponent(uploadInfo.auth) // the auth token + const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` + + try { + const {body: responseText} = await got.post( + url, + { + headers: { + 'Content-Type': 'application/octet-stream', + 'Origin': DEFAULT_ORIGIN + }, + agent: { + https: agent + }, + body: stream, + timeout: timeoutMs + } + ) + const result = JSON.parse(responseText) + + if(result?.url || result?.directPath) { + urls = { + mediaUrl: result.url, + directPath: result.direct_path + } + break + } else { + uploadInfo = await refreshMediaConn(true) + throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) + } + } catch (error) { + const isLast = hostname === hosts[uploadInfo.hosts.length-1] + logger.debug(`Error in uploading to ${hostname} (${error}) ${isLast ? '' : ', retrying...'}`) + } + } + if (!urls) { + throw new Boom( + 'Media upload failed on all hosts', + { statusCode: 500 } + ) + } + return urls + } } \ No newline at end of file diff --git a/src/WABinary/Legacy/constants.ts b/src/WABinary/Legacy/constants.ts new file mode 100644 index 0000000..a9be6d6 --- /dev/null +++ b/src/WABinary/Legacy/constants.ts @@ -0,0 +1,198 @@ + +export const Tags = { + LIST_EMPTY: 0, + STREAM_END: 2, + DICTIONARY_0: 236, + DICTIONARY_1: 237, + DICTIONARY_2: 238, + DICTIONARY_3: 239, + LIST_8: 248, + LIST_16: 249, + JID_PAIR: 250, + HEX_8: 251, + BINARY_8: 252, + BINARY_20: 253, + BINARY_32: 254, + NIBBLE_8: 255, + SINGLE_BYTE_MAX: 256, + PACKED_MAX: 254, +} +export const DoubleByteTokens = [] +export const SingleByteTokens = [ + null, + null, + null, + '200', + '400', + '404', + '500', + '501', + '502', + 'action', + 'add', + 'after', + 'archive', + 'author', + 'available', + 'battery', + 'before', + 'body', + 'broadcast', + 'chat', + 'clear', + 'code', + 'composing', + 'contacts', + 'count', + 'create', + 'debug', + 'delete', + 'demote', + 'duplicate', + 'encoding', + 'error', + 'false', + 'filehash', + 'from', + 'g.us', + 'group', + 'groups_v2', + 'height', + 'id', + 'image', + 'in', + 'index', + 'invis', + 'item', + 'jid', + 'kind', + 'last', + 'leave', + 'live', + 'log', + 'media', + 'message', + 'mimetype', + 'missing', + 'modify', + 'name', + 'notification', + 'notify', + 'out', + 'owner', + 'participant', + 'paused', + 'picture', + 'played', + 'presence', + 'preview', + 'promote', + 'query', + 'raw', + 'read', + 'receipt', + 'received', + 'recipient', + 'recording', + 'relay', + 'remove', + 'response', + 'resume', + 'retry', + 's.whatsapp.net', + 'seconds', + 'set', + 'size', + 'status', + 'subject', + 'subscribe', + 't', + 'text', + 'to', + 'true', + 'type', + 'unarchive', + 'unavailable', + 'url', + 'user', + 'value', + 'web', + 'width', + 'mute', + 'read_only', + 'admin', + 'creator', + 'short', + 'update', + 'powersave', + 'checksum', + 'epoch', + 'block', + 'previous', + '409', + 'replaced', + 'reason', + 'spam', + 'modify_tag', + 'message_info', + 'delivery', + 'emoji', + 'title', + 'description', + 'canonical-url', + 'matched-text', + 'star', + 'unstar', + 'media_key', + 'filename', + 'identity', + 'unread', + 'page', + 'page_count', + 'search', + 'media_message', + 'security', + 'call_log', + 'profile', + 'ciphertext', + 'invite', + 'gif', + 'vcard', + 'frequent', + 'privacy', + 'blacklist', + 'whitelist', + 'verify', + 'location', + 'document', + 'elapsed', + 'revoke_invite', + 'expiration', + 'unsubscribe', + 'disable', + 'vname', + 'old_jid', + 'new_jid', + 'announcement', + 'locked', + 'prop', + 'label', + 'color', + 'call', + 'offer', + 'call-id', + 'quick_reply', + 'sticker', + 'pay_t', + 'accept', + 'reject', + 'sticker_pack', + 'invalid', + 'canceled', + 'missed', + 'connected', + 'result', + 'audio', + 'video', + 'recent', +] \ No newline at end of file diff --git a/src/WABinary/Legacy/index.ts b/src/WABinary/Legacy/index.ts new file mode 100644 index 0000000..945eed0 --- /dev/null +++ b/src/WABinary/Legacy/index.ts @@ -0,0 +1,337 @@ + +import { BinaryNode } from '../types' +import { DoubleByteTokens, SingleByteTokens, Tags } from './constants' + +export const isLegacyBinaryNode = (buffer: Buffer) => { + switch(buffer[0]) { + case Tags.LIST_EMPTY: + case Tags.LIST_8: + case Tags.LIST_16: + return true + default: + return false + } +} + +function decode(buffer: Buffer, indexRef: { index: number }): BinaryNode { + + const checkEOS = (length: number) => { + if (indexRef.index + length > buffer.length) { + throw new Error('end of stream') + } + } + const next = () => { + const value = buffer[indexRef.index] + indexRef.index += 1 + return value + } + const readByte = () => { + checkEOS(1) + return next() + } + const readStringFromChars = (length: number) => { + checkEOS(length) + const value = buffer.slice(indexRef.index, indexRef.index + length) + + indexRef.index += length + return value.toString('utf-8') + } + const readBytes = (n: number) => { + checkEOS(n) + const value = buffer.slice(indexRef.index, indexRef.index + n) + indexRef.index += n + return value + } + const readInt = (n: number, littleEndian = false) => { + checkEOS(n) + let val = 0 + for (let i = 0; i < n; i++) { + const shift = littleEndian ? i : n - 1 - i + val |= next() << (shift * 8) + } + return val + } + const readInt20 = () => { + checkEOS(3) + return ((next() & 15) << 16) + (next() << 8) + next() + } + const unpackHex = (value: number) => { + if (value >= 0 && value < 16) { + return value < 10 ? '0'.charCodeAt(0) + value : 'A'.charCodeAt(0) + value - 10 + } + throw new Error('invalid hex: ' + value) + } + const unpackNibble = (value: number) => { + if (value >= 0 && value <= 9) { + return '0'.charCodeAt(0) + value + } + switch (value) { + case 10: + return '-'.charCodeAt(0) + case 11: + return '.'.charCodeAt(0) + case 15: + return '\0'.charCodeAt(0) + default: + throw new Error('invalid nibble: ' + value) + } + } + const unpackByte = (tag: number, value: number) => { + if (tag === Tags.NIBBLE_8) { + return unpackNibble(value) + } else if (tag === Tags.HEX_8) { + return unpackHex(value) + } else { + throw new Error('unknown tag: ' + tag) + } + } + const readPacked8 = (tag: number) => { + const startByte = readByte() + let value = '' + + for (let i = 0; i < (startByte & 127); i++) { + const curByte = readByte() + value += String.fromCharCode(unpackByte(tag, (curByte & 0xf0) >> 4)) + value += String.fromCharCode(unpackByte(tag, curByte & 0x0f)) + } + if (startByte >> 7 !== 0) { + value = value.slice(0, -1) + } + return value + } + const isListTag = (tag: number) => { + return tag === Tags.LIST_EMPTY || tag === Tags.LIST_8 || tag === Tags.LIST_16 + } + const readListSize = (tag: number) => { + switch (tag) { + case Tags.LIST_EMPTY: + return 0 + case Tags.LIST_8: + return readByte() + case Tags.LIST_16: + return readInt(2) + default: + throw new Error('invalid tag for list size: ' + tag) + } + } + const getToken = (index: number) => { + if (index < 3 || index >= SingleByteTokens.length) { + throw new Error('invalid token index: ' + index) + } + return SingleByteTokens[index] + } + const readString = (tag: number) => { + if (tag >= 3 && tag <= 235) { + const token = getToken(tag) + return token// === 's.whatsapp.net' ? 'c.us' : token + } + + switch (tag) { + case Tags.DICTIONARY_0: + case Tags.DICTIONARY_1: + case Tags.DICTIONARY_2: + case Tags.DICTIONARY_3: + return getTokenDouble(tag - Tags.DICTIONARY_0, readByte()) + case Tags.LIST_EMPTY: + return null + case Tags.BINARY_8: + return readStringFromChars(readByte()) + case Tags.BINARY_20: + return readStringFromChars(readInt20()) + case Tags.BINARY_32: + return readStringFromChars(readInt(4)) + case Tags.JID_PAIR: + const i = readString(readByte()) + const j = readString(readByte()) + if (typeof i === 'string' && j) { + return i + '@' + j + } + throw new Error('invalid jid pair: ' + i + ', ' + j) + case Tags.HEX_8: + case Tags.NIBBLE_8: + return readPacked8(tag) + default: + throw new Error('invalid string with tag: ' + tag) + } + } + const readList = (tag: number) => ( + [...new Array(readListSize(tag))].map(() => decode(buffer, indexRef)) + ) + const getTokenDouble = (index1: number, index2: number) => { + const n = 256 * index1 + index2 + if (n < 0 || n > DoubleByteTokens.length) { + throw new Error('invalid double token index: ' + n) + } + return DoubleByteTokens[n] + } + + const listSize = readListSize(readByte()) + const descrTag = readByte() + if (descrTag === Tags.STREAM_END) { + throw new Error('unexpected stream end') + } + const header = readString(descrTag) + const attrs: BinaryNode['attrs'] = { } + let data: BinaryNode['content'] + if (listSize === 0 || !header) { + throw new Error('invalid node') + } + // read the attributes in + + const attributesLength = (listSize - 1) >> 1 + for (let i = 0; i < attributesLength; i++) { + const key = readString(readByte()) + const b = readByte() + + attrs[key] = readString(b) + } + + if (listSize % 2 === 0) { + const tag = readByte() + if (isListTag(tag)) { + data = readList(tag) + } else { + let decoded: Buffer | string + switch (tag) { + case Tags.BINARY_8: + decoded = readBytes(readByte()) + break + case Tags.BINARY_20: + decoded = readBytes(readInt20()) + break + case Tags.BINARY_32: + decoded = readBytes(readInt(4)) + break + default: + decoded = readString(tag) + break + } + data = decoded + } + } + + return { + tag: header, + attrs, + content: data + } +} + +const encode = ({ tag, attrs, content }: BinaryNode, buffer: number[] = []) => { + + const pushByte = (value: number) => buffer.push(value & 0xff) + + const pushInt = (value: number, n: number, littleEndian=false) => { + for (let i = 0; i < n; i++) { + const curShift = littleEndian ? i : n - 1 - i + buffer.push((value >> (curShift * 8)) & 0xff) + } + } + const pushBytes = (bytes: Uint8Array | Buffer | number[]) => ( + bytes.forEach (b => buffer.push(b)) + ) + const pushInt20 = (value: number) => ( + pushBytes([(value >> 16) & 0x0f, (value >> 8) & 0xff, value & 0xff]) + ) + const writeByteLength = (length: number) => { + if (length >= 4294967296) throw new Error('string too large to encode: ' + length) + + if (length >= 1 << 20) { + pushByte(Tags.BINARY_32) + pushInt(length, 4) // 32 bit integer + } else if (length >= 256) { + pushByte(Tags.BINARY_20) + pushInt20(length) + } else { + pushByte(Tags.BINARY_8) + pushByte(length) + } + } + const writeStringRaw = (str: string) => { + const bytes = Buffer.from (str, 'utf-8') + writeByteLength(bytes.length) + pushBytes(bytes) + } + const writeToken = (token: number) => { + if (token < 245) { + pushByte(token) + } else if (token <= 500) { + throw new Error('invalid token') + } + } + const writeString = (token: string, i?: boolean) => { + if (token === 'c.us') token = 's.whatsapp.net' + + const tokenIndex = SingleByteTokens.indexOf(token) + if (!i && token === 's.whatsapp.net') { + writeToken(tokenIndex) + } else if (tokenIndex >= 0) { + if (tokenIndex < Tags.SINGLE_BYTE_MAX) { + writeToken(tokenIndex) + } else { + const overflow = tokenIndex - Tags.SINGLE_BYTE_MAX + const dictionaryIndex = overflow >> 8 + if (dictionaryIndex < 0 || dictionaryIndex > 3) { + throw new Error('double byte dict token out of range: ' + token + ', ' + tokenIndex) + } + writeToken(Tags.DICTIONARY_0 + dictionaryIndex) + writeToken(overflow % 256) + } + } else if (token) { + const jidSepIndex = token.indexOf('@') + if (jidSepIndex <= 0) { + writeStringRaw(token) + } else { + writeJid(token.slice(0, jidSepIndex), token.slice(jidSepIndex + 1, token.length)) + } + } + } + const writeJid = (left: string, right: string) => { + pushByte(Tags.JID_PAIR) + left && left.length > 0 ? writeString(left) : writeToken(Tags.LIST_EMPTY) + writeString(right) + } + const writeListStart = (listSize: number) => { + if (listSize === 0) { + pushByte(Tags.LIST_EMPTY) + } else if (listSize < 256) { + pushBytes([Tags.LIST_8, listSize]) + } else { + pushBytes([Tags.LIST_16, listSize]) + } + } + const validAttributes = Object.keys(attrs).filter(k => ( + typeof attrs[k] !== 'undefined' && attrs[k] !== null + )) + + writeListStart(2*validAttributes.length + 1 + (typeof content !== 'undefined' && content !== null ? 1 : 0)) + writeString(tag) + + validAttributes.forEach((key) => { + if(typeof attrs[key] === 'string') { + writeString(key) + writeString(attrs[key]) + } + }) + + if (typeof content === 'string') { + writeString(content, true) + } else if (Buffer.isBuffer(content)) { + writeByteLength(content.length) + pushBytes(content) + } else if (Array.isArray(content)) { + writeListStart(content.length) + for(const item of content) { + if(item) encode(item, buffer) + } + } else if(typeof content === 'undefined' || content === null) { + + } else { + throw new Error(`invalid children for header "${tag}": ${content} (${typeof content})`) + } + + return Buffer.from(buffer) +} + +export const encodeBinaryNodeLegacy = encode +export const decodeBinaryNodeLegacy = decode diff --git a/src/WABinary/index.ts b/src/WABinary/index.ts index 644a870..0633c4f 100644 --- a/src/WABinary/index.ts +++ b/src/WABinary/index.ts @@ -2,6 +2,8 @@ import { DICTIONARIES_MAP, SINGLE_BYTE_TOKEN, SINGLE_BYTE_TOKEN_MAP, DICTIONARIE import { jidDecode, jidEncode } from './jid-utils'; import { Binary, numUtf8Bytes } from '../../WABinary/Binary'; import { Boom } from '@hapi/boom'; +import { proto } from '../../WAProto'; +import { BinaryNode } from './types'; const LIST1 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '.', '�', '�', '�', '�']; const LIST2 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']; @@ -209,20 +211,6 @@ function bufferToUInt(e: Uint8Array | Buffer, t: number) { for (let i = 0; i < t; i++) a = 256 * a + e[i] return a } -/** - * the binary node WA uses internally for communication - * - * this is manipulated soley as an object and it does not have any functions. - * This is done for easy serialization, to prevent running into issues with prototypes & - * to maintain functional code structure - * */ -export type BinaryNode = { - tag: string - attrs: { [key: string]: string } - content?: BinaryNode[] | string | Uint8Array -} -export type BinaryNodeAttributes = BinaryNode['attrs'] -export type BinaryNodeData = BinaryNode['content'] export const decodeBinaryNode = (data: Binary): BinaryNode => { //U @@ -319,5 +307,19 @@ export const reduceBinaryNodeToDictionary = (node: BinaryNode, tag: string) => { return dict } +export const getBinaryNodeMessages = ({ content }: BinaryNode) => { + const msgs: proto.WebMessageInfo[] = [] + if(Array.isArray(content)) { + for(const item of content) { + if(item.tag === 'message') { + msgs.push(proto.WebMessageInfo.decode(item.content as Buffer)) + } + } + } + return msgs +} + export * from './jid-utils' -export { Binary } from '../../WABinary/Binary' \ No newline at end of file +export { Binary } from '../../WABinary/Binary' +export * from './types' +export * from './Legacy' \ No newline at end of file diff --git a/src/WABinary/types.ts b/src/WABinary/types.ts new file mode 100644 index 0000000..96e35d4 --- /dev/null +++ b/src/WABinary/types.ts @@ -0,0 +1,14 @@ +/** + * the binary node WA uses internally for communication + * + * this is manipulated soley as an object and it does not have any functions. + * This is done for easy serialization, to prevent running into issues with prototypes & + * to maintain functional code structure + * */ + export type BinaryNode = { + tag: string + attrs: { [key: string]: string } + content?: BinaryNode[] | string | Uint8Array +} +export type BinaryNodeAttributes = BinaryNode['attrs'] +export type BinaryNodeData = BinaryNode['content'] \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index fe1c58f..d445a48 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import makeWASocket from './Socket' +import makeWALegacySocket from './LegacySocket' export * from '../WAProto' export * from './Utils' @@ -7,6 +8,10 @@ export * from './Types' export * from './Defaults' export * from './WABinary' +export type WALegacySocket = ReturnType + +export { makeWALegacySocket } + export type WASocket = ReturnType export default makeWASocket \ No newline at end of file From e393f0f9a8b9f81611f94e7a5800af6c1ba9eb54 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 18 Dec 2021 16:44:31 +0530 Subject: [PATCH 232/311] chore: make APIs similar for legacy + MD --- Example/example-legacy.ts | 2 +- src/LegacySocket/auth.ts | 4 ++-- src/LegacySocket/chats.ts | 28 ++++++++++++++-------------- src/LegacySocket/groups.ts | 2 +- src/LegacySocket/messages.ts | 16 ++++++++++------ src/LegacySocket/socket.ts | 9 ++++----- src/Socket/groups.ts | 2 +- 7 files changed, 33 insertions(+), 30 deletions(-) diff --git a/Example/example-legacy.ts b/Example/example-legacy.ts index 06c6fd0..2660a80 100644 --- a/Example/example-legacy.ts +++ b/Example/example-legacy.ts @@ -22,7 +22,7 @@ const startSock = () => { await sock.sendPresenceUpdate('paused', jid) - await sock.sendWAMessage(jid, msg) + await sock.sendMessage(jid, msg) } sock.ev.on('messages.upsert', async m => { diff --git a/src/LegacySocket/auth.ts b/src/LegacySocket/auth.ts index fbae0b4..e8d87d1 100644 --- a/src/LegacySocket/auth.ts +++ b/src/LegacySocket/auth.ts @@ -64,7 +64,7 @@ const makeAuthSocket = (config: LegacySocketConfig) => { */ const logout = async() => { if(state.connection === 'open') { - await socket.sendMessage({ + await socket.sendNode({ json: ['admin', 'Conn', 'disconnect'], tag: 'goodbye' }) @@ -178,7 +178,7 @@ const makeAuthSocket = (config: LegacySocketConfig) => { return } logger.info('sending login request') - socket.sendMessage({ + socket.sendNode({ json, tag: loginTag }) diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index 67d8c00..e80ad62 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -12,14 +12,14 @@ const makeChatsSocket = (config: LegacySocketConfig) => { currentEpoch, setQuery, query, - sendMessage, + sendNode, getState } = sock const chatsDebounceTimeout = debouncedTimeout(10_000, () => sendChatsQuery(1)) const sendChatsQuery = (epoch: number) => ( - sendMessage({ + sendNode({ json: { tag: 'query', attrs: {type: 'chat', epoch: epoch.toString()} @@ -108,27 +108,27 @@ const makeChatsSocket = (config: LegacySocketConfig) => { if(connection !== 'open') return try { await Promise.all([ - sendMessage({ + sendNode({ json: { tag: 'query', attrs: {type: 'contacts', epoch: '1'} }, binaryTag: [ WAMetric.queryContact, WAFlag.ignore ] }), - sendMessage({ + sendNode({ json: { tag: 'query', attrs: {type: 'status', epoch: '1'} }, binaryTag: [ WAMetric.queryStatus, WAFlag.ignore ] }), - sendMessage({ + sendNode({ json: { tag: 'query', attrs: {type: 'quick_reply', epoch: '1'} }, binaryTag: [ WAMetric.queryQuickReply, WAFlag.ignore ] }), - sendMessage({ + sendNode({ json: { tag: 'query', attrs: {type: 'label', epoch: '1'} }, binaryTag: [ WAMetric.queryLabel, WAFlag.ignore ] }), - sendMessage({ + sendNode({ json: { tag: 'query', attrs: {type: 'emoji', epoch: '1'} }, binaryTag: [ WAMetric.queryEmoji, WAFlag.ignore ] }), - sendMessage({ + sendNode({ json: { tag: 'action', attrs: { type: 'set', epoch: '1' }, @@ -206,7 +206,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { const update: Partial = { id: jidNormalizedUser(attrs.jid) } - if (attrs.type === 'false') update.unreadCount = -1 + if(attrs.type === 'false') update.unreadCount = -1 else update.unreadCount = 0 ev.emit('chats.update', [update]) @@ -277,7 +277,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { * Modify a given chat (archive, pin etc.) * @param jid the ID of the person/group you are modifiying */ - modifyChat: async(jid: string, modification: ChatModification, chatInfo: Pick, index?: WAMessageKey) => { + chatModify: async( modification: ChatModification, jid: string, chatInfo: Pick, index?: WAMessageKey) => { let chatAttrs: BinaryNode['attrs'] = { jid: jid } let data: BinaryNode[] | undefined = undefined const stamp = unixTimestampSeconds() @@ -335,12 +335,12 @@ const makeChatsSocket = (config: LegacySocketConfig) => { * @param str phone number/jid you want to check for * @returns undefined if the number doesn't exists, otherwise the correctly formatted jid */ - isOnWhatsApp: async (str: string) => { + onWhatsApp: async(str: string) => { const { status, jid, biz } = await query({ json: ['query', 'exist', str], requiresPhoneConnection: false }) - if (status === 200) { + if(status === 200) { return { exists: true, jid: jidNormalizedUser(jid), @@ -354,7 +354,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { * @param type your presence */ sendPresenceUpdate: ( type: WAPresence, jid: string | undefined) => ( - sendMessage({ + sendNode({ binaryTag: [WAMetric.presence, WAFlag[type]], // weird stuff WA does json: { tag: 'action', @@ -373,7 +373,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { * this returns nothing, you'll receive updates in chats.update event * */ presenceSubscribe: async (jid: string) => ( - sendMessage({ json: ['action', 'presence', 'subscribe', jid] }) + sendNode({ json: ['action', 'presence', 'subscribe', jid] }) ), /** Query the status of the person (see groupMetadata() for groups) */ getStatus: async(jid: string) => { diff --git a/src/LegacySocket/groups.ts b/src/LegacySocket/groups.ts index b4bba8b..053de2d 100644 --- a/src/LegacySocket/groups.ts +++ b/src/LegacySocket/groups.ts @@ -224,7 +224,7 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { } return metadata }, - inviteCode: async(jid: string) => { + groupInviteCode: async(jid: string) => { const response = await sock.query({ json: ['query', 'inviteCode', jid], expect200: true, diff --git a/src/LegacySocket/messages.ts b/src/LegacySocket/messages.ts index 83d6f58..fbde9a7 100644 --- a/src/LegacySocket/messages.ts +++ b/src/LegacySocket/messages.ts @@ -249,7 +249,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { } /** Relay (send) a WAMessage; more advanced functionality to send a built WA Message, you may want to stick with sendMessage() */ - const relayWAMessage = async(message: WAMessage, { waitForAck } = { waitForAck: true }) => { + const relayMessage = async(message: WAMessage, { waitForAck } = { waitForAck: true }) => { const json: BinaryNode = { tag: 'action', attrs: { epoch: currentEpoch().toString(), type: 'relay' }, @@ -388,13 +388,18 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { return { ...sock, - relayWAMessage, + relayMessage, generateUrlInfo, messageInfo: async(jid: string, messageID: string) => { const { content }: BinaryNode = await query({ json: { tag: 'query', - attrs: {type: 'message_info', index: messageID, jid: jid, epoch: currentEpoch().toString()} + attrs: { + type: 'message_info', + index: messageID, + jid: jid, + epoch: currentEpoch().toString() + } }, binaryTag: [WAMetric.queryRead, WAFlag.ignore], expect200: true, @@ -419,7 +424,6 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { return info }, downloadMediaMessage: async(message: WAMessage, type: 'buffer' | 'stream' = 'buffer') => { - const downloadMediaMessage = async () => { let mContent = extractMessageContent(message.message) if (!mContent) throw new Boom('No message present', { statusCode: 400, data: message }) @@ -486,7 +490,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { messages: getBinaryNodeMessages(node) } }, - sendWAMessage: async( + sendMessage: async( jid: string, content: AnyMessageContent, options: MiscMessageGenerationOptions & { waitForAck?: boolean } = { waitForAck: true } @@ -526,7 +530,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { } ) - await relayWAMessage(msg, { waitForAck: options.waitForAck }) + await relayMessage(msg, { waitForAck: options.waitForAck }) return msg } } diff --git a/src/LegacySocket/socket.ts b/src/LegacySocket/socket.ts index 5f7c3bf..2257c88 100644 --- a/src/LegacySocket/socket.ts +++ b/src/LegacySocket/socket.ts @@ -62,7 +62,7 @@ export const makeSocket = ({ * Send a message to the WA servers * @returns the tag attached in the message * */ - const sendMessage = async( + const sendNode = async( { json, binaryTag, tag, longTag }: SocketSendMessageOptions ) => { tag = tag || generateMessageTag(longTag) @@ -204,7 +204,7 @@ export const makeSocket = ({ } } /** checks for phone connection */ - const sendAdminTest = () => sendMessage({ json: ['admin', 'test'] }) + const sendAdminTest = () => sendNode({ json: ['admin', 'test'] }) /** * Wait for a message with a certain tag to be received * @param tag the message tag to await @@ -266,7 +266,7 @@ export const makeSocket = ({ tag = tag || generateMessageTag(longTag) const { promise, cancelToken } = waitForMessage(tag, requiresPhoneConnection, timeoutMs) try { - await sendMessage({ json, tag, binaryTag }) + await sendNode({ json, tag, binaryTag }) } catch(error) { cancelToken() // swallow error @@ -366,8 +366,7 @@ export const makeSocket = ({ ws, updateKeys: (info: { encKey: Buffer, macKey: Buffer }) => authInfo = info, waitForSocketOpen, - sendRawMessage, - sendMessage, + sendNode, generateMessageTag, waitForMessage, query, diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts index 11a16a1..7a76fb6 100644 --- a/src/Socket/groups.ts +++ b/src/Socket/groups.ts @@ -124,7 +124,7 @@ export const makeGroupsSocket = (config: SocketConfig) => { const inviteNode = getBinaryNodeChild(result, 'invite') return inviteNode.attrs.code }, - groupRevokeInvite: async (jid: string) => { + groupRevokeInvite: async (jid: string) => { const result = await groupQuery(jid, 'set', [{ tag: 'invite', attrs: {} }]) const inviteNode = getBinaryNodeChild(result, 'invite') return inviteNode.attrs.code From 9e33c80add0b267631b1075f5644947ff40064dd Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 18 Dec 2021 16:44:43 +0530 Subject: [PATCH 233/311] fix: use fetchAgent for uploading data --- src/Utils/messages-media.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 8a1f077..83dc872 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -461,7 +461,7 @@ export function extensionForMediaMessage(message: WAMessageContent) { return extension } -export const getWAUploadToServer = ({ customUploadHosts, agent, logger }: CommonSocketConfig, refreshMediaConn: (force: boolean) => Promise): WAMediaUploadFunction => { +export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: CommonSocketConfig, refreshMediaConn: (force: boolean) => Promise): WAMediaUploadFunction => { return async(stream, { mediaType, fileEncSha256B64, timeoutMs }) => { const { default: got } = await import('got') // send a query JSON to obtain the url & auth token to upload our media @@ -482,7 +482,7 @@ export const getWAUploadToServer = ({ customUploadHosts, agent, logger }: Common 'Origin': DEFAULT_ORIGIN }, agent: { - https: agent + https: fetchAgent }, body: stream, timeout: timeoutMs From d09025e8dd6339312cf3818481ea54c97774381c Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 18 Dec 2021 17:01:06 +0530 Subject: [PATCH 234/311] fix: ephemeral toggle not being applied correctly on legacy --- src/LegacySocket/messages.ts | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/LegacySocket/messages.ts b/src/LegacySocket/messages.ts index fbde9a7..399e93d 100644 --- a/src/LegacySocket/messages.ts +++ b/src/LegacySocket/messages.ts @@ -131,19 +131,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { } } - const ephemeralProtocolMsg = message.message?.ephemeralMessage?.message?.protocolMessage - if ( - ephemeralProtocolMsg && - ephemeralProtocolMsg.type === proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING - ) { - chatUpdate.ephemeralSettingTimestamp = message.messageTimestamp - chatUpdate.ephemeralExpiration = ephemeralProtocolMsg.ephemeralExpiration - - if(isJidGroup(jid)) { - emitGroupUpdate({ ephemeralDuration: ephemeralProtocolMsg.ephemeralExpiration || null }) - } - } - const protocolMessage = message.message?.protocolMessage + const protocolMessage = message.message?.protocolMessage || message.message?.ephemeralMessage?.message?.protocolMessage // if it's a message to delete another message if (protocolMessage) { switch (protocolMessage.type) { @@ -158,6 +146,14 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { } ]) return + case proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING: + chatUpdate.ephemeralSettingTimestamp = message.messageTimestamp + chatUpdate.ephemeralExpiration = protocolMessage.ephemeralExpiration + + if(isJidGroup(jid)) { + emitGroupUpdate({ ephemeralDuration: protocolMessage.ephemeralExpiration || null }) + } + break default: break } From 1e97c7714e74f915d71ea5e29720907f01e29025 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 18 Dec 2021 17:01:16 +0530 Subject: [PATCH 235/311] chore: more unification of APIs --- src/LegacySocket/chats.ts | 57 ++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index e80ad62..96c7b34 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -28,7 +28,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { }) ) - const fetchImageUrl = async(jid: string) => { + const profilePictureUrl = async(jid: string) => { const response = await query({ json: ['query', 'ProfilePicThumb', jid], expect200: false, @@ -63,7 +63,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { ev.emit('chats.update', [ { id: jid, archive: false } ]) break case 'pin': - ev.emit('chats.update', [ { id: jid, pin: +attributes.pin } ]) + ev.emit('chats.update', [ { id: jid, pin: attributes.pin ? +attributes.pin : null } ]) break case 'star': case 'unstar': @@ -104,6 +104,26 @@ const makeChatsSocket = (config: LegacySocketConfig) => { return { id, presences: { [participant]: presence } } } + const chatRead = async(fromMessage: WAMessageKey, count: number) => { + await setQuery ( + [ + { + tag: 'read', + attrs: { + jid: fromMessage.remoteJid, + count: count.toString(), + index: fromMessage.id, + owner: fromMessage.fromMe ? 'true' : 'false' + } + } + ], + [ WAMetric.read, WAFlag.ignore ] + ) + if(config.emitOwnEvents) { + ev.emit('chats.update', [{ id: fromMessage.remoteJid, unreadCount: count < 0 ? -1 : 0 }]) + } + } + ev.on('connection.update', async({ connection }) => { if(connection !== 'open') return try { @@ -216,7 +236,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { socketEvents.on('CB:Cmd,type:picture', async json => { json = json[1] const id = jidNormalizedUser(json.jid) - const imgUrl = await fetchImageUrl(id).catch(() => '') + const imgUrl = await profilePictureUrl(id).catch(() => '') ev.emit('contacts.update', [ { id, imgUrl } ]) }) @@ -254,25 +274,8 @@ const makeChatsSocket = (config: LegacySocketConfig) => { return { ...sock, sendChatsQuery, - fetchImageUrl, - chatRead: async(fromMessage: WAMessageKey, count: number) => { - await setQuery ( - [ - { tag: 'read', - attrs: { - jid: fromMessage.remoteJid, - count: count.toString(), - index: fromMessage.id, - owner: fromMessage.fromMe ? 'true' : 'false' - } - } - ], - [ WAMetric.read, WAFlag.ignore ] - ) - if(config.emitOwnEvents) { - ev.emit ('chats.update', [{ id: fromMessage.remoteJid, unreadCount: count < 0 ? -1 : 0 }]) - } - }, + profilePictureUrl, + chatRead, /** * Modify a given chat (archive, pin etc.) * @param jid the ID of the person/group you are modifiying @@ -300,7 +303,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { } } else if('clear' in modification) { chatAttrs.type = 'clear' - chatAttrs.modify_tag = Math.round(Math.random ()*1000000).toString() + chatAttrs.modify_tag = Math.round(Math.random()*1000000).toString() if(modification.clear !== 'all') { data = modification.clear.messages.map(({ id, fromMe }) => ( { @@ -317,6 +320,8 @@ const makeChatsSocket = (config: LegacySocketConfig) => { attrs: { owner: (!!fromMe).toString(), index: id } } )) + } else if('markRead' in modification) { + return chatRead(index!, modification.markRead ? 0 : -1) } if(index) { @@ -326,8 +331,10 @@ const makeChatsSocket = (config: LegacySocketConfig) => { const node = { tag: 'chat', attrs: chatAttrs, content: data } const response = await setQuery([node], [ WAMetric.chat, WAFlag.ignore ]) - // apply it and emit events - executeChatModification(node) + if(config.emitOwnEvents) { + // apply it and emit events + executeChatModification(node) + } return response }, /** From 37c07937d7abb58fd71e734f31ec27e858317ae0 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 18 Dec 2021 19:45:58 +0530 Subject: [PATCH 236/311] refactor: use constant state & authInfo on legacy --- src/LegacySocket/auth.ts | 4 ++-- src/LegacySocket/chats.ts | 16 ++++++++-------- src/LegacySocket/groups.ts | 6 +++--- src/LegacySocket/messages.ts | 10 +++++----- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/LegacySocket/auth.ts b/src/LegacySocket/auth.ts index e8d87d1..262a37c 100644 --- a/src/LegacySocket/auth.ts +++ b/src/LegacySocket/auth.ts @@ -258,9 +258,9 @@ const makeAuthSocket = (config: LegacySocketConfig) => { return { ...socket, + state, + authInfo, ev, - getState: () => state, - getAuthInfo: () => authInfo, waitForConnection, canLogin, logout diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index 96c7b34..9bd39da 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -13,7 +13,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { setQuery, query, sendNode, - getState + state } = sock const chatsDebounceTimeout = debouncedTimeout(10_000, () => sendChatsQuery(1)) @@ -212,10 +212,10 @@ const makeChatsSocket = (config: LegacySocketConfig) => { }) // User Profile Name Updates socketEvents.on('CB:Conn,pushname', json => { - const { legacy: { user }, connection } = getState() + const { legacy: { user }, connection } = state if(connection === 'open' && json[1].pushname !== user.name) { user.name = json[1].pushname - ev.emit('connection.update', { legacy: { ...getState().legacy, user } }) + ev.emit('connection.update', { legacy: { ...state.legacy, user } }) } }) // read updates @@ -397,7 +397,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { } ] ) - ev.emit('contacts.update', [{ id: getState().legacy!.user!.id, status }]) + ev.emit('contacts.update', [{ id: state.legacy!.user!.id, status }]) return response }, /** Updates business profile. */ @@ -420,9 +420,9 @@ const makeChatsSocket = (config: LegacySocketConfig) => { )) as any as {status: number, pushname: string} if(config.emitOwnEvents) { - const user = { ...getState().legacy!.user!, name } + const user = { ...state.legacy!.user!, name } ev.emit('connection.update', { legacy: { - ...getState().legacy, user + ...state.legacy, user } }) ev.emit('contacts.update', [{ id: user.id, name }]) } @@ -446,7 +446,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { ] } - const user = getState().legacy?.user + const user = state.legacy?.user const { eurl } = await this.setQuery ([query], [WAMetric.picture, 136], tag) as { eurl: string, status: number } if(config.emitOwnEvents) { @@ -454,7 +454,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { user.imgUrl = eurl ev.emit('connection.update', { legacy: { - ...getState().legacy, + ...state.legacy, user } }) diff --git a/src/LegacySocket/groups.ts b/src/LegacySocket/groups.ts index 053de2d..88aa673 100644 --- a/src/LegacySocket/groups.ts +++ b/src/LegacySocket/groups.ts @@ -13,7 +13,7 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { generateMessageTag, currentEpoch, setQuery, - getState + state } = sock /** Generic function for group queries */ @@ -23,7 +23,7 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { { tag: 'group', attrs: { - author: getState().legacy?.user?.id, + author: state.legacy?.user?.id, id: tag, type: type, jid: jid, @@ -217,7 +217,7 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { subject: result.name, id: jid, creation: undefined, - owner: getState().legacy?.user?.id, + owner: state.legacy?.user?.id, participants: result.recipients!.map(({ id }) => ( { id: jidNormalizedUser(id), isAdmin: false, isSuperAdmin: false } )) diff --git a/src/LegacySocket/messages.ts b/src/LegacySocket/messages.ts index 399e93d..852bdd2 100644 --- a/src/LegacySocket/messages.ts +++ b/src/LegacySocket/messages.ts @@ -22,7 +22,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { generateMessageTag, currentEpoch, setQuery, - getState + state } = sock let mediaConn: Promise @@ -161,7 +161,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { // check if the message is an action if (message.messageStubType) { - const { user } = getState().legacy! + const { user } = state.legacy! //let actor = jidNormalizedUser (message.participant) let participants: string[] const emitParticipantsUpdate = (action: ParticipantAction) => ( @@ -257,7 +257,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { } ] } - const isMsgToMe = areJidsSameUser(message.key.remoteJid, getState().legacy.user?.id || '') + const isMsgToMe = areJidsSameUser(message.key.remoteJid, state.legacy.user?.id || '') const flag = isMsgToMe ? WAFlag.acknowledge : WAFlag.ignore // acknowledge when sending message to oneself const mID = message.key.id const finalState = isMsgToMe ? WAMessageStatus.READ : WAMessageStatus.SERVER_ACK @@ -353,7 +353,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { } const keyPartial = { remoteJid: jidNormalizedUser(attributes.to), - fromMe: areJidsSameUser(attributes.from, getState().legacy?.user?.id || ''), + fromMe: areJidsSameUser(attributes.from, state.legacy?.user?.id || ''), } const updates = ids.map(id => ({ key: { ...keyPartial, id }, @@ -491,7 +491,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { content: AnyMessageContent, options: MiscMessageGenerationOptions & { waitForAck?: boolean } = { waitForAck: true } ) => { - const userJid = getState().legacy.user?.id + const userJid = state.legacy.user?.id if( typeof content === 'object' && 'disappearingMessagesInChat' in content && From a723b507411c06a6596f3153b6ba86f61c6e6d88 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 18 Dec 2021 19:54:08 +0530 Subject: [PATCH 237/311] chore: add type distinguisher for sockets --- src/LegacySocket/socket.ts | 1 + src/Socket/socket.ts | 1 + src/index.ts | 2 ++ 3 files changed, 4 insertions(+) diff --git a/src/LegacySocket/socket.ts b/src/LegacySocket/socket.ts index 2257c88..f16c2d8 100644 --- a/src/LegacySocket/socket.ts +++ b/src/LegacySocket/socket.ts @@ -363,6 +363,7 @@ export const makeSocket = ({ }) return { + type: 'legacy', ws, updateKeys: (info: { encKey: Buffer, macKey: Buffer }) => authInfo = info, waitForSocketOpen, diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 3aa0073..2007722 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -540,6 +540,7 @@ export const makeSocket = ({ ev.on('creds.update', update => Object.assign(creds, update)) return { + type: 'md', ws, ev, authState: { diff --git a/src/index.ts b/src/index.ts index d445a48..8139a9f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,4 +14,6 @@ export { makeWALegacySocket } export type WASocket = ReturnType +export type AnyWASocket = WASocket | WALegacySocket + export default makeWASocket \ No newline at end of file From 02dd8c93a6f5514d1b5bfa32a2d85354b89a18ce Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 18 Dec 2021 19:56:58 +0530 Subject: [PATCH 238/311] chore: fix types --- src/LegacySocket/socket.ts | 2 +- src/Socket/socket.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LegacySocket/socket.ts b/src/LegacySocket/socket.ts index f16c2d8..d9fa528 100644 --- a/src/LegacySocket/socket.ts +++ b/src/LegacySocket/socket.ts @@ -363,7 +363,7 @@ export const makeSocket = ({ }) return { - type: 'legacy', + type: 'legacy' as 'legacy', ws, updateKeys: (info: { encKey: Buffer, macKey: Buffer }) => authInfo = info, waitForSocketOpen, diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 2007722..059cb33 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -540,7 +540,7 @@ export const makeSocket = ({ ev.on('creds.update', update => Object.assign(creds, update)) return { - type: 'md', + type: 'md' as 'md', ws, ev, authState: { From f61f553e015599d4eb0fcaaaf9d742326899561f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 18 Dec 2021 22:18:51 +0530 Subject: [PATCH 239/311] chore: more unification of legacy APIs 1. unify waitForConnectionUpdate 2. unify printing QR in terminal --- src/Defaults/index.ts | 1 - src/LegacySocket/auth.ts | 47 +++++----------------------------------- src/Socket/socket.ts | 43 +++++++----------------------------- src/Types/Legacy.ts | 2 -- src/Utils/generics.ts | 41 ++++++++++++++++++++++++++++++++++- 5 files changed, 54 insertions(+), 80 deletions(-) diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index dba9ff9..db81210 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -42,7 +42,6 @@ export const DEFAULT_LEGACY_CONNECTION_CONFIG: LegacySocketConfig = { waWebSocketUrl: 'wss://web.whatsapp.com/ws', phoneResponseTimeMs: 20_000, expectResponseTimeout: 60_000, - pendingRequestTimeoutMs: 60_000 } export const MEDIA_PATH_MAP: { [T in MediaType]: string } = { diff --git a/src/LegacySocket/auth.ts b/src/LegacySocket/auth.ts index 262a37c..4ccab6b 100644 --- a/src/LegacySocket/auth.ts +++ b/src/LegacySocket/auth.ts @@ -1,7 +1,7 @@ import { Boom } from '@hapi/boom' import EventEmitter from "events" -import { LegacyBaileysEventEmitter, BaileysEventMap, LegacySocketConfig, CurveKeyPair, WAInitResponse, ConnectionState, DisconnectReason, LegacyAuthenticationCreds } from "../Types" -import { newLegacyAuthCreds, promiseTimeout, computeChallengeResponse, validateNewConnection, Curve } from "../Utils" +import { LegacyBaileysEventEmitter, LegacySocketConfig, CurveKeyPair, WAInitResponse, ConnectionState, DisconnectReason } from "../Types" +import { newLegacyAuthCreds, bindWaitForConnectionUpdate, computeChallengeResponse, validateNewConnection, Curve, printQRIfNecessaryListener } from "../Utils" import { makeSocket } from "./socket" const makeAuthSocket = (config: LegacySocketConfig) => { @@ -10,7 +10,6 @@ const makeAuthSocket = (config: LegacySocketConfig) => { version, browser, connectTimeoutMs, - pendingRequestTimeoutMs, printQRInTerminal, auth: initialAuthInfo } = config @@ -74,34 +73,6 @@ const makeAuthSocket = (config: LegacySocketConfig) => { new Boom('Logged Out', { statusCode: DisconnectReason.loggedOut }) ) } - /** Waits for the connection to WA to open up */ - const waitForConnection = async(waitInfinitely: boolean = false) => { - if(state.connection === 'open') return - - let listener: (item: BaileysEventMap['connection.update']) => void - const timeout = waitInfinitely ? undefined : pendingRequestTimeoutMs - if(timeout < 0) { - throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) - } - - await ( - promiseTimeout( - timeout, - (resolve, reject) => { - listener = ({ connection, lastDisconnect }) => { - if(connection === 'open') resolve() - else if(connection == 'close') { - reject(lastDisconnect.error || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) - } - } - ev.on('connection.update', listener) - } - ) - .finally(() => ( - ev.off('connection.update', listener) - )) - ) - } const updateEncKeys = () => { // update the keys so we can decrypt traffic @@ -246,14 +217,7 @@ const makeAuthSocket = (config: LegacySocketConfig) => { }) if(printQRInTerminal) { - ev.on('connection.update', async({ qr }) => { - if(qr) { - const QR = await import('qrcode-terminal').catch(err => { - logger.error('QR code terminal not added as dependency') - }) - QR?.generate(qr, { small: true }) - } - }) + printQRIfNecessaryListener(ev, logger) } return { @@ -261,9 +225,10 @@ const makeAuthSocket = (config: LegacySocketConfig) => { state, authInfo, ev, - waitForConnection, canLogin, - logout + logout, + /** Waits for the connection to WA to reach a state */ + waitForConnectionUpdate: bindWaitForConnectionUpdate(ev) } } export default makeAuthSocket \ No newline at end of file diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 059cb33..14a6e55 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -4,8 +4,8 @@ import { promisify } from "util" import WebSocket from "ws" import { randomBytes } from 'crypto' import { proto } from '../../WAProto' -import { DisconnectReason, SocketConfig, BaileysEventEmitter, ConnectionState, AuthenticationCreds } from "../Types" -import { Curve, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout, generateOrGetPreKeys, xmppSignedPreKey, xmppPreKey, getPreKeys, makeNoiseHandler, useSingleFileAuthState, addTransactionCapability } from "../Utils" +import { DisconnectReason, SocketConfig, BaileysEventEmitter, AuthenticationCreds } from "../Types" +import { Curve, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout, generateOrGetPreKeys, xmppSignedPreKey, xmppPreKey, getPreKeys, makeNoiseHandler, useSingleFileAuthState, addTransactionCapability, bindWaitForConnectionUpdate, printQRIfNecessaryListener } from "../Utils" import { DEFAULT_ORIGIN, DEF_TAG_PREFIX, DEF_CALLBACK_PREFIX, KEY_BUNDLE_TYPE } from "../Defaults" import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, S_WHATSAPP_NET, getBinaryNodeChild } from '../WABinary' @@ -389,28 +389,6 @@ export const makeSocket = ({ end(new Boom('Intentional Logout', { statusCode: DisconnectReason.loggedOut })) } - /** Waits for the connection to WA to reach a state */ - const waitForConnectionUpdate = async(check: (u: Partial) => boolean, timeoutMs?: number) => { - let listener: (item: Partial) => void - await ( - promiseTimeout( - timeoutMs, - (resolve, reject) => { - listener = (update) => { - if(check(update)) { - resolve() - } else if(update.connection == 'close') { - reject(update.lastDisconnect?.error || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) - } - } - ev.on('connection.update', listener) - } - ) - .finally(() => ( - ev.off('connection.update', listener) - )) - ) - } ws.on('message', onMessageRecieved) ws.on('open', validateConnection) @@ -422,15 +400,6 @@ export const makeSocket = ({ }) // QR gen ws.on('CB:iq,type:set,pair-device', async (stanza: BinaryNode) => { - const postQR = async(qr: string) => { - if(printQRInTerminal) { - const QR = await import('qrcode-terminal').catch(err => { - logger.error('add `qrcode-terminal` as a dependency to auto-print QR') - }) - QR?.generate(qr, { small: true }) - } - } - const iq: BinaryNode = { tag: 'iq', attrs: { @@ -457,7 +426,6 @@ export const makeSocket = ({ const qr = [ref, noiseKeyB64, identityKeyB64, advB64].join(',') ev.emit('connection.update', { qr }) - postQR(qr) qrTimer = setTimeout(genPairQR, qrMs) qrMs = 20_000 // shorter subsequent qrs @@ -539,6 +507,10 @@ export const makeSocket = ({ // update credentials when required ev.on('creds.update', update => Object.assign(creds, update)) + if(printQRInTerminal) { + printQRIfNecessaryListener(ev, logger) + } + return { type: 'md' as 'md', ws, @@ -560,7 +532,8 @@ export const makeSocket = ({ sendNode, logout, end, - waitForConnectionUpdate + /** Waits for the connection to WA to reach a state */ + waitForConnectionUpdate: bindWaitForConnectionUpdate(ev) } } export type Socket = ReturnType \ No newline at end of file diff --git a/src/Types/Legacy.ts b/src/Types/Legacy.ts index 688c122..c30e006 100644 --- a/src/Types/Legacy.ts +++ b/src/Types/Legacy.ts @@ -76,8 +76,6 @@ export type LegacySocketConfig = CommonSocketConfig & phoneResponseTimeMs: number /** max time for WA server to respond before error with 422 */ expectResponseTimeout: number - - pendingRequestTimeoutMs: number } export type LegacyBaileysEventEmitter = CommonBaileysEventEmitter \ No newline at end of file diff --git a/src/Utils/generics.ts b/src/Utils/generics.ts index 50f5065..50675af 100644 --- a/src/Utils/generics.ts +++ b/src/Utils/generics.ts @@ -1,7 +1,10 @@ import { Boom } from '@hapi/boom' import { randomBytes } from 'crypto' import { platform, release } from 'os' +import { Logger } from 'pino' +import { ConnectionState } from '..' import { proto } from '../../WAProto' +import { CommonBaileysEventEmitter, DisconnectReason } from '../Types' import { Binary } from '../WABinary' const PLATFORM_MAP = { @@ -176,4 +179,40 @@ export async function promiseTimeout(ms: number, promise: (resolve: (v?: T)=> return p as Promise } // generate a random ID to attach to a message -export const generateMessageID = () => 'BAE5' + randomBytes(6).toString('hex').toUpperCase() \ No newline at end of file +export const generateMessageID = () => 'BAE5' + randomBytes(6).toString('hex').toUpperCase() + +export const bindWaitForConnectionUpdate = (ev: CommonBaileysEventEmitter) => ( + async(check: (u: Partial) => boolean, timeoutMs?: number) => { + let listener: (item: Partial) => void + await ( + promiseTimeout( + timeoutMs, + (resolve, reject) => { + listener = (update) => { + if(check(update)) { + resolve() + } else if(update.connection == 'close') { + reject(update.lastDisconnect?.error || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) + } + } + ev.on('connection.update', listener) + } + ) + .finally(() => ( + ev.off('connection.update', listener) + )) + ) + } +) + +export const printQRIfNecessaryListener = (ev: CommonBaileysEventEmitter, logger: Logger) => { + ev.on('connection.update', async({ qr }) => { + if(qr) { + const QR = await import('qrcode-terminal') + .catch(err => { + logger.error('QR code terminal not added as dependency') + }) + QR?.generate(qr, { small: true }) + } + }) +} \ No newline at end of file From ae59d6e9c6ecc4d16b73ed13275fae18344b5ae1 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 18 Dec 2021 22:30:03 +0530 Subject: [PATCH 240/311] fix: fire "connection-update" on legacy socket create --- src/LegacySocket/auth.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/LegacySocket/auth.ts b/src/LegacySocket/auth.ts index 4ccab6b..e612d63 100644 --- a/src/LegacySocket/auth.ts +++ b/src/LegacySocket/auth.ts @@ -220,6 +220,16 @@ const makeAuthSocket = (config: LegacySocketConfig) => { printQRIfNecessaryListener(ev, logger) } + process.nextTick(() => { + ev.emit('connection.update', { + connection: 'connecting', + receivedPendingNotifications: false, + legacy: { + phoneConnected: false + } + }) + }) + return { ...socket, state, From 1af46bfb3d091024cf7ea169c453006479d82a7a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 18 Dec 2021 23:20:50 +0530 Subject: [PATCH 241/311] fix: group metadata mapping on legacy --- src/LegacySocket/groups.ts | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/LegacySocket/groups.ts b/src/LegacySocket/groups.ts index 88aa673..ed4d975 100644 --- a/src/LegacySocket/groups.ts +++ b/src/LegacySocket/groups.ts @@ -45,11 +45,23 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { json: ['query', 'GroupMetadata', jid], expect200: true }) - metadata.participants = metadata.participants.map(p => ( - { ...p, id: undefined, jid: jidNormalizedUser(p.id) } - )) - metadata.owner = jidNormalizedUser(metadata.owner) - return metadata as GroupMetadata + + const meta: GroupMetadata = { + id: metadata.id, + subject: metadata.subject, + creation: +metadata.creation, + owner: jidNormalizedUser(metadata.owner), + desc: metadata.desc, + descOwner: metadata.descOwner, + participants: metadata.participants.map( + p => ({ + id: jidNormalizedUser(p.id), + admin: p.isSuperAdmin ? 'super-admin' : p.isAdmin ? 'admin' : undefined + }) + ) + } + + return meta } /** Get the metadata (works after you've left the group also) */ const groupMetadataMinimal = async (jid: string) => { From 89a159aac3116282c5df75add2bd598aa57e29dc Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 18 Dec 2021 23:33:55 +0530 Subject: [PATCH 242/311] fix: clear debounce timeout on close --- src/LegacySocket/chats.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index 9bd39da..f093d9b 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -271,6 +271,10 @@ const makeChatsSocket = (config: LegacySocketConfig) => { ev.emit('blocklist.set', { blocklist }) }) + socketEvents.on('ws-close', () => { + chatsDebounceTimeout.cancel() + }) + return { ...sock, sendChatsQuery, From af0804048c7e68abe3032de6e0d71019c47a6c09 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 19 Dec 2021 00:33:33 +0530 Subject: [PATCH 243/311] fix: incorrect enc msg detection --- src/Utils/legacy-msgs.ts | 69 +++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/src/Utils/legacy-msgs.ts b/src/Utils/legacy-msgs.ts index ba60d2b..8984e8f 100644 --- a/src/Utils/legacy-msgs.ts +++ b/src/Utils/legacy-msgs.ts @@ -30,39 +30,42 @@ export const decodeWAMessage = ( if(typeof data === 'string' || !possiblyEnc) { json = JSON.parse(data.toString()) // parse the JSON } else { - - const { macKey, encKey } = auth || {} - if (!macKey || !encKey) { - throw new Boom('recieved encrypted buffer when auth creds unavailable', { data: message, statusCode: DisconnectReason.badSession }) - } - /* - If the data recieved was not a JSON, then it must be an encrypted message. - Such a message can only be decrypted if we're connected successfully to the servers & have encryption keys - */ - if (fromMe) { - tags = [data[0], data[1]] - data = data.slice(2, data.length) - } - - const checksum = data.slice(0, 32) // the first 32 bytes of the buffer are the HMAC sign of the message - data = data.slice(32, data.length) // the actual message - const computedChecksum = hmacSign(data, macKey) // compute the sign of the message we recieved using our macKey - - if (checksum.equals(computedChecksum)) { - // the checksum the server sent, must match the one we computed for the message to be valid - const decrypted = aesDecrypt(data, encKey) // decrypt using AES - json = decodeBinaryNodeLegacy(decrypted, { index: 0 }) // decode the binary message into a JSON array - } else { - throw new Boom('Bad checksum', { - data: { - received: checksum.toString('hex'), - computed: computedChecksum.toString('hex'), - data: data.slice(0, 80).toString(), - tag: messageTag, - message: message.slice(0, 80).toString() - }, - statusCode: DisconnectReason.badSession - }) + try { + json = JSON.parse(data.toString()) + } catch { + const { macKey, encKey } = auth || {} + if (!macKey || !encKey) { + throw new Boom('recieved encrypted buffer when auth creds unavailable', { data: message, statusCode: DisconnectReason.badSession }) + } + /* + If the data recieved was not a JSON, then it must be an encrypted message. + Such a message can only be decrypted if we're connected successfully to the servers & have encryption keys + */ + if (fromMe) { + tags = [data[0], data[1]] + data = data.slice(2, data.length) + } + + const checksum = data.slice(0, 32) // the first 32 bytes of the buffer are the HMAC sign of the message + data = data.slice(32, data.length) // the actual message + const computedChecksum = hmacSign(data, macKey) // compute the sign of the message we recieved using our macKey + + if (checksum.equals(computedChecksum)) { + // the checksum the server sent, must match the one we computed for the message to be valid + const decrypted = aesDecrypt(data, encKey) // decrypt using AES + json = decodeBinaryNodeLegacy(decrypted, { index: 0 }) // decode the binary message into a JSON array + } else { + throw new Boom('Bad checksum', { + data: { + received: checksum.toString('hex'), + computed: computedChecksum.toString('hex'), + data: data.slice(0, 80).toString(), + tag: messageTag, + message: message.slice(0, 80).toString() + }, + statusCode: DisconnectReason.badSession + }) + } } } } From 2696af4da1fa62639ea60043b3b33837412d9f9b Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 19 Dec 2021 00:35:15 +0530 Subject: [PATCH 244/311] fix: catch unknown user action --- src/LegacySocket/chats.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index f093d9b..fe01273 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -252,9 +252,13 @@ const makeChatsSocket = (config: LegacySocketConfig) => { socketEvents.on('CB:action,,user', (json: BinaryNode) => { if(Array.isArray(json.content)) { const user = json.content[0].attrs - user.id = jidNormalizedUser(user.id) + if(user.id) { + user.id = jidNormalizedUser(user.id) - //ev.emit('contacts.upsert', [user]) + //ev.emit('contacts.upsert', [user]) + } else { + logger.warn({ json }, 'recv unknown action') + } } }) From 9d7aec11dab7e7b3b753c71d62f232975d9c5b76 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 19 Dec 2021 14:35:51 +0530 Subject: [PATCH 245/311] feat: add more logging to media --- src/LegacySocket/messages.ts | 4 ++-- src/Socket/messages-send.ts | 2 +- src/Utils/messages-media.ts | 7 ++++++- src/Utils/messages.ts | 36 +++++++++++++++++++++++++----------- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/LegacySocket/messages.ts b/src/LegacySocket/messages.ts index 852bdd2..30851a9 100644 --- a/src/LegacySocket/messages.ts +++ b/src/LegacySocket/messages.ts @@ -517,12 +517,12 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { jid, content, { - ...options, logger, userJid: userJid, getUrlInfo: generateUrlInfo, upload: waUploadToServer, - mediaCache: config.mediaCache + mediaCache: config.mediaCache, + ...options, } ) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index dcc8a2f..503a300 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -451,13 +451,13 @@ export const makeMessagesSocket = (config: SocketConfig) => { jid, content, { - ...options, logger, userJid, // multi-device does not have this yet //getUrlInfo: generateUrlInfo, upload: waUploadToServer, mediaCache: config.mediaCache, + ...options, } ) const isDeleteMsg = 'delete' in content && !!content.delete diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 83dc872..1f30a6a 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -222,10 +222,13 @@ export const getGotStream = async(url: string | URL, options: Options & { isStre export const encryptedStream = async( media: WAMediaUpload, mediaType: MediaType, - saveOriginalFileIfRequired = true + saveOriginalFileIfRequired = true, + logger?: Logger ) => { const { stream, type } = await getStream(media) + logger?.debug('fetched media stream') + const mediaKey = Crypto.randomBytes(32) const {cipherKey, iv, macKey} = getMediaKeys(mediaKey, mediaType) // random name @@ -277,6 +280,8 @@ export const encryptedStream = async( encWriteStream.push(null) writeStream && writeStream.end() + + logger?.debug('encrypted data successfully') return { mediaKey, diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 47ab76a..456edb5 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -1,5 +1,5 @@ import { Boom } from '@hapi/boom' -import { createReadStream, promises as fs } from "fs" +import { promises as fs } from "fs" import { proto } from '../../WAProto' import { MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from "../Defaults" import { @@ -56,6 +56,8 @@ export const prepareWAMessageMedia = async( message: AnyMediaMessageContent, options: MediaGenerationOptions ) => { + const logger = options.logger + let mediaType: typeof MEDIA_KEYS[number] for(const key of MEDIA_KEYS) { if(key in message) { @@ -79,9 +81,11 @@ export const prepareWAMessageMedia = async( if(cacheableKey) { const mediaBuff: Buffer = options.mediaCache!.get(cacheableKey) if(mediaBuff) { + logger?.debug({ cacheableKey }, `got media cache hit`) return WAProto.Message.decode(mediaBuff) } } + if(mediaType === 'document' && !uploadData.fileName) { uploadData.fileName = 'file' } @@ -110,22 +114,26 @@ export const prepareWAMessageMedia = async( ) const [{ mediaUrl, directPath }] = await Promise.all([ - (() => { - return options.upload( + (async() => { + const result = await options.upload( encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs } ) + logger?.debug(`uploaded media`) + return result })(), (async() => { try { if(requiresThumbnailComputation) { uploadData.jpegThumbnail = await generateThumbnail(bodyPath, mediaType as any, options) + logger?.debug(`generated thumbnail`) } if (requiresDurationComputation) { uploadData.seconds = await getAudioDuration(bodyPath) + logger?.debug(`computed audio duration`) } } catch (error) { - options.logger?.info({ trace: error.stack }, 'failed to obtain extra info') + logger?.warn({ trace: error.stack }, 'failed to obtain extra info') } })(), ]) @@ -133,7 +141,10 @@ export const prepareWAMessageMedia = async( async() => { encWriteStream.destroy() // remove tmp files - didSaveToTmpPath && bodyPath && await fs.unlink(bodyPath) + if(didSaveToTmpPath && bodyPath) { + await fs.unlink(bodyPath) + logger?.debug('removed tmp files') + } } ) @@ -155,6 +166,7 @@ export const prepareWAMessageMedia = async( }) if(cacheableKey) { + logger.debug({ cacheableKey }, `set cache`) options.mediaCache!.set(cacheableKey, WAProto.Message.encode(obj).finish()) } @@ -278,14 +290,14 @@ export const generateWAMessageContent = async( } m = { buttonsMessage } - } else if ('templateButtons' in message && !!message.templateButtons) { + } else if('templateButtons' in message && !!message.templateButtons) { const templateMessage: proto.ITemplateMessage = { hydratedTemplate: { hydratedButtons: message.templateButtons } } - if ('text' in message) { + if('text' in message) { templateMessage.hydratedTemplate.hydratedContentText = message.text } else { @@ -296,7 +308,7 @@ export const generateWAMessageContent = async( Object.assign(templateMessage.hydratedTemplate, m) } - if ('footer' in message && !!message.footer) { + if('footer' in message && !!message.footer) { templateMessage.hydratedTemplate.hydratedFooterText = message.footer } @@ -377,8 +389,10 @@ export const generateWAMessage = async( jid: string, content: AnyMessageContent, options: MessageGenerationOptions, -) => ( - generateWAMessageFromContent( +) => { + // ensure msg ID is with every log + options.logger = options?.logger?.child({ msgId: options.messageId }) + return generateWAMessageFromContent( jid, await generateWAMessageContent( content, @@ -386,7 +400,7 @@ export const generateWAMessage = async( ), options ) -) +} /** * Extract the true message content from a message From 61d1300daeba48ec4d9b314cc73bfd16fbf9c763 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 19 Dec 2021 14:48:09 +0530 Subject: [PATCH 246/311] chore: expose admintest + cleaner initial state update --- src/LegacySocket/auth.ts | 10 ++-------- src/LegacySocket/socket.ts | 1 + 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/LegacySocket/auth.ts b/src/LegacySocket/auth.ts index e612d63..5ab56d1 100644 --- a/src/LegacySocket/auth.ts +++ b/src/LegacySocket/auth.ts @@ -30,9 +30,7 @@ const makeAuthSocket = (config: LegacySocketConfig) => { let initTimeout: NodeJS.Timeout ws.on('phone-connection', ({ value: phoneConnected }) => { - if(phoneConnected !== state.legacy.phoneConnected) { - updateState({ legacy: { ...state.legacy, phoneConnected } }) - } + updateState({ legacy: { ...state.legacy, phoneConnected } }) }) // add close listener ws.on('ws-close', (error: Boom | Error) => { @@ -222,11 +220,7 @@ const makeAuthSocket = (config: LegacySocketConfig) => { process.nextTick(() => { ev.emit('connection.update', { - connection: 'connecting', - receivedPendingNotifications: false, - legacy: { - phoneConnected: false - } + ...state }) }) diff --git a/src/LegacySocket/socket.ts b/src/LegacySocket/socket.ts index d9fa528..c4a761f 100644 --- a/src/LegacySocket/socket.ts +++ b/src/LegacySocket/socket.ts @@ -365,6 +365,7 @@ export const makeSocket = ({ return { type: 'legacy' as 'legacy', ws, + sendAdminTest, updateKeys: (info: { encKey: Buffer, macKey: Buffer }) => authInfo = info, waitForSocketOpen, sendNode, From 9068157cb10bd90a50bf8635c359bcd9fd5cb328 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 19 Dec 2021 20:18:21 +0530 Subject: [PATCH 247/311] chore: replace got with axios Primarily because it had some odd issues with handling streams --- package.json | 4 +- src/Utils/messages-media.ts | 48 ++++------ yarn.lock | 169 +++--------------------------------- 3 files changed, 31 insertions(+), 190 deletions(-) diff --git a/package.json b/package.json index 05b3875..1d12b28 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,8 @@ }, "dependencies": { "@hapi/boom": "^9.1.3", + "axios": "^0.24.0", "curve25519-js": "^0.0.4", - "got": "^11.8.1", "libsignal": "git+https://github.com/adiwajshing/libsignal-node", "music-metadata": "^7.4.1", "node-cache": "^5.1.2", @@ -45,8 +45,8 @@ "ws": "^8.0.0" }, "optionalDependencies": { - "qrcode-terminal": "^0.12.0", "jimp": "^0.16.1", + "qrcode-terminal": "^0.12.0", "sharp": "^0.29.3" }, "files": [ diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 1f30a6a..03d7bbb 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -1,6 +1,5 @@ import type { Logger } from 'pino' import type { IAudioMetadata } from 'music-metadata' -import type { Options, Response } from 'got' import { Boom } from '@hapi/boom' import * as Crypto from 'crypto' import { Readable, Transform } from 'stream' @@ -14,6 +13,7 @@ import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaU import { generateMessageID } from './generics' import { hkdf } from './crypto' import { DEFAULT_ORIGIN, MEDIA_PATH_MAP } from '../Defaults' +import { AxiosRequestConfig } from 'axios' const getTmpFilesDirectory = () => tmpdir() @@ -169,7 +169,7 @@ export const getStream = async (item: WAMediaUpload) => { if(Buffer.isBuffer(item)) return { stream: toReadable(item), type: 'buffer' } if('stream' in item) return { stream: item.stream, type: 'readable' } if(item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) { - return { stream: await getGotStream(item.url), type: 'remote' } + return { stream: await getHttpStream(item.url), type: 'remote' } } return { stream: createReadStream(item.url), type: 'file' } } @@ -200,24 +200,10 @@ export async function generateThumbnail( return thumbnail } -export const getGotStream = async(url: string | URL, options: Options & { isStream?: true } = {}) => { - const { default: { stream: gotStream }} = await import('got') - const fetched = gotStream(url, { ...options, isStream: true }) - await new Promise((resolve, reject) => { - fetched.once('error', reject) - fetched.once('response', ({ statusCode }: Response) => { - if (statusCode >= 400) { - reject( - new Boom( - 'Invalid code (' + statusCode + ') returned', - { statusCode } - )) - } else { - resolve(undefined) - } - }) - }) - return fetched +export const getHttpStream = async(url: string | URL, options: AxiosRequestConfig & { isStream?: true } = {}) => { + const { default: axios } = await import('axios') + const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' }) + return fetched.data as Readable } export const encryptedStream = async( media: WAMediaUpload, @@ -280,6 +266,7 @@ export const encryptedStream = async( encWriteStream.push(null) writeStream && writeStream.end() + stream.destroy() logger?.debug('encrypted data successfully') @@ -300,6 +287,7 @@ export const encryptedStream = async( hmac.destroy(error) sha256Plain.destroy(error) sha256Enc.destroy(error) + stream.destroy(error) throw error } @@ -343,7 +331,7 @@ export const downloadContentFromMessage = async( if(endChunk) rangeHeader += endChunk } // download the message - const fetched = await getGotStream(downloadUrl, { + const fetched = await getHttpStream(downloadUrl, { headers: { Origin: DEFAULT_ORIGIN, Range: rangeHeader @@ -468,7 +456,7 @@ export function extensionForMediaMessage(message: WAMessageContent) { export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: CommonSocketConfig, refreshMediaConn: (force: boolean) => Promise): WAMediaUploadFunction => { return async(stream, { mediaType, fileEncSha256B64, timeoutMs }) => { - const { default: got } = await import('got') + const { default: axios } = await import('axios') // send a query JSON to obtain the url & auth token to upload our media let uploadInfo = await refreshMediaConn(false) @@ -479,21 +467,19 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` try { - const {body: responseText} = await got.post( - url, - { + const {data: result} = await axios.post( + url, + stream, + { headers: { 'Content-Type': 'application/octet-stream', 'Origin': DEFAULT_ORIGIN }, - agent: { - https: fetchAgent - }, - body: stream, - timeout: timeoutMs + httpsAgent: fetchAgent, + timeout: timeoutMs, + responseType: 'json' } ) - const result = JSON.parse(responseText) if(result?.url || result?.directPath) { urls = { diff --git a/yarn.lock b/yarn.lock index b054002..dbeb44b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -872,11 +872,6 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= -"@sindresorhus/is@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.1.tgz#d26729db850fa327b7cacc5522252194404226f5" - integrity sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g== - "@sinonjs/commons@^1.7.0": version "1.8.3" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" @@ -891,13 +886,6 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@szmarczak/http-timer@^4.0.5": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" - integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== - dependencies: - defer-to-connect "^2.0.0" - "@tokenizer/token@^0.1.1": version "0.1.1" resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.1.1.tgz#f0d92c12f87079ddfd1b29f614758b9696bc29e3" @@ -961,16 +949,6 @@ dependencies: "@babel/types" "^7.3.0" -"@types/cacheable-request@^6.0.1": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz#c324da0197de0a98a2312156536ae262429ff6b9" - integrity sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA== - dependencies: - "@types/http-cache-semantics" "*" - "@types/keyv" "*" - "@types/node" "*" - "@types/responselike" "*" - "@types/got@^9.6.11": version "9.6.12" resolved "https://registry.yarnpkg.com/@types/got/-/got-9.6.12.tgz#fd42a6e1f5f64cd6bb422279b08c30bb5a15a56f" @@ -987,11 +965,6 @@ dependencies: "@types/node" "*" -"@types/http-cache-semantics@*": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" - integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== - "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" @@ -1019,13 +992,6 @@ jest-diff "^26.0.0" pretty-format "^26.0.0" -"@types/keyv@*": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.2.tgz#5d97bb65526c20b6e0845f6b0d2ade4f28604ee5" - integrity sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg== - dependencies: - "@types/node" "*" - "@types/long@^4.0.0", "@types/long@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" @@ -1075,13 +1041,6 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3" integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog== -"@types/responselike@*", "@types/responselike@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" - integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== - dependencies: - "@types/node" "*" - "@types/sharp@^0.29.4": version "0.29.4" resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.29.4.tgz#e47d8677befc9944d4b9d76ed837452814166de0" @@ -1271,6 +1230,13 @@ atomic-sleep@^1.0.0: resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== +axios@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" + integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== + dependencies: + follow-redirects "^1.14.4" + babel-jest@^27.0.6: version "27.0.6" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.6.tgz#e99c6e0577da2655118e3608b68761a5a69bd0d8" @@ -1424,24 +1390,6 @@ buffer@^5.2.0, buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" -cacheable-lookup@^5.0.3: - version "5.0.4" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" - integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== - -cacheable-request@^7.0.1: - version "7.0.2" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" - integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^4.0.0" - lowercase-keys "^2.0.0" - normalize-url "^6.0.1" - responselike "^2.0.0" - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1508,13 +1456,6 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" -clone-response@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= - dependencies: - mimic-response "^1.0.0" - clone@2.x: version "2.1.2" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" @@ -1703,11 +1644,6 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== -defer-to-connect@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" - integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1922,6 +1858,11 @@ flatstr@^1.0.12: resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931" integrity sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw== +follow-redirects@^1.14.4: + version "1.14.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd" + integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A== + form-data@^2.5.0: version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -1999,13 +1940,6 @@ get-package-type@^0.1.0: resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - get-stream@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" @@ -2049,23 +1983,6 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -got@^11.8.1: - version "11.8.2" - resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599" - integrity sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ== - dependencies: - "@sindresorhus/is" "^4.0.0" - "@szmarczak/http-timer" "^4.0.5" - "@types/cacheable-request" "^6.0.1" - "@types/responselike" "^1.0.0" - cacheable-lookup "^5.0.3" - cacheable-request "^7.0.1" - decompress-response "^6.0.0" - http2-wrapper "^1.0.0-beta.5.2" - lowercase-keys "^2.0.0" - p-cancelable "^2.0.0" - responselike "^2.0.0" - graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" @@ -2117,11 +2034,6 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== - http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" @@ -2131,14 +2043,6 @@ http-proxy-agent@^4.0.1: agent-base "6" debug "4" -http2-wrapper@^1.0.0-beta.5.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" - integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.0.0" - https-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" @@ -2808,11 +2712,6 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - json5@2.x, json5@^2.1.2, json5@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" @@ -2829,13 +2728,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -keyv@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" - integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA== - dependencies: - json-buffer "3.0.1" - kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" @@ -2892,11 +2784,6 @@ long@^4.0.0: resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -2980,11 +2867,6 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - mimic-response@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" @@ -3097,11 +2979,6 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -3172,11 +3049,6 @@ optionator@^0.8.1: type-check "~0.3.2" word-wrap "~1.2.3" -p-cancelable@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" - integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== - p-each-series@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" @@ -3445,11 +3317,6 @@ quick-format-unescaped@^4.0.3: resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.3.tgz#6d6b66b8207aa2b35eef12be1421bb24c428f652" integrity sha512-MaL/oqh02mhEo5m5J2rwsVL23Iw2PEaGVHgT2vFt8AAsr0lfvQA5dpXo9TPu0rz7tSBdUPgkbam0j/fj5ZM8yg== -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -3511,11 +3378,6 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -resolve-alpn@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.1.2.tgz#30b60cfbb0c0b8dc897940fe13fe255afcdd4d28" - integrity sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA== - resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" @@ -3536,13 +3398,6 @@ resolve@^1.1.6, resolve@^1.20.0: is-core-module "^2.2.0" path-parse "^1.0.6" -responselike@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" - integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== - dependencies: - lowercase-keys "^2.0.0" - rimraf@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" From bacd046a4e977c859f6f100cc24aba7bfbeed8fb Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 19 Dec 2021 20:20:22 +0530 Subject: [PATCH 248/311] fix: tsc error for DOM --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 34c7507..3b6bfec 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,7 @@ "resolveJsonModule": true, "forceConsistentCasingInFileNames": true, "declaration": true, - "lib": ["es2020", "esnext.array"] + "lib": ["es2020", "esnext.array", "DOM"] }, "include": ["./src/**/*.ts"], "exclude": ["node_modules", "src/Tests/*", "src/Binary/GenerateStatics.ts"] From 072706368c849325b939c222be99a82e32b09d99 Mon Sep 17 00:00:00 2001 From: LyFE <76509367+lyfe00011@users.noreply.github.com> Date: Sun, 19 Dec 2021 22:10:18 +0530 Subject: [PATCH 249/311] fix groupMetdata (#1049) --- src/Socket/groups.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts index 7a76fb6..4c8e635 100644 --- a/src/Socket/groups.ts +++ b/src/Socket/groups.ts @@ -199,8 +199,8 @@ export const extractGroupMetadata = (result: BinaryNode) => { owner: group.attrs.creator ? jidNormalizedUser(group.attrs.creator) : undefined, desc, descId, - restrict: !!getBinaryNodeChild(result, 'locked'), - announce: !!getBinaryNodeChild(result, 'announcement'), + restrict: !!getBinaryNodeChild(group, 'locked'), + announce: !!getBinaryNodeChild(group, 'announcement'), participants: getBinaryNodeChildren(group, 'participant').map( ({ attrs }) => { return { From db941f147278f64b473653b2691242b257eba93e Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 19 Dec 2021 22:25:17 +0530 Subject: [PATCH 250/311] fix: download on axios --- src/Utils/messages-media.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 03d7bbb..eed5158 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -324,19 +324,18 @@ export const downloadContentFromMessage = async( firstBlockIsIV = true } } - const endChunk = endByte ? toSmallestChunkSize(endByte || 0)+AES_CHUNK_SIZE : undefined - let rangeHeader: string | undefined = undefined - if(startChunk || endChunk) { - rangeHeader = `bytes=${startChunk}-` - if(endChunk) rangeHeader += endChunk + const endChunk = endByte ? toSmallestChunkSize(endByte || 0)+AES_CHUNK_SIZE : undefined + + const headers: { [_: string]: string } = { + Origin: DEFAULT_ORIGIN, } + if(startChunk || endChunk) { + headers.Range = `bytes=${startChunk}-` + if(endChunk) headers.Range += endChunk + } + // download the message - const fetched = await getHttpStream(downloadUrl, { - headers: { - Origin: DEFAULT_ORIGIN, - Range: rangeHeader - } - }) + const fetched = await getHttpStream(downloadUrl, { headers }) let remainingBytes = Buffer.from([]) const { cipherKey, iv } = getMediaKeys(mediaKey, type) From d62db2bbd685a400de546ec02bec5d775afee6cf Mon Sep 17 00:00:00 2001 From: Rajeh Taher Date: Sun, 19 Dec 2021 18:59:35 +0200 Subject: [PATCH 251/311] Added List message support and removed "saving auth state" (#1048) * Added template support and footers for buttons & templates * Template message readme * got rid of "saving auth state" and added lists * added body * Update README.md --- README.md | 38 +++++++++++++++++++++++++++++++++----- src/Types/Message.ts | 12 +++++++++++- src/Utils/auth-utils.ts | 4 ++-- src/Utils/messages.ts | 12 ++++++++++++ 4 files changed, 58 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 26b46a7..108d086 100644 --- a/README.md +++ b/README.md @@ -264,7 +264,7 @@ const buttons = [ const buttonMessage = { text: "Hi it's button message", - footerText: 'Hello World', + footer: 'Hello World', buttons: buttons, headerType: 1 } @@ -273,18 +273,46 @@ const sendMsg = await sock.sendMessage(id, buttonMessage) //send a template message! const templateButtons = [ - {index: 1, urlButton: {displayText: '⭐ Star Baileys on GitHub!', url: 'https://github.com/adiwajshing/Baileys'}}, - {index: 2, callButton: {displayText: 'Call me!', phoneNumber: '+1 (234) 5678-901'}}, - {index: 3, quickReplyButton: {displayText: 'This is a reply, just like normal buttons!', id: 'id-like-buttons-message'}}, + {index: 1, urlButton: {displayText: '⭐ Star Baileys on GitHub!', url: 'https://github.com/adiwajshing/Baileys'}}, + {index: 2, callButton: {displayText: 'Call me!', phoneNumber: '+1 (234) 5678-901'}}, + {index: 3, quickReplyButton: {displayText: 'This is a reply, just like normal buttons!', id: 'id-like-buttons-message'}}, ] -const buttonMessage = { +const templateMessage = { text: "Hi it's a template message", footer: 'Hello World', templateButtons: templateButttons } const sendMsg = await sock.sendMessage(id, templateMessage) + +// send a list message! +const sections = [ + { + title: "Section 1", + rows: [ + {title: "Option 1", rowId: "option1"}, + {title: "Option 2", rowId: "option2", description: "This is a description"} + ] + }, + { + title: "Section 2", + rows: [ + {title: "Option 3", rowId: "option3"}, + {title: "Option 4", rowId: "option4", description: "This is a description V2"} + ] + }, +] + +const listMessage = { + text: "This is a list", + footer: "nice footer, link: https://google.com", + title: "Amazing boldfaced list title", + buttonText: "Required, text on the button to vie the list", + sections +} + +const sendMsg = await sock.sendMessage(id, listMessage) ``` ### Media Messages diff --git a/src/Types/Message.ts b/src/Types/Message.ts index c06d029..6d63a77 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -58,6 +58,16 @@ type Templatable = { footer?: string } +type Listable = { + /** Sections of the List */ + sections?: proto.ISection[] + + /** Title of a List Message only */ + title?: string + + /** Text of the bnutton on the list (required) */ + buttonText: string +} type WithDimensions = { width?: number height?: number @@ -93,7 +103,7 @@ export type AnyRegularMessageContent = ( ({ text: string } - & Mentionable & Buttonable & Templatable) | + & Mentionable & Buttonable & Templatable & Listable) | AnyMediaMessageContent | { contacts: { diff --git a/src/Utils/auth-utils.ts b/src/Utils/auth-utils.ts index 3a5dc5f..85c002f 100644 --- a/src/Utils/auth-utils.ts +++ b/src/Utils/auth-utils.ts @@ -112,7 +112,7 @@ export const initAuthCreds = (): AuthenticationCreds => { } /** stores the full authentication state in a single JSON file */ -export const useSingleFileAuthState = (filename: string): { state: AuthenticationState, saveState: () => void } => { +export const useSingleFileAuthState = (filename: string, logger?: Logger): { state: AuthenticationState, saveState: () => void } => { // require fs here so that in case "fs" is not available -- the app does not crash const { readFileSync, writeFileSync, existsSync } = require('fs') let creds: AuthenticationCreds @@ -120,7 +120,7 @@ export const useSingleFileAuthState = (filename: string): { state: Authenticatio // save the authentication state to a file const saveState = () => { - console.log('saving auth state') + logger && logger.trace('saving auth state') writeFileSync( filename, // BufferJSON replacer utility saves buffers nicely diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 456edb5..71dcce0 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -314,6 +314,18 @@ export const generateWAMessageContent = async( m = { templateMessage } } + + if ('sections' in message && !!message.sections) { + const listMessage: proto.IListMessage = { + sections: message.sections, + buttonText: message.buttonText, + title: message.title, + footerText: message.footer, + description: message.text + } + + m = { listMessage } + } if('viewOnce' in message && !!message.viewOnce) { m = { viewOnceMessage: { message: m } } From ed4f234fd82761a68440bebc929dda4ff32271fc Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 19 Dec 2021 22:40:16 +0530 Subject: [PATCH 252/311] fix: buttonText should be optional --- src/Types/Message.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 6d63a77..d505a78 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -66,7 +66,7 @@ type Listable = { title?: string /** Text of the bnutton on the list (required) */ - buttonText: string + buttonText?: string } type WithDimensions = { width?: number From c1301deda00c55465e0e9e56fb0e410d805d88fc Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 20 Dec 2021 11:12:21 +0530 Subject: [PATCH 253/311] fix: correctly copy msg for forward --- src/Utils/messages.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 71dcce0..202598f 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -197,7 +197,8 @@ export const generateForwardMessageContent = ( ) => { let content = message.message if (!content) throw new Boom('no content in message', { statusCode: 400 }) - content = JSON.parse(JSON.stringify(content)) // hacky copy + // hacky copy + content = proto.Message.decode(proto.Message.encode(message.message).finish()) let key = Object.keys(content)[0] as MessageType @@ -342,13 +343,13 @@ export const generateWAMessageFromContent = ( message: WAMessageContent, options: MessageGenerationOptionsFromContent ) => { - if (!options.timestamp) options.timestamp = new Date() // set timestamp to now + if(!options.timestamp) options.timestamp = new Date() // set timestamp to now const key = Object.keys(message)[0] const timestamp = unixTimestampSeconds(options.timestamp) const { quoted, userJid } = options - if (quoted) { + if(quoted) { const participant = quoted.key.fromMe ? userJid : (quoted.participant || quoted.key.participant || quoted.key.remoteJid) message[key].contextInfo = message[key].contextInfo || { } @@ -358,7 +359,7 @@ export const generateWAMessageFromContent = ( // if a participant is quoted, then it must be a group // hence, remoteJid of group must also be entered - if (quoted.key.participant || quoted.participant) { + if(quoted.key.participant || quoted.participant) { message[key].contextInfo.remoteJid = quoted.key.remoteJid } } @@ -380,8 +381,9 @@ export const generateWAMessageFromContent = ( message } } - } - message = WAProto.Message.fromObject (message) + } + + message = WAProto.Message.fromObject(message) const messageJSON = { key: { @@ -395,7 +397,7 @@ export const generateWAMessageFromContent = ( participant: jid.includes('@g.us') ? userJid : undefined, status: WAMessageStatus.PENDING } - return WAProto.WebMessageInfo.fromObject (messageJSON) + return WAProto.WebMessageInfo.fromObject(messageJSON) } export const generateWAMessage = async( jid: string, From dbed7fef741c8cd5ed3b79ed4690b6cdb8f5881b Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 20 Dec 2021 12:36:32 +0530 Subject: [PATCH 254/311] chore: add profile picture timeout --- src/LegacySocket/chats.ts | 5 +++-- src/Socket/chats.ts | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index fe01273..c9612d9 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -28,11 +28,12 @@ const makeChatsSocket = (config: LegacySocketConfig) => { }) ) - const profilePictureUrl = async(jid: string) => { + const profilePictureUrl = async(jid: string, timeoutMs?: number) => { const response = await query({ json: ['query', 'ProfilePicThumb', jid], expect200: false, - requiresPhoneConnection: false + requiresPhoneConnection: false, + timeoutMs }) return response.eurl as string | undefined } diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 49448e0..5e27a84 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -270,7 +270,7 @@ export const makeChatsSocket = (config: SocketConfig) => { * type = "preview" for a low res picture * type = "image for the high res picture" */ - const profilePictureUrl = async(jid: string, type: 'preview' | 'image' = 'preview') => { + const profilePictureUrl = async(jid: string, type: 'preview' | 'image' = 'preview', timeoutMs?: number) => { jid = jidNormalizedUser(jid) const result = await query({ tag: 'iq', @@ -282,7 +282,7 @@ export const makeChatsSocket = (config: SocketConfig) => { content: [ { tag: 'picture', attrs: { type, query: 'url' } } ] - }) + }, timeoutMs) const child = getBinaryNodeChild(result, 'picture') return child?.attrs?.url } From 258b2f2747900cfe33d4c41f4ad6a0e9b6a39e7a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 20 Dec 2021 12:37:18 +0530 Subject: [PATCH 255/311] chore: update legacy connection close msgs --- src/LegacySocket/auth.ts | 4 ++-- src/LegacySocket/socket.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/LegacySocket/auth.ts b/src/LegacySocket/auth.ts index 5ab56d1..68b2516 100644 --- a/src/LegacySocket/auth.ts +++ b/src/LegacySocket/auth.ts @@ -34,11 +34,11 @@ const makeAuthSocket = (config: LegacySocketConfig) => { }) // add close listener ws.on('ws-close', (error: Boom | Error) => { - logger.info({ error }, 'Closed connection to WhatsApp') + logger.info({ error }, 'closed connection to WhatsApp') initTimeout && clearTimeout(initTimeout) // if no reconnects occur // send close event - updateState({ + updateState({ connection: 'close', qr: undefined, lastDisconnect: { diff --git a/src/LegacySocket/socket.ts b/src/LegacySocket/socket.ts index c4a761f..7cb9ccf 100644 --- a/src/LegacySocket/socket.ts +++ b/src/LegacySocket/socket.ts @@ -96,7 +96,7 @@ export const makeSocket = ({ return tag } const end = (error: Error | undefined) => { - logger.debug({ error }, 'connection closed') + logger.info({ error }, 'connection closed') ws.removeAllListeners('close') ws.removeAllListeners('error') @@ -213,7 +213,7 @@ export const makeSocket = ({ */ const waitForMessage = (tag: string, requiresPhoneConnection: boolean, timeoutMs?: number) => { if(ws.readyState !== ws.OPEN) { - throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + throw new Boom('Connection not open', { statusCode: DisconnectReason.connectionClosed }) } let cancelToken = () => { } @@ -228,7 +228,7 @@ export const makeSocket = ({ (resolve, reject) => { onRecv = resolve onErr = err => { - reject(err || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) + reject(err || new Boom('Intentional Close', { statusCode: DisconnectReason.connectionClosed })) } cancelToken = () => onErr(new Boom('Cancelled', { statusCode: 500 })) @@ -311,7 +311,7 @@ export const makeSocket = ({ const waitForSocketOpen = async() => { if(ws.readyState === ws.OPEN) return if(ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { - throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + throw new Boom('Connection Already Closed', { statusCode: DisconnectReason.connectionClosed }) } let onOpen: () => void let onClose: (err: Error) => void From e9d90aa0a5cac9987fabfef632a92c8d020b9677 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 20 Dec 2021 13:58:39 +0530 Subject: [PATCH 256/311] fix: remove dup eventemitter --- src/Types/index.ts | 56 +--------------------------------------------- 1 file changed, 1 insertion(+), 55 deletions(-) diff --git a/src/Types/index.ts b/src/Types/index.ts index 641bedb..5e91fa3 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -8,16 +8,9 @@ export * from './Legacy' export * from './Socket' export * from './Events' -import type EventEmitter from "events" import type NodeCache from 'node-cache' import { AuthenticationState, AuthenticationCreds } from './Auth' -import { Chat, PresenceData } from './Chat' -import { Contact } from './Contact' -import { ConnectionState } from './State' - -import { GroupMetadata, ParticipantAction } from './GroupMetadata' -import { MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageUpdate, WAMessageKey } from './Message' import { proto } from '../../WAProto' import { CommonSocketConfig } from './Socket' @@ -74,51 +67,4 @@ export type WABusinessProfile = { wid?: string } -export type CurveKeyPair = { private: Uint8Array; public: Uint8Array } - -export type BaileysEventMap = { - /** connection state has been updated -- WS closed, opened, connecting etc. */ - 'connection.update': Partial - /** credentials updated -- some metadata, keys or something */ - 'creds.update': Partial - /** set chats (history sync), messages are reverse chronologically sorted */ - 'chats.set': { chats: Chat[], messages: WAMessage[] } - /** upsert chats */ - 'chats.upsert': Chat[] - /** update the given chats */ - 'chats.update': Partial[] - /** delete chats with given ID */ - 'chats.delete': string[] - /** presence of contact in a chat updated */ - 'presence.update': { id: string, presences: { [participant: string]: PresenceData } } - - 'contacts.upsert': Contact[] - 'contacts.update': Partial[] - - 'messages.delete': { keys: WAMessageKey[] } | { jid: string, all: true } - 'messages.update': WAMessageUpdate[] - /** - * add/update the given messages. If they were received while the connection was online, - * the update will have type: "notify" - * */ - 'messages.upsert': { messages: WAMessage[], type: MessageUpdateType } - - 'message-info.update': MessageInfoUpdate[] - - 'groups.upsert': GroupMetadata[] - 'groups.update': Partial[] - /** apply an action to participants in a group */ - 'group-participants.update': { id: string, participants: string[], action: ParticipantAction } - - 'blocklist.set': { blocklist: string[] } - 'blocklist.update': { blocklist: string[], type: 'add' | 'remove' } -} - -export interface CommonBaileysEventEmitter extends EventEmitter { - on>(event: T, listener: (arg: BaileysEventMap[T]) => void): this - off>(event: T, listener: (arg: BaileysEventMap[T]) => void): this - removeAllListeners>(event: T): this - emit>(event: T, arg: BaileysEventMap[T]): boolean -} - -export type BaileysEventEmitter = CommonBaileysEventEmitter \ No newline at end of file +export type CurveKeyPair = { private: Uint8Array; public: Uint8Array } \ No newline at end of file From 677f50baaa3e858242835e5e02ba2309980aa004 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 20 Dec 2021 13:59:04 +0530 Subject: [PATCH 257/311] feat: add contacts to chats.set event --- Example/example-legacy.ts | 4 +++- src/LegacySocket/chats.ts | 11 ++++++++--- src/Socket/messages-recv.ts | 19 ++++++++++++++----- src/Types/Events.ts | 2 +- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Example/example-legacy.ts b/Example/example-legacy.ts index 2660a80..9a7df6f 100644 --- a/Example/example-legacy.ts +++ b/Example/example-legacy.ts @@ -26,7 +26,9 @@ const startSock = () => { } sock.ev.on('messages.upsert', async m => { - console.log(JSON.stringify(m, undefined, 2)) + if(m.type === 'append' || m.type === 'notify') { + console.log(JSON.stringify(m, undefined, 2)) + } const msg = m.messages[0] if(!msg.key.fromMe && m.type === 'notify') { diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index c9612d9..f692eb4 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -170,7 +170,12 @@ const makeChatsSocket = (config: LegacySocketConfig) => { socketEvents.on('CB:response,type:chat', async ({ content: data }: BinaryNode) => { chatsDebounceTimeout.cancel() if(Array.isArray(data)) { + const contacts: Contact[] = [] const chats = data.map(({ attrs }): Chat => { + const id = jidNormalizedUser(attrs.jid) + if(attrs.name) { + contacts.push({ id, name: attrs.name }) + } return { id: jidNormalizedUser(attrs.jid), conversationTimestamp: attrs.t ? +attrs.t : undefined, @@ -186,8 +191,8 @@ const makeChatsSocket = (config: LegacySocketConfig) => { } }) - logger.info(`got ${chats.length} chats`) - ev.emit('chats.set', { chats, messages: [] }) + logger.info(`got ${chats.length} chats, extracted ${contacts.length} contacts with name`) + ev.emit('chats.set', { chats, messages: [], contacts }) } }) // got all contacts from phone @@ -203,7 +208,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { }) logger.info(`got ${contacts.length} contacts`) - ev.emit('contacts.upsert', contacts) + ev.emit('chats.set', { chats: [], messages: [], contacts }) } }) // status updates diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 51cac7b..16cc761 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -1,5 +1,5 @@ -import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata, WAMessageKey } from "../Types" +import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata, WAMessageKey, Contact } from "../Types" import { decodeMessageStanza, encodeBigEndian, toNumber, downloadHistory, generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils" import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser, getAllBinaryNodeChildren, BinaryNodeAttributes, isJidGroup } from '../WABinary' import { proto } from "../../WAProto" @@ -222,11 +222,18 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const processHistoryMessage = (item: proto.HistorySync) => { const messages: proto.IWebMessageInfo[] = [] + const contacts: Contact[] = [] switch(item.syncType) { case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_BOOTSTRAP: const chats = item.conversations!.map( c => { const chat: Chat = { ...c } + if(chat.name) { + contacts.push({ + id: chat.id, + name: chat.name + }) + } //@ts-expect-error delete chat.messages for(const msg of c.messages || []) { @@ -237,7 +244,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { return chat } ) - ev.emit('chats.set', { chats, messages }) + ev.emit('chats.set', { chats, messages, contacts }) break case proto.HistorySync.HistorySyncHistorySyncType.RECENT: // push remaining messages @@ -251,10 +258,12 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } break case proto.HistorySync.HistorySyncHistorySyncType.PUSH_NAME: - const contacts = item.pushnames.map( - p => ({ notify: p.pushname, id: p.id }) + contacts.push( + ...item.pushnames.map( + p => ({ notify: p.pushname, id: p.id }) + ) ) - ev.emit('contacts.upsert', contacts) + ev.emit('chats.set', { chats: [], messages: [], contacts }) break case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_STATUS_V3: // TODO diff --git a/src/Types/Events.ts b/src/Types/Events.ts index 33889a7..7aa534e 100644 --- a/src/Types/Events.ts +++ b/src/Types/Events.ts @@ -14,7 +14,7 @@ export type BaileysEventMap = { /** credentials updated -- some metadata, keys or something */ 'creds.update': Partial /** set chats (history sync), messages are reverse chronologically sorted */ - 'chats.set': { chats: Chat[], messages: WAMessage[] } + 'chats.set': { chats: Chat[], messages: WAMessage[], contacts: Contact[] } /** upsert chats */ 'chats.upsert': Chat[] /** update the given chats */ From c87d8b81290a2262129b3e224300f2b54d770b05 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 21 Dec 2021 10:53:39 +0530 Subject: [PATCH 258/311] refactor: update chat modifications to be uniform across MD + legacy --- README.md | 6 +++--- src/LegacySocket/chats.ts | 22 ++++++++++++---------- src/Socket/chats.ts | 4 ++-- src/Types/Chat.ts | 11 ++++++++++- src/Utils/chat-utils.ts | 11 +++++------ 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 108d086..bd2c71e 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ export type BaileysEventMap = { /** auth credentials updated -- some pre key state, device ID etc. */ 'creds.update': Partial /** set chats (history sync), messages are reverse chronologically sorted */ - 'chats.set': { chats: Chat[], messages: WAMessage[] } + 'chats.set': { chats: Chat[], messages: WAMessage[], contacts: Contact[] } /** upsert chats */ 'chats.upsert': Chat[] /** update the given chats */ @@ -495,7 +495,7 @@ WA uses an encrypted form of communication to send chat/app updates. This has be - Archive a chat ``` ts const lastMsgInChat = await getLastMessageInChat('123456@s.whatsapp.net') // implement this on your end - await sock.chatModify({ archive: true }, '123456@s.whatsapp.net', [lastMsgInChat]) + await sock.chatModify({ archive: true, lastMessages: [lastMsgInChat] }, '123456@s.whatsapp.net') ``` - Mute/unmute a chat ``` ts @@ -508,7 +508,7 @@ WA uses an encrypted form of communication to send chat/app updates. This has be ``` ts const lastMsgInChat = await getLastMessageInChat('123456@s.whatsapp.net') // implement this on your end // mark it unread - await sock.chatModify({ markRead: false }, '123456@s.whatsapp.net', [lastMsgInChat]) + await sock.chatModify({ markRead: false, lastMessages: [lastMsgInChat] }, '123456@s.whatsapp.net') ``` - Delete message for me diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index f692eb4..8847b2a 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -294,24 +294,30 @@ const makeChatsSocket = (config: LegacySocketConfig) => { * Modify a given chat (archive, pin etc.) * @param jid the ID of the person/group you are modifiying */ - chatModify: async( modification: ChatModification, jid: string, chatInfo: Pick, index?: WAMessageKey) => { + chatModify: async(modification: ChatModification, jid: string, chatInfo: Pick, timestampNow?: number) => { let chatAttrs: BinaryNode['attrs'] = { jid: jid } let data: BinaryNode[] | undefined = undefined - const stamp = unixTimestampSeconds() + + timestampNow = timestampNow || unixTimestampSeconds() if('archive' in modification) { chatAttrs.type = modification.archive ? 'archive' : 'unarchive' + const indexKey = modification.lastMessages[modification.lastMessages.length-1].key + if(indexKey) { + chatAttrs.index = indexKey.id + chatAttrs.owner = indexKey.fromMe ? 'true' : 'false' + } } else if('pin' in modification) { chatAttrs.type = 'pin' if(modification.pin) { - chatAttrs.pin = stamp.toString() + chatAttrs.pin = timestampNow.toString() } else { chatAttrs.previous = chatInfo.pin!.toString() } } else if('mute' in modification) { chatAttrs.type = 'mute' if(modification.mute) { - chatAttrs.mute = (stamp + modification.mute).toString() + chatAttrs.mute = (timestampNow + modification.mute).toString() } else { chatAttrs.previous = chatInfo.mute!.toString() } @@ -335,12 +341,8 @@ const makeChatsSocket = (config: LegacySocketConfig) => { } )) } else if('markRead' in modification) { - return chatRead(index!, modification.markRead ? 0 : -1) - } - - if(index) { - chatAttrs.index = index.id - chatAttrs.owner = index.fromMe ? 'true' : 'false' + const indexKey = modification.lastMessages[modification.lastMessages.length-1].key + return chatRead(indexKey, modification.markRead ? 0 : -1) } const node = { tag: 'chat', attrs: chatAttrs, content: data } diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 5e27a84..8c16e66 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -541,8 +541,8 @@ export const makeChatsSocket = (config: SocketConfig) => { * lastMessages must be sorted in reverse chronologically * requires the last messages till the last message received; required for archive & unread */ - const chatModify = (mod: ChatModification, jid: string, lastMessages: Pick[]) => { - const patch = chatModificationToAppPatch(mod, jid, lastMessages) + const chatModify = (mod: ChatModification, jid: string) => { + const patch = chatModificationToAppPatch(mod, jid) return appPatch(patch) } diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index a959c91..f2d01e4 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -27,9 +27,17 @@ export type Chat = Omit & { pin?: number | null archive?: boolean } +/** + * the last messages in a chat, sorted reverse-chronologically + * for MD modifications, the last message in the array must be the last message recv in the chat + * */ +export type LastMessageList = Pick[] export type ChatModification = - { archive: boolean } | + { + archive: boolean + lastMessages: LastMessageList + } | { pin: boolean } | @@ -48,5 +56,6 @@ export type ChatModification = } | { markRead: boolean + lastMessages: LastMessageList } | { delete: true } \ No newline at end of file diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 1d324ee..0990eea 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -1,6 +1,6 @@ import { Boom } from '@hapi/boom' import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./crypto" -import { WAPatchCreate, ChatMutation, WAPatchName, LTHashState, ChatModification, SignalKeyStore } from "../Types" +import { WAPatchCreate, ChatMutation, WAPatchName, LTHashState, ChatModification, LastMessageList } from "../Types" import { proto } from '../../WAProto' import { LT_HASH_ANTI_TAMPERING } from './lt-hash' import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren } from '../WABinary' @@ -418,11 +418,10 @@ export const decodePatches = async( export const chatModificationToAppPatch = ( mod: ChatModification, - jid: string, - lastMessages: Pick[] + jid: string ) => { const OP = proto.SyncdMutation.SyncdMutationSyncdOperation - const getMessageRange = () => { + const getMessageRange = (lastMessages: LastMessageList) => { if(!lastMessages?.length) { throw new Boom('Expected last message to be not from me', { statusCode: 400 }) } @@ -455,7 +454,7 @@ export const chatModificationToAppPatch = ( syncAction: { archiveChatAction: { archived: !!mod.archive, - messageRange: getMessageRange() + messageRange: getMessageRange(mod.lastMessages) } }, index: ['archive', jid], @@ -468,7 +467,7 @@ export const chatModificationToAppPatch = ( syncAction: { markChatAsReadAction: { read: mod.markRead, - messageRange: getMessageRange() + messageRange: getMessageRange(mod.lastMessages) } }, index: ['markChatAsRead', jid], From 4710f6603ad4bd5f23954a997adc0a3b9eb1a6d2 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 21 Dec 2021 17:21:25 +0530 Subject: [PATCH 259/311] fix: delete chat on legacy --- src/LegacySocket/chats.ts | 15 ++++++++++----- src/Types/Chat.ts | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index 8847b2a..d43cec1 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -302,11 +302,6 @@ const makeChatsSocket = (config: LegacySocketConfig) => { if('archive' in modification) { chatAttrs.type = modification.archive ? 'archive' : 'unarchive' - const indexKey = modification.lastMessages[modification.lastMessages.length-1].key - if(indexKey) { - chatAttrs.index = indexKey.id - chatAttrs.owner = indexKey.fromMe ? 'true' : 'false' - } } else if('pin' in modification) { chatAttrs.type = 'pin' if(modification.pin) { @@ -343,6 +338,16 @@ const makeChatsSocket = (config: LegacySocketConfig) => { } else if('markRead' in modification) { const indexKey = modification.lastMessages[modification.lastMessages.length-1].key return chatRead(indexKey, modification.markRead ? 0 : -1) + } else if('delete' in modification) { + chatAttrs.type = 'delete' + } + + if('lastMessages' in modification) { + const indexKey = modification.lastMessages[modification.lastMessages.length-1].key + if(indexKey) { + chatAttrs.index = indexKey.id + chatAttrs.owner = indexKey.fromMe ? 'true' : 'false' + } } const node = { tag: 'chat', attrs: chatAttrs, content: data } diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index f2d01e4..3d6c77d 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -58,4 +58,4 @@ export type ChatModification = markRead: boolean lastMessages: LastMessageList } | - { delete: true } \ No newline at end of file + { delete: true, lastMessages: LastMessageList } \ No newline at end of file From 98af4a66241563c784b44b4c57d70c230713fd77 Mon Sep 17 00:00:00 2001 From: burstfreeze <87532537+burstfreeze@users.noreply.github.com> Date: Wed, 22 Dec 2021 16:27:58 +0100 Subject: [PATCH 260/311] Fix #1010 by asking for full list of sync states when needed (#1043) * Process patches that are longer. * Fixed type declaration * Changed resync behavior from recusive to iterative * refactor: cleaner handling of hasMorePatches Co-authored-by: Adhiraj Singh --- src/Socket/chats.ts | 135 ++++++++++++++++++++++------------------ src/Types/Chat.ts | 2 + src/Utils/chat-utils.ts | 6 +- 3 files changed, 80 insertions(+), 63 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 8c16e66..50b8ba5 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1,4 +1,4 @@ -import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, LTHashState, ChatModification, Contact } from "../Types"; +import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, AppStateChunk, LTHashState, ChatModification, Contact } from "../Types"; import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET, reduceBinaryNodeToDictionary } from "../WABinary"; import { proto } from '../../WAProto' import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch, decodeSyncdSnapshot, newLTHashState } from "../Utils"; @@ -180,88 +180,101 @@ export const makeChatsSocket = (config: SocketConfig) => { const resyncAppStateInternal = async(collections: WAPatchName[], fromScratch: boolean = false, returnSnapshot: boolean = false) => { if(fromScratch) returnSnapshot = true - const totalMutations: ChatMutation[] = [] + const appStateChunk : AppStateChunk = {totalMutations: [], collectionsToHandle: []} await authState.keys.transaction( async() => { - const states = { } as { [T in WAPatchName]: LTHashState } - for(const name of collections) { - let state: LTHashState - if(!fromScratch) { - const result = await authState.keys.get('app-state-sync-version', [name]) - state = result[name] - } - if(!state) state = newLTHashState() - - states[name] = state - - logger.info(`resyncing ${name} from v${state.version}`) - } - const result = await query({ - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - xmlns: 'w:sync:app:state', - type: 'set' - }, - content: [ - { - tag: 'sync', - attrs: { }, - content: collections.map( - (name) => ({ - tag: 'collection', - attrs: { - name, - version: states[name].version.toString(), - return_snapshot: returnSnapshot ? 'true' : 'false' - } - }) - ) + const collectionsToHandle = new Set(collections) + // keep executing till all collections are done + // sometimes a single patch request will not return all the patches (God knows why) + // so we fetch till they're all done (this is determined by the "has_more_patches" flag) + while(collectionsToHandle.size) { + const states = { } as { [T in WAPatchName]: LTHashState } + for(const name of collectionsToHandle) { + let state: LTHashState + if(!fromScratch) { + const result = await authState.keys.get('app-state-sync-version', [name]) + state = result[name] } - ] - }) + if(!state) state = newLTHashState() + + states[name] = state + + logger.info(`resyncing ${name} from v${state.version}`) + } + const result = await query({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + xmlns: 'w:sync:app:state', + type: 'set' + }, + content: [ + { + tag: 'sync', + attrs: { }, + content: collections.map( + (name) => ({ + tag: 'collection', + attrs: { + name, + version: states[name].version.toString(), + return_snapshot: returnSnapshot ? 'true' : 'false' + } + }) + ) + } + ] + }) + + const decoded = await extractSyncdPatches(result) // extract from binary node + for(const key in decoded) { + const name = key as WAPatchName + const { patches, hasMorePatches, snapshot } = decoded[name] + if(snapshot) { + const newState = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey) + states[name] = newState + + logger.info(`restored state of ${name} from snapshot to v${newState.version}`) + } + // only process if there are syncd patches + if(patches.length) { + const { newMutations, state: newState } = await decodePatches(name, patches, states[name], getAppStateSyncKey, true) + + await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) - const decoded = await extractSyncdPatches(result) // extract from binary node - for(const key in decoded) { - const name = key as WAPatchName - const { patches, snapshot } = decoded[name] - if(snapshot) { - const newState = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey) - states[name] = newState + logger.info(`synced ${name} to v${newState.version}`) + if(newMutations.length) { + logger.trace({ newMutations, name }, 'recv new mutations') + } - logger.info(`restored state of ${name} from snapshot to v${newState.version}`) - } - // only process if there are syncd patches - if(patches.length) { - const { newMutations, state: newState } = await decodePatches(name, patches, states[name], getAppStateSyncKey, true) - - await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) - - logger.info(`synced ${name} to v${newState.version}`) - if(newMutations.length) { - logger.trace({ newMutations, name }, 'recv new mutations') + appStateChunk.totalMutations.push(...newMutations) + } + if(hasMorePatches) { + logger.info(`${name} has more patches...`) + } else { // collection is done with sync + collectionsToHandle.delete(name) } - - totalMutations.push(...newMutations) } } } ) - processSyncActions(totalMutations) + processSyncActions(appStateChunk.totalMutations) - return totalMutations + return appStateChunk } const resyncAppState = async(collections: WAPatchName[], returnSnapshot: boolean = false) => { - let result: ChatMutation[] + let result : AppStateChunk + try { result = await resyncAppStateInternal(collections, false, returnSnapshot) } catch(error) { logger.info({ collections, error: error.stack }, 'failed to sync state from version, trying from scratch') result = await resyncAppStateInternal(collections, true, true) } + return result } diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 3d6c77d..994821e 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -12,6 +12,8 @@ export interface PresenceData { export type ChatMutation = { syncAction: proto.ISyncActionData, index: string[], indexMac: Uint8Array, valueMac: Uint8Array, operation: number } +export type AppStateChunk = { totalMutations : ChatMutation[], collectionsToHandle: WAPatchName[] } + export type WAPatchCreate = { syncAction: proto.ISyncActionValue index: string[] diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 0990eea..0b25d5a 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -272,7 +272,7 @@ export const extractSyncdPatches = async(result: BinaryNode) => { const syncNode = getBinaryNodeChild(result, 'sync') const collectionNodes = getBinaryNodeChildren(syncNode, 'collection') - const final = { } as { [T in WAPatchName]: { patches: proto.ISyncdPatch[], snapshot?: proto.ISyncdSnapshot } } + const final = { } as { [T in WAPatchName]: { patches: proto.ISyncdPatch[], hasMorePatches: boolean, snapshot?: proto.ISyncdSnapshot } } await Promise.all( collectionNodes.map( async collectionNode => { @@ -283,6 +283,8 @@ export const extractSyncdPatches = async(result: BinaryNode) => { const syncds: proto.ISyncdPatch[] = [] const name = collectionNode.attrs.name as WAPatchName + + const hasMorePatches = collectionNode.attrs.has_more_patches == 'true' let snapshot: proto.ISyncdSnapshot | undefined = undefined if(snapshotNode && !!snapshotNode.content) { @@ -309,7 +311,7 @@ export const extractSyncdPatches = async(result: BinaryNode) => { } } - final[name] = { patches: syncds, snapshot } + final[name] = { patches: syncds, hasMorePatches, snapshot } } ) ) From 110b9d1f096fbb1591cab65bd918bb85ed812cf3 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 22 Dec 2021 21:37:27 +0530 Subject: [PATCH 261/311] fix: transaction not respecting null set --- src/Utils/auth-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/auth-utils.ts b/src/Utils/auth-utils.ts index 85c002f..9230147 100644 --- a/src/Utils/auth-utils.ts +++ b/src/Utils/auth-utils.ts @@ -26,7 +26,7 @@ export const addTransactionCapability = (state: SignalKeyStore, logger: Logger): } const dict = transactionCache[type] - const idsRequiringFetch = ids.filter(item => !dict?.[item]) + const idsRequiringFetch = dict ? ids.filter(item => !(item in dict)) : ids // only fetch if there are any items to fetch if(idsRequiringFetch.length) { const result = await state.get(type, idsRequiringFetch) From a9373fa0cd64480ae503bb34a75b1e07026f1042 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 22 Dec 2021 21:37:39 +0530 Subject: [PATCH 262/311] refactor: cleaner + faster app state sync --- src/Socket/chats.ts | 97 ++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 50b8ba5..29f852c 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -6,6 +6,8 @@ import { makeMessagesSocket } from "./messages-send"; import makeMutex from "../Utils/make-mutex"; import { Boom } from "@hapi/boom"; +const MAX_SYNC_ATTEMPTS = 5 + export const makeChatsSocket = (config: SocketConfig) => { const { logger } = config const sock = makeMessagesSocket(config) @@ -177,19 +179,21 @@ export const makeChatsSocket = (config: SocketConfig) => { }) } - const resyncAppStateInternal = async(collections: WAPatchName[], fromScratch: boolean = false, returnSnapshot: boolean = false) => { - if(fromScratch) returnSnapshot = true - + const resyncAppState = async(collections: WAPatchName[], fromScratch: boolean = false) => { const appStateChunk : AppStateChunk = {totalMutations: [], collectionsToHandle: []} await authState.keys.transaction( async() => { const collectionsToHandle = new Set(collections) + // in case something goes wrong -- ensure we don't enter a loop that cannot be exited from + const attemptsMap = { } as { [T in WAPatchName]: number | undefined } // keep executing till all collections are done // sometimes a single patch request will not return all the patches (God knows why) // so we fetch till they're all done (this is determined by the "has_more_patches" flag) while(collectionsToHandle.size) { const states = { } as { [T in WAPatchName]: LTHashState } + const nodes: BinaryNode[] = [] + for(const name of collectionsToHandle) { let state: LTHashState if(!fromScratch) { @@ -201,7 +205,18 @@ export const makeChatsSocket = (config: SocketConfig) => { states[name] = state logger.info(`resyncing ${name} from v${state.version}`) + + nodes.push({ + tag: 'collection', + attrs: { + name, + version: state.version.toString(), + // return snapshot if being synced from scratch + return_snapshot: (!state.version).toString() + } + }) } + const result = await query({ tag: 'iq', attrs: { @@ -213,16 +228,7 @@ export const makeChatsSocket = (config: SocketConfig) => { { tag: 'sync', attrs: { }, - content: collections.map( - (name) => ({ - tag: 'collection', - attrs: { - name, - version: states[name].version.toString(), - return_snapshot: returnSnapshot ? 'true' : 'false' - } - }) - ) + content: nodes } ] }) @@ -231,29 +237,41 @@ export const makeChatsSocket = (config: SocketConfig) => { for(const key in decoded) { const name = key as WAPatchName const { patches, hasMorePatches, snapshot } = decoded[name] - if(snapshot) { - const newState = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey) - states[name] = newState + try { + if(snapshot) { + const newState = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey) + states[name] = newState + + logger.info(`restored state of ${name} from snapshot to v${newState.version}`) - logger.info(`restored state of ${name} from snapshot to v${newState.version}`) - } - // only process if there are syncd patches - if(patches.length) { - const { newMutations, state: newState } = await decodePatches(name, patches, states[name], getAppStateSyncKey, true) - - await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) - - logger.info(`synced ${name} to v${newState.version}`) - if(newMutations.length) { - logger.trace({ newMutations, name }, 'recv new mutations') + await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) } + // only process if there are syncd patches + if(patches.length) { + const { newMutations, state: newState } = await decodePatches(name, patches, states[name], getAppStateSyncKey, true) + + await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) + + logger.info(`synced ${name} to v${newState.version}`) + if(newMutations.length) { + logger.trace({ newMutations, name }, 'recv new mutations') + } + + appStateChunk.totalMutations.push(...newMutations) + } + if(hasMorePatches) { + logger.info(`${name} has more patches...`) + } else { // collection is done with sync + collectionsToHandle.delete(name) + } + } catch(error) { + logger.info({ name, error: error.stack }, 'failed to sync state from version, removing and trying from scratch') + await authState.keys.set({ "app-state-sync-version": { [name]: null } }) - appStateChunk.totalMutations.push(...newMutations) - } - if(hasMorePatches) { - logger.info(`${name} has more patches...`) - } else { // collection is done with sync - collectionsToHandle.delete(name) + attemptsMap[name] = (attemptsMap[name] || 0) + 1 + if(attemptsMap[name] >= MAX_SYNC_ATTEMPTS) { + collectionsToHandle.delete(name) + } } } } @@ -265,19 +283,6 @@ export const makeChatsSocket = (config: SocketConfig) => { return appStateChunk } - const resyncAppState = async(collections: WAPatchName[], returnSnapshot: boolean = false) => { - let result : AppStateChunk - - try { - result = await resyncAppStateInternal(collections, false, returnSnapshot) - } catch(error) { - logger.info({ collections, error: error.stack }, 'failed to sync state from version, trying from scratch') - result = await resyncAppStateInternal(collections, true, true) - } - - return result - } - /** * fetch the profile picture of a user/group * type = "preview" for a low res picture From ee3486124d23c5c15b7a429e92dfdb9236ac7aa2 Mon Sep 17 00:00:00 2001 From: nanda <69896924+nugraizy@users.noreply.github.com> Date: Thu, 23 Dec 2021 00:18:40 +0700 Subject: [PATCH 263/311] Fix: fetchBlocklist (#1042) --- src/Socket/chats.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 29f852c..8a3622f 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -135,6 +135,7 @@ export const makeChatsSocket = (config: SocketConfig) => { type: 'get' } }) + return result.content[0].content.map(i => i.attrs.jid) } const updateBlockStatus = async(jid: string, action: 'block' | 'unblock') => { From 8c37ccf525a2e6ebcb1d2e05a67ec974cf1e9b6a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 23 Dec 2021 10:12:29 +0530 Subject: [PATCH 264/311] fix: tsc error --- src/Socket/chats.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 8a3622f..91a9ee1 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -135,7 +135,8 @@ export const makeChatsSocket = (config: SocketConfig) => { type: 'get' } }) - return result.content[0].content.map(i => i.attrs.jid) + const child = result.content?.[0] as BinaryNode + return (child.content as BinaryNode[])?.map(i => i.attrs.jid) } const updateBlockStatus = async(jid: string, action: 'block' | 'unblock') => { From 5ae0b9863685f31f9fc8fd911894720fe6441cef Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 23 Dec 2021 10:54:17 +0530 Subject: [PATCH 265/311] feat: add replace type for messages.upsert --- src/LegacySocket/messages.ts | 16 +++++++--------- src/Types/Message.ts | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/LegacySocket/messages.ts b/src/LegacySocket/messages.ts index 30851a9..a0e8e8d 100644 --- a/src/LegacySocket/messages.ts +++ b/src/LegacySocket/messages.ts @@ -98,12 +98,12 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { const attrs = response.attrs Object.assign(content, attrs) // update message - ev.emit('messages.update', [{ key: message.key, update: { message: message.message } }]) + ev.emit('messages.upsert', { messages: [message], type: 'replace' }) return response } - const onMessage = (message: WAMessage, type: MessageUpdateType | 'update') => { + const onMessage = (message: WAMessage, type: MessageUpdateType) => { const jid = message.key.remoteJid! // store chat updates in this const chatUpdate: Partial = { @@ -213,11 +213,8 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { if(Object.keys(chatUpdate).length > 1) { ev.emit('chats.update', [chatUpdate]) } - if(type === 'update') { - ev.emit('messages.update', [ { update: message, key: message.key } ]) - } else { - ev.emit('messages.upsert', { messages: [message], type }) - } + + ev.emit('messages.upsert', { messages: [message], type }) } const waUploadToServer = getWAUploadToServer(config, refreshMediaConn) @@ -306,11 +303,12 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { onMessage(msg, 'notify') } }) - // If a message has been updated (usually called when a video message gets its upload url, or live locations) + // If a message has been updated + // usually called when a video message gets its upload url, or live locations or ciphertext message gets fixed socketEvents.on ('CB:action,add:update,message', (node: BinaryNode) => { const msgs = getBinaryNodeMessages(node) for(const msg of msgs) { - onMessage(msg, 'update') + onMessage(msg, 'replace') } }) // message status updates diff --git a/src/Types/Message.ts b/src/Types/Message.ts index d505a78..cc251d1 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -165,7 +165,7 @@ export type MessageContentGenerationOptions = MediaGenerationOptions & { } export type MessageGenerationOptions = MessageContentGenerationOptions & MessageGenerationOptionsFromContent -export type MessageUpdateType = 'append' | 'notify' | 'prepend' | 'last' +export type MessageUpdateType = 'append' | 'notify' | 'prepend' | 'last' | 'replace' export type MessageInfoEventMap = { [jid: string]: Date } export interface MessageInfo { From 71a545e97221a119d1906c3c9f4901c87226c4a6 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 23 Dec 2021 10:54:46 +0530 Subject: [PATCH 266/311] feat: add "getMessage" to example --- Example/example.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Example/example.ts b/Example/example.ts index d3e48d8..cb63358 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -10,7 +10,13 @@ const startSock = () => { const sock = makeWASocket({ logger: P({ level: 'trace' }), printQRInTerminal: true, - auth: state + auth: state, + // implement to handle retries + getMessage: async key => { + return { + conversation: 'hello' + } + } }) const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { From 83bfa0e9b9c8e5363c47cde36f9ef4b7eb02fe9d Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 24 Dec 2021 10:18:21 +0530 Subject: [PATCH 267/311] chore: minor fixes --- src/LegacySocket/messages.ts | 3 ++- src/Utils/generics.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/LegacySocket/messages.ts b/src/LegacySocket/messages.ts index a0e8e8d..ba2e5d8 100644 --- a/src/LegacySocket/messages.ts +++ b/src/LegacySocket/messages.ts @@ -32,7 +32,8 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { mediaConn = (async() => { const {media_conn} = await query({ json: ['query', 'mediaConn'], - requiresPhoneConnection: false + requiresPhoneConnection: false, + expect200: true }) media_conn.fetchDate = new Date() return media_conn as MediaConnInfo diff --git a/src/Utils/generics.ts b/src/Utils/generics.ts index 50675af..54a37ff 100644 --- a/src/Utils/generics.ts +++ b/src/Utils/generics.ts @@ -165,7 +165,7 @@ export async function promiseTimeout(ms: number, promise: (resolve: (v?: T)=> delay .then(() => reject( new Boom('Timed Out', { - statusCode: 408, + statusCode: DisconnectReason.timedOut, data: { stack } From d8c6b0a5803e9fbaebabaaa263c0c85c5e06dfcd Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 24 Dec 2021 10:27:04 +0530 Subject: [PATCH 268/311] chore: update legacy example logging --- Example/example-legacy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/example-legacy.ts b/Example/example-legacy.ts index 9a7df6f..76bb044 100644 --- a/Example/example-legacy.ts +++ b/Example/example-legacy.ts @@ -39,7 +39,7 @@ const startSock = () => { }) - sock.ev.on('messages.update', m => console.log(m)) + sock.ev.on('messages.update', m => console.log(JSON.stringify(m, undefined, 2))) sock.ev.on('presence.update', m => console.log(m)) sock.ev.on('chats.update', m => console.log(m)) sock.ev.on('contacts.update', m => console.log(m)) From 415e4ed8a49f47898fd9f1bea2e283d6e9773ea5 Mon Sep 17 00:00:00 2001 From: Denis Didenko Date: Fri, 24 Dec 2021 09:18:29 +0300 Subject: [PATCH 269/311] fix smallbug readme (#1063) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bd2c71e..ed02ca1 100644 --- a/README.md +++ b/README.md @@ -281,7 +281,7 @@ const templateButtons = [ const templateMessage = { text: "Hi it's a template message", footer: 'Hello World', - templateButtons: templateButttons + templateButtons: templateButtons } const sendMsg = await sock.sendMessage(id, templateMessage) From 3176551a306900a3e3840260aa00aee611f4a264 Mon Sep 17 00:00:00 2001 From: Guilherme <50055027+guiguicdd@users.noreply.github.com> Date: Tue, 28 Dec 2021 15:49:03 -0300 Subject: [PATCH 270/311] MD - Update README.md (#1072) * Update README.md * Update README.md --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ed02ca1..06eda13 100644 --- a/README.md +++ b/README.md @@ -513,7 +513,6 @@ WA uses an encrypted form of communication to send chat/app updates. This has be - Delete message for me ``` ts - // mark it unread await sock.chatModify( { clear: { message: { id: 'ATWYHDNNWU81732J', fromMe: true } } }, '123456@s.whatsapp.net', @@ -633,10 +632,10 @@ Of course, replace ``` xyz ``` with an actual ID. const metadata = await sock.groupMetadata("abcd-xyz@g.us") console.log(metadata.id + ", title: " + metadata.subject + ", description: " + metadata.desc) ``` -- To join the group using the invitation code (not supported yet) +- To join the group using the invitation code ``` ts - const response = await sock.acceptInvite("xxx") - console.log("joined to: " + response.gid) + const response = await sock.groupAcceptInvite("xxx") + console.log("joined to: " + response) ``` Of course, replace ``` xxx ``` with invitation code. From 3534221e11a8a4f28bb97b1435a728d8c0e063ee Mon Sep 17 00:00:00 2001 From: rafaelwedbiz <30352114+rafaelwedbiz@users.noreply.github.com> Date: Wed, 29 Dec 2021 03:30:35 -0300 Subject: [PATCH 271/311] Fix Played Status (message update event) (#1089) * Fix Played Status * Update messages-recv.ts Co-authored-by: Adhiraj Singh --- src/Socket/messages-recv.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 16cc761..dc800e0 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -7,16 +7,14 @@ import { KEY_BUNDLE_TYPE } from "../Defaults" import { makeChatsSocket } from "./chats" import { extractGroupMetadata } from "./groups" -const getStatusFromReceiptType = (type: string | undefined) => { - if(type === 'read' || type === 'read-self') { - return proto.WebMessageInfo.WebMessageInfoStatus.READ - } - if(typeof type === 'undefined') { - return proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK - } - return undefined +const STATUS_MAP: { [_: string]: proto.WebMessageInfo.WebMessageInfoStatus } = { + 'played': proto.WebMessageInfo.WebMessageInfoStatus.PLAYED, + 'read': proto.WebMessageInfo.WebMessageInfoStatus.READ, + 'read-self': proto.WebMessageInfo.WebMessageInfoStatus.READ } +const getStatusFromReceiptType = (type: string | undefined) => STATUS_MAP[type] + export const makeMessagesRecvSocket = (config: SocketConfig) => { const { logger } = config const sock = makeChatsSocket(config) @@ -606,4 +604,4 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { }) return { ...sock, processMessage, sendMessageAck } -} \ No newline at end of file +} From 03f33852dfb76e521d483f3cec24cd54f7e6f1f3 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 29 Dec 2021 14:10:00 +0530 Subject: [PATCH 272/311] fix: ensure media cache does not override caption & other properties --- src/Utils/messages.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 202598f..d399751 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -77,14 +77,6 @@ export const prepareWAMessageMedia = async( // generate the key mediaType + ':' + uploadData.media.url!.toString() ) - // check for cache hit - if(cacheableKey) { - const mediaBuff: Buffer = options.mediaCache!.get(cacheableKey) - if(mediaBuff) { - logger?.debug({ cacheableKey }, `got media cache hit`) - return WAProto.Message.decode(mediaBuff) - } - } if(mediaType === 'document' && !uploadData.fileName) { uploadData.fileName = 'file' @@ -92,6 +84,18 @@ export const prepareWAMessageMedia = async( if(!uploadData.mimetype) { uploadData.mimetype = MIMETYPE_MAP[mediaType] } + + // check for cache hit + if(cacheableKey) { + const mediaBuff: Buffer = options.mediaCache!.get(cacheableKey) + if(mediaBuff) { + logger?.debug({ cacheableKey }, `got media cache hit`) + const obj = WAProto.Message.decode(mediaBuff) + const key = `${mediaType}Message` + return Object.assign(obj[key], { ...uploadData }) + } + } + const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined' const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') && (typeof uploadData['jpegThumbnail'] === 'undefined') From 3713646980d1b6e6c2283254b1c5bf3d8b1a3d52 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 30 Dec 2021 10:48:10 +0530 Subject: [PATCH 273/311] fix: media cache --- src/Utils/messages.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index d399751..7afa12d 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -66,9 +66,9 @@ export const prepareWAMessageMedia = async( } const uploadData: MediaUploadData = { ...message, - [mediaType]: undefined, media: message[mediaType] } + delete uploadData[mediaType] // check if cacheable + generate cache key const cacheableKey = typeof uploadData.media === 'object' && ('url' in uploadData.media) && @@ -90,9 +90,14 @@ export const prepareWAMessageMedia = async( const mediaBuff: Buffer = options.mediaCache!.get(cacheableKey) if(mediaBuff) { logger?.debug({ cacheableKey }, `got media cache hit`) + const obj = WAProto.Message.decode(mediaBuff) const key = `${mediaType}Message` - return Object.assign(obj[key], { ...uploadData }) + + delete uploadData.media + Object.assign(obj[key], { ...uploadData }) + + return obj } } From b191e1b23a9a66d65c872f4f3c991aeb65ddfbfe Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 31 Dec 2021 15:14:55 +0530 Subject: [PATCH 274/311] fix: remove limits on max body and content length --- src/Utils/messages-media.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index eed5158..291e4c7 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -335,7 +335,14 @@ export const downloadContentFromMessage = async( } // download the message - const fetched = await getHttpStream(downloadUrl, { headers }) + const fetched = await getHttpStream( + downloadUrl, + { + headers, + maxBodyLength: Infinity, + maxContentLength: Infinity, + } + ) let remainingBytes = Buffer.from([]) const { cipherKey, iv } = getMediaKeys(mediaKey, type) @@ -476,7 +483,9 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C }, httpsAgent: fetchAgent, timeout: timeoutMs, - responseType: 'json' + responseType: 'json', + maxBodyLength: Infinity, + maxContentLength: Infinity, } ) @@ -492,7 +501,7 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C } } catch (error) { const isLast = hostname === hosts[uploadInfo.hosts.length-1] - logger.debug(`Error in uploading to ${hostname} (${error}) ${isLast ? '' : ', retrying...'}`) + logger.debug({ trace: error.stack }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`) } } if (!urls) { From 3ad02f03170624f89d1f79dc93f6d56fd6437548 Mon Sep 17 00:00:00 2001 From: Pokoke <74485230+Pokoke-01@users.noreply.github.com> Date: Fri, 31 Dec 2021 17:15:35 +0700 Subject: [PATCH 275/311] fix listMessage (#1070) * fix listMessage * Default listType Co-authored-by: Rajeh Taher * use the ListMessageListType enum * use the ListMessageListType enum Co-authored-by: Rajeh Taher --- src/Types/Message.ts | 2 +- src/Utils/messages.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Types/Message.ts b/src/Types/Message.ts index cc251d1..2de2198 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -177,4 +177,4 @@ export type WAMessageUpdate = { update: Partial, key: proto.IMessageK export type WAMessageCursor = { before: WAMessageKey | undefined } | { after: WAMessageKey | undefined } -export type MessageInfoUpdate = { key: proto.IMessageKey, update: Partial } \ No newline at end of file +export type MessageInfoUpdate = { key: proto.IMessageKey, update: Partial } diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 7afa12d..bd91f93 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -331,7 +331,8 @@ export const generateWAMessageContent = async( buttonText: message.buttonText, title: message.title, footerText: message.footer, - description: message.text + description: message.text, + listType: proto.ListMessage.ListMessageListType['SINGLE_SELECT'] } m = { listMessage } From 923b38f24bf375f3a08be7d9facdb0dd3748c694 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 3 Jan 2022 12:05:23 +0530 Subject: [PATCH 276/311] chore: more descriptive logging --- src/LegacySocket/socket.ts | 2 +- src/Utils/messages-media.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/LegacySocket/socket.ts b/src/LegacySocket/socket.ts index 7cb9ccf..b101027 100644 --- a/src/LegacySocket/socket.ts +++ b/src/LegacySocket/socket.ts @@ -285,7 +285,7 @@ export const makeSocket = ({ const message = STATUS_CODES[responseStatusCode] || 'unknown' throw new Boom( `Unexpected status in '${Array.isArray(json) ? json[0] : (json?.tag || 'query')}': ${message}(${responseStatusCode})`, - { data: { query: json, message }, statusCode: response.status } + { data: { query: json, response }, statusCode: response.status } ) } return response diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 291e4c7..dbb78ff 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -471,9 +471,9 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C for (let hostname of hosts) { const auth = encodeURIComponent(uploadInfo.auth) // the auth token const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` - + let result: any try { - const {data: result} = await axios.post( + const body = await axios.post( url, stream, { @@ -488,6 +488,7 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C maxContentLength: Infinity, } ) + result = body.data if(result?.url || result?.directPath) { urls = { @@ -501,7 +502,7 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C } } catch (error) { const isLast = hostname === hosts[uploadInfo.hosts.length-1] - logger.debug({ trace: error.stack }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`) + logger.debug({ trace: error.stack, uploadResult: result }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`) } } if (!urls) { From 63c510a8691694f032f868d641fdab1610a1173c Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 3 Jan 2022 12:29:27 +0530 Subject: [PATCH 277/311] fix: use tmp buffer for upload for multiple retries --- src/Utils/messages-media.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index dbb78ff..61c31f0 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -468,6 +468,14 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C let urls: { mediaUrl: string, directPath: string } const hosts = [ ...customUploadHosts, ...uploadInfo.hosts.map(h => h.hostname) ] + + let chunks: Buffer[] = [] + for await(const chunk of stream) { + chunks.push(chunk) + } + + let reqBody = Buffer.concat(chunks) + for (let hostname of hosts) { const auth = encodeURIComponent(uploadInfo.auth) // the auth token const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` @@ -475,7 +483,7 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C try { const body = await axios.post( url, - stream, + reqBody, { headers: { 'Content-Type': 'application/octet-stream', @@ -505,12 +513,16 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C logger.debug({ trace: error.stack, uploadResult: result }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`) } } - if (!urls) { + // clear buffer just to be sure we're releasing the memory + reqBody = undefined + + if(!urls) { throw new Boom( 'Media upload failed on all hosts', { statusCode: 500 } ) } + return urls } } \ No newline at end of file From 9c0a3b89629ea2e011d050840e857151282ec177 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 3 Jan 2022 12:40:55 +0530 Subject: [PATCH 278/311] feat: add option to specify limit for custom upload host --- src/Types/Message.ts | 2 +- src/Types/Socket.ts | 3 ++- src/Types/index.ts | 2 -- src/Utils/messages-media.ts | 18 ++++++++++++++---- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 2de2198..6150290 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -28,7 +28,7 @@ export type DownloadableMessage = { mediaKey?: Uint8Array, directPath?: string, export type MediaConnInfo = { auth: string ttl: number - hosts: { hostname: string }[] + hosts: { hostname: string, maxContentLengthBytes: number }[] fetchDate: Date } diff --git a/src/Types/Socket.ts b/src/Types/Socket.ts index b9d8f42..8b2c403 100644 --- a/src/Types/Socket.ts +++ b/src/Types/Socket.ts @@ -3,6 +3,7 @@ import type { Agent } from "https" import type { Logger } from "pino" import type { URL } from "url" import type NodeCache from 'node-cache' +import { MediaConnInfo } from "./Message" export type WAVersion = [number, number, number] export type WABrowserDescription = [string, string, string] @@ -35,5 +36,5 @@ export type CommonSocketConfig = { /** provide a cache to store media, so does not have to be re-uploaded */ mediaCache?: NodeCache - customUploadHosts: string[] + customUploadHosts: MediaConnInfo['hosts'] } diff --git a/src/Types/index.ts b/src/Types/index.ts index 5e91fa3..9dbc635 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -19,8 +19,6 @@ export type SocketConfig = CommonSocketConfig & { userDevicesCache?: NodeCache /** map to store the retry counts for failed messages */ msgRetryCounterMap?: { [msgId: string]: number } - /** custom domains to push media via */ - customUploadHosts: string[] /** * fetch a message from your store * implement this so that messages failed to send (solves the "this message can take a while" issue) can be retried diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 61c31f0..ab4a0c6 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -467,7 +467,7 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C let uploadInfo = await refreshMediaConn(false) let urls: { mediaUrl: string, directPath: string } - const hosts = [ ...customUploadHosts, ...uploadInfo.hosts.map(h => h.hostname) ] + const hosts = [ ...customUploadHosts, ...uploadInfo.hosts ] let chunks: Buffer[] = [] for await(const chunk of stream) { @@ -476,11 +476,17 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C let reqBody = Buffer.concat(chunks) - for (let hostname of hosts) { + for (let { hostname, maxContentLengthBytes } of hosts) { + logger.debug(`uploading to "${hostname}"`) + const auth = encodeURIComponent(uploadInfo.auth) // the auth token const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` let result: any try { + if(maxContentLengthBytes && reqBody.length > maxContentLengthBytes) { + throw new Boom(`Body too large for "${hostname}"`, { statusCode: 413 }) + } + const body = await axios.post( url, reqBody, @@ -509,8 +515,12 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: C throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) } } catch (error) { - const isLast = hostname === hosts[uploadInfo.hosts.length-1] - logger.debug({ trace: error.stack, uploadResult: result }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`) + if(axios.isAxiosError(error)) { + result = error.response?.data + } + + const isLast = hostname === hosts[uploadInfo.hosts.length-1]?.hostname + logger.warn({ trace: error.stack, uploadResult: result }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`) } } // clear buffer just to be sure we're releasing the memory From 473c5bdce57a1a7ee6aab5cdfefa17bd9d5f54a0 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 3 Jan 2022 13:33:49 +0530 Subject: [PATCH 279/311] chore: add guard for sendRawMessage --- src/LegacySocket/socket.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/LegacySocket/socket.ts b/src/LegacySocket/socket.ts index b101027..edce5e7 100644 --- a/src/LegacySocket/socket.ts +++ b/src/LegacySocket/socket.ts @@ -57,7 +57,13 @@ export const makeSocket = ({ epoch += 1 // increment message count, it makes the 'epoch' field when sending binary messages return tag } - const sendRawMessage = (data: Buffer | string) => sendPromise.call(ws, data) as Promise + const sendRawMessage = (data: Buffer | string) => { + if(ws.readyState !== ws.OPEN) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } + + return sendPromise.call(ws, data) as Promise + } /** * Send a message to the WA servers * @returns the tag attached in the message From 7ffa10a5c5aa6d35e26ac886132a2100c6e7d34d Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 6 Jan 2022 15:11:33 +0530 Subject: [PATCH 280/311] fix: delivery receipt --- src/Socket/messages-recv.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index dc800e0..4cce50f 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -13,7 +13,13 @@ const STATUS_MAP: { [_: string]: proto.WebMessageInfo.WebMessageInfoStatus } = { 'read-self': proto.WebMessageInfo.WebMessageInfoStatus.READ } -const getStatusFromReceiptType = (type: string | undefined) => STATUS_MAP[type] +const getStatusFromReceiptType = (type: string | undefined) => { + const status = STATUS_MAP[type] + if(typeof type === 'undefined') { + return proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK + } + return status +} export const makeMessagesRecvSocket = (config: SocketConfig) => { const { logger } = config From 0b5d772b081804c6c2e232700a8c1b8ca9d62ff6 Mon Sep 17 00:00:00 2001 From: BochilGaming <79433517+BochilGaming@users.noreply.github.com> Date: Thu, 6 Jan 2022 23:45:52 +0700 Subject: [PATCH 281/311] Fix ContactsArrayMessage and add getBusinessProfile (#1074) * Fix: ContactsArrayMessage and add getBusinessProfile * delete package-lock.json * edit readme.md * add bussines hours * make type same with leagcy * revert --- README.md | 10 +++++++++ src/Socket/chats.ts | 49 +++++++++++++++++++++++++++++++++++++++++-- src/Types/index.ts | 5 +++-- src/Utils/messages.ts | 2 +- 4 files changed, 61 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 06eda13..c755d60 100644 --- a/README.md +++ b/README.md @@ -582,6 +582,11 @@ await sock.sendMessage( await sock.updateBlockStatus("xyz@s.whatsapp.net", "block") // Block user await sock.updateBlockStatus("xyz@s.whatsapp.net", "unblock") // Unblock user ``` +- To get a business profile, such as description, category + ```ts + const profile = await sock.getBusinessProfile("xyz@s.whatsapp.net") + console.log("business description: " + profile.description + ", category: " + profile.category) + ``` Of course, replace ``` xyz ``` with an actual ID. ## Groups @@ -627,6 +632,11 @@ Of course, replace ``` xyz ``` with an actual ID. const code = await sock.groupInviteCode("abcd-xyz@g.us") console.log("group code: " + code) ``` +- To revoke the invite code in a group + ```ts + const code = await sock.groupRevokeInvite("abcd-xyz@g.us") + console.log("New group code: " + code) + ``` - To query the metadata of a group ``` ts const metadata = await sock.groupMetadata("abcd-xyz@g.us") diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 91a9ee1..6b55ec5 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1,4 +1,4 @@ -import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, AppStateChunk, LTHashState, ChatModification, Contact } from "../Types"; +import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, AppStateChunk, LTHashState, ChatModification, Contact, WABusinessProfile, WABusinessHoursConfig } from "../Types"; import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET, reduceBinaryNodeToDictionary } from "../WABinary"; import { proto } from '../../WAProto' import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch, decodeSyncdSnapshot, newLTHashState } from "../Utils"; @@ -159,6 +159,50 @@ export const makeChatsSocket = (config: SocketConfig) => { }) } + const getBusinessProfile = async (jid: string): Promise => { + const results = await query({ + tag: 'iq', + attrs: { + to: 's.whatsapp.net', + xmlns: 'w:biz', + type: 'get' + }, + content: [{ + tag: 'business_profile', + attrs: { v: '244' }, + content: [{ + tag: 'profile', + attrs: { jid } + }] + }] + }) + const profiles = getBinaryNodeChild(getBinaryNodeChild(results, 'business_profile'), 'profile') + if (!profiles) { + // if not bussines + if (logger.level == 'trace') logger.trace({ jid }, 'Not bussines') + return + } + const address = getBinaryNodeChild(profiles, 'address') + const description = getBinaryNodeChild(profiles, 'description') + const website = getBinaryNodeChild(profiles, 'website') + const email = getBinaryNodeChild(profiles, 'email') + const category = getBinaryNodeChild(getBinaryNodeChild(profiles, 'categories'), 'category') + const business_hours = getBinaryNodeChild(profiles, 'business_hours') + const business_hours_config = business_hours && getBinaryNodeChildren(business_hours, 'business_hours_config') + return { + wid: profiles.attrs?.jid, + address: address?.content.toString(), + description: description?.content.toString(), + website: [website?.content.toString()], + email: email?.content.toString(), + category: category?.content.toString(), + business_hours: { + timezone: business_hours?.attrs?.timezone, + business_config: business_hours_config?.map(({ attrs }) => attrs as unknown as WABusinessHoursConfig) + } + } as unknown as WABusinessProfile + } + const updateAccountSyncTimestamp = async(fromTimestamp: number | string) => { logger.info({ fromTimestamp }, 'requesting account sync') await sendNode({ @@ -621,8 +665,9 @@ export const makeChatsSocket = (config: SocketConfig) => { fetchStatus, updateProfilePicture, updateBlockStatus, + getBusinessProfile, resyncAppState, chatModify, resyncMainAppState, } -} +} \ No newline at end of file diff --git a/src/Types/index.ts b/src/Types/index.ts index 9dbc635..1edee43 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -43,7 +43,7 @@ export type WAInitResponse = { status: 200 } -type WABusinessHoursConfig = { +export type WABusinessHoursConfig = { day_of_week: string mode: string open_time?: number @@ -53,7 +53,7 @@ export type WABusinessProfile = { description: string email: string business_hours: { - timezone: string + timezone?: string config?: WABusinessHoursConfig[] business_config?: WABusinessHoursConfig[] } @@ -65,4 +65,5 @@ export type WABusinessProfile = { wid?: string } + export type CurveKeyPair = { private: Uint8Array; public: Uint8Array } \ No newline at end of file diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index bd91f93..cbb6dab 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -253,7 +253,7 @@ export const generateWAMessageContent = async( if(contactLen === 1) { m.contactMessage = WAProto.ContactMessage.fromObject(message.contacts.contacts[0]) } else { - m.contactsArrayMessage = WAProto.ContactsArrayMessage.fromObject({ contacts: message.contacts }) + m.contactsArrayMessage = WAProto.ContactsArrayMessage.fromObject(message.contacts) } } else if('location' in message) { m.locationMessage = WAProto.LocationMessage.fromObject(message.location) From 6a2cb5a4139d8eb0a75c4c4ea7ed52adc0aec20f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 6 Jan 2022 23:27:14 +0530 Subject: [PATCH 282/311] refactor: message decoding 1. removes redundant receipt (was exactly the same as delivery receipt without the timestamp) 2. decodeWAMessage now returns a proper message struct 3. each message stanza results in exactly one message decoded --- src/Socket/messages-recv.ts | 104 ++++----------------------------- src/Socket/messages-send.ts | 11 ++-- src/Utils/decode-wa-message.ts | 60 ++++++++++--------- 3 files changed, 51 insertions(+), 124 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 4cce50f..96b6069 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -32,7 +32,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { assertingPreKeys, sendNode, relayMessage, - sendDeliveryReceipt, + sendReceipt, resyncMainAppState, } = sock @@ -357,102 +357,23 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } // recv a message ws.on('CB:message', async(stanza: BinaryNode) => { - const dec = await decodeMessageStanza(stanza, authState) - const fullMessages: proto.IWebMessageInfo[] = [] - - const { attrs } = stanza - const isGroup = !!stanza.attrs.participant - const sender = (attrs.participant || attrs.from)?.toString() - const isMe = areJidsSameUser(sender, authState.creds.me!.id) - - const remoteJid = jidNormalizedUser(dec.chatId) - - const key: WAMessageKey = { - remoteJid, - fromMe: isMe, - id: dec.msgId, - participant: dec.participant - } - const partialMsg: Partial = { - messageTimestamp: dec.timestamp, - pushName: dec.pushname - } - - if(!dec.failures.length) { - await sendMessageAck(stanza, { class: 'receipt' }) - } - - // if there were some successful decryptions - if(dec.successes.length) { - // send message receipt - let recpAttrs: { [_: string]: any } - if(isMe) { - recpAttrs = { - type: 'sender', - id: stanza.attrs.id, - to: stanza.attrs.from, - } - if(isGroup) { - recpAttrs.participant = stanza.attrs.participant - } else { - recpAttrs.recipient = stanza.attrs.recipient - } - } else { - const isStatus = isJidStatusBroadcast(stanza.attrs.from) - recpAttrs = { - id: stanza.attrs.id, - } - if(isGroup || isStatus) { - recpAttrs.participant = stanza.attrs.participant - recpAttrs.to = dec.chatId - } else { - recpAttrs.to = jidNormalizedUser(dec.chatId) - } - } - - await sendNode({ tag: 'receipt', attrs: recpAttrs }) - logger.debug({ msgId: dec.msgId }, 'sent message receipt') - - await sendDeliveryReceipt(dec.chatId, dec.participant, [dec.msgId]) - logger.debug({ msgId: dec.msgId }, 'sent delivery receipt') - } - - for(const msg of dec.successes) { - const message = msg.deviceSentMessage?.message || msg - fullMessages.push({ - key, - message, - status: isMe ? proto.WebMessageInfo.WebMessageInfoStatus.SERVER_ACK : null, - ...partialMsg - }) - } - - for(const { error } of dec.failures) { + const msg = await decodeMessageStanza(stanza, authState) + // message failed to decrypt + if(msg.messageStubType === proto.WebMessageInfo.WebMessageInfoStubType.CIPHERTEXT) { logger.error( - { msgId: dec.msgId, trace: error.stack, data: error.data }, + { msgId: msg.key.id, params: msg.messageStubParameters }, 'failure in decrypting message' ) await sendRetryRequest(stanza) - - fullMessages.push({ - key, - messageStubType: WAMessageStubType.CIPHERTEXT, - messageStubParameters: [error.message], - ...partialMsg - }) - } - - if(fullMessages.length) { - ev.emit( - 'messages.upsert', - { - messages: fullMessages.map(m => proto.WebMessageInfo.fromObject(m)), - type: stanza.attrs.offline ? 'append' : 'notify' - } - ) } else { - logger.warn({ stanza }, `received node with 0 messages`) + await sendMessageAck(stanza, { class: 'receipt' }) + // no type in the receipt => message delivered + await sendReceipt(msg.key.remoteJid!, msg.key.participant, [msg.key.id!], undefined) + logger.debug({ msg: msg.key }, 'sent delivery receipt') } + + msg.key.remoteJid = jidNormalizedUser(msg.key.remoteJid!) + ev.emit('messages.upsert', { messages: [msg], type: stanza.attrs.offline ? 'append' : 'notify' }) }) ws.on('CB:ack,class:message', async(node: BinaryNode) => { @@ -477,7 +398,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { }) const sendMessagesAgain = async(key: proto.IMessageKey, ids: string[]) => { - const msgs = await Promise.all( ids.map(id => ( config.getMessage({ ...key, id }) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 503a300..58cd2f8 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -73,7 +73,10 @@ export const makeMessagesSocket = (config: SocketConfig) => { } return mediaConn } - + /** + * generic send receipt function + * used for receipts of phone call, read, delivery etc. + * */ const sendReceipt = async(jid: string, participant: string | undefined, messageIds: string[], type: 'read' | 'read-self' | undefined) => { const node: BinaryNode = { tag: 'receipt', @@ -107,10 +110,6 @@ export const makeMessagesSocket = (config: SocketConfig) => { await sendNode(node) } - const sendDeliveryReceipt = (jid: string, participant: string | undefined, messageIds: string[]) => { - return sendReceipt(jid, participant, messageIds, undefined) - } - const sendReadReceipt = async(jid: string, participant: string | undefined, messageIds: string[]) => { const privacySettings = await fetchPrivacySettings() // based on privacy settings, we have to change the read type @@ -424,7 +423,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { ...sock, assertSessions, relayMessage, - sendDeliveryReceipt, + sendReceipt, sendReadReceipt, refreshMediaConn, waUploadToServer, diff --git a/src/Utils/decode-wa-message.ts b/src/Utils/decode-wa-message.ts index 130c774..159790b 100644 --- a/src/Utils/decode-wa-message.ts +++ b/src/Utils/decode-wa-message.ts @@ -1,15 +1,15 @@ import { Boom } from '@hapi/boom' import { unpadRandomMax16 } from "./generics" -import { AuthenticationState } from "../Types" -import { areJidsSameUser, BinaryNode as BinaryNodeM, encodeBinaryNode, isJidBroadcast, isJidGroup, isJidStatusBroadcast, isJidUser } from '../WABinary' +import { WAMessageKey, AuthenticationState } from '../Types' +import { areJidsSameUser, BinaryNode, isJidBroadcast, isJidGroup, isJidStatusBroadcast, isJidUser, jidNormalizedUser } from '../WABinary' import { decryptGroupSignalProto, decryptSignalProto, processSenderKeyMessage } from './signal' import { proto } from '../../WAProto' type MessageType = 'chat' | 'peer_broadcast' | 'other_broadcast' | 'group' | 'direct_peer_status' | 'other_status' -export const decodeMessageStanza = async(stanza: BinaryNodeM, auth: AuthenticationState) => { - const deviceIdentity = (stanza.content as BinaryNodeM[])?.find(m => m.tag === 'device-identity') - const deviceIdentityBytes = deviceIdentity ? deviceIdentity.content as Buffer : undefined +export const decodeMessageStanza = async(stanza: BinaryNode, auth: AuthenticationState) => { + //const deviceIdentity = (stanza.content as BinaryNodeM[])?.find(m => m.tag === 'device-identity') + //const deviceIdentityBytes = deviceIdentity ? deviceIdentity.content as Buffer : undefined let msgType: MessageType let chatId: string @@ -53,18 +53,34 @@ export const decodeMessageStanza = async(stanza: BinaryNodeM, auth: Authenticati chatId = from author = participant } + const sender = msgType === 'chat' ? author : chatId - const successes: proto.Message[] = [] - const failures: { error: Boom }[] = [] + const fromMe = isMe(participant || chatId) + const pushname = stanza.attrs.notify + + const key: WAMessageKey = { + remoteJid: chatId, + fromMe, + id: msgId, + participant + } + + const fullMessage: proto.IWebMessageInfo = { + key, + messageTimestamp: +stanza.attrs.t, + pushName: pushname, + status: key.fromMe ? proto.WebMessageInfo.WebMessageInfoStatus.SERVER_ACK : null, + } + if(Array.isArray(stanza.content)) { - for(const { tag, attrs, content } of stanza.content as BinaryNodeM[]) { + for(const { tag, attrs, content } of stanza.content) { if(tag !== 'enc') continue - if(!Buffer.isBuffer(content) && !(content instanceof Uint8Array)) continue + if(!(content instanceof Uint8Array)) continue + + let msgBuffer: Buffer try { - let msgBuffer: Buffer - const e2eType = attrs.type switch(e2eType) { case 'skmsg': @@ -76,28 +92,20 @@ export const decodeMessageStanza = async(stanza: BinaryNodeM, auth: Authenticati msgBuffer = await decryptSignalProto(user, e2eType, content as Buffer, auth) break } - const msg = proto.Message.decode(unpadRandomMax16(msgBuffer)) + let msg: proto.IMessage = proto.Message.decode(unpadRandomMax16(msgBuffer)) + msg = msg.deviceSentMessage?.message || msg if(msg.senderKeyDistributionMessage) { await processSenderKeyMessage(author, msg.senderKeyDistributionMessage, auth) } - successes.push(msg) + if(fullMessage.message) Object.assign(fullMessage.message, msg) + else fullMessage.message = msg } catch(error) { - failures.push({ error: new Boom(error, { data: Buffer.from(encodeBinaryNode(stanza)).toString('base64') }) }) + fullMessage.messageStubType = proto.WebMessageInfo.WebMessageInfoStubType.CIPHERTEXT + fullMessage.messageStubParameters = [error.message] } } } - return { - msgId, - chatId, - author, - from, - timestamp: +stanza.attrs.t, - participant, - recipient, - pushname: stanza.attrs.notify, - successes, - failures - } + return fullMessage } \ No newline at end of file From da65ae8f42d169436a74e526db29050309275922 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 7 Jan 2022 13:55:26 +0530 Subject: [PATCH 283/311] fix: do not update chat + contact on prepend messages --- src/Socket/messages-recv.ts | 50 +++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 96b6069..7c62e00 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -498,34 +498,36 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } }) - ev.on('messages.upsert', async({ messages }) => { - const chat: Partial = { id: messages[0].key.remoteJid } - const contactNameUpdates: { [_: string]: string } = { } - for(const msg of messages) { - if(!!msg.pushName) { - const jid = msg.key.fromMe ? jidNormalizedUser(authState.creds.me!.id) : (msg.key.participant || msg.key.remoteJid) - contactNameUpdates[jid] = msg.pushName - // update our pushname too - if(msg.key.fromMe && authState.creds.me?.name !== msg.pushName) { - ev.emit('creds.update', { me: { ...authState.creds.me!, name: msg.pushName! } }) + ev.on('messages.upsert', async({ messages, type }) => { + if(type === 'notify' || type === 'append') { + const chat: Partial = { id: messages[0].key.remoteJid } + const contactNameUpdates: { [_: string]: string } = { } + for(const msg of messages) { + if(!!msg.pushName) { + const jid = msg.key.fromMe ? jidNormalizedUser(authState.creds.me!.id) : (msg.key.participant || msg.key.remoteJid) + contactNameUpdates[jid] = msg.pushName + // update our pushname too + if(msg.key.fromMe && authState.creds.me?.name !== msg.pushName) { + ev.emit('creds.update', { me: { ...authState.creds.me!, name: msg.pushName! } }) + } } - } - await processMessage(msg, chat) - if(!!msg.message && !msg.message!.protocolMessage) { - chat.conversationTimestamp = toNumber(msg.messageTimestamp) - if(!msg.key.fromMe) { - chat.unreadCount = (chat.unreadCount || 0) + 1 + await processMessage(msg, chat) + if(!!msg.message && !msg.message!.protocolMessage) { + chat.conversationTimestamp = toNumber(msg.messageTimestamp) + if(!msg.key.fromMe) { + chat.unreadCount = (chat.unreadCount || 0) + 1 + } } } - } - if(Object.keys(chat).length > 1) { - ev.emit('chats.update', [ chat ]) - } - if(Object.keys(contactNameUpdates).length) { - ev.emit('contacts.update', Object.keys(contactNameUpdates).map( - id => ({ id, notify: contactNameUpdates[id] }) - )) + if(Object.keys(chat).length > 1) { + ev.emit('chats.update', [ chat ]) + } + if(Object.keys(contactNameUpdates).length) { + ev.emit('contacts.update', Object.keys(contactNameUpdates).map( + id => ({ id, notify: contactNameUpdates[id] }) + )) + } } }) From d15bde5d17d61e2872d96321768464693de58c7e Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 7 Jan 2022 14:29:52 +0530 Subject: [PATCH 284/311] refactor: app state handling 1. fixes snapshot patches not being included 2. fixes all mutations being passed when syncing from scratch 3. simpler chat mutation model 4. do not retry if key is not found --- src/Socket/chats.ts | 44 +++++++++++++++++++++++++------------- src/Types/Chat.ts | 5 ++++- src/Utils/chat-utils.ts | 47 +++++++++++++++++++++++------------------ 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 6b55ec5..1866c32 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -143,7 +143,7 @@ export const makeChatsSocket = (config: SocketConfig) => { await query({ tag: 'iq', attrs: { - xmlns: 'blocklist', + xmlns: 'blocklist', to: S_WHATSAPP_NET, type: 'set' }, @@ -225,9 +225,12 @@ export const makeChatsSocket = (config: SocketConfig) => { }) } - const resyncAppState = async(collections: WAPatchName[], fromScratch: boolean = false) => { - const appStateChunk : AppStateChunk = {totalMutations: [], collectionsToHandle: []} - + const resyncAppState = async(collections: WAPatchName[]) => { + const appStateChunk: AppStateChunk = {totalMutations: [], collectionsToHandle: []} + // we use this to determine which events to fire + // otherwise when we resync from scratch -- all notifications will fire + const initialVersionMap: { [T in WAPatchName]?: number } = { } + await authState.keys.transaction( async() => { const collectionsToHandle = new Set(collections) @@ -241,12 +244,16 @@ export const makeChatsSocket = (config: SocketConfig) => { const nodes: BinaryNode[] = [] for(const name of collectionsToHandle) { - let state: LTHashState - if(!fromScratch) { - const result = await authState.keys.get('app-state-sync-version', [name]) - state = result[name] + const result = await authState.keys.get('app-state-sync-version', [name]) + let state = result[name] + + if(state) { + if(typeof initialVersionMap[name] === 'undefined') { + initialVersionMap[name] = state.version + } + } else { + state = newLTHashState() } - if(!state) state = newLTHashState() states[name] = state @@ -285,16 +292,18 @@ export const makeChatsSocket = (config: SocketConfig) => { const { patches, hasMorePatches, snapshot } = decoded[name] try { if(snapshot) { - const newState = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey) + const { state: newState, mutations } = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey, initialVersionMap[name]) states[name] = newState - logger.info(`restored state of ${name} from snapshot to v${newState.version}`) + logger.info(`restored state of ${name} from snapshot to v${newState.version} with ${mutations.length} mutations`) await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) + + appStateChunk.totalMutations.push(...mutations) } // only process if there are syncd patches if(patches.length) { - const { newMutations, state: newState } = await decodePatches(name, patches, states[name], getAppStateSyncKey, true) + const { newMutations, state: newState } = await decodePatches(name, patches, states[name], getAppStateSyncKey, initialVersionMap[name]) await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) @@ -313,9 +322,12 @@ export const makeChatsSocket = (config: SocketConfig) => { } catch(error) { logger.info({ name, error: error.stack }, 'failed to sync state from version, removing and trying from scratch') await authState.keys.set({ "app-state-sync-version": { [name]: null } }) - + // increment number of retries attemptsMap[name] = (attemptsMap[name] || 0) + 1 - if(attemptsMap[name] >= MAX_SYNC_ATTEMPTS) { + // if retry attempts overshoot + // or key not found + if(attemptsMap[name] >= MAX_SYNC_ATTEMPTS || error.output?.statusCode === 404) { + // stop retrying collectionsToHandle.delete(name) } } @@ -431,6 +443,8 @@ export const makeChatsSocket = (config: SocketConfig) => { } const processSyncActions = (actions: ChatMutation[]) => { + console.log(actions) + const updates: { [jid: string]: Partial } = {} const contactUpdates: { [jid: string]: Contact } = {} const msgDeletes: proto.IMessageKey[] = [] @@ -637,7 +651,7 @@ export const makeChatsSocket = (config: SocketConfig) => { const name = update.attrs.name as WAPatchName mutationMutex.mutex( async() => { - await resyncAppState([name], false) + await resyncAppState([name]) .catch(err => logger.error({ trace: err.stack, node }, `failed to sync state`)) } ) diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 994821e..06b7e50 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -10,7 +10,10 @@ export interface PresenceData { lastSeen?: number } -export type ChatMutation = { syncAction: proto.ISyncActionData, index: string[], indexMac: Uint8Array, valueMac: Uint8Array, operation: number } +export type ChatMutation = { + syncAction: proto.ISyncActionData + index: string[] +} export type AppStateChunk = { totalMutations : ChatMutation[], collectionsToHandle: WAPatchName[] } diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 0b25d5a..fd2fc10 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -187,7 +187,7 @@ export const decodeSyncdMutations = async( if(!key) { const keyEnc = await getAppStateSyncKey(base64Key) if(!keyEnc) { - throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500, data: { msgMutations } }) + throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 404, data: { msgMutations } }) } const result = mutationKeys(keyEnc.keyData!) keyCache[base64Key] = result @@ -229,17 +229,16 @@ export const decodeSyncdMutations = async( } } - const indexStr = Buffer.from(syncAction.index).toString() - const mutation: ChatMutation = { + const indexStr = Buffer.from(syncAction.index).toString() + mutations.push({ syncAction, index: JSON.parse(indexStr), + }) + ltGenerator.mix({ indexMac: record.index!.blob!, valueMac: ogValueMac, - operation: operation, - } - mutations.push(mutation) - - ltGenerator.mix(mutation) + operation: operation + }) } return { mutations, ...ltGenerator.finish() } @@ -339,20 +338,15 @@ export const decodeSyncdSnapshot = async( name: WAPatchName, snapshot: proto.ISyncdSnapshot, getAppStateSyncKey: FetchAppStateSyncKey, + minimumVersionNumber: number | undefined, validateMacs: boolean = true ) => { const newState = newLTHashState() newState.version = toNumber(snapshot.version!.version!) - const records = snapshot.records! - - const ltGenerator = makeLtHashGenerator(newState) - for(const { index, value } of records) { - const valueMac = value.blob!.slice(-32)! - ltGenerator.mix({ indexMac: index.blob!, valueMac, operation: 0 }) - } - - Object.assign(newState, ltGenerator.finish()) + let { hash, indexValueMap, mutations } = await decodeSyncdMutations(snapshot.records!, newState, getAppStateSyncKey, validateMacs) + newState.hash = hash + newState.indexValueMap = indexValueMap if(validateMacs) { const base64Key = Buffer.from(snapshot.keyId!.id!).toString('base64') @@ -367,7 +361,15 @@ export const decodeSyncdSnapshot = async( } } - return newState + const areMutationsRequired = typeof minimumVersionNumber === 'undefined' || newState.version > minimumVersionNumber + if(!areMutationsRequired) { + mutations = [] + } + + return { + state: newState, + mutations + } } export const decodePatches = async( @@ -375,6 +377,7 @@ export const decodePatches = async( syncds: proto.ISyncdPatch[], initial: LTHashState, getAppStateSyncKey: FetchAppStateSyncKey, + minimumVersionNumber?: number, validateMacs: boolean = true ) => { const successfulMutations: ChatMutation[] = [] @@ -390,14 +393,18 @@ export const decodePatches = async( const ref = await downloadExternalPatch(syncd.externalMutations) syncd.mutations.push(...ref.mutations) } + + const patchVersion = toNumber(version.version!) - newState.version = toNumber(version.version!) + newState.version = patchVersion const decodeResult = await decodeSyncdPatch(syncd, name, newState, getAppStateSyncKey, validateMacs) newState.hash = decodeResult.hash newState.indexValueMap = decodeResult.indexValueMap - successfulMutations.push(...decodeResult.mutations) + if(typeof minimumVersionNumber === 'undefined' || patchVersion > minimumVersionNumber) { + successfulMutations.push(...decodeResult.mutations) + } if(validateMacs) { const base64Key = Buffer.from(keyId!.id!).toString('base64') From db6a02c4a562465d7a93c3c171d8f07fd3c939a0 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 7 Jan 2022 21:04:54 +0530 Subject: [PATCH 285/311] chore: remove redundant log --- src/Socket/chats.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 1866c32..a96994a 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -443,8 +443,6 @@ export const makeChatsSocket = (config: SocketConfig) => { } const processSyncActions = (actions: ChatMutation[]) => { - console.log(actions) - const updates: { [jid: string]: Partial } = {} const contactUpdates: { [jid: string]: Contact } = {} const msgDeletes: proto.IMessageKey[] = [] From 6c08f0cd76077fbeb0f1cbe2792e86ae8104f047 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 7 Jan 2022 21:15:27 +0530 Subject: [PATCH 286/311] fix: incorrect from me --- src/Utils/decode-wa-message.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/decode-wa-message.ts b/src/Utils/decode-wa-message.ts index 159790b..ee4a5a1 100644 --- a/src/Utils/decode-wa-message.ts +++ b/src/Utils/decode-wa-message.ts @@ -56,7 +56,7 @@ export const decodeMessageStanza = async(stanza: BinaryNode, auth: Authenticatio const sender = msgType === 'chat' ? author : chatId - const fromMe = isMe(participant || chatId) + const fromMe = isMe(stanza.attrs.participant || stanza.attrs.from) const pushname = stanza.attrs.notify const key: WAMessageKey = { From 67f3ddeaff1bbf7f4100eefe85d6e879582962f7 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 7 Jan 2022 21:24:29 +0530 Subject: [PATCH 287/311] chore: remove null status from not fromMe msgs --- src/Utils/decode-wa-message.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Utils/decode-wa-message.ts b/src/Utils/decode-wa-message.ts index ee4a5a1..083d3ee 100644 --- a/src/Utils/decode-wa-message.ts +++ b/src/Utils/decode-wa-message.ts @@ -69,8 +69,11 @@ export const decodeMessageStanza = async(stanza: BinaryNode, auth: Authenticatio const fullMessage: proto.IWebMessageInfo = { key, messageTimestamp: +stanza.attrs.t, - pushName: pushname, - status: key.fromMe ? proto.WebMessageInfo.WebMessageInfoStatus.SERVER_ACK : null, + pushName: pushname + } + + if(key.fromMe) { + fullMessage.status = proto.WebMessageInfo.WebMessageInfoStatus.SERVER_ACK } if(Array.isArray(stanza.content)) { From a0003f0fe97572b4ebe37eef54898d4dbf96fa36 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 7 Jan 2022 21:24:46 +0530 Subject: [PATCH 288/311] fix: read receipts not being available --- src/Socket/messages-recv.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 7c62e00..b33ff80 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -429,9 +429,9 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { let shouldAck = true const { attrs, content } = node - const isNodeFromMe = areJidsSameUser(attrs.from, authState.creds.me?.id) - const remoteJid = attrs.recipient || attrs.from - const fromMe = isNodeFromMe || (attrs.recipient ? false : true) + const isNodeFromMe = areJidsSameUser(attrs.participant || attrs.from, authState.creds.me?.id) + const remoteJid = !isNodeFromMe ? attrs.from : attrs.recipient + const fromMe = !attrs.recipient const ids = [attrs.id] if(Array.isArray(content)) { @@ -447,7 +447,15 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } const status = getStatusFromReceiptType(attrs.type) - if(typeof status !== 'undefined' && !isNodeFromMe) { + if( + typeof status !== 'undefined' && + ( + // basically, we only want to know when a message from us has been delivered to/read by the other person + // or another device of ours has read some messages + status > proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK || + !isNodeFromMe + ) + ) { ev.emit('messages.update', ids.map(id => ({ key: { ...key, id }, update: { status } From 127e21b92026b96bfc5c24eaaf28ff361ca7c3de Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 8 Jan 2022 11:27:19 +0530 Subject: [PATCH 289/311] feat: implement getAuthenticationCredsType --- src/Utils/legacy-msgs.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Utils/legacy-msgs.ts b/src/Utils/legacy-msgs.ts index 8984e8f..590b65d 100644 --- a/src/Utils/legacy-msgs.ts +++ b/src/Utils/legacy-msgs.ts @@ -3,7 +3,7 @@ import { randomBytes } from 'crypto' import { decodeBinaryNodeLegacy, jidNormalizedUser } from "../WABinary" import { aesDecrypt, hmacSign, hkdf, Curve } from "./crypto" import { BufferJSON } from './generics' -import { DisconnectReason, WATag, LegacyAuthenticationCreds, CurveKeyPair, Contact } from "../Types" +import { DisconnectReason, WATag, LegacyAuthenticationCreds, AuthenticationCreds, CurveKeyPair, Contact } from "../Types" export const newLegacyAuthCreds = () => ({ clientID: randomBytes(16).toString('base64') @@ -173,4 +173,13 @@ export const useSingleFileLegacyAuthState = (file: string) => { writeFileSync(file, str) } } +} + +export const getAuthenticationCredsType = (creds: LegacyAuthenticationCreds | AuthenticationCreds) => { + if('clientID' in creds && !!creds.clientID) { + return 'legacy' + } + if('noiseKey' in creds && !!creds.noiseKey) { + return 'md' + } } \ No newline at end of file From 5febb86e14e12064173b9565637080944af38b94 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 8 Jan 2022 23:01:55 +0530 Subject: [PATCH 290/311] fix: message delete not reflecting correctly for others --- src/Socket/messages-recv.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index b33ff80..af01a82 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -167,7 +167,10 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { case proto.ProtocolMessage.ProtocolMessageType.REVOKE: ev.emit('messages.update', [ { - key: protocolMsg.key, + key: { + ...message.key, + id: protocolMsg.key!.id + }, update: { message: null, messageStubType: WAMessageStubType.REVOKE, key: message.key } } ]) From c7ceb0ab11ccaa2245971cbcadca2486182403eb Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Mon, 10 Jan 2022 15:21:34 +0530 Subject: [PATCH 291/311] chore: use peerDependencies instead of optional --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1d12b28..aba51f0 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "protobufjs": "^6.10.1", "ws": "^8.0.0" }, - "optionalDependencies": { + "peerDependencies": { "jimp": "^0.16.1", "qrcode-terminal": "^0.12.0", "sharp": "^0.29.3" From ede40b16f1de8616a62e4e576de7da4dea3bc1e7 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 11 Jan 2022 11:00:19 +0530 Subject: [PATCH 292/311] fix: update MD mismatch error code Because 403 can mean other things as well -- don't want to conflate the two --- src/Types/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Types/index.ts b/src/Types/index.ts index 1edee43..1809154 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -34,7 +34,7 @@ export enum DisconnectReason { loggedOut = 401, badSession = 500, restartRequired = 410, - multideviceMismatch = 403 + multideviceMismatch = 411 } export type WAInitResponse = { From f09e0f85ccf93e47a7ca81a35df7928ed24623f4 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 13 Jan 2022 16:26:56 +0530 Subject: [PATCH 293/311] feat: add getContentType --- src/Utils/messages.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index cbb6dab..31655f0 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -426,6 +426,14 @@ export const generateWAMessage = async( ) } +/** Get the key to access the true type of content */ +export const getContentType = (content: WAProto.IMessage | undefined) => { + if(content) { + const keys = Object.keys(content) + const key = keys.find(k => (k === 'conversation' || k.endsWith('Message')) && k !== 'senderKeyDistributionMessage') + return key as keyof typeof content + } +} /** * Extract the true message content from a message * Eg. extracts the inner message from a disappearing message/view once message From 793b23cb2104aa76d1bcc9a744339cdd1b87cc02 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 16 Jan 2022 12:51:08 +0530 Subject: [PATCH 294/311] refactor: history processing 1. fixes issue when some chats/messages are not synced 2. adds info about whether the history chunk is the latest --- src/Socket/messages-recv.ts | 68 ++++++------------------------------ src/Types/index.ts | 3 +- src/Utils/history.ts | 69 +++++++++++++++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 62 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index af01a82..ed9d316 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -1,7 +1,7 @@ -import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata, WAMessageKey, Contact } from "../Types" -import { decodeMessageStanza, encodeBigEndian, toNumber, downloadHistory, generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils" -import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser, getAllBinaryNodeChildren, BinaryNodeAttributes, isJidGroup } from '../WABinary' +import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata } from "../Types" +import { decodeMessageStanza, encodeBigEndian, toNumber, downloadAndProcessHistorySyncNotification, generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils" +import { BinaryNode, jidDecode, jidEncode, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser, getAllBinaryNodeChildren, BinaryNodeAttributes, isJidGroup } from '../WABinary' import { proto } from "../../WAProto" import { KEY_BUNDLE_TYPE } from "../Defaults" import { makeChatsSocket } from "./chats" @@ -38,6 +38,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const msgRetryMap = config.msgRetryCounterMap || { } + const historyCache = new Set() + const sendMessageAck = async({ tag, attrs }: BinaryNode, extraAttrs: BinaryNodeAttributes) => { const stanza: BinaryNode = { tag: 'ack', @@ -122,6 +124,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { logger.info({ msgAttrs: node.attrs, retryCount }, 'sent retry receipt') }) } + const processMessage = async(message: proto.IWebMessageInfo, chatUpdate: Partial) => { const protocolMsg = message.message?.protocolMessage if(protocolMsg) { @@ -129,11 +132,9 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { case proto.ProtocolMessage.ProtocolMessageType.HISTORY_SYNC_NOTIFICATION: const histNotification = protocolMsg!.historySyncNotification - logger.info({ type: histNotification.syncType!, id: message.key.id }, 'got history notification') - const history = await downloadHistory(histNotification) + logger.info({ histNotification, id: message.key.id }, 'got history notification') + const info = await downloadAndProcessHistorySyncNotification(histNotification, historyCache) - processHistoryMessage(history) - const meJid = authState.creds.me!.id await sendNode({ tag: 'receipt', @@ -143,6 +144,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { to: jidEncode(jidDecode(meJid).user, 'c.us') } }) + + info && ev.emit('chats.set', info) break case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_SHARE: const keys = protocolMsg.appStateSyncKeyShare!.keys @@ -227,57 +230,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } } - const processHistoryMessage = (item: proto.HistorySync) => { - const messages: proto.IWebMessageInfo[] = [] - const contacts: Contact[] = [] - switch(item.syncType) { - case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_BOOTSTRAP: - const chats = item.conversations!.map( - c => { - const chat: Chat = { ...c } - if(chat.name) { - contacts.push({ - id: chat.id, - name: chat.name - }) - } - //@ts-expect-error - delete chat.messages - for(const msg of c.messages || []) { - if(msg.message) { - messages.push(msg.message) - } - } - return chat - } - ) - ev.emit('chats.set', { chats, messages, contacts }) - break - case proto.HistorySync.HistorySyncHistorySyncType.RECENT: - // push remaining messages - for(const conv of item.conversations) { - for(const m of (conv.messages || [])) { - messages.push(m.message!) - } - } - if(messages.length) { - ev.emit('messages.upsert', { messages, type: 'prepend' }) - } - break - case proto.HistorySync.HistorySyncHistorySyncType.PUSH_NAME: - contacts.push( - ...item.pushnames.map( - p => ({ notify: p.pushname, id: p.id }) - ) - ) - ev.emit('chats.set', { chats: [], messages: [], contacts }) - break - case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_STATUS_V3: - // TODO - break - } - } - const processNotification = (node: BinaryNode): Partial => { const result: Partial = { } const [child] = getAllBinaryNodeChildren(node) diff --git a/src/Types/index.ts b/src/Types/index.ts index 1809154..c04d218 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -10,7 +10,7 @@ export * from './Events' import type NodeCache from 'node-cache' -import { AuthenticationState, AuthenticationCreds } from './Auth' +import { AuthenticationState } from './Auth' import { proto } from '../../WAProto' import { CommonSocketConfig } from './Socket' @@ -49,6 +49,7 @@ export type WABusinessHoursConfig = { open_time?: number close_time?: number } + export type WABusinessProfile = { description: string email: string diff --git a/src/Utils/history.ts b/src/Utils/history.ts index b5df9c2..6c556d1 100644 --- a/src/Utils/history.ts +++ b/src/Utils/history.ts @@ -1,7 +1,8 @@ -import { downloadContentFromMessage } from "./messages-media"; -import { proto } from "../../WAProto"; +import { downloadContentFromMessage } from "./messages-media" +import { proto } from "../../WAProto" import { promisify } from 'util' -import { inflate } from "zlib"; +import { inflate } from "zlib" +import { Chat, Contact } from "../Types" const inflatePromise = promisify(inflate) @@ -16,4 +17,66 @@ export const downloadHistory = async(msg: proto.IHistorySyncNotification) => { const syncData = proto.HistorySync.decode(buffer) return syncData +} + +export const processHistoryMessage = (item: proto.IHistorySync, historyCache: Set) => { + const isLatest = historyCache.size === 0 + const messages: proto.IWebMessageInfo[] = [] + const contacts: Contact[] = [] + const chats: Chat[] = [] + switch(item.syncType) { + case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_BOOTSTRAP: + case proto.HistorySync.HistorySyncHistorySyncType.RECENT: + for(const chat of item.conversations) { + const contactId = `c:${chat.id}` + if(chat.name && !historyCache.has(contactId)) { + contacts.push({ + id: chat.id, + name: chat.name + }) + historyCache.add(contactId) + } + + for(const { message } of chat.messages || []) { + const uqId = `${message?.key.remoteJid}:${message.key.id}` + if(message && !historyCache.has(uqId)) { + messages.push(message) + historyCache.add(uqId) + } + } + + delete chat.messages + if(!historyCache.has(chat.id)) { + chats.push(chat) + historyCache.add(chat.id) + } + } + break + case proto.HistorySync.HistorySyncHistorySyncType.PUSH_NAME: + for(const c of item.pushnames) { + const contactId = `c:${c.id}` + if(historyCache.has(contactId)) { + contacts.push({ notify: c.pushname, id: c.id }) + historyCache.add(contactId) + } + } + break + case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_STATUS_V3: + // TODO + break + } + + if(chats.length || contacts.length || messages.length) { + return { + chats, + contacts, + messages, + isLatest, + } + } +} + +export const downloadAndProcessHistorySyncNotification = async(msg: proto.IHistorySyncNotification, historyCache: Set) => { + const historyMsg = await downloadHistory(msg) + return processHistoryMessage(historyMsg, historyCache) } \ No newline at end of file From 09553def8aa9210fd5ce0543cc69aabb5ae4f2c8 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 16 Jan 2022 12:54:08 +0530 Subject: [PATCH 295/311] fix: include isLatest in events --- src/Types/Events.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Types/Events.ts b/src/Types/Events.ts index 7aa534e..e17cc0b 100644 --- a/src/Types/Events.ts +++ b/src/Types/Events.ts @@ -14,7 +14,7 @@ export type BaileysEventMap = { /** credentials updated -- some metadata, keys or something */ 'creds.update': Partial /** set chats (history sync), messages are reverse chronologically sorted */ - 'chats.set': { chats: Chat[], messages: WAMessage[], contacts: Contact[] } + 'chats.set': { chats: Chat[], messages: WAMessage[], contacts: Contact[], isLatest: boolean } /** upsert chats */ 'chats.upsert': Chat[] /** update the given chats */ From 7bb6e3ceeb9b78672eb86064333be9e1a9dd58d8 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 16 Jan 2022 13:02:38 +0530 Subject: [PATCH 296/311] refactor: chats.set event --- README.md | 8 ++++++-- src/LegacySocket/chats.ts | 4 ++-- src/LegacySocket/messages.ts | 10 +++++----- src/Socket/messages-recv.ts | 7 +++++-- src/Types/Events.ts | 8 ++++++-- src/Types/Message.ts | 2 +- src/Utils/history.ts | 12 +++++------- 7 files changed, 30 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index c755d60..3f30ac0 100644 --- a/README.md +++ b/README.md @@ -178,8 +178,12 @@ export type BaileysEventMap = { 'connection.update': Partial /** auth credentials updated -- some pre key state, device ID etc. */ 'creds.update': Partial - /** set chats (history sync), messages are reverse chronologically sorted */ - 'chats.set': { chats: Chat[], messages: WAMessage[], contacts: Contact[] } + /** set chats (history sync), chats are reverse chronologically sorted */ + 'chats.set': { chats: Chat[], isLatest: boolean } + /** set messages (history sync), messages are reverse chronologically sorted */ + 'messages.set': { messages: WAMessage[], isLatest: boolean } + /** set contacts (history sync) */ + 'contacts.set': { contacts: Contact[] } /** upsert chats */ 'chats.upsert': Chat[] /** update the given chats */ diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index d43cec1..bc0b88f 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -192,7 +192,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { }) logger.info(`got ${chats.length} chats, extracted ${contacts.length} contacts with name`) - ev.emit('chats.set', { chats, messages: [], contacts }) + ev.emit('chats.set', { chats, isLatest: true }) } }) // got all contacts from phone @@ -208,7 +208,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { }) logger.info(`got ${contacts.length} contacts`) - ev.emit('chats.set', { chats: [], messages: [], contacts }) + ev.emit('contacts.set', { contacts }) } }) // status updates diff --git a/src/LegacySocket/messages.ts b/src/LegacySocket/messages.ts index ba2e5d8..d1f11a8 100644 --- a/src/LegacySocket/messages.ts +++ b/src/LegacySocket/messages.ts @@ -287,15 +287,15 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { } // messages received - const messagesUpdate = (node: BinaryNode, type: 'prepend' | 'last') => { + const messagesUpdate = (node: BinaryNode, isLatest: boolean) => { const messages = getBinaryNodeMessages(node) messages.reverse() - ev.emit('messages.upsert', { messages, type }) + ev.emit('messages.set', { messages, isLatest }) } - socketEvents.on('CB:action,add:last', json => messagesUpdate(json, 'last')) - socketEvents.on('CB:action,add:unread', json => messagesUpdate(json, 'prepend')) - socketEvents.on('CB:action,add:before', json => messagesUpdate(json, 'prepend')) + socketEvents.on('CB:action,add:last', json => messagesUpdate(json, true)) + socketEvents.on('CB:action,add:unread', json => messagesUpdate(json, false)) + socketEvents.on('CB:action,add:before', json => messagesUpdate(json, false)) // new messages socketEvents.on('CB:action,add:relay,message', (node: BinaryNode) => { diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index ed9d316..b3bbc20 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -133,7 +133,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const histNotification = protocolMsg!.historySyncNotification logger.info({ histNotification, id: message.key.id }, 'got history notification') - const info = await downloadAndProcessHistorySyncNotification(histNotification, historyCache) + const { chats, contacts, messages, isLatest } = await downloadAndProcessHistorySyncNotification(histNotification, historyCache) const meJid = authState.creds.me!.id await sendNode({ @@ -145,7 +145,10 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } }) - info && ev.emit('chats.set', info) + if(chats.length) ev.emit('chats.set', { chats, isLatest }) + if(messages.length) ev.emit('messages.set', { messages, isLatest }) + if(contacts.length) ev.emit('contacts.set', { contacts }) + break case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_SHARE: const keys = protocolMsg.appStateSyncKeyShare!.keys diff --git a/src/Types/Events.ts b/src/Types/Events.ts index e17cc0b..dc7a4d0 100644 --- a/src/Types/Events.ts +++ b/src/Types/Events.ts @@ -13,8 +13,12 @@ export type BaileysEventMap = { 'connection.update': Partial /** credentials updated -- some metadata, keys or something */ 'creds.update': Partial - /** set chats (history sync), messages are reverse chronologically sorted */ - 'chats.set': { chats: Chat[], messages: WAMessage[], contacts: Contact[], isLatest: boolean } + /** set chats (history sync), chats are reverse chronologically sorted */ + 'chats.set': { chats: Chat[], isLatest: boolean } + /** set messages (history sync), messages are reverse chronologically sorted */ + 'messages.set': { messages: WAMessage[], isLatest: boolean } + /** set contacts (history sync) */ + 'contacts.set': { contacts: Contact[] } /** upsert chats */ 'chats.upsert': Chat[] /** update the given chats */ diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 6150290..277c00d 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -165,7 +165,7 @@ export type MessageContentGenerationOptions = MediaGenerationOptions & { } export type MessageGenerationOptions = MessageContentGenerationOptions & MessageGenerationOptionsFromContent -export type MessageUpdateType = 'append' | 'notify' | 'prepend' | 'last' | 'replace' +export type MessageUpdateType = 'append' | 'notify' | 'replace' export type MessageInfoEventMap = { [jid: string]: Date } export interface MessageInfo { diff --git a/src/Utils/history.ts b/src/Utils/history.ts index 6c556d1..d53e84d 100644 --- a/src/Utils/history.ts +++ b/src/Utils/history.ts @@ -66,13 +66,11 @@ export const processHistoryMessage = (item: proto.IHistorySync, historyCache: Se break } - if(chats.length || contacts.length || messages.length) { - return { - chats, - contacts, - messages, - isLatest, - } + return { + chats, + contacts, + messages, + isLatest, } } From 4112c685564087fc10346c22654f14064121d494 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 16 Jan 2022 15:33:26 +0530 Subject: [PATCH 297/311] feat: expose sendRetryRequest --- src/Socket/messages-recv.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index b3bbc20..dc3119f 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -86,7 +86,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { { tag: 'retry', attrs: { - count: retryCount.toString(), id: node.attrs.id, + count: retryCount.toString(), + id: node.attrs.id, t: node.attrs.t, v: '1' } @@ -497,5 +498,5 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } }) - return { ...sock, processMessage, sendMessageAck } + return { ...sock, processMessage, sendMessageAck, sendRetryRequest } } From f7f86e69d6272c2f16d25e46301a12562615eb20 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 16 Jan 2022 16:03:22 +0530 Subject: [PATCH 298/311] chore: update log --- src/Socket/messages-send.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 58cd2f8..22eaf1f 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -106,7 +106,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { ] } - logger.debug({ jid, messageIds }, 'reading messages') + logger.debug({ jid, messageIds, type }, 'sending receipt for messages') await sendNode(node) } From 8f11f0be76d17937c28be236bd2e66e43789b0f3 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 19 Jan 2022 15:54:02 +0530 Subject: [PATCH 299/311] chore: add linting --- .eslintignore | 6 + .eslintrc.json | 3 + Example/example.ts | 6 +- package.json | 7 +- src/Defaults/index.ts | 46 +- src/LegacySocket/auth.ts | 149 ++-- src/LegacySocket/chats.ts | 162 ++-- src/LegacySocket/groups.ts | 75 +- src/LegacySocket/index.ts | 2 +- src/LegacySocket/messages.ts | 304 ++++--- src/LegacySocket/socket.ts | 579 ++++++------ src/Socket/chats.ts | 1216 +++++++++++++------------- src/Socket/groups.ts | 50 +- src/Socket/index.ts | 2 +- src/Socket/messages-recv.ts | 881 ++++++++++--------- src/Socket/messages-send.ts | 780 +++++++++-------- src/Socket/socket.ts | 918 +++++++++---------- src/Store/make-ordered-dictionary.ts | 0 src/Tests/test.media-download.ts | 10 +- src/Types/Auth.ts | 4 +- src/Types/Chat.ts | 2 +- src/Types/Events.ts | 8 +- src/Types/GroupMetadata.ts | 2 +- src/Types/Legacy.ts | 6 +- src/Types/Message.ts | 11 +- src/Types/Socket.ts | 8 +- src/Types/State.ts | 2 +- src/Types/index.ts | 3 +- src/Utils/auth-utils.ts | 30 +- src/Utils/chat-utils.ts | 838 +++++++++--------- src/Utils/crypto.ts | 85 +- src/Utils/decode-wa-message.ts | 200 +++-- src/Utils/generics.ts | 322 +++---- src/Utils/history.ts | 81 +- src/Utils/legacy-msgs.ts | 251 +++--- src/Utils/lt-hash.ts | 30 +- src/Utils/make-mutex.ts | 17 +- src/Utils/messages-media.ts | 814 +++++++++-------- src/Utils/messages.ts | 143 +-- src/Utils/noise-handler.ts | 44 +- src/Utils/signal.ts | 46 +- src/Utils/validate-connection.ts | 232 ++--- src/WABinary/Legacy/index.ts | 587 +++++++------ src/WABinary/generic-utils.ts | 81 ++ src/WABinary/index.ts | 1 + src/WABinary/jid-utils.ts | 40 +- src/WABinary/types.ts | 2 +- src/index.ts | 2 +- yarn.lock | 1026 +++++++++++++++++++++- 49 files changed, 5800 insertions(+), 4314 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.json create mode 100644 src/Store/make-ordered-dictionary.ts create mode 100644 src/WABinary/generic-utils.ts diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..1d9dd7b --- /dev/null +++ b/.eslintignore @@ -0,0 +1,6 @@ +# Ignore artifacts: +lib +coverage +*.lock +.eslintrc.json +src/WABinary/index.ts \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..7d37e83 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "@adiwajshing" +} \ No newline at end of file diff --git a/Example/example.ts b/Example/example.ts index cb63358..7dcc2be 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -31,6 +31,10 @@ const startSock = () => { await sock.sendMessage(jid, msg) } + sock.ev.on('chats.set', item => console.log(`recv ${item.chats.length} chats (is latest: ${item.isLatest})`)) + sock.ev.on('messages.set', item => console.log(`recv ${item.messages.length} messages (is latest: ${item.isLatest})`)) + sock.ev.on('contacts.set', item => console.log(`recv ${item.contacts.length} contacts`)) + sock.ev.on('messages.upsert', async m => { console.log(JSON.stringify(m, undefined, 2)) @@ -46,7 +50,7 @@ const startSock = () => { sock.ev.on('messages.update', m => console.log(m)) sock.ev.on('presence.update', m => console.log(m)) sock.ev.on('chats.update', m => console.log(m)) - sock.ev.on('contacts.update', m => console.log(m)) + sock.ev.on('contacts.upsert', m => console.log(m)) sock.ev.on('connection.update', (update) => { const { connection, lastDisconnect } = update diff --git a/package.json b/package.json index aba51f0..50d112b 100644 --- a/package.json +++ b/package.json @@ -19,14 +19,15 @@ "scripts": { "test": "jest", "prepare": "tsc", - "lint": "eslint '*/*.ts' --quiet --fix", "build:all": "tsc && typedoc", "build:docs": "typedoc", "build:tsc": "tsc", "example": "node --inspect -r ts-node/register Example/example.ts", "example:legacy": "node --inspect -r ts-node/register Example/example-legacy.ts", "gen-protobuf": "bash src/BinaryNode/GenerateStatics.sh", - "browser-decode": "yarn ts-node src/BrowserMessageDecoding.ts" + "browser-decode": "yarn ts-node src/BrowserMessageDecoding.ts", + "lint": "eslint ./src --ext .js,.ts,.jsx,.tsx", + "lint:fix": "eslint ./src --fix --ext .js,.ts,.jsx,.tsx" }, "author": "Adhiraj Singh", "license": "MIT", @@ -56,12 +57,14 @@ "WABinary/*.js" ], "devDependencies": { + "@adiwajshing/eslint-config": "git+https://github.com/adiwajshing/eslint-config", "@types/got": "^9.6.11", "@types/jest": "^26.0.24", "@types/node": "^14.6.2", "@types/pino": "^6.3.2", "@types/sharp": "^0.29.4", "@types/ws": "^8.0.0", + "eslint": "^7.0.0", "jest": "^27.0.6", "jimp": "^0.16.1", "qrcode-terminal": "^0.12.0", diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index db81210..1d247f9 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -1,6 +1,6 @@ -import P from "pino" -import type { MediaType, SocketConfig, LegacySocketConfig, CommonSocketConfig } from "../Types" -import { Browsers } from "../Utils" +import P from 'pino' +import type { CommonSocketConfig, LegacySocketConfig, MediaType, SocketConfig } from '../Types' +import { Browsers } from '../Utils' export const UNAUTHORIZED_CODES = [401, 403, 419] @@ -18,40 +18,40 @@ export const NOISE_WA_HEADER = new Uint8Array([87, 65, 5, 2]) // last is "DICT_V export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi const BASE_CONNECTION_CONFIG: CommonSocketConfig = { - version: [2, 2147, 16], + version: [2, 2147, 16], browser: Browsers.baileys('Chrome'), - waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', - connectTimeoutMs: 20_000, - keepAliveIntervalMs: 25_000, - logger: P().child({ class: 'baileys' }), + waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', + connectTimeoutMs: 20_000, + keepAliveIntervalMs: 25_000, + logger: P().child({ class: 'baileys' }), printQRInTerminal: false, - emitOwnEvents: true, - defaultQueryTimeoutMs: 60_000, - customUploadHosts: [], + emitOwnEvents: true, + defaultQueryTimeoutMs: 60_000, + customUploadHosts: [], } export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { ...BASE_CONNECTION_CONFIG, - waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', - getMessage: async() => undefined + waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', + getMessage: async() => undefined } export const DEFAULT_LEGACY_CONNECTION_CONFIG: LegacySocketConfig = { ...BASE_CONNECTION_CONFIG, - waWebSocketUrl: 'wss://web.whatsapp.com/ws', - phoneResponseTimeMs: 20_000, - expectResponseTimeout: 60_000, + waWebSocketUrl: 'wss://web.whatsapp.com/ws', + phoneResponseTimeMs: 20_000, + expectResponseTimeout: 60_000, } export const MEDIA_PATH_MAP: { [T in MediaType]: string } = { - image: '/mms/image', - video: '/mms/video', - document: '/mms/document', - audio: '/mms/audio', - sticker: '/mms/image', - history: '', - 'md-app-state': '' + image: '/mms/image', + video: '/mms/video', + document: '/mms/document', + audio: '/mms/audio', + sticker: '/mms/image', + history: '', + 'md-app-state': '' } export const MEDIA_KEYS = Object.keys(MEDIA_PATH_MAP) as MediaType[] diff --git a/src/LegacySocket/auth.ts b/src/LegacySocket/auth.ts index 68b2516..6d551cd 100644 --- a/src/LegacySocket/auth.ts +++ b/src/LegacySocket/auth.ts @@ -1,8 +1,8 @@ import { Boom } from '@hapi/boom' -import EventEmitter from "events" -import { LegacyBaileysEventEmitter, LegacySocketConfig, CurveKeyPair, WAInitResponse, ConnectionState, DisconnectReason } from "../Types" -import { newLegacyAuthCreds, bindWaitForConnectionUpdate, computeChallengeResponse, validateNewConnection, Curve, printQRIfNecessaryListener } from "../Utils" -import { makeSocket } from "./socket" +import EventEmitter from 'events' +import { ConnectionState, CurveKeyPair, DisconnectReason, LegacyBaileysEventEmitter, LegacySocketConfig, WAInitResponse } from '../Types' +import { bindWaitForConnectionUpdate, computeChallengeResponse, Curve, newLegacyAuthCreds, printQRIfNecessaryListener, validateNewConnection } from '../Utils' +import { makeSocket } from './socket' const makeAuthSocket = (config: LegacySocketConfig) => { const { @@ -60,14 +60,15 @@ const makeAuthSocket = (config: LegacySocketConfig) => { * If connected, invalidates the credentials with the server */ const logout = async() => { - if(state.connection === 'open') { - await socket.sendNode({ + if(state.connection === 'open') { + await socket.sendNode({ json: ['admin', 'Conn', 'disconnect'], tag: 'goodbye' }) - } + } + // will call state update to close connection - socket?.end( + socket?.end( new Boom('Logged Out', { statusCode: DisconnectReason.loggedOut }) ) } @@ -86,13 +87,15 @@ const makeAuthSocket = (config: LegacySocketConfig) => { const qr = [ref, publicKey, authInfo.clientID].join(',') updateState({ qr }) - initTimeout = setTimeout(async () => { - if(state.connection !== 'connecting') return + initTimeout = setTimeout(async() => { + if(state.connection !== 'connecting') { + return + } logger.debug('regenerating QR') try { // request new QR - const {ref: newRef, ttl: newTTL} = await socket.query({ + const { ref: newRef, ttl: newTTL } = await socket.query({ json: ['admin', 'Conn', 'reref'], expect200: true, longTag: true, @@ -100,94 +103,104 @@ const makeAuthSocket = (config: LegacySocketConfig) => { }) ttl = newTTL ref = newRef - } catch (error) { - logger.error({ error }, `error in QR gen`) - if (error.output?.statusCode === 429) { // too many QR requests + } catch(error) { + logger.error({ error }, 'error in QR gen') + if(error.output?.statusCode === 429) { // too many QR requests socket.end(error) return } } + qrGens += 1 qrLoop(ttl) }, ttl || 20_000) // default is 20s, on the off-chance ttl is not present } + qrLoop(ttl) } + const onOpen = async() => { const canDoLogin = canLogin() - const initQuery = (async () => { - const {ref, ttl} = await socket.query({ - json: ['admin', 'init', version, browser, authInfo.clientID, true], - expect200: true, - longTag: true, - requiresPhoneConnection: false - }) as WAInitResponse + const initQuery = (async() => { + const { ref, ttl } = await socket.query({ + json: ['admin', 'init', version, browser, authInfo.clientID, true], + expect200: true, + longTag: true, + requiresPhoneConnection: false + }) as WAInitResponse - if (!canDoLogin) { - generateKeysForAuth(ref, ttl) - } - })(); - let loginTag: string - if(canDoLogin) { + if(!canDoLogin) { + generateKeysForAuth(ref, ttl) + } + })() + let loginTag: string + if(canDoLogin) { updateEncKeys() - // if we have the info to restore a closed session - const json = [ + // if we have the info to restore a closed session + const json = [ 'admin', - 'login', - authInfo.clientToken, - authInfo.serverToken, - authInfo.clientID, + 'login', + authInfo.clientToken, + authInfo.serverToken, + authInfo.clientID, 'takeover' - ] - loginTag = socket.generateMessageTag(true) - // send login every 10s - const sendLoginReq = () => { - if(state.connection === 'open') { - logger.warn('Received login timeout req when state=open, ignoring...') - return - } - logger.info('sending login request') - socket.sendNode({ + ] + loginTag = socket.generateMessageTag(true) + // send login every 10s + const sendLoginReq = () => { + if(state.connection === 'open') { + logger.warn('Received login timeout req when state=open, ignoring...') + return + } + + logger.info('sending login request') + socket.sendNode({ json, tag: loginTag }) - initTimeout = setTimeout(sendLoginReq, 10_000) - } - sendLoginReq() - } - await initQuery + initTimeout = setTimeout(sendLoginReq, 10_000) + } - // wait for response with tag "s1" - let response = await Promise.race( - [ + sendLoginReq() + } + + await initQuery + + // wait for response with tag "s1" + let response = await Promise.race( + [ socket.waitForMessage('s1', false, undefined).promise, ...(loginTag ? [socket.waitForMessage(loginTag, false, connectTimeoutMs).promise] : []) ] - ) - initTimeout && clearTimeout(initTimeout) - initTimeout = undefined + ) + initTimeout && clearTimeout(initTimeout) + initTimeout = undefined - if(response.status && response.status !== 200) { - throw new Boom(`Unexpected error in login`, { data: response, statusCode: response.status }) - } - // if its a challenge request (we get it when logging in) - if(response[1]?.challenge) { + if(response.status && response.status !== 200) { + throw new Boom('Unexpected error in login', { data: response, statusCode: response.status }) + } + + // if its a challenge request (we get it when logging in) + if(response[1]?.challenge) { const json = computeChallengeResponse(response[1].challenge, authInfo) logger.info('resolving login challenge') await socket.query({ json, expect200: true, timeoutMs: connectTimeoutMs }) response = await socket.waitForMessage('s2', true).promise - } + } + if(!response || !response[1]) { throw new Boom('Received unexpected login response', { data: response }) } + if(response[1].type === 'upgrade_md_prod') { throw new Boom('Require multi-device edition', { statusCode: DisconnectReason.multideviceMismatch }) } - // validate the new connection - const {user, auth} = validateNewConnection(response[1], authInfo, curveKeys)// validate the connection - const isNewLogin = user.id !== state.legacy!.user?.id + + // validate the new connection + const { user, auth } = validateNewConnection(response[1], authInfo, curveKeys)// validate the connection + const isNewLogin = user.id !== state.legacy!.user?.id Object.assign(authInfo, auth) updateEncKeys() @@ -206,6 +219,7 @@ const makeAuthSocket = (config: LegacySocketConfig) => { qr: undefined }) } + ws.once('open', async() => { try { await onOpen() @@ -219,10 +233,10 @@ const makeAuthSocket = (config: LegacySocketConfig) => { } process.nextTick(() => { - ev.emit('connection.update', { + ev.emit('connection.update', { ...state }) - }) + }) return { ...socket, @@ -231,8 +245,9 @@ const makeAuthSocket = (config: LegacySocketConfig) => { ev, canLogin, logout, - /** Waits for the connection to WA to reach a state */ - waitForConnectionUpdate: bindWaitForConnectionUpdate(ev) + /** Waits for the connection to WA to reach a state */ + waitForConnectionUpdate: bindWaitForConnectionUpdate(ev) } } + export default makeAuthSocket \ No newline at end of file diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index bc0b88f..5e69cf3 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -1,7 +1,7 @@ -import { BinaryNode, jidNormalizedUser } from "../WABinary"; -import { Chat, Contact, WAPresence, PresenceData, LegacySocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessageUpdate, BaileysEventMap } from "../Types"; -import { debouncedTimeout, unixTimestampSeconds } from "../Utils/generics"; -import makeAuthSocket from "./auth"; +import { BaileysEventMap, Chat, ChatModification, Contact, LegacySocketConfig, PresenceData, WABusinessProfile, WAFlag, WAMessageKey, WAMessageUpdate, WAMetric, WAPresence } from '../Types' +import { debouncedTimeout, unixTimestampSeconds } from '../Utils/generics' +import { BinaryNode, jidNormalizedUser } from '../WABinary' +import makeAuthSocket from './auth' const makeChatsSocket = (config: LegacySocketConfig) => { const { logger } = config @@ -22,7 +22,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { sendNode({ json: { tag: 'query', - attrs: {type: 'chat', epoch: epoch.toString()} + attrs: { type: 'chat', epoch: epoch.toString() } }, binaryTag: [ WAMetric.queryChat, WAFlag.ignore ] }) @@ -43,62 +43,64 @@ const makeChatsSocket = (config: LegacySocketConfig) => { const updateType = attributes.type const jid = jidNormalizedUser(attributes?.jid) - switch(updateType) { - case 'delete': - ev.emit('chats.delete', [jid]) - break - case 'clear': - if(node.content) { - const ids = (node.content as BinaryNode[]).map( - ({ attrs }) => attrs.index - ) - ev.emit('messages.delete', { keys: ids.map(id => ({ id, remoteJid: jid })) }) - } else { - ev.emit('messages.delete', { jid, all: true }) - } - break - case 'archive': - ev.emit('chats.update', [ { id: jid, archive: true } ]) - break - case 'unarchive': - ev.emit('chats.update', [ { id: jid, archive: false } ]) - break - case 'pin': - ev.emit('chats.update', [ { id: jid, pin: attributes.pin ? +attributes.pin : null } ]) - break - case 'star': - case 'unstar': - const starred = updateType === 'star' - const updates: WAMessageUpdate[] = (node.content as BinaryNode[]).map( - ({ attrs }) => ({ - key: { - remoteJid: jid, - id: attrs.index, - fromMe: attrs.owner === 'true' - }, - update: { starred } - }) + switch (updateType) { + case 'delete': + ev.emit('chats.delete', [jid]) + break + case 'clear': + if(node.content) { + const ids = (node.content as BinaryNode[]).map( + ({ attrs }) => attrs.index ) - ev.emit('messages.update', updates) - break - case 'mute': - if(attributes.mute === '0') { - ev.emit('chats.update', [{ id: jid, mute: null }]) - } else { - ev.emit('chats.update', [{ id: jid, mute: +attributes.mute }]) - } - break - default: - logger.warn({ node }, `received unrecognized chat update`) - break + ev.emit('messages.delete', { keys: ids.map(id => ({ id, remoteJid: jid })) }) + } else { + ev.emit('messages.delete', { jid, all: true }) + } + + break + case 'archive': + ev.emit('chats.update', [ { id: jid, archive: true } ]) + break + case 'unarchive': + ev.emit('chats.update', [ { id: jid, archive: false } ]) + break + case 'pin': + ev.emit('chats.update', [ { id: jid, pin: attributes.pin ? +attributes.pin : null } ]) + break + case 'star': + case 'unstar': + const starred = updateType === 'star' + const updates: WAMessageUpdate[] = (node.content as BinaryNode[]).map( + ({ attrs }) => ({ + key: { + remoteJid: jid, + id: attrs.index, + fromMe: attrs.owner === 'true' + }, + update: { starred } + }) + ) + ev.emit('messages.update', updates) + break + case 'mute': + if(attributes.mute === '0') { + ev.emit('chats.update', [{ id: jid, mute: null }]) + } else { + ev.emit('chats.update', [{ id: jid, mute: +attributes.mute }]) + } + + break + default: + logger.warn({ node }, 'received unrecognized chat update') + break } } const applyingPresenceUpdate = (update: BinaryNode['attrs']): BaileysEventMap['presence.update'] => { const id = jidNormalizedUser(update.id) - const participant = jidNormalizedUser(update.participant || update.id) + const participant = jidNormalizedUser(update.participant || update.id) - const presence: PresenceData = { + const presence: PresenceData = { lastSeen: update.t ? +update.t : undefined, lastKnownPresence: update.type as WAPresence } @@ -126,27 +128,30 @@ const makeChatsSocket = (config: LegacySocketConfig) => { } ev.on('connection.update', async({ connection }) => { - if(connection !== 'open') return + if(connection !== 'open') { + return + } + try { await Promise.all([ sendNode({ - json: { tag: 'query', attrs: {type: 'contacts', epoch: '1'} }, + json: { tag: 'query', attrs: { type: 'contacts', epoch: '1' } }, binaryTag: [ WAMetric.queryContact, WAFlag.ignore ] }), sendNode({ - json: { tag: 'query', attrs: {type: 'status', epoch: '1'} }, + json: { tag: 'query', attrs: { type: 'status', epoch: '1' } }, binaryTag: [ WAMetric.queryStatus, WAFlag.ignore ] }), sendNode({ - json: { tag: 'query', attrs: {type: 'quick_reply', epoch: '1'} }, + json: { tag: 'query', attrs: { type: 'quick_reply', epoch: '1' } }, binaryTag: [ WAMetric.queryQuickReply, WAFlag.ignore ] }), sendNode({ - json: { tag: 'query', attrs: {type: 'label', epoch: '1'} }, + json: { tag: 'query', attrs: { type: 'label', epoch: '1' } }, binaryTag: [ WAMetric.queryLabel, WAFlag.ignore ] }), sendNode({ - json: { tag: 'query', attrs: {type: 'emoji', epoch: '1'} }, + json: { tag: 'query', attrs: { type: 'emoji', epoch: '1' } }, binaryTag: [ WAMetric.queryEmoji, WAFlag.ignore ] }), sendNode({ @@ -154,7 +159,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { tag: 'action', attrs: { type: 'set', epoch: '1' }, content: [ - { tag: 'presence', attrs: {type: 'available'} } + { tag: 'presence', attrs: { type: 'available' } } ] }, binaryTag: [ WAMetric.presence, WAFlag.available ] @@ -167,7 +172,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { logger.error(`error in sending init queries: ${error}`) } }) - socketEvents.on('CB:response,type:chat', async ({ content: data }: BinaryNode) => { + socketEvents.on('CB:response,type:chat', async({ content: data }: BinaryNode) => { chatsDebounceTimeout.cancel() if(Array.isArray(data)) { const contacts: Contact[] = [] @@ -176,6 +181,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { if(attrs.name) { contacts.push({ id, name: attrs.name }) } + return { id: jidNormalizedUser(attrs.jid), conversationTimestamp: attrs.t ? +attrs.t : undefined, @@ -196,7 +202,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { } }) // got all contacts from phone - socketEvents.on('CB:response,type:contacts', async ({ content: data }: BinaryNode) => { + socketEvents.on('CB:response,type:contacts', async({ content: data }: BinaryNode) => { if(Array.isArray(data)) { const contacts = data.map(({ attrs }): Contact => { return { @@ -225,15 +231,18 @@ const makeChatsSocket = (config: LegacySocketConfig) => { } }) // read updates - socketEvents.on ('CB:action,,read', async ({ content }: BinaryNode) => { + socketEvents.on ('CB:action,,read', async({ content }: BinaryNode) => { if(Array.isArray(content)) { const { attrs } = content[0] const update: Partial = { id: jidNormalizedUser(attrs.jid) } - if(attrs.type === 'false') update.unreadCount = -1 - else update.unreadCount = 0 + if(attrs.type === 'false') { + update.unreadCount = -1 + } else { + update.unreadCount = 0 + } ev.emit('chats.update', [update]) } @@ -295,7 +304,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { * @param jid the ID of the person/group you are modifiying */ chatModify: async(modification: ChatModification, jid: string, chatInfo: Pick, timestampNow?: number) => { - let chatAttrs: BinaryNode['attrs'] = { jid: jid } + const chatAttrs: BinaryNode['attrs'] = { jid: jid } let data: BinaryNode[] | undefined = undefined timestampNow = timestampNow || unixTimestampSeconds() @@ -356,6 +365,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { // apply it and emit events executeChatModification(node) } + return response }, /** @@ -381,7 +391,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { * @param jid the ID of the person/group who you are updating * @param type your presence */ - sendPresenceUpdate: ( type: WAPresence, jid: string | undefined) => ( + sendPresenceUpdate: (type: WAPresence, jid: string | undefined) => ( sendNode({ binaryTag: [WAMetric.presence, WAFlag[type]], // weird stuff WA does json: { @@ -400,7 +410,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { * Request updates on the presence of a user * this returns nothing, you'll receive updates in chats.update event * */ - presenceSubscribe: async (jid: string) => ( + presenceSubscribe: async(jid: string) => ( sendNode({ json: ['action', 'presence', 'subscribe', jid] }) ), /** Query the status of the person (see groupMetadata() for groups) */ @@ -423,11 +433,12 @@ const makeChatsSocket = (config: LegacySocketConfig) => { }, /** Updates business profile. */ updateBusinessProfile: async(profile: WABusinessProfile) => { - if (profile.business_hours?.config) { + if(profile.business_hours?.config) { profile.business_hours.business_config = profile.business_hours.config delete profile.business_hours.config } - const json = ['action', "editBusinessProfile", {...profile, v: 2}] + + const json = ['action', 'editBusinessProfile', { ...profile, v: 2 }] await query({ json, expect200: true, requiresPhoneConnection: true }) }, updateProfileName: async(name: string) => { @@ -447,6 +458,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { } }) ev.emit('contacts.update', [{ id: user.id, name }]) } + return response }, /** @@ -454,7 +466,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { * @param jid * @param img */ - async updateProfilePicture (jid: string, img: Buffer) { + async updateProfilePicture(jid: string, img: Buffer) { jid = jidNormalizedUser (jid) const data = { img: Buffer.from([]), preview: Buffer.from([]) } //await generateProfilePicture(img) TODO const tag = this.generateMessageTag () @@ -480,6 +492,7 @@ const makeChatsSocket = (config: LegacySocketConfig) => { } }) } + ev.emit('contacts.update', [ { id: jid, imgUrl: eurl } ]) } }, @@ -513,8 +526,8 @@ const makeChatsSocket = (config: LegacySocketConfig) => { }] } = await query({ json: [ - "query", "businessProfile", - [ { "wid": jid.replace('@s.whatsapp.net', '@c.us') } ], + 'query', 'businessProfile', + [ { 'wid': jid.replace('@s.whatsapp.net', '@c.us') } ], 84 ], expect200: true, @@ -528,4 +541,5 @@ const makeChatsSocket = (config: LegacySocketConfig) => { } } } + export default makeChatsSocket \ No newline at end of file diff --git a/src/LegacySocket/groups.ts b/src/LegacySocket/groups.ts index ed4d975..038f21b 100644 --- a/src/LegacySocket/groups.ts +++ b/src/LegacySocket/groups.ts @@ -1,7 +1,7 @@ -import { BinaryNode, jidNormalizedUser } from "../WABinary"; -import { LegacySocketConfig, GroupModificationResponse, ParticipantAction, GroupMetadata, WAFlag, WAMetric, WAGroupCreateResponse, GroupParticipant } from "../Types"; -import { generateMessageID, unixTimestampSeconds } from "../Utils/generics"; -import makeMessagesSocket from "./messages"; +import { GroupMetadata, GroupModificationResponse, GroupParticipant, LegacySocketConfig, ParticipantAction, WAFlag, WAGroupCreateResponse, WAMetric } from '../Types' +import { generateMessageID, unixTimestampSeconds } from '../Utils/generics' +import { BinaryNode, jidNormalizedUser } from '../WABinary' +import makeMessagesSocket from './messages' const makeGroupsSocket = (config: LegacySocketConfig) => { const { logger } = config @@ -17,9 +17,9 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { } = sock /** Generic function for group queries */ - const groupQuery = async(type: string, jid?: string, subject?: string, participants?: string[], additionalNodes?: BinaryNode[]) => { - const tag = generateMessageTag() - const result = await setQuery ([ + const groupQuery = async(type: string, jid?: string, subject?: string, participants?: string[], additionalNodes?: BinaryNode[]) => { + const tag = generateMessageTag() + const result = await setQuery ([ { tag: 'group', attrs: { @@ -36,12 +36,12 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { additionalNodes } ], [WAMetric.group, 136], tag) - return result - } + return result + } - /** Get the metadata of the group from WA */ - const groupMetadataFull = async (jid: string) => { - const metadata = await query({ + /** Get the metadata of the group from WA */ + const groupMetadataFull = async(jid: string) => { + const metadata = await query({ json: ['query', 'GroupMetadata', jid], expect200: true }) @@ -62,13 +62,14 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { } return meta - } - /** Get the metadata (works after you've left the group also) */ - const groupMetadataMinimal = async (jid: string) => { - const { attrs, content }:BinaryNode = await query({ + } + + /** Get the metadata (works after you've left the group also) */ + const groupMetadataMinimal = async(jid: string) => { + const { attrs, content }:BinaryNode = await query({ json: { tag: 'query', - attrs: {type: 'group', jid: jid, epoch: currentEpoch().toString()} + attrs: { type: 'group', jid: jid, epoch: currentEpoch().toString() } }, binaryTag: [WAMetric.group, WAFlag.ignore], expect200: true @@ -89,16 +90,17 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { } } } - const meta: GroupMetadata = { - id: jid, - owner: attrs?.creator, - creation: +attrs?.create, - subject: null, - desc, - participants - } + + const meta: GroupMetadata = { + id: jid, + owner: attrs?.creator, + creation: +attrs?.create, + subject: null, + desc, + participants + } return meta - } + } socketEvents.on('CB:Chat,cmd:action', (json: BinaryNode) => { /*const data = json[1].data @@ -129,8 +131,11 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { groupMetadata: async(jid: string, minimal: boolean) => { let result: GroupMetadata - if(minimal) result = await groupMetadataMinimal(jid) - else result = await groupMetadataFull(jid) + if(minimal) { + result = await groupMetadataMinimal(jid) + } else { + result = await groupMetadataFull(jid) + } return result }, @@ -139,13 +144,13 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { * @param title like, the title of the group * @param participants people to include in the group */ - groupCreate: async (title: string, participants: string[]) => { + groupCreate: async(title: string, participants: string[]) => { const response = await groupQuery('create', null, title, participants) as WAGroupCreateResponse const gid = response.gid let metadata: GroupMetadata try { metadata = await groupMetadataFull(gid) - } catch (error) { + } catch(error) { logger.warn (`error in group creation: ${error}, switching gid & checking`) // if metadata is not available const comps = gid.replace ('@g.us', '').split ('-') @@ -154,6 +159,7 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { metadata = await groupMetadataFull(gid) logger.warn (`group ID switched from ${gid} to ${response.gid}`) } + ev.emit('chats.upsert', [ { id: response.gid!, @@ -168,7 +174,7 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { * Leave a group * @param jid the ID of the group */ - groupLeave: async (id: string) => { + groupLeave: async(id: string) => { await groupQuery('leave', id) ev.emit('chats.update', [ { id, readOnly: true } ]) }, @@ -177,7 +183,7 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { * @param {string} jid the ID of the group * @param {string} title the new title of the group */ - groupUpdateSubject: async (id: string, title: string) => { + groupUpdateSubject: async(id: string, title: string) => { await groupQuery('subject', id, title) ev.emit('chats.update', [ { id, name: title } ]) ev.emit('contacts.update', [ { id, name: title } ]) @@ -188,11 +194,11 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { * @param {string} jid the ID of the group * @param {string} title the new title of the group */ - groupUpdateDescription: async (jid: string, description: string) => { + groupUpdateDescription: async(jid: string, description: string) => { const metadata = await groupMetadataFull(jid) const node: BinaryNode = { tag: 'description', - attrs: {id: generateMessageID(), prev: metadata?.descId}, + attrs: { id: generateMessageID(), prev: metadata?.descId }, content: Buffer.from(description, 'utf-8') } @@ -247,4 +253,5 @@ const makeGroupsSocket = (config: LegacySocketConfig) => { } } + export default makeGroupsSocket \ No newline at end of file diff --git a/src/LegacySocket/index.ts b/src/LegacySocket/index.ts index 3f1f7bf..78caed4 100644 --- a/src/LegacySocket/index.ts +++ b/src/LegacySocket/index.ts @@ -1,5 +1,5 @@ -import { LegacySocketConfig } from '../Types' import { DEFAULT_LEGACY_CONNECTION_CONFIG } from '../Defaults' +import { LegacySocketConfig } from '../Types' import _makeLegacySocket from './groups' // export the last socket layer const makeLegacySocket = (config: Partial) => ( diff --git a/src/LegacySocket/messages.ts b/src/LegacySocket/messages.ts index d1f11a8..f9b8a8d 100644 --- a/src/LegacySocket/messages.ts +++ b/src/LegacySocket/messages.ts @@ -1,15 +1,15 @@ -import { BinaryNode, getBinaryNodeMessages, isJidGroup, jidNormalizedUser, areJidsSameUser } from "../WABinary"; import { Boom } from '@hapi/boom' -import { Chat, WAMessageCursor, WAMessage, LegacySocketConfig, WAMessageKey, ParticipantAction, WAMessageStatus, WAMessageStubType, GroupMetadata, AnyMessageContent, MiscMessageGenerationOptions, WAFlag, WAMetric, WAUrlInfo, MediaConnInfo, MessageUpdateType, MessageInfo, MessageInfoUpdate, WAMessageUpdate } from "../Types"; -import { toNumber, generateWAMessage, decryptMediaMessageBuffer, extractMessageContent, getWAUploadToServer } from "../Utils"; -import makeChatsSocket from "./chats"; -import { WA_DEFAULT_EPHEMERAL } from "../Defaults"; -import { proto } from "../../WAProto"; +import { proto } from '../../WAProto' +import { WA_DEFAULT_EPHEMERAL } from '../Defaults' +import { AnyMessageContent, Chat, GroupMetadata, LegacySocketConfig, MediaConnInfo, MessageInfo, MessageInfoUpdate, MessageUpdateType, MiscMessageGenerationOptions, ParticipantAction, WAFlag, WAMessage, WAMessageCursor, WAMessageKey, WAMessageStatus, WAMessageStubType, WAMessageUpdate, WAMetric, WAUrlInfo } from '../Types' +import { decryptMediaMessageBuffer, extractMessageContent, generateWAMessage, getWAUploadToServer, toNumber } from '../Utils' +import { areJidsSameUser, BinaryNode, getBinaryNodeMessages, isJidGroup, jidNormalizedUser } from '../WABinary' +import makeChatsSocket from './chats' const STATUS_MAP = { read: WAMessageStatus.READ, message: WAMessageStatus.DELIVERY_ACK, - error: WAMessageStatus.ERROR + error: WAMessageStatus.ERROR } as { [_: string]: WAMessageStatus } const makeMessagesSocket = (config: LegacySocketConfig) => { @@ -27,10 +27,10 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { let mediaConn: Promise const refreshMediaConn = async(forceGet = false) => { - let media = await mediaConn - if (!media || forceGet || (new Date().getTime()-media.fetchDate.getTime()) > media.ttl*1000) { + const media = await mediaConn + if(!media || forceGet || (new Date().getTime()-media.fetchDate.getTime()) > media.ttl*1000) { mediaConn = (async() => { - const {media_conn} = await query({ + const { media_conn } = await query({ json: ['query', 'mediaConn'], requiresPhoneConnection: false, expect200: true @@ -38,9 +38,10 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { media_conn.fetchDate = new Date() return media_conn as MediaConnInfo })() - } - return mediaConn - } + } + + return mediaConn + } const fetchMessagesFromWA = async( jid: string, @@ -51,7 +52,8 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { if(cursor) { key = 'before' in cursor ? cursor.before : cursor.after } - const { content }:BinaryNode = await query({ + + const { content }:BinaryNode = await query({ json: { tag: 'query', attrs: { @@ -71,15 +73,18 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { if(Array.isArray(content)) { return content.map(data => proto.WebMessageInfo.decode(data.content as Buffer)) } + return [] - } + } const updateMediaMessage = async(message: WAMessage) => { const content = message.message?.audioMessage || message.message?.videoMessage || message.message?.imageMessage || message.message?.stickerMessage || message.message?.documentMessage - if (!content) throw new Boom( - `given message ${message.key.id} is not a media message`, - { statusCode: 400, data: message } - ) + if(!content) { + throw new Boom( + `given message ${message.key.id} is not a media message`, + { statusCode: 400, data: message } + ) + } const response: BinaryNode = await query ({ json: { @@ -133,35 +138,36 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { } const protocolMessage = message.message?.protocolMessage || message.message?.ephemeralMessage?.message?.protocolMessage - // if it's a message to delete another message - if (protocolMessage) { - switch (protocolMessage.type) { - case proto.ProtocolMessage.ProtocolMessageType.REVOKE: - const key = protocolMessage.key - const messageStubType = WAMessageStubType.REVOKE - ev.emit('messages.update', [ - { - // the key of the deleted message is updated - update: { message: null, key: message.key, messageStubType }, - key - } - ]) - return - case proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING: - chatUpdate.ephemeralSettingTimestamp = message.messageTimestamp + // if it's a message to delete another message + if(protocolMessage) { + switch (protocolMessage.type) { + case proto.ProtocolMessage.ProtocolMessageType.REVOKE: + const key = protocolMessage.key + const messageStubType = WAMessageStubType.REVOKE + ev.emit('messages.update', [ + { + // the key of the deleted message is updated + update: { message: null, key: message.key, messageStubType }, + key + } + ]) + return + case proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING: + chatUpdate.ephemeralSettingTimestamp = message.messageTimestamp chatUpdate.ephemeralExpiration = protocolMessage.ephemeralExpiration - if(isJidGroup(jid)) { - emitGroupUpdate({ ephemeralDuration: protocolMessage.ephemeralExpiration || null }) - } - break - default: - break - } - } + if(isJidGroup(jid)) { + emitGroupUpdate({ ephemeralDuration: protocolMessage.ephemeralExpiration || null }) + } + + break + default: + break + } + } // check if the message is an action - if (message.messageStubType) { + if(message.messageStubType) { const { user } = state.legacy! //let actor = jidNormalizedUser (message.participant) let participants: string[] @@ -170,44 +176,47 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { ) switch (message.messageStubType) { - case WAMessageStubType.CHANGE_EPHEMERAL_SETTING: - chatUpdate.ephemeralSettingTimestamp = message.messageTimestamp - chatUpdate.ephemeralExpiration = +message.messageStubParameters[0] - if(isJidGroup(jid)) { - emitGroupUpdate({ ephemeralDuration: +message.messageStubParameters[0] || null }) - } - break - case WAMessageStubType.GROUP_PARTICIPANT_LEAVE: - case WAMessageStubType.GROUP_PARTICIPANT_REMOVE: - participants = message.messageStubParameters.map (jidNormalizedUser) - emitParticipantsUpdate('remove') - // mark the chat read only if you left the group - if (participants.includes(user.id)) { - chatUpdate.readOnly = true - } - break - case WAMessageStubType.GROUP_PARTICIPANT_ADD: - case WAMessageStubType.GROUP_PARTICIPANT_INVITE: - case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN: - participants = message.messageStubParameters.map (jidNormalizedUser) - if (participants.includes(user.id)) { - chatUpdate.readOnly = null - } - emitParticipantsUpdate('add') - break - case WAMessageStubType.GROUP_CHANGE_ANNOUNCE: - const announce = message.messageStubParameters[0] === 'on' - emitGroupUpdate({ announce }) - break - case WAMessageStubType.GROUP_CHANGE_RESTRICT: - const restrict = message.messageStubParameters[0] === 'on' - emitGroupUpdate({ restrict }) - break - case WAMessageStubType.GROUP_CHANGE_SUBJECT: - case WAMessageStubType.GROUP_CREATE: - chatUpdate.name = message.messageStubParameters[0] - emitGroupUpdate({ subject: chatUpdate.name }) - break + case WAMessageStubType.CHANGE_EPHEMERAL_SETTING: + chatUpdate.ephemeralSettingTimestamp = message.messageTimestamp + chatUpdate.ephemeralExpiration = +message.messageStubParameters[0] + if(isJidGroup(jid)) { + emitGroupUpdate({ ephemeralDuration: +message.messageStubParameters[0] || null }) + } + + break + case WAMessageStubType.GROUP_PARTICIPANT_LEAVE: + case WAMessageStubType.GROUP_PARTICIPANT_REMOVE: + participants = message.messageStubParameters.map (jidNormalizedUser) + emitParticipantsUpdate('remove') + // mark the chat read only if you left the group + if(participants.includes(user.id)) { + chatUpdate.readOnly = true + } + + break + case WAMessageStubType.GROUP_PARTICIPANT_ADD: + case WAMessageStubType.GROUP_PARTICIPANT_INVITE: + case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN: + participants = message.messageStubParameters.map (jidNormalizedUser) + if(participants.includes(user.id)) { + chatUpdate.readOnly = null + } + + emitParticipantsUpdate('add') + break + case WAMessageStubType.GROUP_CHANGE_ANNOUNCE: + const announce = message.messageStubParameters[0] === 'on' + emitGroupUpdate({ announce }) + break + case WAMessageStubType.GROUP_CHANGE_RESTRICT: + const restrict = message.messageStubParameters[0] === 'on' + emitGroupUpdate({ restrict }) + break + case WAMessageStubType.GROUP_CHANGE_SUBJECT: + case WAMessageStubType.GROUP_CREATE: + chatUpdate.name = message.messageStubParameters[0] + emitGroupUpdate({ subject: chatUpdate.name }) + break } } @@ -221,8 +230,8 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { const waUploadToServer = getWAUploadToServer(config, refreshMediaConn) /** Query a string to check if it has a url, if it does, return WAUrlInfo */ - const generateUrlInfo = async(text: string) => { - const response: BinaryNode = await query({ + const generateUrlInfo = async(text: string) => { + const response: BinaryNode = await query({ json: { tag: 'query', attrs: { @@ -236,14 +245,15 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { requiresPhoneConnection: false }) const urlInfo = { ...response.attrs } as any as WAUrlInfo - if(response && response.content) { - urlInfo.jpegThumbnail = response.content as Buffer - } - return urlInfo - } + if(response && response.content) { + urlInfo.jpegThumbnail = response.content as Buffer + } + + return urlInfo + } /** Relay (send) a WAMessage; more advanced functionality to send a built WA Message, you may want to stick with sendMessage() */ - const relayMessage = async(message: WAMessage, { waitForAck } = { waitForAck: true }) => { + const relayMessage = async(message: WAMessage, { waitForAck } = { waitForAck: true }) => { const json: BinaryNode = { tag: 'action', attrs: { epoch: currentEpoch().toString(), type: 'relay' }, @@ -256,35 +266,37 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { ] } const isMsgToMe = areJidsSameUser(message.key.remoteJid, state.legacy.user?.id || '') - const flag = isMsgToMe ? WAFlag.acknowledge : WAFlag.ignore // acknowledge when sending message to oneself - const mID = message.key.id + const flag = isMsgToMe ? WAFlag.acknowledge : WAFlag.ignore // acknowledge when sending message to oneself + const mID = message.key.id const finalState = isMsgToMe ? WAMessageStatus.READ : WAMessageStatus.SERVER_ACK - message.status = WAMessageStatus.PENDING - const promise = query({ - json, - binaryTag: [WAMetric.message, flag], - tag: mID, - expect200: true, - requiresPhoneConnection: true - }) + message.status = WAMessageStatus.PENDING + const promise = query({ + json, + binaryTag: [WAMetric.message, flag], + tag: mID, + expect200: true, + requiresPhoneConnection: true + }) - if(waitForAck) { - await promise + if(waitForAck) { + await promise message.status = finalState - } else { - const emitUpdate = (status: WAMessageStatus) => { - message.status = status - ev.emit('messages.update', [ { key: message.key, update: { status } } ]) - } - promise + } else { + const emitUpdate = (status: WAMessageStatus) => { + message.status = status + ev.emit('messages.update', [ { key: message.key, update: { status } } ]) + } + + promise .then(() => emitUpdate(finalState)) .catch(() => emitUpdate(WAMessageStatus.ERROR)) - } + } + if(config.emitOwnEvents) { onMessage(message, 'append') } - } + } // messages received const messagesUpdate = (node: BinaryNode, isLatest: boolean) => { @@ -330,26 +342,30 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { logger.warn({ content, key }, 'got unknown status update for message') } } + ev.emit('messages.update', updates) } } - const onMessageInfoUpdate = ([,attributes]: [string,{[_: string]: any}]) => { + + const onMessageInfoUpdate = ([, attributes]: [string, {[_: string]: any}]) => { let ids = attributes.id as string[] | string if(typeof ids === 'string') { ids = [ids] } + let updateKey: keyof MessageInfoUpdate['update'] - switch(attributes.ack.toString()) { - case '2': - updateKey = 'deliveries' - break - case '3': - updateKey = 'reads' - break - default: - logger.warn({ attributes }, `received unknown message info update`) - return + switch (attributes.ack.toString()) { + case '2': + updateKey = 'deliveries' + break + case '3': + updateKey = 'reads' + break + default: + logger.warn({ attributes }, 'received unknown message info update') + return } + const keyPartial = { remoteJid: jidNormalizedUser(attributes.to), fromMe: areJidsSameUser(attributes.from, state.legacy?.user?.id || ''), @@ -406,38 +422,43 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { const [{ attrs }] = (innerData as BinaryNode[]) const jid = jidNormalizedUser(attrs.jid) const date = new Date(+attrs.t * 1000) - switch(tag) { - case 'read': - info.reads[jid] = date - break - case 'delivery': - info.deliveries[jid] = date - break + switch (tag) { + case 'read': + info.reads[jid] = date + break + case 'delivery': + info.deliveries[jid] = date + break } } } + return info }, downloadMediaMessage: async(message: WAMessage, type: 'buffer' | 'stream' = 'buffer') => { - const downloadMediaMessage = async () => { - let mContent = extractMessageContent(message.message) - if (!mContent) throw new Boom('No message present', { statusCode: 400, data: message }) + const downloadMediaMessage = async() => { + const mContent = extractMessageContent(message.message) + if(!mContent) { + throw new Boom('No message present', { statusCode: 400, data: message }) + } const stream = await decryptMediaMessageBuffer(mContent) if(type === 'buffer') { let buffer = Buffer.from([]) - for await(const chunk of stream) { + for await (const chunk of stream) { buffer = Buffer.concat([buffer, chunk]) } + return buffer } + return stream } try { const result = await downloadMediaMessage() return result - } catch (error) { + } catch(error) { if(error.message.includes('404')) { // media needs to be updated logger.info (`updating media of message: ${message.key.id}`) @@ -446,6 +467,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { const result = await downloadMediaMessage() return result } + throw error } }, @@ -453,15 +475,15 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { fetchMessagesFromWA, /** Load a single message specified by the ID */ loadMessageFromWA: async(jid: string, id: string) => { - let message: WAMessage - // load the message before the given message - let messages = (await fetchMessagesFromWA(jid, 1, { before: {id, fromMe: true} })) - if(!messages[0]) messages = (await fetchMessagesFromWA(jid, 1, { before: {id, fromMe: false} })) + let messages = (await fetchMessagesFromWA(jid, 1, { before: { id, fromMe: true } })) + if(!messages[0]) { + messages = (await fetchMessagesFromWA(jid, 1, { before: { id, fromMe: false } })) + } + // the message after the loaded message is the message required const [actual] = await fetchMessagesFromWA(jid, 1, { after: messages[0] && messages[0].key }) - message = actual - return message + return actual }, searchMessages: async(txt: string, inJid: string | null, count: number, page: number) => { const node: BinaryNode = await query({ @@ -499,8 +521,8 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { ) { const { disappearingMessagesInChat } = content const value = typeof disappearingMessagesInChat === 'boolean' ? - (disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : - disappearingMessagesInChat + (disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : + disappearingMessagesInChat const tag = generateMessageTag(true) await setQuery([ { diff --git a/src/LegacySocket/socket.ts b/src/LegacySocket/socket.ts index edce5e7..333ca99 100644 --- a/src/LegacySocket/socket.ts +++ b/src/LegacySocket/socket.ts @@ -1,11 +1,11 @@ import { Boom } from '@hapi/boom' -import { STATUS_CODES } from "http" -import { promisify } from "util" -import WebSocket from "ws" -import { BinaryNode, encodeBinaryNodeLegacy } from "../WABinary" -import { DisconnectReason, LegacySocketConfig, SocketQueryOptions, SocketSendMessageOptions, WAFlag, WAMetric, WATag } from "../Types" -import { aesEncrypt, hmacSign, promiseTimeout, unixTimestampSeconds, decodeWAMessage } from "../Utils" -import { DEFAULT_ORIGIN, DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, PHONE_CONNECTION_CB } from "../Defaults" +import { STATUS_CODES } from 'http' +import { promisify } from 'util' +import WebSocket from 'ws' +import { DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, DEFAULT_ORIGIN, PHONE_CONNECTION_CB } from '../Defaults' +import { DisconnectReason, LegacySocketConfig, SocketQueryOptions, SocketSendMessageOptions, WAFlag, WAMetric, WATag } from '../Types' +import { aesEncrypt, decodeWAMessage, hmacSign, promiseTimeout, unixTimestampSeconds } from '../Utils' +import { BinaryNode, encodeBinaryNodeLegacy } from '../WABinary' /** * Connects to WA servers and performs: @@ -14,13 +14,13 @@ import { DEFAULT_ORIGIN, DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, PHONE_CONNECTION_C * - query phone connection */ export const makeSocket = ({ - waWebSocketUrl, - connectTimeoutMs, - phoneResponseTimeMs, - logger, - agent, - keepAliveIntervalMs, - expectResponseTimeout, + waWebSocketUrl, + connectTimeoutMs, + phoneResponseTimeMs, + logger, + agent, + keepAliveIntervalMs, + expectResponseTimeout, }: LegacySocketConfig) => { // for generating tags const referenceDateSeconds = unixTimestampSeconds(new Date()) @@ -37,33 +37,35 @@ export const makeSocket = ({ 'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits', } }) - ws.setMaxListeners(0) + ws.setMaxListeners(0) let lastDateRecv: Date let epoch = 0 let authInfo: { encKey: Buffer, macKey: Buffer } let keepAliveReq: NodeJS.Timeout - let phoneCheckInterval: NodeJS.Timeout - let phoneCheckListeners = 0 + let phoneCheckInterval: NodeJS.Timeout + let phoneCheckListeners = 0 - const phoneConnectionChanged = (value: boolean) => { - ws.emit('phone-connection', { value }) - } + const phoneConnectionChanged = (value: boolean) => { + ws.emit('phone-connection', { value }) + } const sendPromise = promisify(ws.send) /** generate message tag and increment epoch */ const generateMessageTag = (longTag: boolean = false) => { - const tag = `${longTag ? referenceDateSeconds : (referenceDateSeconds%1000)}.--${epoch}` - epoch += 1 // increment message count, it makes the 'epoch' field when sending binary messages - return tag - } - const sendRawMessage = (data: Buffer | string) => { - if(ws.readyState !== ws.OPEN) { - throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) - } + const tag = `${longTag ? referenceDateSeconds : (referenceDateSeconds%1000)}.--${epoch}` + epoch += 1 // increment message count, it makes the 'epoch' field when sending binary messages + return tag + } + + const sendRawMessage = (data: Buffer | string) => { + if(ws.readyState !== ws.OPEN) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } + + return sendPromise.call(ws, data) as Promise + } - return sendPromise.call(ws, data) as Promise - } /** * Send a message to the WA servers * @returns the tag attached in the message @@ -73,17 +75,19 @@ export const makeSocket = ({ ) => { tag = tag || generateMessageTag(longTag) let data: Buffer | string - if(logger.level === 'trace') { - logger.trace({ tag, fromMe: true, json, binaryTag }, 'communication') - } + if(logger.level === 'trace') { + logger.trace({ tag, fromMe: true, json, binaryTag }, 'communication') + } if(binaryTag) { - if(Array.isArray(json)) { - throw new Boom('Expected BinaryNode with binary code', { statusCode: 400 }) - } + if(Array.isArray(json)) { + throw new Boom('Expected BinaryNode with binary code', { statusCode: 400 }) + } + if(!authInfo) { throw new Boom('No encryption/mac keys to encrypt node with', { statusCode: 400 }) } + const binary = encodeBinaryNodeLegacy(json) // encode the JSON to the WhatsApp binary format const buff = aesEncrypt(binary, authInfo.encKey) // encrypt it using AES and our encKey @@ -98,242 +102,268 @@ export const makeSocket = ({ } else { data = `${tag},${JSON.stringify(json)}` } + await sendRawMessage(data) return tag } + const end = (error: Error | undefined) => { - logger.info({ error }, 'connection closed') + logger.info({ error }, 'connection closed') - ws.removeAllListeners('close') - ws.removeAllListeners('error') - ws.removeAllListeners('open') - ws.removeAllListeners('message') + ws.removeAllListeners('close') + ws.removeAllListeners('error') + ws.removeAllListeners('open') + ws.removeAllListeners('message') - phoneCheckListeners = 0 - clearInterval(keepAliveReq) - clearPhoneCheckInterval() + phoneCheckListeners = 0 + clearInterval(keepAliveReq) + clearPhoneCheckInterval() - if(ws.readyState !== ws.CLOSED && ws.readyState !== ws.CLOSING) { - try { ws.close() } catch { } - } + if(ws.readyState !== ws.CLOSED && ws.readyState !== ws.CLOSING) { + try { + ws.close() + } catch{ } + } - ws.emit('ws-close', error) - ws.removeAllListeners('ws-close') + ws.emit('ws-close', error) + ws.removeAllListeners('ws-close') } + const onMessageRecieved = (message: string | Buffer) => { - if(message[0] === '!' || message[0] === '!'.charCodeAt(0)) { - // when the first character in the message is an '!', the server is sending a pong frame - const timestamp = message.slice(1, message.length).toString() - lastDateRecv = new Date(parseInt(timestamp)) - ws.emit('received-pong') - } else { - let messageTag: string - let json: any - try { - const dec = decodeWAMessage(message, authInfo) - messageTag = dec[0] - json = dec[1] - if (!json) return - } catch (error) { - end(error) + if(message[0] === '!' || message[0] === '!'.charCodeAt(0)) { + // when the first character in the message is an '!', the server is sending a pong frame + const timestamp = message.slice(1, message.length).toString() + lastDateRecv = new Date(parseInt(timestamp)) + ws.emit('received-pong') + } else { + let messageTag: string + let json: any + try { + const dec = decodeWAMessage(message, authInfo) + messageTag = dec[0] + json = dec[1] + if(!json) { + return + } + } catch(error) { + end(error) return - } - //if (this.shouldLogMessages) this.messageLog.push ({ tag: messageTag, json: JSON.stringify(json), fromMe: false }) + } + //if (this.shouldLogMessages) this.messageLog.push ({ tag: messageTag, json: JSON.stringify(json), fromMe: false }) - if (logger.level === 'trace') { - logger.trace({ tag: messageTag, fromMe: false, json }, 'communication') - } + if(logger.level === 'trace') { + logger.trace({ tag: messageTag, fromMe: false, json }, 'communication') + } - let anyTriggered = false - /* Check if this is a response to a message we sent */ - anyTriggered = ws.emit(`${DEF_TAG_PREFIX}${messageTag}`, json) - /* Check if this is a response to a message we are expecting */ - const l0 = json.tag || json[0] || '' - const l1 = json?.attrs || json?.[1] || { } - const l2 = json?.content?.[0]?.tag || json[2]?.[0] || '' + let anyTriggered = false + /* Check if this is a response to a message we sent */ + anyTriggered = ws.emit(`${DEF_TAG_PREFIX}${messageTag}`, json) + /* Check if this is a response to a message we are expecting */ + const l0 = json.tag || json[0] || '' + const l1 = json?.attrs || json?.[1] || { } + const l2 = json?.content?.[0]?.tag || json[2]?.[0] || '' - Object.keys(l1).forEach(key => { - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, json) || anyTriggered - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, json) || anyTriggered - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, json) || anyTriggered - }) - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, json) || anyTriggered - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0}`, json) || anyTriggered + Object.keys(l1).forEach(key => { + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, json) || anyTriggered + }) + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, json) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0}`, json) || anyTriggered - if (!anyTriggered && logger.level === 'debug') { - logger.debug({ unhandled: true, tag: messageTag, fromMe: false, json }, 'communication recv') - } - } - } + if(!anyTriggered && logger.level === 'debug') { + logger.debug({ unhandled: true, tag: messageTag, fromMe: false, json }, 'communication recv') + } + } + } /** Exits a query if the phone connection is active and no response is still found */ - const exitQueryIfResponseNotExpected = (tag: string, cancel: (error: Boom) => void) => { - let timeout: NodeJS.Timeout - const listener = ([, connected]) => { - if(connected) { - timeout = setTimeout(() => { - logger.info({ tag }, `cancelling wait for message as a response is no longer expected from the phone`) + const exitQueryIfResponseNotExpected = (tag: string, cancel: (error: Boom) => void) => { + let timeout: NodeJS.Timeout + const listener = ([, connected]) => { + if(connected) { + timeout = setTimeout(() => { + logger.info({ tag }, 'cancelling wait for message as a response is no longer expected from the phone') cancel(new Boom('Not expecting a response', { statusCode: 422 })) - }, expectResponseTimeout) - ws.off(PHONE_CONNECTION_CB, listener) - } - } - ws.on(PHONE_CONNECTION_CB, listener) - return () => { - ws.off(PHONE_CONNECTION_CB, listener) - timeout && clearTimeout(timeout) - } - } - /** interval is started when a query takes too long to respond */ - const startPhoneCheckInterval = () => { - phoneCheckListeners += 1 - if (!phoneCheckInterval) { - // if its been a long time and we haven't heard back from WA, send a ping - phoneCheckInterval = setInterval(() => { - if(phoneCheckListeners <= 0) { - logger.warn('phone check called without listeners') - return - } - logger.info('checking phone connection...') - sendAdminTest() + }, expectResponseTimeout) + ws.off(PHONE_CONNECTION_CB, listener) + } + } + + ws.on(PHONE_CONNECTION_CB, listener) + return () => { + ws.off(PHONE_CONNECTION_CB, listener) + timeout && clearTimeout(timeout) + } + } + + /** interval is started when a query takes too long to respond */ + const startPhoneCheckInterval = () => { + phoneCheckListeners += 1 + if(!phoneCheckInterval) { + // if its been a long time and we haven't heard back from WA, send a ping + phoneCheckInterval = setInterval(() => { + if(phoneCheckListeners <= 0) { + logger.warn('phone check called without listeners') + return + } + + logger.info('checking phone connection...') + sendAdminTest() + + phoneConnectionChanged(false) + }, phoneResponseTimeMs) + } + } + + const clearPhoneCheckInterval = () => { + phoneCheckListeners -= 1 + if(phoneCheckListeners <= 0) { + clearInterval(phoneCheckInterval) + phoneCheckInterval = undefined + phoneCheckListeners = 0 + } + } - phoneConnectionChanged(false) - }, phoneResponseTimeMs) - } - } - const clearPhoneCheckInterval = () => { - phoneCheckListeners -= 1 - if (phoneCheckListeners <= 0) { - clearInterval(phoneCheckInterval) - phoneCheckInterval = undefined - phoneCheckListeners = 0 - } - } /** checks for phone connection */ - const sendAdminTest = () => sendNode({ json: ['admin', 'test'] }) - /** + const sendAdminTest = () => sendNode({ json: ['admin', 'test'] }) + /** * Wait for a message with a certain tag to be received * @param tag the message tag to await * @param json query that was sent * @param timeoutMs timeout after which the promise will reject */ const waitForMessage = (tag: string, requiresPhoneConnection: boolean, timeoutMs?: number) => { - if(ws.readyState !== ws.OPEN) { - throw new Boom('Connection not open', { statusCode: DisconnectReason.connectionClosed }) - } + if(ws.readyState !== ws.OPEN) { + throw new Boom('Connection not open', { statusCode: DisconnectReason.connectionClosed }) + } - let cancelToken = () => { } + let cancelToken = () => { } - return { - promise: (async() => { - let onRecv: (json) => void - let onErr: (err) => void - let cancelPhoneChecker: () => void - try { - const result = await promiseTimeout(timeoutMs, - (resolve, reject) => { - onRecv = resolve - onErr = err => { - reject(err || new Boom('Intentional Close', { statusCode: DisconnectReason.connectionClosed })) - } - cancelToken = () => onErr(new Boom('Cancelled', { statusCode: 500 })) + return { + promise: (async() => { + let onRecv: (json) => void + let onErr: (err) => void + let cancelPhoneChecker: () => void + try { + const result = await promiseTimeout(timeoutMs, + (resolve, reject) => { + onRecv = resolve + onErr = err => { + reject(err || new Boom('Intentional Close', { statusCode: DisconnectReason.connectionClosed })) + } + + cancelToken = () => onErr(new Boom('Cancelled', { statusCode: 500 })) - if(requiresPhoneConnection) { - startPhoneCheckInterval() - cancelPhoneChecker = exitQueryIfResponseNotExpected(tag, onErr) - } + if(requiresPhoneConnection) { + startPhoneCheckInterval() + cancelPhoneChecker = exitQueryIfResponseNotExpected(tag, onErr) + } - ws.on(`TAG:${tag}`, onRecv) - ws.on('ws-close', onErr) // if the socket closes, you'll never receive the message - }, - ) - return result as any - } finally { - requiresPhoneConnection && clearPhoneCheckInterval() - cancelPhoneChecker && cancelPhoneChecker() + ws.on(`TAG:${tag}`, onRecv) + ws.on('ws-close', onErr) // if the socket closes, you'll never receive the message + }, + ) + return result as any + } finally { + requiresPhoneConnection && clearPhoneCheckInterval() + cancelPhoneChecker && cancelPhoneChecker() - ws.off(`TAG:${tag}`, onRecv) - ws.off('ws-close', onErr) // if the socket closes, you'll never receive the message - } - })(), - cancelToken: () => { cancelToken() } - } - } - /** + ws.off(`TAG:${tag}`, onRecv) + ws.off('ws-close', onErr) // if the socket closes, you'll never receive the message + } + })(), + cancelToken: () => { + cancelToken() + } + } + } + + /** * Query something from the WhatsApp servers * @param json the query itself * @param binaryTags the tags to attach if the query is supposed to be sent encoded in binary * @param timeoutMs timeout after which the query will be failed (set to null to disable a timeout) * @param tag the tag to attach to the message */ - const query = async( - { json, timeoutMs, expect200, tag, longTag, binaryTag, requiresPhoneConnection }: SocketQueryOptions - ) => { + const query = async( + { json, timeoutMs, expect200, tag, longTag, binaryTag, requiresPhoneConnection }: SocketQueryOptions + ) => { tag = tag || generateMessageTag(longTag) - const { promise, cancelToken } = waitForMessage(tag, requiresPhoneConnection, timeoutMs) - try { - await sendNode({ json, tag, binaryTag }) - } catch(error) { - cancelToken() - // swallow error - await promise.catch(() => { }) - // throw back the error - throw error - } + const { promise, cancelToken } = waitForMessage(tag, requiresPhoneConnection, timeoutMs) + try { + await sendNode({ json, tag, binaryTag }) + } catch(error) { + cancelToken() + // swallow error + await promise.catch(() => { }) + // throw back the error + throw error + } - const response = await promise - const responseStatusCode = +(response.status ? response.status : 200) // default status - // read here: http://getstatuscode.com/599 - if(responseStatusCode === 599) { // the connection has gone bad - end(new Boom('WA server overloaded', { statusCode: 599, data: { query: json, response } })) - } - if(expect200 && Math.floor(responseStatusCode/100) !== 2) { - const message = STATUS_CODES[responseStatusCode] || 'unknown' - throw new Boom( - `Unexpected status in '${Array.isArray(json) ? json[0] : (json?.tag || 'query')}': ${message}(${responseStatusCode})`, - { data: { query: json, response }, statusCode: response.status } - ) - } - return response - } + const response = await promise + const responseStatusCode = +(response.status ? response.status : 200) // default status + // read here: http://getstatuscode.com/599 + if(responseStatusCode === 599) { // the connection has gone bad + end(new Boom('WA server overloaded', { statusCode: 599, data: { query: json, response } })) + } + + if(expect200 && Math.floor(responseStatusCode/100) !== 2) { + const message = STATUS_CODES[responseStatusCode] || 'unknown' + throw new Boom( + `Unexpected status in '${Array.isArray(json) ? json[0] : (json?.tag || 'query')}': ${message}(${responseStatusCode})`, + { data: { query: json, response }, statusCode: response.status } + ) + } + + return response + } + const startKeepAliveRequest = () => ( - keepAliveReq = setInterval(() => { - if (!lastDateRecv) lastDateRecv = new Date() - const diff = Date.now() - lastDateRecv.getTime() - /* + keepAliveReq = setInterval(() => { + if(!lastDateRecv) { + lastDateRecv = new Date() + } + + const diff = Date.now() - lastDateRecv.getTime() + /* check if it's been a suspicious amount of time since the server responded with our last seen it could be that the network is down */ - if (diff > keepAliveIntervalMs+5000) { - end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost })) - } else if(ws.readyState === ws.OPEN) { - sendRawMessage('?,,') // if its all good, send a keep alive request - } else { - logger.warn('keep alive called when WS not open') - } - }, keepAliveIntervalMs) - ) + if(diff > keepAliveIntervalMs+5000) { + end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost })) + } else if(ws.readyState === ws.OPEN) { + sendRawMessage('?,,') // if its all good, send a keep alive request + } else { + logger.warn('keep alive called when WS not open') + } + }, keepAliveIntervalMs) + ) - const waitForSocketOpen = async() => { - if(ws.readyState === ws.OPEN) return - if(ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { - throw new Boom('Connection Already Closed', { statusCode: DisconnectReason.connectionClosed }) - } - let onOpen: () => void - let onClose: (err: Error) => void - await new Promise((resolve, reject) => { - onOpen = () => resolve(undefined) - onClose = reject - ws.on('open', onOpen) - ws.on('close', onClose) - ws.on('error', onClose) - }) - .finally(() => { - ws.off('open', onOpen) - ws.off('close', onClose) - ws.off('error', onClose) - }) - } + const waitForSocketOpen = async() => { + if(ws.readyState === ws.OPEN) { + return + } + + if(ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { + throw new Boom('Connection Already Closed', { statusCode: DisconnectReason.connectionClosed }) + } + + let onOpen: () => void + let onClose: (err: Error) => void + await new Promise((resolve, reject) => { + onOpen = () => resolve(undefined) + onClose = reject + ws.on('open', onOpen) + ws.on('close', onClose) + ws.on('error', onClose) + }) + .finally(() => { + ws.off('open', onOpen) + ws.off('close', onClose) + ws.off('error', onClose) + }) + } ws.on('message', onMessageRecieved) ws.on('open', () => { @@ -343,57 +373,58 @@ export const makeSocket = ({ ws.on('error', end) ws.on('close', () => end(new Boom('Connection Terminated', { statusCode: DisconnectReason.connectionLost }))) - ws.on(PHONE_CONNECTION_CB, json => { - if (!json[1]) { - end(new Boom('Connection terminated by phone', { statusCode: DisconnectReason.connectionLost })) - logger.info('Connection terminated by phone, closing...') - } else { - phoneConnectionChanged(true) - } - }) - ws.on('CB:Cmd,type:disconnect', json => { - const {kind} = json[1] - let reason: DisconnectReason - switch(kind) { - case 'replaced': - reason = DisconnectReason.connectionReplaced - break - default: - reason = DisconnectReason.connectionLost - break - } - end(new Boom( - `Connection terminated by server: "${kind || 'unknown'}"`, - { statusCode: reason } - )) - }) + ws.on(PHONE_CONNECTION_CB, json => { + if(!json[1]) { + end(new Boom('Connection terminated by phone', { statusCode: DisconnectReason.connectionLost })) + logger.info('Connection terminated by phone, closing...') + } else { + phoneConnectionChanged(true) + } + }) + ws.on('CB:Cmd,type:disconnect', json => { + const { kind } = json[1] + let reason: DisconnectReason + switch (kind) { + case 'replaced': + reason = DisconnectReason.connectionReplaced + break + default: + reason = DisconnectReason.connectionLost + break + } + + end(new Boom( + `Connection terminated by server: "${kind || 'unknown'}"`, + { statusCode: reason } + )) + }) return { - type: 'legacy' as 'legacy', - ws, - sendAdminTest, - updateKeys: (info: { encKey: Buffer, macKey: Buffer }) => authInfo = info, - waitForSocketOpen, + type: 'legacy' as 'legacy', + ws, + sendAdminTest, + updateKeys: (info: { encKey: Buffer, macKey: Buffer }) => authInfo = info, + waitForSocketOpen, sendNode, generateMessageTag, - waitForMessage, - query, - /** Generic function for action, set queries */ - setQuery: async(nodes: BinaryNode[], binaryTag: WATag = [WAMetric.group, WAFlag.ignore], tag?: string) => { - const json: BinaryNode = { - tag: 'action', - attrs: { epoch: epoch.toString(), type: 'set' }, - content: nodes - } + waitForMessage, + query, + /** Generic function for action, set queries */ + setQuery: async(nodes: BinaryNode[], binaryTag: WATag = [WAMetric.group, WAFlag.ignore], tag?: string) => { + const json: BinaryNode = { + tag: 'action', + attrs: { epoch: epoch.toString(), type: 'set' }, + content: nodes + } - return query({ - json, - binaryTag, - tag, - expect200: true, - requiresPhoneConnection: true - }) as Promise<{ status: number }> - }, + return query({ + json, + binaryTag, + tag, + expect200: true, + requiresPhoneConnection: true + }) as Promise<{ status: number }> + }, currentEpoch: () => epoch, end } diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index a96994a..385dd18 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1,10 +1,10 @@ -import { SocketConfig, WAPresence, PresenceData, Chat, WAPatchCreate, WAMediaUpload, ChatMutation, WAPatchName, AppStateChunk, LTHashState, ChatModification, Contact, WABusinessProfile, WABusinessHoursConfig } from "../Types"; -import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, S_WHATSAPP_NET, reduceBinaryNodeToDictionary } from "../WABinary"; +import { Boom } from '@hapi/boom' import { proto } from '../../WAProto' -import { generateProfilePicture, toNumber, encodeSyncdPatch, decodePatches, extractSyncdPatches, chatModificationToAppPatch, decodeSyncdSnapshot, newLTHashState } from "../Utils"; -import { makeMessagesSocket } from "./messages-send"; -import makeMutex from "../Utils/make-mutex"; -import { Boom } from "@hapi/boom"; +import { AppStateChunk, Chat, ChatModification, ChatMutation, Contact, LTHashState, PresenceData, SocketConfig, WABusinessHoursConfig, WABusinessProfile, WAMediaUpload, WAPatchCreate, WAPatchName, WAPresence } from '../Types' +import { chatModificationToAppPatch, decodePatches, decodeSyncdSnapshot, encodeSyncdPatch, extractSyncdPatches, generateProfilePicture, newLTHashState, toNumber } from '../Utils' +import makeMutex from '../Utils/make-mutex' +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, reduceBinaryNodeToDictionary, S_WHATSAPP_NET } from '../WABinary' +import { makeMessagesSocket } from './messages-send' const MAX_SYNC_ATTEMPTS = 5 @@ -15,671 +15,687 @@ export const makeChatsSocket = (config: SocketConfig) => { ev, ws, authState, - generateMessageTag, + generateMessageTag, sendNode, - query, - fetchPrivacySettings, + query, + fetchPrivacySettings, } = sock - const mutationMutex = makeMutex() + const mutationMutex = makeMutex() - const getAppStateSyncKey = async(keyId: string) => { - const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId]) - return key - } + const getAppStateSyncKey = async(keyId: string) => { + const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId]) + return key + } - const interactiveQuery = async(userNodes: BinaryNode[], queryNode: BinaryNode) => { - const result = await query({ - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - type: 'get', - xmlns: 'usync', - }, - content: [ - { - tag: 'usync', - attrs: { - sid: generateMessageTag(), - mode: 'query', - last: 'true', - index: '0', - context: 'interactive', - }, - content: [ - { - tag: 'query', - attrs: { }, - content: [ queryNode ] - }, - { - tag: 'list', - attrs: { }, - content: userNodes - } - ] - } - ], - }) + const interactiveQuery = async(userNodes: BinaryNode[], queryNode: BinaryNode) => { + const result = await query({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'get', + xmlns: 'usync', + }, + content: [ + { + tag: 'usync', + attrs: { + sid: generateMessageTag(), + mode: 'query', + last: 'true', + index: '0', + context: 'interactive', + }, + content: [ + { + tag: 'query', + attrs: { }, + content: [ queryNode ] + }, + { + tag: 'list', + attrs: { }, + content: userNodes + } + ] + } + ], + }) - const usyncNode = getBinaryNodeChild(result, 'usync') - const listNode = getBinaryNodeChild(usyncNode, 'list') - const users = getBinaryNodeChildren(listNode, 'user') + const usyncNode = getBinaryNodeChild(result, 'usync') + const listNode = getBinaryNodeChild(usyncNode, 'list') + const users = getBinaryNodeChildren(listNode, 'user') - return users - } + return users + } - const onWhatsApp = async(...jids: string[]) => { - const results = await interactiveQuery( - [ - { - tag: 'user', - attrs: { }, - content: jids.map( - jid => ({ - tag: 'contact', - attrs: { }, - content: `+${jid}` - }) - ) - } - ], - { tag: 'contact', attrs: { } } - ) + const onWhatsApp = async(...jids: string[]) => { + const results = await interactiveQuery( + [ + { + tag: 'user', + attrs: { }, + content: jids.map( + jid => ({ + tag: 'contact', + attrs: { }, + content: `+${jid}` + }) + ) + } + ], + { tag: 'contact', attrs: { } } + ) - return results.map(user => { - const contact = getBinaryNodeChild(user, 'contact') - return { exists: contact.attrs.type === 'in', jid: user.attrs.jid } - }).filter(item => item.exists) - } + return results.map(user => { + const contact = getBinaryNodeChild(user, 'contact') + return { exists: contact.attrs.type === 'in', jid: user.attrs.jid } + }).filter(item => item.exists) + } - const fetchStatus = async(jid: string) => { - const [result] = await interactiveQuery( - [{ tag: 'user', attrs: { jid } }], - { tag: 'status', attrs: { } } - ) - if(result) { - const status = getBinaryNodeChild(result, 'status') - return { - status: status.content!.toString(), - setAt: new Date(+status.attrs.t * 1000) - } - } - } + const fetchStatus = async(jid: string) => { + const [result] = await interactiveQuery( + [{ tag: 'user', attrs: { jid } }], + { tag: 'status', attrs: { } } + ) + if(result) { + const status = getBinaryNodeChild(result, 'status') + return { + status: status.content!.toString(), + setAt: new Date(+status.attrs.t * 1000) + } + } + } - const updateProfilePicture = async(jid: string, content: WAMediaUpload) => { - const { img } = await generateProfilePicture(content) - await query({ - tag: 'iq', - attrs: { - to: jidNormalizedUser(jid), - type: 'set', - xmlns: 'w:profile:picture' - }, - content: [ - { - tag: 'picture', - attrs: { type: 'image' }, - content: img - } - ] - }) - } + const updateProfilePicture = async(jid: string, content: WAMediaUpload) => { + const { img } = await generateProfilePicture(content) + await query({ + tag: 'iq', + attrs: { + to: jidNormalizedUser(jid), + type: 'set', + xmlns: 'w:profile:picture' + }, + content: [ + { + tag: 'picture', + attrs: { type: 'image' }, + content: img + } + ] + }) + } - const fetchBlocklist = async() => { - const result = await query({ - tag: 'iq', - attrs: { - xmlns: 'blocklist', - to: S_WHATSAPP_NET, - type: 'get' - } - }) - const child = result.content?.[0] as BinaryNode - return (child.content as BinaryNode[])?.map(i => i.attrs.jid) - } + const fetchBlocklist = async() => { + const result = await query({ + tag: 'iq', + attrs: { + xmlns: 'blocklist', + to: S_WHATSAPP_NET, + type: 'get' + } + }) + const child = result.content?.[0] as BinaryNode + return (child.content as BinaryNode[])?.map(i => i.attrs.jid) + } - const updateBlockStatus = async(jid: string, action: 'block' | 'unblock') => { - await query({ - tag: 'iq', - attrs: { - xmlns: 'blocklist', - to: S_WHATSAPP_NET, - type: 'set' - }, - content: [ - { - tag: 'item', - attrs: { - action, - jid - } - } - ] - }) - } + const updateBlockStatus = async(jid: string, action: 'block' | 'unblock') => { + await query({ + tag: 'iq', + attrs: { + xmlns: 'blocklist', + to: S_WHATSAPP_NET, + type: 'set' + }, + content: [ + { + tag: 'item', + attrs: { + action, + jid + } + } + ] + }) + } - const getBusinessProfile = async (jid: string): Promise => { - const results = await query({ - tag: 'iq', - attrs: { - to: 's.whatsapp.net', - xmlns: 'w:biz', - type: 'get' - }, - content: [{ - tag: 'business_profile', - attrs: { v: '244' }, - content: [{ - tag: 'profile', - attrs: { jid } - }] - }] - }) - const profiles = getBinaryNodeChild(getBinaryNodeChild(results, 'business_profile'), 'profile') - if (!profiles) { - // if not bussines - if (logger.level == 'trace') logger.trace({ jid }, 'Not bussines') - return - } - const address = getBinaryNodeChild(profiles, 'address') - const description = getBinaryNodeChild(profiles, 'description') - const website = getBinaryNodeChild(profiles, 'website') - const email = getBinaryNodeChild(profiles, 'email') - const category = getBinaryNodeChild(getBinaryNodeChild(profiles, 'categories'), 'category') - const business_hours = getBinaryNodeChild(profiles, 'business_hours') - const business_hours_config = business_hours && getBinaryNodeChildren(business_hours, 'business_hours_config') - return { - wid: profiles.attrs?.jid, - address: address?.content.toString(), - description: description?.content.toString(), - website: [website?.content.toString()], - email: email?.content.toString(), - category: category?.content.toString(), - business_hours: { - timezone: business_hours?.attrs?.timezone, - business_config: business_hours_config?.map(({ attrs }) => attrs as unknown as WABusinessHoursConfig) - } - } as unknown as WABusinessProfile - } + const getBusinessProfile = async(jid: string): Promise => { + const results = await query({ + tag: 'iq', + attrs: { + to: 's.whatsapp.net', + xmlns: 'w:biz', + type: 'get' + }, + content: [{ + tag: 'business_profile', + attrs: { v: '244' }, + content: [{ + tag: 'profile', + attrs: { jid } + }] + }] + }) + const profiles = getBinaryNodeChild(getBinaryNodeChild(results, 'business_profile'), 'profile') + if(!profiles) { + // if not bussines + if(logger.level === 'trace') { + logger.trace({ jid }, 'Not bussines') + } - const updateAccountSyncTimestamp = async(fromTimestamp: number | string) => { - logger.info({ fromTimestamp }, 'requesting account sync') - await sendNode({ - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - type: 'set', - xmlns: 'urn:xmpp:whatsapp:dirty', - id: generateMessageTag(), - }, - content: [ - { - tag: 'clean', - attrs: { - type: 'account_sync', - timestamp: fromTimestamp.toString(), - } - } - ] - }) - } + return + } - const resyncAppState = async(collections: WAPatchName[]) => { - const appStateChunk: AppStateChunk = {totalMutations: [], collectionsToHandle: []} - // we use this to determine which events to fire - // otherwise when we resync from scratch -- all notifications will fire - const initialVersionMap: { [T in WAPatchName]?: number } = { } + const address = getBinaryNodeChild(profiles, 'address') + const description = getBinaryNodeChild(profiles, 'description') + const website = getBinaryNodeChild(profiles, 'website') + const email = getBinaryNodeChild(profiles, 'email') + const category = getBinaryNodeChild(getBinaryNodeChild(profiles, 'categories'), 'category') + const business_hours = getBinaryNodeChild(profiles, 'business_hours') + const business_hours_config = business_hours && getBinaryNodeChildren(business_hours, 'business_hours_config') + return { + wid: profiles.attrs?.jid, + address: address?.content.toString(), + description: description?.content.toString(), + website: [website?.content.toString()], + email: email?.content.toString(), + category: category?.content.toString(), + business_hours: { + timezone: business_hours?.attrs?.timezone, + business_config: business_hours_config?.map(({ attrs }) => attrs as unknown as WABusinessHoursConfig) + } + } as unknown as WABusinessProfile + } - await authState.keys.transaction( - async() => { - const collectionsToHandle = new Set(collections) - // in case something goes wrong -- ensure we don't enter a loop that cannot be exited from - const attemptsMap = { } as { [T in WAPatchName]: number | undefined } - // keep executing till all collections are done - // sometimes a single patch request will not return all the patches (God knows why) - // so we fetch till they're all done (this is determined by the "has_more_patches" flag) - while(collectionsToHandle.size) { - const states = { } as { [T in WAPatchName]: LTHashState } - const nodes: BinaryNode[] = [] + const updateAccountSyncTimestamp = async(fromTimestamp: number | string) => { + logger.info({ fromTimestamp }, 'requesting account sync') + await sendNode({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'set', + xmlns: 'urn:xmpp:whatsapp:dirty', + id: generateMessageTag(), + }, + content: [ + { + tag: 'clean', + attrs: { + type: 'account_sync', + timestamp: fromTimestamp.toString(), + } + } + ] + }) + } - for(const name of collectionsToHandle) { - const result = await authState.keys.get('app-state-sync-version', [name]) - let state = result[name] + const resyncAppState = async(collections: WAPatchName[]) => { + const appStateChunk: AppStateChunk = { totalMutations: [], collectionsToHandle: [] } + // we use this to determine which events to fire + // otherwise when we resync from scratch -- all notifications will fire + const initialVersionMap: { [T in WAPatchName]?: number } = { } - if(state) { - if(typeof initialVersionMap[name] === 'undefined') { - initialVersionMap[name] = state.version - } - } else { - state = newLTHashState() - } + await authState.keys.transaction( + async() => { + const collectionsToHandle = new Set(collections) + // in case something goes wrong -- ensure we don't enter a loop that cannot be exited from + const attemptsMap = { } as { [T in WAPatchName]: number | undefined } + // keep executing till all collections are done + // sometimes a single patch request will not return all the patches (God knows why) + // so we fetch till they're all done (this is determined by the "has_more_patches" flag) + while(collectionsToHandle.size) { + const states = { } as { [T in WAPatchName]: LTHashState } + const nodes: BinaryNode[] = [] - states[name] = state + for(const name of collectionsToHandle) { + const result = await authState.keys.get('app-state-sync-version', [name]) + let state = result[name] - logger.info(`resyncing ${name} from v${state.version}`) + if(state) { + if(typeof initialVersionMap[name] === 'undefined') { + initialVersionMap[name] = state.version + } + } else { + state = newLTHashState() + } - nodes.push({ - tag: 'collection', - attrs: { - name, - version: state.version.toString(), - // return snapshot if being synced from scratch - return_snapshot: (!state.version).toString() - } - }) - } + states[name] = state - const result = await query({ - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - xmlns: 'w:sync:app:state', - type: 'set' - }, - content: [ - { - tag: 'sync', - attrs: { }, - content: nodes - } - ] - }) + logger.info(`resyncing ${name} from v${state.version}`) + + nodes.push({ + tag: 'collection', + attrs: { + name, + version: state.version.toString(), + // return snapshot if being synced from scratch + return_snapshot: (!state.version).toString() + } + }) + } + + const result = await query({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + xmlns: 'w:sync:app:state', + type: 'set' + }, + content: [ + { + tag: 'sync', + attrs: { }, + content: nodes + } + ] + }) - const decoded = await extractSyncdPatches(result) // extract from binary node - for(const key in decoded) { - const name = key as WAPatchName - const { patches, hasMorePatches, snapshot } = decoded[name] - try { - if(snapshot) { - const { state: newState, mutations } = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey, initialVersionMap[name]) - states[name] = newState + const decoded = await extractSyncdPatches(result) // extract from binary node + for(const key in decoded) { + const name = key as WAPatchName + const { patches, hasMorePatches, snapshot } = decoded[name] + try { + if(snapshot) { + const { state: newState, mutations } = await decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey, initialVersionMap[name]) + states[name] = newState - logger.info(`restored state of ${name} from snapshot to v${newState.version} with ${mutations.length} mutations`) + logger.info(`restored state of ${name} from snapshot to v${newState.version} with ${mutations.length} mutations`) - await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) + await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) - appStateChunk.totalMutations.push(...mutations) - } - // only process if there are syncd patches - if(patches.length) { - const { newMutations, state: newState } = await decodePatches(name, patches, states[name], getAppStateSyncKey, initialVersionMap[name]) + appStateChunk.totalMutations.push(...mutations) + } + + // only process if there are syncd patches + if(patches.length) { + const { newMutations, state: newState } = await decodePatches(name, patches, states[name], getAppStateSyncKey, initialVersionMap[name]) - await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) + await authState.keys.set({ 'app-state-sync-version': { [name]: newState } }) - logger.info(`synced ${name} to v${newState.version}`) - if(newMutations.length) { - logger.trace({ newMutations, name }, 'recv new mutations') - } + logger.info(`synced ${name} to v${newState.version}`) + if(newMutations.length) { + logger.trace({ newMutations, name }, 'recv new mutations') + } - appStateChunk.totalMutations.push(...newMutations) - } - if(hasMorePatches) { - logger.info(`${name} has more patches...`) - } else { // collection is done with sync - collectionsToHandle.delete(name) - } - } catch(error) { - logger.info({ name, error: error.stack }, 'failed to sync state from version, removing and trying from scratch') - await authState.keys.set({ "app-state-sync-version": { [name]: null } }) - // increment number of retries - attemptsMap[name] = (attemptsMap[name] || 0) + 1 - // if retry attempts overshoot - // or key not found - if(attemptsMap[name] >= MAX_SYNC_ATTEMPTS || error.output?.statusCode === 404) { - // stop retrying - collectionsToHandle.delete(name) - } - } - } - } - } - ) + appStateChunk.totalMutations.push(...newMutations) + } - processSyncActions(appStateChunk.totalMutations) + if(hasMorePatches) { + logger.info(`${name} has more patches...`) + } else { // collection is done with sync + collectionsToHandle.delete(name) + } + } catch(error) { + logger.info({ name, error: error.stack }, 'failed to sync state from version, removing and trying from scratch') + await authState.keys.set({ 'app-state-sync-version': { [name]: null } }) + // increment number of retries + attemptsMap[name] = (attemptsMap[name] || 0) + 1 + // if retry attempts overshoot + // or key not found + if(attemptsMap[name] >= MAX_SYNC_ATTEMPTS || error.output?.statusCode === 404) { + // stop retrying + collectionsToHandle.delete(name) + } + } + } + } + } + ) - return appStateChunk - } + processSyncActions(appStateChunk.totalMutations) - /** + return appStateChunk + } + + /** * fetch the profile picture of a user/group * type = "preview" for a low res picture * type = "image for the high res picture" */ - const profilePictureUrl = async(jid: string, type: 'preview' | 'image' = 'preview', timeoutMs?: number) => { - jid = jidNormalizedUser(jid) - const result = await query({ - tag: 'iq', - attrs: { - to: jid, - type: 'get', - xmlns: 'w:profile:picture' - }, - content: [ - { tag: 'picture', attrs: { type, query: 'url' } } - ] - }, timeoutMs) - const child = getBinaryNodeChild(result, 'picture') - return child?.attrs?.url - } + const profilePictureUrl = async(jid: string, type: 'preview' | 'image' = 'preview', timeoutMs?: number) => { + jid = jidNormalizedUser(jid) + const result = await query({ + tag: 'iq', + attrs: { + to: jid, + type: 'get', + xmlns: 'w:profile:picture' + }, + content: [ + { tag: 'picture', attrs: { type, query: 'url' } } + ] + }, timeoutMs) + const child = getBinaryNodeChild(result, 'picture') + return child?.attrs?.url + } - const sendPresenceUpdate = async(type: WAPresence, toJid?: string) => { - const me = authState.creds.me! - if(type === 'available' || type === 'unavailable') { - await sendNode({ - tag: 'presence', - attrs: { - name: me!.name, - type - } - }) - } else { - await sendNode({ - tag: 'chatstate', - attrs: { - from: me!.id!, - to: toJid, - }, - content: [ - { tag: type, attrs: { } } - ] - }) - } - } + const sendPresenceUpdate = async(type: WAPresence, toJid?: string) => { + const me = authState.creds.me! + if(type === 'available' || type === 'unavailable') { + await sendNode({ + tag: 'presence', + attrs: { + name: me!.name, + type + } + }) + } else { + await sendNode({ + tag: 'chatstate', + attrs: { + from: me!.id!, + to: toJid, + }, + content: [ + { tag: type, attrs: { } } + ] + }) + } + } - const presenceSubscribe = (toJid: string) => ( - sendNode({ - tag: 'presence', - attrs: { - to: toJid, - id: generateMessageTag(), - type: 'subscribe' - } - }) - ) + const presenceSubscribe = (toJid: string) => ( + sendNode({ + tag: 'presence', + attrs: { + to: toJid, + id: generateMessageTag(), + type: 'subscribe' + } + }) + ) - const handlePresenceUpdate = ({ tag, attrs, content }: BinaryNode) => { - let presence: PresenceData - const jid = attrs.from - const participant = attrs.participant || attrs.from - if(tag === 'presence') { - presence = { - lastKnownPresence: attrs.type === 'unavailable' ? 'unavailable' : 'available', - lastSeen: attrs.t ? +attrs.t : undefined - } - } else if(Array.isArray(content)) { - const [firstChild] = content - let type = firstChild.tag as WAPresence - if(type === 'paused') { - type = 'available' - } - presence = { lastKnownPresence: type } - } else { - logger.error({ tag, attrs, content }, 'recv invalid presence node') - } - if(presence) { - ev.emit('presence.update', { id: jid, presences: { [participant]: presence } }) - } - } + const handlePresenceUpdate = ({ tag, attrs, content }: BinaryNode) => { + let presence: PresenceData + const jid = attrs.from + const participant = attrs.participant || attrs.from + if(tag === 'presence') { + presence = { + lastKnownPresence: attrs.type === 'unavailable' ? 'unavailable' : 'available', + lastSeen: attrs.t ? +attrs.t : undefined + } + } else if(Array.isArray(content)) { + const [firstChild] = content + let type = firstChild.tag as WAPresence + if(type === 'paused') { + type = 'available' + } - const resyncMainAppState = async() => { + presence = { lastKnownPresence: type } + } else { + logger.error({ tag, attrs, content }, 'recv invalid presence node') + } + + if(presence) { + ev.emit('presence.update', { id: jid, presences: { [participant]: presence } }) + } + } + + const resyncMainAppState = async() => { - logger.debug('resyncing main app state') + logger.debug('resyncing main app state') - await ( - mutationMutex.mutex( - () => resyncAppState([ - 'critical_block', - 'critical_unblock_low', - 'regular_high', - 'regular_low', - 'regular' - ]) - ) - .catch(err => ( - logger.warn({ trace: err.stack }, 'failed to sync app state') - )) - ) - } + await ( + mutationMutex.mutex( + () => resyncAppState([ + 'critical_block', + 'critical_unblock_low', + 'regular_high', + 'regular_low', + 'regular' + ]) + ) + .catch(err => ( + logger.warn({ trace: err.stack }, 'failed to sync app state') + )) + ) + } - const processSyncActions = (actions: ChatMutation[]) => { - const updates: { [jid: string]: Partial } = {} - const contactUpdates: { [jid: string]: Contact } = {} - const msgDeletes: proto.IMessageKey[] = [] + const processSyncActions = (actions: ChatMutation[]) => { + const updates: { [jid: string]: Partial } = {} + const contactUpdates: { [jid: string]: Contact } = {} + const msgDeletes: proto.IMessageKey[] = [] - for(const { syncAction: { value: action }, index: [_, id, msgId, fromMe] } of actions) { - const update: Partial = { id } - if(action?.muteAction) { - update.mute = action.muteAction?.muted ? - toNumber(action.muteAction!.muteEndTimestamp!) : - undefined - } else if(action?.archiveChatAction) { - update.archive = !!action.archiveChatAction?.archived - } else if(action?.markChatAsReadAction) { - update.unreadCount = !!action.markChatAsReadAction?.read ? 0 : -1 - } else if(action?.clearChatAction) { - msgDeletes.push({ - remoteJid: id, - id: msgId, - fromMe: fromMe === '1' - }) - } else if(action?.contactAction) { - contactUpdates[id] = { - ...(contactUpdates[id] || {}), - id, - name: action.contactAction!.fullName - } - } else if(action?.pushNameSetting) { - const me = { - ...authState.creds.me!, - name: action?.pushNameSetting?.name! - } - ev.emit('creds.update', { me }) - } else if(action?.pinAction) { - update.pin = action.pinAction?.pinned ? toNumber(action.timestamp) : undefined - } else { - logger.warn({ action, id }, 'unprocessable update') - } + for(const { syncAction: { value: action }, index: [_, id, msgId, fromMe] } of actions) { + const update: Partial = { id } + if(action?.muteAction) { + update.mute = action.muteAction?.muted ? + toNumber(action.muteAction!.muteEndTimestamp!) : + undefined + } else if(action?.archiveChatAction) { + update.archive = !!action.archiveChatAction?.archived + } else if(action?.markChatAsReadAction) { + update.unreadCount = !!action.markChatAsReadAction?.read ? 0 : -1 + } else if(action?.clearChatAction) { + msgDeletes.push({ + remoteJid: id, + id: msgId, + fromMe: fromMe === '1' + }) + } else if(action?.contactAction) { + contactUpdates[id] = { + ...(contactUpdates[id] || {}), + id, + name: action.contactAction!.fullName + } + } else if(action?.pushNameSetting) { + const me = { + ...authState.creds.me!, + name: action?.pushNameSetting?.name! + } + ev.emit('creds.update', { me }) + } else if(action?.pinAction) { + update.pin = action.pinAction?.pinned ? toNumber(action.timestamp) : undefined + } else { + logger.warn({ action, id }, 'unprocessable update') + } - if(Object.keys(update).length > 1) { - updates[update.id] = { - ...(updates[update.id] || {}), - ...update - } - } - } + if(Object.keys(update).length > 1) { + updates[update.id] = { + ...(updates[update.id] || {}), + ...update + } + } + } - if(Object.values(updates).length) { - ev.emit('chats.update', Object.values(updates)) - } - if(Object.values(contactUpdates).length) { - ev.emit('contacts.upsert', Object.values(contactUpdates)) - } - if(msgDeletes.length) { - ev.emit('messages.delete', { keys: msgDeletes }) - } - } + if(Object.values(updates).length) { + ev.emit('chats.update', Object.values(updates)) + } - const appPatch = async(patchCreate: WAPatchCreate) => { - const name = patchCreate.type - const myAppStateKeyId = authState.creds.myAppStateKeyId - if(!myAppStateKeyId) { - throw new Boom(`App state key not present!`, { statusCode: 400 }) - } + if(Object.values(contactUpdates).length) { + ev.emit('contacts.upsert', Object.values(contactUpdates)) + } - await mutationMutex.mutex( - async() => { - logger.debug({ patch: patchCreate }, 'applying app patch') + if(msgDeletes.length) { + ev.emit('messages.delete', { keys: msgDeletes }) + } + } - await resyncAppState([name]) - const { [name]: initial } = await authState.keys.get('app-state-sync-version', [name]) - const { patch, state } = await encodeSyncdPatch( - patchCreate, - myAppStateKeyId, - initial, - getAppStateSyncKey, - ) + const appPatch = async(patchCreate: WAPatchCreate) => { + const name = patchCreate.type + const myAppStateKeyId = authState.creds.myAppStateKeyId + if(!myAppStateKeyId) { + throw new Boom('App state key not present!', { statusCode: 400 }) + } - const node: BinaryNode = { - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - type: 'set', - xmlns: 'w:sync:app:state' - }, - content: [ - { - tag: 'sync', - attrs: { }, - content: [ - { - tag: 'collection', - attrs: { - name, - version: (state.version-1).toString(), - return_snapshot: 'false' - }, - content: [ - { - tag: 'patch', - attrs: { }, - content: proto.SyncdPatch.encode(patch).finish() - } - ] - } - ] - } - ] - } - await query(node) + await mutationMutex.mutex( + async() => { + logger.debug({ patch: patchCreate }, 'applying app patch') + + await resyncAppState([name]) + const { [name]: initial } = await authState.keys.get('app-state-sync-version', [name]) + const { patch, state } = await encodeSyncdPatch( + patchCreate, + myAppStateKeyId, + initial, + getAppStateSyncKey, + ) + + const node: BinaryNode = { + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'set', + xmlns: 'w:sync:app:state' + }, + content: [ + { + tag: 'sync', + attrs: { }, + content: [ + { + tag: 'collection', + attrs: { + name, + version: (state.version-1).toString(), + return_snapshot: 'false' + }, + content: [ + { + tag: 'patch', + attrs: { }, + content: proto.SyncdPatch.encode(patch).finish() + } + ] + } + ] + } + ] + } + await query(node) - await authState.keys.set({ 'app-state-sync-version': { [name]: state } }) + await authState.keys.set({ 'app-state-sync-version': { [name]: state } }) - if(config.emitOwnEvents) { - const result = await decodePatches(name, [{ ...patch, version: { version: state.version }, }], initial, getAppStateSyncKey) - processSyncActions(result.newMutations) - } - } - ) - } - /** sending abt props may fix QR scan fail if server expects */ - const fetchAbt = async() => { - const abtNode = await query({ - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - xmlns: 'abt', - type: 'get', - id: generateMessageTag(), - }, - content: [ - { tag: 'props', attrs: { protocol: '1' } } - ] - }) + if(config.emitOwnEvents) { + const result = await decodePatches(name, [{ ...patch, version: { version: state.version }, }], initial, getAppStateSyncKey) + processSyncActions(result.newMutations) + } + } + ) + } - const propsNode = getBinaryNodeChild(abtNode, 'props') + /** sending abt props may fix QR scan fail if server expects */ + const fetchAbt = async() => { + const abtNode = await query({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + xmlns: 'abt', + type: 'get', + id: generateMessageTag(), + }, + content: [ + { tag: 'props', attrs: { protocol: '1' } } + ] + }) + + const propsNode = getBinaryNodeChild(abtNode, 'props') - let props: { [_: string]: string } = { } - if(propsNode) { - props = reduceBinaryNodeToDictionary(propsNode, 'prop') - } - logger.debug('fetched abt') + let props: { [_: string]: string } = { } + if(propsNode) { + props = reduceBinaryNodeToDictionary(propsNode, 'prop') + } - return props - } - /** sending non-abt props may fix QR scan fail if server expects */ - const fetchProps = async() => { - const resultNode = await query({ - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - xmlns: 'w', - type: 'get', - id: generateMessageTag(), - }, - content: [ - { tag: 'props', attrs: { } } - ] - }) + logger.debug('fetched abt') - const propsNode = getBinaryNodeChild(resultNode, 'props') + return props + } + + /** sending non-abt props may fix QR scan fail if server expects */ + const fetchProps = async() => { + const resultNode = await query({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + xmlns: 'w', + type: 'get', + id: generateMessageTag(), + }, + content: [ + { tag: 'props', attrs: { } } + ] + }) + + const propsNode = getBinaryNodeChild(resultNode, 'props') - let props: { [_: string]: string } = { } - if(propsNode) { - props = reduceBinaryNodeToDictionary(propsNode, 'prop') - } - logger.debug('fetched props') + let props: { [_: string]: string } = { } + if(propsNode) { + props = reduceBinaryNodeToDictionary(propsNode, 'prop') + } - return props - } - /** + logger.debug('fetched props') + + return props + } + + /** * modify a chat -- mark unread, read etc. * lastMessages must be sorted in reverse chronologically * requires the last messages till the last message received; required for archive & unread */ - const chatModify = (mod: ChatModification, jid: string) => { - const patch = chatModificationToAppPatch(mod, jid) - return appPatch(patch) - } + const chatModify = (mod: ChatModification, jid: string) => { + const patch = chatModificationToAppPatch(mod, jid) + return appPatch(patch) + } - ws.on('CB:presence', handlePresenceUpdate) - ws.on('CB:chatstate', handlePresenceUpdate) + ws.on('CB:presence', handlePresenceUpdate) + ws.on('CB:chatstate', handlePresenceUpdate) - ws.on('CB:ib,,dirty', async(node: BinaryNode) => { - const { attrs } = getBinaryNodeChild(node, 'dirty') - const type = attrs.type - switch(type) { - case 'account_sync': - let { lastAccountSyncTimestamp } = authState.creds - if(lastAccountSyncTimestamp) { - await updateAccountSyncTimestamp(lastAccountSyncTimestamp) - } - lastAccountSyncTimestamp = +attrs.timestamp - ev.emit('creds.update', { lastAccountSyncTimestamp }) - break - default: - logger.info({ node }, `received unknown sync`) - break - } - }) + ws.on('CB:ib,,dirty', async(node: BinaryNode) => { + const { attrs } = getBinaryNodeChild(node, 'dirty') + const type = attrs.type + switch (type) { + case 'account_sync': + let { lastAccountSyncTimestamp } = authState.creds + if(lastAccountSyncTimestamp) { + await updateAccountSyncTimestamp(lastAccountSyncTimestamp) + } - ws.on('CB:notification,type:server_sync', (node: BinaryNode) => { - const update = getBinaryNodeChild(node, 'collection') - if(update) { - const name = update.attrs.name as WAPatchName - mutationMutex.mutex( - async() => { - await resyncAppState([name]) - .catch(err => logger.error({ trace: err.stack, node }, `failed to sync state`)) - } - ) - } - }) + lastAccountSyncTimestamp = +attrs.timestamp + ev.emit('creds.update', { lastAccountSyncTimestamp }) + break + default: + logger.info({ node }, 'received unknown sync') + break + } + }) - ev.on('connection.update', ({ connection }) => { - if(connection === 'open') { - sendPresenceUpdate('available') - fetchBlocklist() - fetchPrivacySettings() - fetchAbt() - fetchProps() - } - }) + ws.on('CB:notification,type:server_sync', (node: BinaryNode) => { + const update = getBinaryNodeChild(node, 'collection') + if(update) { + const name = update.attrs.name as WAPatchName + mutationMutex.mutex( + async() => { + await resyncAppState([name]) + .catch(err => logger.error({ trace: err.stack, node }, 'failed to sync state')) + } + ) + } + }) + + ev.on('connection.update', ({ connection }) => { + if(connection === 'open') { + sendPresenceUpdate('available') + fetchBlocklist() + fetchPrivacySettings() + fetchAbt() + fetchProps() + } + }) return { ...sock, - appPatch, + appPatch, sendPresenceUpdate, presenceSubscribe, - profilePictureUrl, - onWhatsApp, - fetchBlocklist, - fetchStatus, - updateProfilePicture, - updateBlockStatus, - getBusinessProfile, - resyncAppState, - chatModify, - resyncMainAppState, + profilePictureUrl, + onWhatsApp, + fetchBlocklist, + fetchStatus, + updateProfilePicture, + updateBlockStatus, + getBusinessProfile, + resyncAppState, + chatModify, + resyncMainAppState, } } \ No newline at end of file diff --git a/src/Socket/groups.ts b/src/Socket/groups.ts index 4c8e635..b6e8097 100644 --- a/src/Socket/groups.ts +++ b/src/Socket/groups.ts @@ -1,7 +1,7 @@ -import { generateMessageID } from "../Utils"; -import { SocketConfig, GroupMetadata, ParticipantAction } from "../Types"; -import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidEncode, jidNormalizedUser } from "../WABinary"; -import { makeSocket } from "./socket"; +import { GroupMetadata, ParticipantAction, SocketConfig } from '../Types' +import { generateMessageID } from '../Utils' +import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidEncode, jidNormalizedUser } from '../WABinary' +import { makeSocket } from './socket' export const makeGroupsSocket = (config: SocketConfig) => { const sock = makeSocket(config) @@ -9,24 +9,24 @@ export const makeGroupsSocket = (config: SocketConfig) => { const groupQuery = async(jid: string, type: 'get' | 'set', content: BinaryNode[]) => ( query({ - tag: 'iq', - attrs: { - type, - xmlns: 'w:g2', - to: jid, - }, - content - }) + tag: 'iq', + attrs: { + type, + xmlns: 'w:g2', + to: jid, + }, + content + }) ) - const groupMetadata = async(jid: string) => { - const result = await groupQuery( + const groupMetadata = async(jid: string) => { + const result = await groupQuery( jid, 'get', [ { tag: 'query', attrs: { request: 'interactive' } } ] ) - return extractGroupMetadata(result) - } + return extractGroupMetadata(result) + } return { ...sock, @@ -101,8 +101,8 @@ export const makeGroupsSocket = (config: SocketConfig) => { return participantsAffected.map(p => p.attrs.jid) }, groupUpdateDescription: async(jid: string, description?: string) => { - const metadata = await groupMetadata(jid); - const prev = metadata.descId ?? null; + const metadata = await groupMetadata(jid) + const prev = metadata.descId ?? null await groupQuery( jid, @@ -111,10 +111,10 @@ export const makeGroupsSocket = (config: SocketConfig) => { { tag: 'description', attrs: { - ...( description ? { id: generateMessageID() } : { delete: 'true' } ), + ...(description ? { id: generateMessageID() } : { delete: 'true' }), ...(prev ? { prev } : {}) }, - content: description ? [{tag: 'body', attrs: {}, content: Buffer.from(description, 'utf-8')}] : null + content: description ? [{ tag: 'body', attrs: {}, content: Buffer.from(description, 'utf-8') }] : null } ] ) @@ -124,12 +124,12 @@ export const makeGroupsSocket = (config: SocketConfig) => { const inviteNode = getBinaryNodeChild(result, 'invite') return inviteNode.attrs.code }, - groupRevokeInvite: async (jid: string) => { + groupRevokeInvite: async(jid: string) => { const result = await groupQuery(jid, 'set', [{ tag: 'invite', attrs: {} }]) const inviteNode = getBinaryNodeChild(result, 'invite') return inviteNode.attrs.code }, - groupAcceptInvite: async (code: string) => { + groupAcceptInvite: async(code: string) => { const results = await groupQuery('@g.us', 'set', [{ tag: 'invite', attrs: { code } }]) const result = getBinaryNodeChild(results, 'group') return result.attrs.jid @@ -148,8 +148,8 @@ export const makeGroupsSocket = (config: SocketConfig) => { tag: 'iq', attrs: { to: '@g.us', - xmlns: 'w:g2', - type: 'get', + xmlns: 'w:g2', + type: 'get', }, content: [ { @@ -175,6 +175,7 @@ export const makeGroupsSocket = (config: SocketConfig) => { data[meta.id] = meta } } + return data } } @@ -190,6 +191,7 @@ export const extractGroupMetadata = (result: BinaryNode) => { desc = getBinaryNodeChild(descChild, 'body')?.content as string descId = descChild.attrs.id } + const groupId = group.attrs.id.includes('@') ? group.attrs.id : jidEncode(group.attrs.id, 'g.us') const eph = getBinaryNodeChild(group, 'ephemeral')?.attrs.expiration const metadata: GroupMetadata = { diff --git a/src/Socket/index.ts b/src/Socket/index.ts index e2f7f1e..b61c19e 100644 --- a/src/Socket/index.ts +++ b/src/Socket/index.ts @@ -1,5 +1,5 @@ -import { SocketConfig } from '../Types' import { DEFAULT_CONNECTION_CONFIG } from '../Defaults' +import { SocketConfig } from '../Types' import { makeMessagesRecvSocket as _makeSocket } from './messages-recv' // export the last socket layer diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index dc3119f..7146431 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -1,24 +1,25 @@ -import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata } from "../Types" -import { decodeMessageStanza, encodeBigEndian, toNumber, downloadAndProcessHistorySyncNotification, generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils" -import { BinaryNode, jidDecode, jidEncode, areJidsSameUser, getBinaryNodeChildren, jidNormalizedUser, getAllBinaryNodeChildren, BinaryNodeAttributes, isJidGroup } from '../WABinary' -import { proto } from "../../WAProto" -import { KEY_BUNDLE_TYPE } from "../Defaults" -import { makeChatsSocket } from "./chats" -import { extractGroupMetadata } from "./groups" +import { proto } from '../../WAProto' +import { KEY_BUNDLE_TYPE } from '../Defaults' +import { Chat, GroupMetadata, ParticipantAction, SocketConfig, WAMessageStubType } from '../Types' +import { decodeMessageStanza, downloadAndProcessHistorySyncNotification, encodeBigEndian, generateSignalPubKey, toNumber, xmppPreKey, xmppSignedPreKey } from '../Utils' +import { areJidsSameUser, BinaryNode, BinaryNodeAttributes, getAllBinaryNodeChildren, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser } from '../WABinary' +import { makeChatsSocket } from './chats' +import { extractGroupMetadata } from './groups' const STATUS_MAP: { [_: string]: proto.WebMessageInfo.WebMessageInfoStatus } = { - 'played': proto.WebMessageInfo.WebMessageInfoStatus.PLAYED, - 'read': proto.WebMessageInfo.WebMessageInfoStatus.READ, - 'read-self': proto.WebMessageInfo.WebMessageInfoStatus.READ + 'played': proto.WebMessageInfo.WebMessageInfoStatus.PLAYED, + 'read': proto.WebMessageInfo.WebMessageInfoStatus.READ, + 'read-self': proto.WebMessageInfo.WebMessageInfoStatus.READ } const getStatusFromReceiptType = (type: string | undefined) => { - const status = STATUS_MAP[type] - if(typeof type === 'undefined') { - return proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK - } - return status + const status = STATUS_MAP[type] + if(typeof type === 'undefined') { + return proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK + } + + return status } export const makeMessagesRecvSocket = (config: SocketConfig) => { @@ -26,477 +27,501 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const sock = makeChatsSocket(config) const { ev, - authState, + authState, ws, - assertSessions, - assertingPreKeys, + assertSessions, + assertingPreKeys, sendNode, - relayMessage, - sendReceipt, - resyncMainAppState, + relayMessage, + sendReceipt, + resyncMainAppState, } = sock - const msgRetryMap = config.msgRetryCounterMap || { } + const msgRetryMap = config.msgRetryCounterMap || { } - const historyCache = new Set() + const historyCache = new Set() - const sendMessageAck = async({ tag, attrs }: BinaryNode, extraAttrs: BinaryNodeAttributes) => { - const stanza: BinaryNode = { - tag: 'ack', - attrs: { - id: attrs.id, - to: attrs.from, - ...extraAttrs, - } - } - if(!!attrs.participant) { - stanza.attrs.participant = attrs.participant - } - logger.debug({ recv: attrs, sent: stanza.attrs }, `sent "${tag}" ack`) - await sendNode(stanza) - } + const sendMessageAck = async({ tag, attrs }: BinaryNode, extraAttrs: BinaryNodeAttributes) => { + const stanza: BinaryNode = { + tag: 'ack', + attrs: { + id: attrs.id, + to: attrs.from, + ...extraAttrs, + } + } + if(!!attrs.participant) { + stanza.attrs.participant = attrs.participant + } - const sendRetryRequest = async(node: BinaryNode) => { - const msgId = node.attrs.id - const retryCount = msgRetryMap[msgId] || 1 - if(retryCount >= 5) { - logger.debug({ retryCount, msgId }, 'reached retry limit, clearing') - delete msgRetryMap[msgId] - return - } - msgRetryMap[msgId] = retryCount+1 + logger.debug({ recv: attrs, sent: stanza.attrs }, `sent "${tag}" ack`) + await sendNode(stanza) + } - const isGroup = !!node.attrs.participant - const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds + const sendRetryRequest = async(node: BinaryNode) => { + const msgId = node.attrs.id + const retryCount = msgRetryMap[msgId] || 1 + if(retryCount >= 5) { + logger.debug({ retryCount, msgId }, 'reached retry limit, clearing') + delete msgRetryMap[msgId] + return + } + + msgRetryMap[msgId] = retryCount+1 + + const isGroup = !!node.attrs.participant + const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds - const deviceIdentity = proto.ADVSignedDeviceIdentity.encode(account).finish() - await assertingPreKeys(1, async preKeys => { - const [keyId] = Object.keys(preKeys) - const key = preKeys[+keyId] + const deviceIdentity = proto.ADVSignedDeviceIdentity.encode(account).finish() + await assertingPreKeys(1, async preKeys => { + const [keyId] = Object.keys(preKeys) + const key = preKeys[+keyId] - const decFrom = node.attrs.from ? jidDecode(node.attrs.from) : undefined - const receipt: BinaryNode = { - tag: 'receipt', - attrs: { - id: msgId, - type: 'retry', - to: isGroup ? node.attrs.from : jidEncode(decFrom!.user, 's.whatsapp.net', decFrom!.device, 0) - }, - content: [ - { - tag: 'retry', - attrs: { - count: retryCount.toString(), - id: node.attrs.id, - t: node.attrs.t, - v: '1' - } - }, - { - tag: 'registration', - attrs: { }, - content: encodeBigEndian(authState.creds.registrationId) - } - ] - } - if(node.attrs.recipient) { - receipt.attrs.recipient = node.attrs.recipient - } - if(node.attrs.participant) { - receipt.attrs.participant = node.attrs.participant - } - if(retryCount > 1) { - const exec = generateSignalPubKey(Buffer.from(KEY_BUNDLE_TYPE)).slice(0, 1); + const decFrom = node.attrs.from ? jidDecode(node.attrs.from) : undefined + const receipt: BinaryNode = { + tag: 'receipt', + attrs: { + id: msgId, + type: 'retry', + to: isGroup ? node.attrs.from : jidEncode(decFrom!.user, 's.whatsapp.net', decFrom!.device, 0) + }, + content: [ + { + tag: 'retry', + attrs: { + count: retryCount.toString(), + id: node.attrs.id, + t: node.attrs.t, + v: '1' + } + }, + { + tag: 'registration', + attrs: { }, + content: encodeBigEndian(authState.creds.registrationId) + } + ] + } + if(node.attrs.recipient) { + receipt.attrs.recipient = node.attrs.recipient + } - (receipt.content! as BinaryNode[]).push({ - tag: 'keys', - attrs: { }, - content: [ - { tag: 'type', attrs: { }, content: exec }, - { tag: 'identity', attrs: { }, content: identityKey.public }, - xmppPreKey(key, +keyId), - xmppSignedPreKey(signedPreKey), - { tag: 'device-identity', attrs: { }, content: deviceIdentity } - ] - }) - } - await sendNode(receipt) + if(node.attrs.participant) { + receipt.attrs.participant = node.attrs.participant + } - logger.info({ msgAttrs: node.attrs, retryCount }, 'sent retry receipt') - }) - } + if(retryCount > 1) { + const exec = generateSignalPubKey(Buffer.from(KEY_BUNDLE_TYPE)).slice(0, 1); - const processMessage = async(message: proto.IWebMessageInfo, chatUpdate: Partial) => { - const protocolMsg = message.message?.protocolMessage - if(protocolMsg) { - switch(protocolMsg.type) { - case proto.ProtocolMessage.ProtocolMessageType.HISTORY_SYNC_NOTIFICATION: - const histNotification = protocolMsg!.historySyncNotification + (receipt.content! as BinaryNode[]).push({ + tag: 'keys', + attrs: { }, + content: [ + { tag: 'type', attrs: { }, content: exec }, + { tag: 'identity', attrs: { }, content: identityKey.public }, + xmppPreKey(key, +keyId), + xmppSignedPreKey(signedPreKey), + { tag: 'device-identity', attrs: { }, content: deviceIdentity } + ] + }) + } + + await sendNode(receipt) + + logger.info({ msgAttrs: node.attrs, retryCount }, 'sent retry receipt') + }) + } + + const processMessage = async(message: proto.IWebMessageInfo, chatUpdate: Partial) => { + const protocolMsg = message.message?.protocolMessage + if(protocolMsg) { + switch (protocolMsg.type) { + case proto.ProtocolMessage.ProtocolMessageType.HISTORY_SYNC_NOTIFICATION: + const histNotification = protocolMsg!.historySyncNotification - logger.info({ histNotification, id: message.key.id }, 'got history notification') - const { chats, contacts, messages, isLatest } = await downloadAndProcessHistorySyncNotification(histNotification, historyCache) + logger.info({ histNotification, id: message.key.id }, 'got history notification') + const { chats, contacts, messages, isLatest } = await downloadAndProcessHistorySyncNotification(histNotification, historyCache) - const meJid = authState.creds.me!.id - await sendNode({ - tag: 'receipt', - attrs: { - id: message.key.id, - type: 'hist_sync', - to: jidEncode(jidDecode(meJid).user, 'c.us') - } - }) + const meJid = authState.creds.me!.id + await sendNode({ + tag: 'receipt', + attrs: { + id: message.key.id, + type: 'hist_sync', + to: jidEncode(jidDecode(meJid).user, 'c.us') + } + }) - if(chats.length) ev.emit('chats.set', { chats, isLatest }) - if(messages.length) ev.emit('messages.set', { messages, isLatest }) - if(contacts.length) ev.emit('contacts.set', { contacts }) + if(chats.length) { + ev.emit('chats.set', { chats, isLatest }) + } - break - case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_SHARE: - const keys = protocolMsg.appStateSyncKeyShare!.keys - if(keys?.length) { - let newAppStateSyncKeyId = '' - for(const { keyData, keyId } of keys) { - const strKeyId = Buffer.from(keyId.keyId!).toString('base64') + if(messages.length) { + ev.emit('messages.set', { messages, isLatest }) + } + + if(contacts.length) { + ev.emit('contacts.set', { contacts }) + } + + break + case proto.ProtocolMessage.ProtocolMessageType.APP_STATE_SYNC_KEY_SHARE: + const keys = protocolMsg.appStateSyncKeyShare!.keys + if(keys?.length) { + let newAppStateSyncKeyId = '' + for(const { keyData, keyId } of keys) { + const strKeyId = Buffer.from(keyId.keyId!).toString('base64') - logger.info({ strKeyId }, 'injecting new app state sync key') - await authState.keys.set({ 'app-state-sync-key': { [strKeyId]: keyData } }) + logger.info({ strKeyId }, 'injecting new app state sync key') + await authState.keys.set({ 'app-state-sync-key': { [strKeyId]: keyData } }) - newAppStateSyncKeyId = strKeyId - } + newAppStateSyncKeyId = strKeyId + } - ev.emit('creds.update', { myAppStateKeyId: newAppStateSyncKeyId }) + ev.emit('creds.update', { myAppStateKeyId: newAppStateSyncKeyId }) - resyncMainAppState() - } else [ - logger.info({ protocolMsg }, 'recv app state sync with 0 keys') - ] - break - case proto.ProtocolMessage.ProtocolMessageType.REVOKE: - ev.emit('messages.update', [ - { - key: { - ...message.key, - id: protocolMsg.key!.id - }, - update: { message: null, messageStubType: WAMessageStubType.REVOKE, key: message.key } - } - ]) - break - case proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING: - chatUpdate.ephemeralSettingTimestamp = toNumber(message.messageTimestamp) - chatUpdate.ephemeralExpiration = protocolMsg.ephemeralExpiration || null - break - } - } else if(message.messageStubType) { - const meJid = authState.creds.me!.id - const jid = message.key!.remoteJid! - //let actor = whatsappID (message.participant) - let participants: string[] - const emitParticipantsUpdate = (action: ParticipantAction) => ( - ev.emit('group-participants.update', { id: jid, participants, action }) - ) - const emitGroupUpdate = (update: Partial) => { - ev.emit('groups.update', [ { id: jid, ...update } ]) - } + resyncMainAppState() + } else { + [ + logger.info({ protocolMsg }, 'recv app state sync with 0 keys') + ] + } - switch (message.messageStubType) { - case WAMessageStubType.GROUP_PARTICIPANT_LEAVE: - case WAMessageStubType.GROUP_PARTICIPANT_REMOVE: - participants = message.messageStubParameters - emitParticipantsUpdate('remove') - // mark the chat read only if you left the group - if(participants.includes(meJid)) { - chatUpdate.readOnly = true - } - break - case WAMessageStubType.GROUP_PARTICIPANT_ADD: - case WAMessageStubType.GROUP_PARTICIPANT_INVITE: - case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN: - participants = message.messageStubParameters - if (participants.includes(meJid)) { - chatUpdate.readOnly = false - } - emitParticipantsUpdate('add') - break - case WAMessageStubType.GROUP_CHANGE_ANNOUNCE: - const announceValue = message.messageStubParameters[0] - emitGroupUpdate({ announce: announceValue === 'true' || announceValue === 'on' }) - break - case WAMessageStubType.GROUP_CHANGE_RESTRICT: - const restrictValue = message.messageStubParameters[0] - emitGroupUpdate({ restrict: restrictValue === 'true' || restrictValue === 'on' }) - break - case WAMessageStubType.GROUP_CHANGE_SUBJECT: - chatUpdate.name = message.messageStubParameters[0] - emitGroupUpdate({ subject: chatUpdate.name }) - break - } - } - } + break + case proto.ProtocolMessage.ProtocolMessageType.REVOKE: + ev.emit('messages.update', [ + { + key: { + ...message.key, + id: protocolMsg.key!.id + }, + update: { message: null, messageStubType: WAMessageStubType.REVOKE, key: message.key } + } + ]) + break + case proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING: + chatUpdate.ephemeralSettingTimestamp = toNumber(message.messageTimestamp) + chatUpdate.ephemeralExpiration = protocolMsg.ephemeralExpiration || null + break + } + } else if(message.messageStubType) { + const meJid = authState.creds.me!.id + const jid = message.key!.remoteJid! + //let actor = whatsappID (message.participant) + let participants: string[] + const emitParticipantsUpdate = (action: ParticipantAction) => ( + ev.emit('group-participants.update', { id: jid, participants, action }) + ) + const emitGroupUpdate = (update: Partial) => { + ev.emit('groups.update', [ { id: jid, ...update } ]) + } - const processNotification = (node: BinaryNode): Partial => { - const result: Partial = { } - const [child] = getAllBinaryNodeChildren(node) + switch (message.messageStubType) { + case WAMessageStubType.GROUP_PARTICIPANT_LEAVE: + case WAMessageStubType.GROUP_PARTICIPANT_REMOVE: + participants = message.messageStubParameters + emitParticipantsUpdate('remove') + // mark the chat read only if you left the group + if(participants.includes(meJid)) { + chatUpdate.readOnly = true + } - if(node.attrs.type === 'w:gp2') { - switch(child?.tag) { - case 'create': - const metadata = extractGroupMetadata(child) + break + case WAMessageStubType.GROUP_PARTICIPANT_ADD: + case WAMessageStubType.GROUP_PARTICIPANT_INVITE: + case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN: + participants = message.messageStubParameters + if(participants.includes(meJid)) { + chatUpdate.readOnly = false + } - result.messageStubType = WAMessageStubType.GROUP_CREATE - result.messageStubParameters = [metadata.subject] - result.key = { participant: metadata.owner } + emitParticipantsUpdate('add') + break + case WAMessageStubType.GROUP_CHANGE_ANNOUNCE: + const announceValue = message.messageStubParameters[0] + emitGroupUpdate({ announce: announceValue === 'true' || announceValue === 'on' }) + break + case WAMessageStubType.GROUP_CHANGE_RESTRICT: + const restrictValue = message.messageStubParameters[0] + emitGroupUpdate({ restrict: restrictValue === 'true' || restrictValue === 'on' }) + break + case WAMessageStubType.GROUP_CHANGE_SUBJECT: + chatUpdate.name = message.messageStubParameters[0] + emitGroupUpdate({ subject: chatUpdate.name }) + break + } + } + } - ev.emit('chats.upsert', [{ - id: metadata.id, - name: metadata.subject, - conversationTimestamp: metadata.creation, - }]) - ev.emit('groups.upsert', [metadata]) - break - case 'ephemeral': - case 'not_ephemeral': - result.message = { - protocolMessage: { - type: proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING, - ephemeralExpiration: +(child.attrs.expiration || 0) - } - } - break - case 'promote': - case 'demote': - case 'remove': - case 'add': - case 'leave': - const stubType = `GROUP_PARTICIPANT_${child.tag!.toUpperCase()}` - result.messageStubType = WAMessageStubType[stubType] + const processNotification = (node: BinaryNode): Partial => { + const result: Partial = { } + const [child] = getAllBinaryNodeChildren(node) - const participants = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid) - if( - participants.length === 1 && + if(node.attrs.type === 'w:gp2') { + switch (child?.tag) { + case 'create': + const metadata = extractGroupMetadata(child) + + result.messageStubType = WAMessageStubType.GROUP_CREATE + result.messageStubParameters = [metadata.subject] + result.key = { participant: metadata.owner } + + ev.emit('chats.upsert', [{ + id: metadata.id, + name: metadata.subject, + conversationTimestamp: metadata.creation, + }]) + ev.emit('groups.upsert', [metadata]) + break + case 'ephemeral': + case 'not_ephemeral': + result.message = { + protocolMessage: { + type: proto.ProtocolMessage.ProtocolMessageType.EPHEMERAL_SETTING, + ephemeralExpiration: +(child.attrs.expiration || 0) + } + } + break + case 'promote': + case 'demote': + case 'remove': + case 'add': + case 'leave': + const stubType = `GROUP_PARTICIPANT_${child.tag!.toUpperCase()}` + result.messageStubType = WAMessageStubType[stubType] + + const participants = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid) + if( + participants.length === 1 && // if recv. "remove" message and sender removed themselves // mark as left areJidsSameUser(participants[0], node.attrs.participant) && child.tag === 'remove' - ) { - result.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_LEAVE - } - result.messageStubParameters = participants - break - case 'subject': - result.messageStubType = WAMessageStubType.GROUP_CHANGE_SUBJECT - result.messageStubParameters = [ child.attrs.subject ] - break - case 'announcement': - case 'not_announcement': - result.messageStubType = WAMessageStubType.GROUP_CHANGE_ANNOUNCE - result.messageStubParameters = [ (child.tag === 'announcement') ? 'on' : 'off' ] - break - case 'locked': - case 'unlocked': - result.messageStubType = WAMessageStubType.GROUP_CHANGE_RESTRICT - result.messageStubParameters = [ (child.tag === 'locked') ? 'on' : 'off' ] - break + ) { + result.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_LEAVE + } + + result.messageStubParameters = participants + break + case 'subject': + result.messageStubType = WAMessageStubType.GROUP_CHANGE_SUBJECT + result.messageStubParameters = [ child.attrs.subject ] + break + case 'announcement': + case 'not_announcement': + result.messageStubType = WAMessageStubType.GROUP_CHANGE_ANNOUNCE + result.messageStubParameters = [ (child.tag === 'announcement') ? 'on' : 'off' ] + break + case 'locked': + case 'unlocked': + result.messageStubType = WAMessageStubType.GROUP_CHANGE_RESTRICT + result.messageStubParameters = [ (child.tag === 'locked') ? 'on' : 'off' ] + break - } - } else { - switch(child.tag) { - case 'devices': - const devices = getBinaryNodeChildren(child, 'device') - if(areJidsSameUser(child.attrs.jid, authState.creds!.me!.id)) { - const deviceJids = devices.map(d => d.attrs.jid) - logger.info({ deviceJids }, 'got my own devices') - } - break - } - } - if(Object.keys(result).length) { - return result - } - } - // recv a message - ws.on('CB:message', async(stanza: BinaryNode) => { - const msg = await decodeMessageStanza(stanza, authState) - // message failed to decrypt - if(msg.messageStubType === proto.WebMessageInfo.WebMessageInfoStubType.CIPHERTEXT) { - logger.error( - { msgId: msg.key.id, params: msg.messageStubParameters }, - 'failure in decrypting message' - ) - await sendRetryRequest(stanza) - } else { - await sendMessageAck(stanza, { class: 'receipt' }) - // no type in the receipt => message delivered - await sendReceipt(msg.key.remoteJid!, msg.key.participant, [msg.key.id!], undefined) - logger.debug({ msg: msg.key }, 'sent delivery receipt') - } + } + } else { + switch (child.tag) { + case 'devices': + const devices = getBinaryNodeChildren(child, 'device') + if(areJidsSameUser(child.attrs.jid, authState.creds!.me!.id)) { + const deviceJids = devices.map(d => d.attrs.jid) + logger.info({ deviceJids }, 'got my own devices') + } + + break + } + } + + if(Object.keys(result).length) { + return result + } + } + + // recv a message + ws.on('CB:message', async(stanza: BinaryNode) => { + const msg = await decodeMessageStanza(stanza, authState) + // message failed to decrypt + if(msg.messageStubType === proto.WebMessageInfo.WebMessageInfoStubType.CIPHERTEXT) { + logger.error( + { msgId: msg.key.id, params: msg.messageStubParameters }, + 'failure in decrypting message' + ) + await sendRetryRequest(stanza) + } else { + await sendMessageAck(stanza, { class: 'receipt' }) + // no type in the receipt => message delivered + await sendReceipt(msg.key.remoteJid!, msg.key.participant, [msg.key.id!], undefined) + logger.debug({ msg: msg.key }, 'sent delivery receipt') + } - msg.key.remoteJid = jidNormalizedUser(msg.key.remoteJid!) - ev.emit('messages.upsert', { messages: [msg], type: stanza.attrs.offline ? 'append' : 'notify' }) - }) + msg.key.remoteJid = jidNormalizedUser(msg.key.remoteJid!) + ev.emit('messages.upsert', { messages: [msg], type: stanza.attrs.offline ? 'append' : 'notify' }) + }) - ws.on('CB:ack,class:message', async(node: BinaryNode) => { - await sendNode({ - tag: 'ack', - attrs: { - class: 'receipt', - id: node.attrs.id, - from: node.attrs.from - } - }) - logger.debug({ attrs: node.attrs }, 'sending receipt for ack') - }) + ws.on('CB:ack,class:message', async(node: BinaryNode) => { + await sendNode({ + tag: 'ack', + attrs: { + class: 'receipt', + id: node.attrs.id, + from: node.attrs.from + } + }) + logger.debug({ attrs: node.attrs }, 'sending receipt for ack') + }) - ws.on('CB:call', async(node: BinaryNode) => { - logger.info({ node }, 'recv call') + ws.on('CB:call', async(node: BinaryNode) => { + logger.info({ node }, 'recv call') - const [child] = getAllBinaryNodeChildren(node) - if(!!child?.tag) { - await sendMessageAck(node, { class: 'call', type: child.tag }) - } - }) + const [child] = getAllBinaryNodeChildren(node) + if(!!child?.tag) { + await sendMessageAck(node, { class: 'call', type: child.tag }) + } + }) - const sendMessagesAgain = async(key: proto.IMessageKey, ids: string[]) => { - const msgs = await Promise.all( - ids.map(id => ( - config.getMessage({ ...key, id }) - )) - ) + const sendMessagesAgain = async(key: proto.IMessageKey, ids: string[]) => { + const msgs = await Promise.all( + ids.map(id => ( + config.getMessage({ ...key, id }) + )) + ) - const participant = key.participant || key.remoteJid - await assertSessions([participant], true) + const participant = key.participant || key.remoteJid + await assertSessions([participant], true) - if(isJidGroup(key.remoteJid)) { - await authState.keys.set({ 'sender-key-memory': { [key.remoteJid]: null } }) - } + if(isJidGroup(key.remoteJid)) { + await authState.keys.set({ 'sender-key-memory': { [key.remoteJid]: null } }) + } - logger.debug({ participant }, 'forced new session for retry recp') + logger.debug({ participant }, 'forced new session for retry recp') - for(let i = 0; i < msgs.length;i++) { - if(msgs[i]) { - await relayMessage(key.remoteJid, msgs[i], { - messageId: ids[i], - participant - }) - } else { - logger.debug({ jid: key.remoteJid, id: ids[i] }, 'recv retry request, but message not available') - } - } - } + for(let i = 0; i < msgs.length;i++) { + if(msgs[i]) { + await relayMessage(key.remoteJid, msgs[i], { + messageId: ids[i], + participant + }) + } else { + logger.debug({ jid: key.remoteJid, id: ids[i] }, 'recv retry request, but message not available') + } + } + } - const handleReceipt = async(node: BinaryNode) => { - let shouldAck = true + const handleReceipt = async(node: BinaryNode) => { + let shouldAck = true - const { attrs, content } = node - const isNodeFromMe = areJidsSameUser(attrs.participant || attrs.from, authState.creds.me?.id) - const remoteJid = !isNodeFromMe ? attrs.from : attrs.recipient - const fromMe = !attrs.recipient + const { attrs, content } = node + const isNodeFromMe = areJidsSameUser(attrs.participant || attrs.from, authState.creds.me?.id) + const remoteJid = !isNodeFromMe ? attrs.from : attrs.recipient + const fromMe = !attrs.recipient - const ids = [attrs.id] - if(Array.isArray(content)) { - const items = getBinaryNodeChildren(content[0], 'item') - ids.push(...items.map(i => i.attrs.id)) - } + const ids = [attrs.id] + if(Array.isArray(content)) { + const items = getBinaryNodeChildren(content[0], 'item') + ids.push(...items.map(i => i.attrs.id)) + } - const key: proto.IMessageKey = { - remoteJid, - id: '', - fromMe, - participant: attrs.participant - } + const key: proto.IMessageKey = { + remoteJid, + id: '', + fromMe, + participant: attrs.participant + } - const status = getStatusFromReceiptType(attrs.type) - if( - typeof status !== 'undefined' && + const status = getStatusFromReceiptType(attrs.type) + if( + typeof status !== 'undefined' && ( - // basically, we only want to know when a message from us has been delivered to/read by the other person - // or another device of ours has read some messages - status > proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK || + // basically, we only want to know when a message from us has been delivered to/read by the other person + // or another device of ours has read some messages + status > proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK || !isNodeFromMe ) - ) { - ev.emit('messages.update', ids.map(id => ({ - key: { ...key, id }, - update: { status } - }))) - } + ) { + ev.emit('messages.update', ids.map(id => ({ + key: { ...key, id }, + update: { status } + }))) + } - if(attrs.type === 'retry') { - // correctly set who is asking for the retry - key.participant = key.participant || attrs.from - if(key.fromMe) { - try { - logger.debug({ attrs }, 'recv retry request') - await sendMessagesAgain(key, ids) - } catch(error) { - logger.error({ key, ids, trace: error.stack }, 'error in sending message again') - shouldAck = false - } - } else { - logger.info({ attrs, key }, 'recv retry for not fromMe message') - } - } + if(attrs.type === 'retry') { + // correctly set who is asking for the retry + key.participant = key.participant || attrs.from + if(key.fromMe) { + try { + logger.debug({ attrs }, 'recv retry request') + await sendMessagesAgain(key, ids) + } catch(error) { + logger.error({ key, ids, trace: error.stack }, 'error in sending message again') + shouldAck = false + } + } else { + logger.info({ attrs, key }, 'recv retry for not fromMe message') + } + } - if(shouldAck) { - await sendMessageAck(node, { class: 'receipt', type: attrs.type }) - } + if(shouldAck) { + await sendMessageAck(node, { class: 'receipt', type: attrs.type }) + } - } + } - ws.on('CB:receipt', handleReceipt) + ws.on('CB:receipt', handleReceipt) - ws.on('CB:notification', async(node: BinaryNode) => { - await sendMessageAck(node, { class: 'notification', type: node.attrs.type }) + ws.on('CB:notification', async(node: BinaryNode) => { + await sendMessageAck(node, { class: 'notification', type: node.attrs.type }) - const msg = processNotification(node) - if(msg) { - const fromMe = areJidsSameUser(node.attrs.participant || node.attrs.from, authState.creds.me!.id) - msg.key = { - remoteJid: node.attrs.from, - fromMe, - participant: node.attrs.participant, - id: node.attrs.id, - ...(msg.key || {}) - } - msg.messageTimestamp = +node.attrs.t + const msg = processNotification(node) + if(msg) { + const fromMe = areJidsSameUser(node.attrs.participant || node.attrs.from, authState.creds.me!.id) + msg.key = { + remoteJid: node.attrs.from, + fromMe, + participant: node.attrs.participant, + id: node.attrs.id, + ...(msg.key || {}) + } + msg.messageTimestamp = +node.attrs.t - const fullMsg = proto.WebMessageInfo.fromObject(msg) - ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) - } - }) + const fullMsg = proto.WebMessageInfo.fromObject(msg) + ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) + } + }) - ev.on('messages.upsert', async({ messages, type }) => { - if(type === 'notify' || type === 'append') { - const chat: Partial = { id: messages[0].key.remoteJid } - const contactNameUpdates: { [_: string]: string } = { } - for(const msg of messages) { - if(!!msg.pushName) { - const jid = msg.key.fromMe ? jidNormalizedUser(authState.creds.me!.id) : (msg.key.participant || msg.key.remoteJid) - contactNameUpdates[jid] = msg.pushName - // update our pushname too - if(msg.key.fromMe && authState.creds.me?.name !== msg.pushName) { - ev.emit('creds.update', { me: { ...authState.creds.me!, name: msg.pushName! } }) - } - } + ev.on('messages.upsert', async({ messages, type }) => { + if(type === 'notify' || type === 'append') { + const chat: Partial = { id: messages[0].key.remoteJid } + const contactNameUpdates: { [_: string]: string } = { } + for(const msg of messages) { + if(!!msg.pushName) { + const jid = msg.key.fromMe ? jidNormalizedUser(authState.creds.me!.id) : (msg.key.participant || msg.key.remoteJid) + contactNameUpdates[jid] = msg.pushName + // update our pushname too + if(msg.key.fromMe && authState.creds.me?.name !== msg.pushName) { + ev.emit('creds.update', { me: { ...authState.creds.me!, name: msg.pushName! } }) + } + } - await processMessage(msg, chat) - if(!!msg.message && !msg.message!.protocolMessage) { - chat.conversationTimestamp = toNumber(msg.messageTimestamp) - if(!msg.key.fromMe) { - chat.unreadCount = (chat.unreadCount || 0) + 1 - } - } - } - if(Object.keys(chat).length > 1) { - ev.emit('chats.update', [ chat ]) - } - if(Object.keys(contactNameUpdates).length) { - ev.emit('contacts.update', Object.keys(contactNameUpdates).map( - id => ({ id, notify: contactNameUpdates[id] }) - )) - } - } - }) + await processMessage(msg, chat) + if(!!msg.message && !msg.message!.protocolMessage) { + chat.conversationTimestamp = toNumber(msg.messageTimestamp) + if(!msg.key.fromMe) { + chat.unreadCount = (chat.unreadCount || 0) + 1 + } + } + } + + if(Object.keys(chat).length > 1) { + ev.emit('chats.update', [ chat ]) + } + + if(Object.keys(contactNameUpdates).length) { + ev.emit('contacts.update', Object.keys(contactNameUpdates).map( + id => ({ id, notify: contactNameUpdates[id] }) + )) + } + } + }) return { ...sock, processMessage, sendMessageAck, sendRetryRequest } } diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 22eaf1f..e6b0cfd 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -1,439 +1,452 @@ -import { SocketConfig, MediaConnInfo, AnyMessageContent, MiscMessageGenerationOptions, WAMediaUploadFunction, MessageRelayOptions } from "../Types" -import { encodeWAMessage, generateMessageID, generateWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, jidToSignalProtocolAddress, parseAndInjectE2ESessions, getWAUploadToServer } from "../Utils" -import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, S_WHATSAPP_NET, BinaryNodeAttributes, JidWithDevice, reduceBinaryNodeToDictionary } from '../WABinary' -import { proto } from "../../WAProto" -import { WA_DEFAULT_EPHEMERAL } from "../Defaults" -import { makeGroupsSocket } from "./groups" -import NodeCache from "node-cache" +import NodeCache from 'node-cache' +import { proto } from '../../WAProto' +import { WA_DEFAULT_EPHEMERAL } from '../Defaults' +import { AnyMessageContent, MediaConnInfo, MessageRelayOptions, MiscMessageGenerationOptions, SocketConfig } from '../Types' +import { encodeWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, generateMessageID, generateWAMessage, getWAUploadToServer, jidToSignalProtocolAddress, parseAndInjectE2ESessions } from '../Utils' +import { BinaryNode, BinaryNodeAttributes, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser, JidWithDevice, reduceBinaryNodeToDictionary, S_WHATSAPP_NET } from '../WABinary' +import { makeGroupsSocket } from './groups' export const makeMessagesSocket = (config: SocketConfig) => { const { logger } = config const sock = makeGroupsSocket(config) const { ev, - authState, - query, - generateMessageTag, + authState, + query, + generateMessageTag, sendNode, - groupMetadata, - groupToggleEphemeral + groupMetadata, + groupToggleEphemeral } = sock - const userDevicesCache = config.userDevicesCache || new NodeCache({ - stdTTL: 300, // 5 minutes - useClones: false - }) - let privacySettings: { [_: string]: string } | undefined + const userDevicesCache = config.userDevicesCache || new NodeCache({ + stdTTL: 300, // 5 minutes + useClones: false + }) + let privacySettings: { [_: string]: string } | undefined - const fetchPrivacySettings = async(force: boolean = false) => { - if(!privacySettings || force) { - const { content } = await query({ - tag: 'iq', - attrs: { - xmlns: 'privacy', - to: S_WHATSAPP_NET, - type: 'get' - }, - content: [ - { tag: 'privacy', attrs: { } } - ] - }) - privacySettings = reduceBinaryNodeToDictionary(content[0] as BinaryNode, 'category') - } - return privacySettings - } + const fetchPrivacySettings = async(force: boolean = false) => { + if(!privacySettings || force) { + const { content } = await query({ + tag: 'iq', + attrs: { + xmlns: 'privacy', + to: S_WHATSAPP_NET, + type: 'get' + }, + content: [ + { tag: 'privacy', attrs: { } } + ] + }) + privacySettings = reduceBinaryNodeToDictionary(content[0] as BinaryNode, 'category') + } - let mediaConn: Promise - const refreshMediaConn = async(forceGet = false) => { - let media = await mediaConn - if (!media || forceGet || (new Date().getTime()-media.fetchDate.getTime()) > media.ttl*1000) { + return privacySettings + } + + let mediaConn: Promise + const refreshMediaConn = async(forceGet = false) => { + const media = await mediaConn + if(!media || forceGet || (new Date().getTime()-media.fetchDate.getTime()) > media.ttl*1000) { mediaConn = (async() => { const result = await query({ - tag: 'iq', - attrs: { - type: 'set', - xmlns: 'w:m', - to: S_WHATSAPP_NET, - }, - content: [ { tag: 'media_conn', attrs: { } } ] - }) - const mediaConnNode = getBinaryNodeChild(result, 'media_conn') - const node: MediaConnInfo = { - hosts: getBinaryNodeChildren(mediaConnNode, 'host').map( - item => item.attrs as any - ), - auth: mediaConnNode.attrs.auth, - ttl: +mediaConnNode.attrs.ttl, - fetchDate: new Date() - } - logger.debug('fetched media conn') + tag: 'iq', + attrs: { + type: 'set', + xmlns: 'w:m', + to: S_WHATSAPP_NET, + }, + content: [ { tag: 'media_conn', attrs: { } } ] + }) + const mediaConnNode = getBinaryNodeChild(result, 'media_conn') + const node: MediaConnInfo = { + hosts: getBinaryNodeChildren(mediaConnNode, 'host').map( + item => item.attrs as any + ), + auth: mediaConnNode.attrs.auth, + ttl: +mediaConnNode.attrs.ttl, + fetchDate: new Date() + } + logger.debug('fetched media conn') return node })() - } - return mediaConn - } - /** + } + + return mediaConn + } + + /** * generic send receipt function * used for receipts of phone call, read, delivery etc. * */ - const sendReceipt = async(jid: string, participant: string | undefined, messageIds: string[], type: 'read' | 'read-self' | undefined) => { - const node: BinaryNode = { - tag: 'receipt', - attrs: { - id: messageIds[0], - t: Date.now().toString(), - to: jid, - }, - } - if(type) { - node.attrs.type = type - } - if(participant) { - node.attrs.participant = participant - } - const remainingMessageIds = messageIds.slice(1) - if(remainingMessageIds.length) { - node.content = [ - { - tag: 'list', - attrs: { }, - content: remainingMessageIds.map(id => ({ - tag: 'item', - attrs: { id } - })) - } - ] - } + const sendReceipt = async(jid: string, participant: string | undefined, messageIds: string[], type: 'read' | 'read-self' | undefined) => { + const node: BinaryNode = { + tag: 'receipt', + attrs: { + id: messageIds[0], + t: Date.now().toString(), + to: jid, + }, + } + if(type) { + node.attrs.type = type + } - logger.debug({ jid, messageIds, type }, 'sending receipt for messages') - await sendNode(node) - } + if(participant) { + node.attrs.participant = participant + } - const sendReadReceipt = async(jid: string, participant: string | undefined, messageIds: string[]) => { - const privacySettings = await fetchPrivacySettings() - // based on privacy settings, we have to change the read type - const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self' - return sendReceipt(jid, participant, messageIds, readType) - } + const remainingMessageIds = messageIds.slice(1) + if(remainingMessageIds.length) { + node.content = [ + { + tag: 'list', + attrs: { }, + content: remainingMessageIds.map(id => ({ + tag: 'item', + attrs: { id } + })) + } + ] + } - const getUSyncDevices = async(jids: string[], ignoreZeroDevices: boolean) => { - const deviceResults: JidWithDevice[] = [] + logger.debug({ jid, messageIds, type }, 'sending receipt for messages') + await sendNode(node) + } + + const sendReadReceipt = async(jid: string, participant: string | undefined, messageIds: string[]) => { + const privacySettings = await fetchPrivacySettings() + // based on privacy settings, we have to change the read type + const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self' + return sendReceipt(jid, participant, messageIds, readType) + } + + const getUSyncDevices = async(jids: string[], ignoreZeroDevices: boolean) => { + const deviceResults: JidWithDevice[] = [] - const users: BinaryNode[] = [] - jids = Array.from(new Set(jids)) - for(let jid of jids) { - const user = jidDecode(jid).user - jid = jidNormalizedUser(jid) - if(userDevicesCache.has(user)) { - const devices: JidWithDevice[] = userDevicesCache.get(user) - deviceResults.push(...devices) + const users: BinaryNode[] = [] + jids = Array.from(new Set(jids)) + for(let jid of jids) { + const user = jidDecode(jid).user + jid = jidNormalizedUser(jid) + if(userDevicesCache.has(user)) { + const devices: JidWithDevice[] = userDevicesCache.get(user) + deviceResults.push(...devices) - logger.trace({ user }, 'using cache for devices') - } else { - users.push({ tag: 'user', attrs: { jid } }) - } - } + logger.trace({ user }, 'using cache for devices') + } else { + users.push({ tag: 'user', attrs: { jid } }) + } + } - const iq: BinaryNode = { - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - type: 'get', - xmlns: 'usync', - }, - content: [ - { - tag: 'usync', - attrs: { - sid: generateMessageTag(), - mode: 'query', - last: 'true', - index: '0', - context: 'message', - }, - content: [ - { - tag: 'query', - attrs: { }, - content: [ - { - tag: 'devices', - attrs: { version: '2' } - } - ] - }, - { tag: 'list', attrs: { }, content: users } - ] - }, - ], - } - const result = await query(iq) - const extracted = extractDeviceJids(result, authState.creds.me!.id, ignoreZeroDevices) - const deviceMap: { [_: string]: JidWithDevice[] } = {} + const iq: BinaryNode = { + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'get', + xmlns: 'usync', + }, + content: [ + { + tag: 'usync', + attrs: { + sid: generateMessageTag(), + mode: 'query', + last: 'true', + index: '0', + context: 'message', + }, + content: [ + { + tag: 'query', + attrs: { }, + content: [ + { + tag: 'devices', + attrs: { version: '2' } + } + ] + }, + { tag: 'list', attrs: { }, content: users } + ] + }, + ], + } + const result = await query(iq) + const extracted = extractDeviceJids(result, authState.creds.me!.id, ignoreZeroDevices) + const deviceMap: { [_: string]: JidWithDevice[] } = {} - for(const item of extracted) { - deviceMap[item.user] = deviceMap[item.user] || [] - deviceMap[item.user].push(item) + for(const item of extracted) { + deviceMap[item.user] = deviceMap[item.user] || [] + deviceMap[item.user].push(item) - deviceResults.push(item) - } + deviceResults.push(item) + } - for(const key in deviceMap) { - userDevicesCache.set(key, deviceMap[key]) - } + for(const key in deviceMap) { + userDevicesCache.set(key, deviceMap[key]) + } - return deviceResults - } + return deviceResults + } - const assertSessions = async(jids: string[], force: boolean) => { - let jidsRequiringFetch: string[] = [] - if(force) { - jidsRequiringFetch = jids - } else { - const addrs = jids.map(jid => jidToSignalProtocolAddress(jid).toString()) - const sessions = await authState.keys.get('session', addrs) - for(const jid of jids) { - const signalId = jidToSignalProtocolAddress(jid).toString() - if(!sessions[signalId]) { - jidsRequiringFetch.push(jid) - } - } - } + const assertSessions = async(jids: string[], force: boolean) => { + let jidsRequiringFetch: string[] = [] + if(force) { + jidsRequiringFetch = jids + } else { + const addrs = jids.map(jid => jidToSignalProtocolAddress(jid).toString()) + const sessions = await authState.keys.get('session', addrs) + for(const jid of jids) { + const signalId = jidToSignalProtocolAddress(jid).toString() + if(!sessions[signalId]) { + jidsRequiringFetch.push(jid) + } + } + } - if(jidsRequiringFetch.length) { - logger.debug({ jidsRequiringFetch }, `fetching sessions`) - const result = await query({ - tag: 'iq', - attrs: { - xmlns: 'encrypt', - type: 'get', - to: S_WHATSAPP_NET, - }, - content: [ - { - tag: 'key', - attrs: { }, - content: jidsRequiringFetch.map( - jid => ({ - tag: 'user', - attrs: { jid, reason: 'identity' }, - }) - ) - } - ] - }) - await parseAndInjectE2ESessions(result, authState) - return true - } - return false - } + if(jidsRequiringFetch.length) { + logger.debug({ jidsRequiringFetch }, 'fetching sessions') + const result = await query({ + tag: 'iq', + attrs: { + xmlns: 'encrypt', + type: 'get', + to: S_WHATSAPP_NET, + }, + content: [ + { + tag: 'key', + attrs: { }, + content: jidsRequiringFetch.map( + jid => ({ + tag: 'user', + attrs: { jid, reason: 'identity' }, + }) + ) + } + ] + }) + await parseAndInjectE2ESessions(result, authState) + return true + } - const createParticipantNodes = async(jids: string[], bytes: Buffer) => { - await assertSessions(jids, false) + return false + } - if(authState.keys.isInTransaction()) { - await authState.keys.prefetch( - 'session', - jids.map(jid => jidToSignalProtocolAddress(jid).toString()) - ) - } + const createParticipantNodes = async(jids: string[], bytes: Buffer) => { + await assertSessions(jids, false) + + if(authState.keys.isInTransaction()) { + await authState.keys.prefetch( + 'session', + jids.map(jid => jidToSignalProtocolAddress(jid).toString()) + ) + } - const nodes = await Promise.all( - jids.map( - async jid => { - const { type, ciphertext } = await encryptSignalProto(jid, bytes, authState) - const node: BinaryNode = { - tag: 'to', - attrs: { jid }, - content: [{ - tag: 'enc', - attrs: { v: '2', type }, - content: ciphertext - }] - } - return node - } - ) - ) - return nodes - } + const nodes = await Promise.all( + jids.map( + async jid => { + const { type, ciphertext } = await encryptSignalProto(jid, bytes, authState) + const node: BinaryNode = { + tag: 'to', + attrs: { jid }, + content: [{ + tag: 'enc', + attrs: { v: '2', type }, + content: ciphertext + }] + } + return node + } + ) + ) + return nodes + } - const relayMessage = async( - jid: string, - message: proto.IMessage, - { messageId: msgId, participant, additionalAttributes, cachedGroupMetadata }: MessageRelayOptions - ) => { - const meId = authState.creds.me!.id + const relayMessage = async( + jid: string, + message: proto.IMessage, + { messageId: msgId, participant, additionalAttributes, cachedGroupMetadata }: MessageRelayOptions + ) => { + const meId = authState.creds.me!.id - const { user, server } = jidDecode(jid) - const isGroup = server === 'g.us' - msgId = msgId || generateMessageID() + const { user, server } = jidDecode(jid) + const isGroup = server === 'g.us' + msgId = msgId || generateMessageID() - const encodedMsg = encodeWAMessage(message) - const participants: BinaryNode[] = [] + const encodedMsg = encodeWAMessage(message) + const participants: BinaryNode[] = [] - const destinationJid = jidEncode(user, isGroup ? 'g.us' : 's.whatsapp.net') + const destinationJid = jidEncode(user, isGroup ? 'g.us' : 's.whatsapp.net') - const binaryNodeContent: BinaryNode[] = [] + const binaryNodeContent: BinaryNode[] = [] - const devices: JidWithDevice[] = [] - if(participant) { - const { user, device } = jidDecode(participant) - devices.push({ user, device }) - } + const devices: JidWithDevice[] = [] + if(participant) { + const { user, device } = jidDecode(participant) + devices.push({ user, device }) + } - await authState.keys.transaction( - async() => { - if(isGroup) { - const { ciphertext, senderKeyDistributionMessageKey } = await encryptSenderKeyMsgSignalProto(destinationJid, encodedMsg, meId, authState) + await authState.keys.transaction( + async() => { + if(isGroup) { + const { ciphertext, senderKeyDistributionMessageKey } = await encryptSenderKeyMsgSignalProto(destinationJid, encodedMsg, meId, authState) - const [groupData, senderKeyMap] = await Promise.all([ - (async() => { - let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined - if(!groupData) groupData = await groupMetadata(jid) - return groupData - })(), - (async() => { - const result = await authState.keys.get('sender-key-memory', [jid]) - return result[jid] || { } - })() - ]) + const [groupData, senderKeyMap] = await Promise.all([ + (async() => { + let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined + if(!groupData) { + groupData = await groupMetadata(jid) + } + + return groupData + })(), + (async() => { + const result = await authState.keys.get('sender-key-memory', [jid]) + return result[jid] || { } + })() + ]) - if(!participant) { - const participantsList = groupData.participants.map(p => p.id) - const additionalDevices = await getUSyncDevices(participantsList, false) - devices.push(...additionalDevices) - } + if(!participant) { + const participantsList = groupData.participants.map(p => p.id) + const additionalDevices = await getUSyncDevices(participantsList, false) + devices.push(...additionalDevices) + } - const senderKeyJids: string[] = [] - // ensure a connection is established with every device - for(const {user, device} of devices) { - const jid = jidEncode(user, 's.whatsapp.net', device) - if(!senderKeyMap[jid]) { - senderKeyJids.push(jid) - // store that this person has had the sender keys sent to them - senderKeyMap[jid] = true - } - } - // if there are some participants with whom the session has not been established - // if there are, we re-send the senderkey - if(senderKeyJids.length) { - logger.debug({ senderKeyJids }, 'sending new sender key') + const senderKeyJids: string[] = [] + // ensure a connection is established with every device + for(const { user, device } of devices) { + const jid = jidEncode(user, 's.whatsapp.net', device) + if(!senderKeyMap[jid]) { + senderKeyJids.push(jid) + // store that this person has had the sender keys sent to them + senderKeyMap[jid] = true + } + } + + // if there are some participants with whom the session has not been established + // if there are, we re-send the senderkey + if(senderKeyJids.length) { + logger.debug({ senderKeyJids }, 'sending new sender key') - const encSenderKeyMsg = encodeWAMessage({ - senderKeyDistributionMessage: { - axolotlSenderKeyDistributionMessage: senderKeyDistributionMessageKey, - groupId: destinationJid - } - }) + const encSenderKeyMsg = encodeWAMessage({ + senderKeyDistributionMessage: { + axolotlSenderKeyDistributionMessage: senderKeyDistributionMessageKey, + groupId: destinationJid + } + }) - participants.push( - ...(await createParticipantNodes(senderKeyJids, encSenderKeyMsg)) - ) - } + participants.push( + ...(await createParticipantNodes(senderKeyJids, encSenderKeyMsg)) + ) + } - binaryNodeContent.push({ - tag: 'enc', - attrs: { v: '2', type: 'skmsg' }, - content: ciphertext - }) + binaryNodeContent.push({ + tag: 'enc', + attrs: { v: '2', type: 'skmsg' }, + content: ciphertext + }) - await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } }) - } else { - const { user: meUser } = jidDecode(meId) + await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } }) + } else { + const { user: meUser } = jidDecode(meId) - const encodedMeMsg = encodeWAMessage({ - deviceSentMessage: { - destinationJid, - message - } - }) + const encodedMeMsg = encodeWAMessage({ + deviceSentMessage: { + destinationJid, + message + } + }) - if(!participant) { - devices.push({ user }) - devices.push({ user: meUser }) + if(!participant) { + devices.push({ user }) + devices.push({ user: meUser }) - const additionalDevices = await getUSyncDevices([ meId, jid ], true) - devices.push(...additionalDevices) - } + const additionalDevices = await getUSyncDevices([ meId, jid ], true) + devices.push(...additionalDevices) + } - const meJids: string[] = [] - const otherJids: string[] = [] - for(const { user, device } of devices) { - const jid = jidEncode(user, 's.whatsapp.net', device) - const isMe = user === meUser - if(isMe) meJids.push(jid) - else otherJids.push(jid) - } + const meJids: string[] = [] + const otherJids: string[] = [] + for(const { user, device } of devices) { + const jid = jidEncode(user, 's.whatsapp.net', device) + const isMe = user === meUser + if(isMe) { + meJids.push(jid) + } else { + otherJids.push(jid) + } + } - const [meNodes, otherNodes] = await Promise.all([ - createParticipantNodes(meJids, encodedMeMsg), - createParticipantNodes(otherJids, encodedMsg) - ]) - participants.push(...meNodes) - participants.push(...otherNodes) - } + const [meNodes, otherNodes] = await Promise.all([ + createParticipantNodes(meJids, encodedMeMsg), + createParticipantNodes(otherJids, encodedMsg) + ]) + participants.push(...meNodes) + participants.push(...otherNodes) + } - if(participants.length) { - binaryNodeContent.push({ - tag: 'participants', - attrs: { }, - content: participants - }) - } + if(participants.length) { + binaryNodeContent.push({ + tag: 'participants', + attrs: { }, + content: participants + }) + } - const stanza: BinaryNode = { - tag: 'message', - attrs: { - id: msgId, - type: 'text', - to: destinationJid, - ...(additionalAttributes || {}) - }, - content: binaryNodeContent - } + const stanza: BinaryNode = { + tag: 'message', + attrs: { + id: msgId, + type: 'text', + to: destinationJid, + ...(additionalAttributes || {}) + }, + content: binaryNodeContent + } - const shouldHaveIdentity = !!participants.find( - participant => (participant.content! as BinaryNode[]).find(n => n.attrs.type === 'pkmsg') - ) + const shouldHaveIdentity = !!participants.find( + participant => (participant.content! as BinaryNode[]).find(n => n.attrs.type === 'pkmsg') + ) - if(shouldHaveIdentity) { - (stanza.content as BinaryNode[]).push({ - tag: 'device-identity', - attrs: { }, - content: proto.ADVSignedDeviceIdentity.encode(authState.creds.account).finish() - }) + if(shouldHaveIdentity) { + (stanza.content as BinaryNode[]).push({ + tag: 'device-identity', + attrs: { }, + content: proto.ADVSignedDeviceIdentity.encode(authState.creds.account).finish() + }) - logger.debug({ jid }, 'adding device identity') - } + logger.debug({ jid }, 'adding device identity') + } - logger.debug({ msgId }, `sending message to ${participants.length} devices`) + logger.debug({ msgId }, `sending message to ${participants.length} devices`) - await sendNode(stanza) - } - ) + await sendNode(stanza) + } + ) - return msgId - } + return msgId + } - const waUploadToServer = getWAUploadToServer(config, refreshMediaConn) + const waUploadToServer = getWAUploadToServer(config, refreshMediaConn) return { ...sock, - assertSessions, - relayMessage, - sendReceipt, - sendReadReceipt, - refreshMediaConn, + assertSessions, + relayMessage, + sendReceipt, + sendReadReceipt, + refreshMediaConn, waUploadToServer, - fetchPrivacySettings, - sendMessage: async( + fetchPrivacySettings, + sendMessage: async( jid: string, content: AnyMessageContent, options: MiscMessageGenerationOptions = { } ) => { - const userJid = authState.creds.me!.id + const userJid = authState.creds.me!.id if( typeof content === 'object' && 'disappearingMessagesInChat' in content && @@ -442,9 +455,9 @@ export const makeMessagesSocket = (config: SocketConfig) => { ) { const { disappearingMessagesInChat } = content const value = typeof disappearingMessagesInChat === 'boolean' ? - (disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : - disappearingMessagesInChat - await groupToggleEphemeral(jid, value) + (disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : + disappearingMessagesInChat + await groupToggleEphemeral(jid, value) } else { const fullMsg = await generateWAMessage( jid, @@ -452,28 +465,29 @@ export const makeMessagesSocket = (config: SocketConfig) => { { logger, userJid, - // multi-device does not have this yet + // multi-device does not have this yet //getUrlInfo: generateUrlInfo, upload: waUploadToServer, - mediaCache: config.mediaCache, + mediaCache: config.mediaCache, ...options, } ) - const isDeleteMsg = 'delete' in content && !!content.delete - const additionalAttributes: BinaryNodeAttributes = { } - // required for delete - if(isDeleteMsg) { - additionalAttributes.edit = '7' - } + const isDeleteMsg = 'delete' in content && !!content.delete + const additionalAttributes: BinaryNodeAttributes = { } + // required for delete + if(isDeleteMsg) { + additionalAttributes.edit = '7' + } await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id!, additionalAttributes }) - if(config.emitOwnEvents) { - process.nextTick(() => { - ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) - }) - } + if(config.emitOwnEvents) { + process.nextTick(() => { + ev.emit('messages.upsert', { messages: [fullMsg], type: 'append' }) + }) + } + return fullMsg } - } + } } } diff --git a/src/Socket/socket.ts b/src/Socket/socket.ts index 14a6e55..d31df02 100644 --- a/src/Socket/socket.ts +++ b/src/Socket/socket.ts @@ -1,13 +1,13 @@ import { Boom } from '@hapi/boom' -import EventEmitter from 'events' -import { promisify } from "util" -import WebSocket from "ws" import { randomBytes } from 'crypto' +import EventEmitter from 'events' +import { promisify } from 'util' +import WebSocket from 'ws' import { proto } from '../../WAProto' -import { DisconnectReason, SocketConfig, BaileysEventEmitter, AuthenticationCreds } from "../Types" -import { Curve, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout, generateOrGetPreKeys, xmppSignedPreKey, xmppPreKey, getPreKeys, makeNoiseHandler, useSingleFileAuthState, addTransactionCapability, bindWaitForConnectionUpdate, printQRIfNecessaryListener } from "../Utils" -import { DEFAULT_ORIGIN, DEF_TAG_PREFIX, DEF_CALLBACK_PREFIX, KEY_BUNDLE_TYPE } from "../Defaults" -import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, S_WHATSAPP_NET, getBinaryNodeChild } from '../WABinary' +import { DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, DEFAULT_ORIGIN, KEY_BUNDLE_TYPE } from '../Defaults' +import { AuthenticationCreds, BaileysEventEmitter, DisconnectReason, SocketConfig } from '../Types' +import { addTransactionCapability, bindWaitForConnectionUpdate, configureSuccessfulPairing, Curve, encodeBigEndian, generateLoginNode, generateOrGetPreKeys, generateRegistrationNode, getPreKeys, makeNoiseHandler, printQRIfNecessaryListener, promiseTimeout, useSingleFileAuthState, xmppPreKey, xmppSignedPreKey } from '../Utils' +import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, getBinaryNodeChild, S_WHATSAPP_NET } from '../WABinary' /** * Connects to WA servers and performs: @@ -16,16 +16,16 @@ import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, S_WHATSAPP_NET, getB * - query phone connection */ export const makeSocket = ({ - waWebSocketUrl, - connectTimeoutMs, - logger, - agent, - keepAliveIntervalMs, - version, - browser, - auth: initialAuthState, - printQRInTerminal, - defaultQueryTimeoutMs + waWebSocketUrl, + connectTimeoutMs, + logger, + agent, + keepAliveIntervalMs, + version, + browser, + auth: initialAuthState, + printQRInTerminal, + defaultQueryTimeoutMs }: SocketConfig) => { const ws = new WebSocket(waWebSocketUrl, undefined, { origin: DEFAULT_ORIGIN, @@ -40,500 +40,524 @@ export const makeSocket = ({ 'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits' } }) - ws.setMaxListeners(0) - const ev = new EventEmitter() as BaileysEventEmitter - /** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */ - const ephemeralKeyPair = Curve.generateKeyPair() - /** WA noise protocol wrapper */ - const noise = makeNoiseHandler(ephemeralKeyPair) - let authState = initialAuthState - if(!authState) { - authState = useSingleFileAuthState('./auth-info-multi.json').state + ws.setMaxListeners(0) + const ev = new EventEmitter() as BaileysEventEmitter + /** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */ + const ephemeralKeyPair = Curve.generateKeyPair() + /** WA noise protocol wrapper */ + const noise = makeNoiseHandler(ephemeralKeyPair) + let authState = initialAuthState + if(!authState) { + authState = useSingleFileAuthState('./auth-info-multi.json').state - logger.warn(` + logger.warn(` Baileys just created a single file state for your credentials. This will not be supported soon. Please pass the credentials in the config itself `) - } - const { creds } = authState + } + + const { creds } = authState - let lastDateRecv: Date + let lastDateRecv: Date let epoch = 0 let keepAliveReq: NodeJS.Timeout - let qrTimer: NodeJS.Timeout + let qrTimer: NodeJS.Timeout - const uqTagId = `${randomBytes(1).toString('hex')[0]}.${randomBytes(1).toString('hex')[0]}-` - const generateMessageTag = () => `${uqTagId}${epoch++}` + const uqTagId = `${randomBytes(1).toString('hex')[0]}.${randomBytes(1).toString('hex')[0]}-` + const generateMessageTag = () => `${uqTagId}${epoch++}` const sendPromise = promisify(ws.send) /** send a raw buffer */ const sendRawMessage = async(data: Buffer | Uint8Array) => { - if(ws.readyState !== ws.OPEN) { - throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) - } - const bytes = noise.encodeFrame(data) + if(ws.readyState !== ws.OPEN) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } + + const bytes = noise.encodeFrame(data) await sendPromise.call(ws, bytes) as Promise - } - /** send a binary node */ - const sendNode = (node: BinaryNode) => { - let buff = encodeBinaryNode(node) - return sendRawMessage(buff) - } - /** await the next incoming message */ - const awaitNextMessage = async(sendMsg?: Uint8Array) => { - if(ws.readyState !== ws.OPEN) { - throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) - } - let onOpen: (data: any) => void - let onClose: (err: Error) => void + } - const result = new Promise((resolve, reject) => { - onOpen = (data: any) => resolve(data) - onClose = reject - ws.on('frame', onOpen) - ws.on('close', onClose) - ws.on('error', onClose) - }) - .finally(() => { - ws.off('frame', onOpen) - ws.off('close', onClose) - ws.off('error', onClose) - }) + /** send a binary node */ + const sendNode = (node: BinaryNode) => { + const buff = encodeBinaryNode(node) + return sendRawMessage(buff) + } - if(sendMsg) { - sendRawMessage(sendMsg).catch(onClose) - } + /** await the next incoming message */ + const awaitNextMessage = async(sendMsg?: Uint8Array) => { + if(ws.readyState !== ws.OPEN) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } - return result - } + let onOpen: (data: any) => void + let onClose: (err: Error) => void - /** + const result = new Promise((resolve, reject) => { + onOpen = (data: any) => resolve(data) + onClose = reject + ws.on('frame', onOpen) + ws.on('close', onClose) + ws.on('error', onClose) + }) + .finally(() => { + ws.off('frame', onOpen) + ws.off('close', onClose) + ws.off('error', onClose) + }) + + if(sendMsg) { + sendRawMessage(sendMsg).catch(onClose) + } + + return result + } + + /** * Wait for a message with a certain tag to be received * @param tag the message tag to await * @param json query that was sent * @param timeoutMs timeout after which the promise will reject */ const waitForMessage = async(msgId: string, timeoutMs = defaultQueryTimeoutMs) => { - let onRecv: (json) => void - let onErr: (err) => void - try { - const result = await promiseTimeout(timeoutMs, - (resolve, reject) => { - onRecv = resolve - onErr = err => { - reject(err || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) - } + let onRecv: (json) => void + let onErr: (err) => void + try { + const result = await promiseTimeout(timeoutMs, + (resolve, reject) => { + onRecv = resolve + onErr = err => { + reject(err || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) + } - ws.on(`TAG:${msgId}`, onRecv) - ws.on('close', onErr) // if the socket closes, you'll never receive the message - ws.off('error', onErr) - }, - ) - return result as any - } finally { - ws.off(`TAG:${msgId}`, onRecv) - ws.off('close', onErr) // if the socket closes, you'll never receive the message - ws.off('error', onErr) - } - } - /** send a query, and wait for its response. auto-generates message ID if not provided */ - const query = async(node: BinaryNode, timeoutMs?: number) => { - if(!node.attrs.id) node.attrs.id = generateMessageTag() - - const msgId = node.attrs.id - const wait = waitForMessage(msgId, timeoutMs) - - await sendNode(node) - - const result = await (wait as Promise) - if('tag' in result) { - assertNodeErrorFree(result) - } - return result - } - /** connection handshake */ - const validateConnection = async () => { - logger.info('connected to WA Web') - - const init = proto.HandshakeMessage.encode({ - clientHello: { ephemeral: ephemeralKeyPair.public } - }).finish() - - const result = await awaitNextMessage(init) - const handshake = proto.HandshakeMessage.decode(result) - - logger.debug('handshake recv from WA Web') - - const keyEnc = noise.processHandshake(handshake, creds.noiseKey) - logger.info('handshake complete') - - let node: Uint8Array - if(!creds.me) { - logger.info('not logged in, attempting registration...') - node = generateRegistrationNode(creds, { version, browser }) - } else { - logger.info('logging in...') - node = generateLoginNode(creds.me!.id, { version, browser }) - } - const payloadEnc = noise.encrypt(node) - await sendRawMessage( - proto.HandshakeMessage.encode({ - clientFinish: { - static: new Uint8Array(keyEnc), - payload: new Uint8Array(payloadEnc), - }, - }).finish() - ) - noise.finishInit() - startKeepAliveRequest() - } - /** get some pre-keys and do something with them */ - const assertingPreKeys = async(range: number, execute: (keys: { [_: number]: any }) => Promise) => { - const { newPreKeys, lastPreKeyId, preKeysRange } = generateOrGetPreKeys(authState.creds, range) - - const update: Partial = { - nextPreKeyId: Math.max(lastPreKeyId+1, creds.nextPreKeyId), - firstUnuploadedPreKeyId: Math.max(creds.firstUnuploadedPreKeyId, lastPreKeyId+1) - } - if(!creds.serverHasPreKeys) { - update.serverHasPreKeys = true - } - - await authState.keys.set({ 'pre-key': newPreKeys }) - - const preKeys = await getPreKeys(authState.keys, preKeysRange[0], preKeysRange[0] + preKeysRange[1]) - await execute(preKeys) - - ev.emit('creds.update', update) - } - /** generates and uploads a set of pre-keys */ - const uploadPreKeys = async() => { - await assertingPreKeys(30, async preKeys => { - const node: BinaryNode = { - tag: 'iq', - attrs: { - id: generateMessageTag(), - xmlns: 'encrypt', - type: 'set', - to: S_WHATSAPP_NET, - }, - content: [ - { tag: 'registration', attrs: { }, content: encodeBigEndian(creds.registrationId) }, - { tag: 'type', attrs: { }, content: KEY_BUNDLE_TYPE }, - { tag: 'identity', attrs: { }, content: creds.signedIdentityKey.public }, - { tag: 'list', attrs: { }, content: Object.keys(preKeys).map(k => xmppPreKey(preKeys[+k], +k)) }, - xmppSignedPreKey(creds.signedPreKey) - ] - } - await sendNode(node) - - logger.info('uploaded pre-keys') - }) - } - - const onMessageRecieved = (data: Buffer) => { - noise.decodeFrame(data, frame => { - ws.emit('frame', frame) - // if it's a binary node - if(!(frame instanceof Uint8Array)) { - const msgId = frame.attrs.id - - if(logger.level === 'trace') { - logger.trace({ msgId, fromMe: false, frame }, 'communication') - } - - let anyTriggered = false - /* Check if this is a response to a message we sent */ - anyTriggered = ws.emit(`${DEF_TAG_PREFIX}${msgId}`, frame) - /* Check if this is a response to a message we are expecting */ - const l0 = frame.tag - const l1 = frame.attrs || { } - const l2 = Array.isArray(frame.content) ? frame.content[0]?.tag : '' - - Object.keys(l1).forEach(key => { - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, frame) || anyTriggered - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, frame) || anyTriggered - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, frame) || anyTriggered - }) - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, frame) || anyTriggered - anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0}`, frame) || anyTriggered - anyTriggered = ws.emit('frame', frame) || anyTriggered - - if (!anyTriggered && logger.level === 'debug') { - logger.debug({ unhandled: true, msgId, fromMe: false, frame }, 'communication recv') - } - } - }) - } - - const end = (error: Error | undefined) => { - logger.info({ error }, 'connection closed') - - clearInterval(keepAliveReq) - clearInterval(qrTimer) - - ws.removeAllListeners('close') - ws.removeAllListeners('error') - ws.removeAllListeners('open') - ws.removeAllListeners('message') - - if(ws.readyState !== ws.CLOSED && ws.readyState !== ws.CLOSING) { - try { ws.close() } catch { } - } - - ev.emit('connection.update', { - connection: 'close', - lastDisconnect: { - error, - date: new Date() - } - }) - ev.removeAllListeners('connection.update') + ws.on(`TAG:${msgId}`, onRecv) + ws.on('close', onErr) // if the socket closes, you'll never receive the message + ws.off('error', onErr) + }, + ) + return result as any + } finally { + ws.off(`TAG:${msgId}`, onRecv) + ws.off('close', onErr) // if the socket closes, you'll never receive the message + ws.off('error', onErr) + } } - const waitForSocketOpen = async() => { - if(ws.readyState === ws.OPEN) return - if(ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { - throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) - } - let onOpen: () => void - let onClose: (err: Error) => void - await new Promise((resolve, reject) => { - onOpen = () => resolve(undefined) - onClose = reject - ws.on('open', onOpen) - ws.on('close', onClose) - ws.on('error', onClose) - }) - .finally(() => { - ws.off('open', onOpen) - ws.off('close', onClose) - ws.off('error', onClose) - }) - } + /** send a query, and wait for its response. auto-generates message ID if not provided */ + const query = async(node: BinaryNode, timeoutMs?: number) => { + if(!node.attrs.id) { + node.attrs.id = generateMessageTag() + } - const startKeepAliveRequest = () => ( - keepAliveReq = setInterval(() => { - if (!lastDateRecv) lastDateRecv = new Date() - const diff = Date.now() - lastDateRecv.getTime() - /* + const msgId = node.attrs.id + const wait = waitForMessage(msgId, timeoutMs) + + await sendNode(node) + + const result = await (wait as Promise) + if('tag' in result) { + assertNodeErrorFree(result) + } + + return result + } + + /** connection handshake */ + const validateConnection = async() => { + logger.info('connected to WA Web') + + const init = proto.HandshakeMessage.encode({ + clientHello: { ephemeral: ephemeralKeyPair.public } + }).finish() + + const result = await awaitNextMessage(init) + const handshake = proto.HandshakeMessage.decode(result) + + logger.debug('handshake recv from WA Web') + + const keyEnc = noise.processHandshake(handshake, creds.noiseKey) + logger.info('handshake complete') + + let node: Uint8Array + if(!creds.me) { + logger.info('not logged in, attempting registration...') + node = generateRegistrationNode(creds, { version, browser }) + } else { + logger.info('logging in...') + node = generateLoginNode(creds.me!.id, { version, browser }) + } + + const payloadEnc = noise.encrypt(node) + await sendRawMessage( + proto.HandshakeMessage.encode({ + clientFinish: { + static: new Uint8Array(keyEnc), + payload: new Uint8Array(payloadEnc), + }, + }).finish() + ) + noise.finishInit() + startKeepAliveRequest() + } + + /** get some pre-keys and do something with them */ + const assertingPreKeys = async(range: number, execute: (keys: { [_: number]: any }) => Promise) => { + const { newPreKeys, lastPreKeyId, preKeysRange } = generateOrGetPreKeys(authState.creds, range) + + const update: Partial = { + nextPreKeyId: Math.max(lastPreKeyId+1, creds.nextPreKeyId), + firstUnuploadedPreKeyId: Math.max(creds.firstUnuploadedPreKeyId, lastPreKeyId+1) + } + if(!creds.serverHasPreKeys) { + update.serverHasPreKeys = true + } + + await authState.keys.set({ 'pre-key': newPreKeys }) + + const preKeys = await getPreKeys(authState.keys, preKeysRange[0], preKeysRange[0] + preKeysRange[1]) + await execute(preKeys) + + ev.emit('creds.update', update) + } + + /** generates and uploads a set of pre-keys */ + const uploadPreKeys = async() => { + await assertingPreKeys(30, async preKeys => { + const node: BinaryNode = { + tag: 'iq', + attrs: { + id: generateMessageTag(), + xmlns: 'encrypt', + type: 'set', + to: S_WHATSAPP_NET, + }, + content: [ + { tag: 'registration', attrs: { }, content: encodeBigEndian(creds.registrationId) }, + { tag: 'type', attrs: { }, content: KEY_BUNDLE_TYPE }, + { tag: 'identity', attrs: { }, content: creds.signedIdentityKey.public }, + { tag: 'list', attrs: { }, content: Object.keys(preKeys).map(k => xmppPreKey(preKeys[+k], +k)) }, + xmppSignedPreKey(creds.signedPreKey) + ] + } + await sendNode(node) + + logger.info('uploaded pre-keys') + }) + } + + const onMessageRecieved = (data: Buffer) => { + noise.decodeFrame(data, frame => { + ws.emit('frame', frame) + // if it's a binary node + if(!(frame instanceof Uint8Array)) { + const msgId = frame.attrs.id + + if(logger.level === 'trace') { + logger.trace({ msgId, fromMe: false, frame }, 'communication') + } + + let anyTriggered = false + /* Check if this is a response to a message we sent */ + anyTriggered = ws.emit(`${DEF_TAG_PREFIX}${msgId}`, frame) + /* Check if this is a response to a message we are expecting */ + const l0 = frame.tag + const l1 = frame.attrs || { } + const l2 = Array.isArray(frame.content) ? frame.content[0]?.tag : '' + + Object.keys(l1).forEach(key => { + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, frame) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, frame) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, frame) || anyTriggered + }) + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, frame) || anyTriggered + anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0}`, frame) || anyTriggered + anyTriggered = ws.emit('frame', frame) || anyTriggered + + if(!anyTriggered && logger.level === 'debug') { + logger.debug({ unhandled: true, msgId, fromMe: false, frame }, 'communication recv') + } + } + }) + } + + const end = (error: Error | undefined) => { + logger.info({ error }, 'connection closed') + + clearInterval(keepAliveReq) + clearInterval(qrTimer) + + ws.removeAllListeners('close') + ws.removeAllListeners('error') + ws.removeAllListeners('open') + ws.removeAllListeners('message') + + if(ws.readyState !== ws.CLOSED && ws.readyState !== ws.CLOSING) { + try { + ws.close() + } catch{ } + } + + ev.emit('connection.update', { + connection: 'close', + lastDisconnect: { + error, + date: new Date() + } + }) + ev.removeAllListeners('connection.update') + } + + const waitForSocketOpen = async() => { + if(ws.readyState === ws.OPEN) { + return + } + + if(ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { + throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed }) + } + + let onOpen: () => void + let onClose: (err: Error) => void + await new Promise((resolve, reject) => { + onOpen = () => resolve(undefined) + onClose = reject + ws.on('open', onOpen) + ws.on('close', onClose) + ws.on('error', onClose) + }) + .finally(() => { + ws.off('open', onOpen) + ws.off('close', onClose) + ws.off('error', onClose) + }) + } + + const startKeepAliveRequest = () => ( + keepAliveReq = setInterval(() => { + if(!lastDateRecv) { + lastDateRecv = new Date() + } + + const diff = Date.now() - lastDateRecv.getTime() + /* check if it's been a suspicious amount of time since the server responded with our last seen it could be that the network is down */ - if (diff > keepAliveIntervalMs+5000) { - end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost })) - } else if(ws.readyState === ws.OPEN) { - // if its all good, send a keep alive request - query( - { - tag: 'iq', - attrs: { - id: generateMessageTag(), - to: S_WHATSAPP_NET, - type: 'get', - xmlns: 'w:p', - }, - content: [{ tag: 'ping', attrs: { } }] - }, - keepAliveIntervalMs - ) - .then(() => { - lastDateRecv = new Date() - logger.trace('recv keep alive') - }) - .catch(err => end(err)) - } else { - logger.warn('keep alive called when WS not open') - } - }, keepAliveIntervalMs) - ) - /** i have no idea why this exists. pls enlighten me */ - const sendPassiveIq = (tag: 'passive' | 'active') => ( - sendNode({ - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - xmlns: 'passive', - type: 'set', - id: generateMessageTag(), - }, - content: [ - { tag, attrs: { } } - ] - }) - ) - /** logout & invalidate connection */ - const logout = async() => { - const jid = authState.creds.me?.id - if(jid) { - await sendNode({ - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - type: 'set', - id: generateMessageTag(), - xmlns: 'md' - }, - content: [ - { - tag: 'remove-companion-device', - attrs: { - jid: jid, - reason: 'user_initiated' - } - } - ] - }) - } + if(diff > keepAliveIntervalMs+5000) { + end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost })) + } else if(ws.readyState === ws.OPEN) { + // if its all good, send a keep alive request + query( + { + tag: 'iq', + attrs: { + id: generateMessageTag(), + to: S_WHATSAPP_NET, + type: 'get', + xmlns: 'w:p', + }, + content: [{ tag: 'ping', attrs: { } }] + }, + keepAliveIntervalMs + ) + .then(() => { + lastDateRecv = new Date() + logger.trace('recv keep alive') + }) + .catch(err => end(err)) + } else { + logger.warn('keep alive called when WS not open') + } + }, keepAliveIntervalMs) + ) + /** i have no idea why this exists. pls enlighten me */ + const sendPassiveIq = (tag: 'passive' | 'active') => ( + sendNode({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + xmlns: 'passive', + type: 'set', + id: generateMessageTag(), + }, + content: [ + { tag, attrs: { } } + ] + }) + ) + /** logout & invalidate connection */ + const logout = async() => { + const jid = authState.creds.me?.id + if(jid) { + await sendNode({ + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'set', + id: generateMessageTag(), + xmlns: 'md' + }, + content: [ + { + tag: 'remove-companion-device', + attrs: { + jid: jid, + reason: 'user_initiated' + } + } + ] + }) + } - end(new Boom('Intentional Logout', { statusCode: DisconnectReason.loggedOut })) - } + end(new Boom('Intentional Logout', { statusCode: DisconnectReason.loggedOut })) + } ws.on('message', onMessageRecieved) ws.on('open', validateConnection) ws.on('error', end) ws.on('close', () => end(new Boom('Connection Terminated', { statusCode: DisconnectReason.connectionClosed }))) - // the server terminated the connection - ws.on('CB:xmlstreamend', () => { - end(new Boom('Connection Terminated by Server', { statusCode: DisconnectReason.connectionClosed })) - }) - // QR gen - ws.on('CB:iq,type:set,pair-device', async (stanza: BinaryNode) => { - const iq: BinaryNode = { - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - type: 'result', - id: stanza.attrs.id, - } - } - await sendNode(iq) + // the server terminated the connection + ws.on('CB:xmlstreamend', () => { + end(new Boom('Connection Terminated by Server', { statusCode: DisconnectReason.connectionClosed })) + }) + // QR gen + ws.on('CB:iq,type:set,pair-device', async(stanza: BinaryNode) => { + const iq: BinaryNode = { + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'result', + id: stanza.attrs.id, + } + } + await sendNode(iq) - const refs = ((stanza.content[0] as BinaryNode).content as BinaryNode[]).map(n => n.content as string) - const noiseKeyB64 = Buffer.from(creds.noiseKey.public).toString('base64') - const identityKeyB64 = Buffer.from(creds.signedIdentityKey.public).toString('base64') - const advB64 = creds.advSecretKey + const refs = ((stanza.content[0] as BinaryNode).content as BinaryNode[]).map(n => n.content as string) + const noiseKeyB64 = Buffer.from(creds.noiseKey.public).toString('base64') + const identityKeyB64 = Buffer.from(creds.signedIdentityKey.public).toString('base64') + const advB64 = creds.advSecretKey - let qrMs = 60_000 // time to let a QR live - const genPairQR = () => { - const ref = refs.shift() - if(!ref) { - end(new Boom('QR refs attempts ended', { statusCode: DisconnectReason.timedOut })) - return - } + let qrMs = 60_000 // time to let a QR live + const genPairQR = () => { + const ref = refs.shift() + if(!ref) { + end(new Boom('QR refs attempts ended', { statusCode: DisconnectReason.timedOut })) + return + } - const qr = [ref, noiseKeyB64, identityKeyB64, advB64].join(',') + const qr = [ref, noiseKeyB64, identityKeyB64, advB64].join(',') - ev.emit('connection.update', { qr }) + ev.emit('connection.update', { qr }) - qrTimer = setTimeout(genPairQR, qrMs) - qrMs = 20_000 // shorter subsequent qrs - } + qrTimer = setTimeout(genPairQR, qrMs) + qrMs = 20_000 // shorter subsequent qrs + } - genPairQR() - }) - // device paired for the first time - // if device pairs successfully, the server asks to restart the connection - ws.on('CB:iq,,pair-success', async(stanza: BinaryNode) => { - logger.debug('pair success recv') - try { - const { reply, creds: updatedCreds } = configureSuccessfulPairing(stanza, creds) + genPairQR() + }) + // device paired for the first time + // if device pairs successfully, the server asks to restart the connection + ws.on('CB:iq,,pair-success', async(stanza: BinaryNode) => { + logger.debug('pair success recv') + try { + const { reply, creds: updatedCreds } = configureSuccessfulPairing(stanza, creds) - logger.debug('pairing configured successfully') + logger.debug('pairing configured successfully') - const waiting = awaitNextMessage() - await sendNode(reply) + const waiting = awaitNextMessage() + await sendNode(reply) - const value = (await waiting) as BinaryNode - if(value.tag === 'stream:error') { - if(value.attrs?.code !== '515') { - throw new Boom('Authentication failed', { statusCode: +(value.attrs.code || 500) }) - } - } + const value = (await waiting) as BinaryNode + if(value.tag === 'stream:error') { + if(value.attrs?.code !== '515') { + throw new Boom('Authentication failed', { statusCode: +(value.attrs.code || 500) }) + } + } - logger.info({ jid: updatedCreds.me!.id }, 'registered connection, restart server') + logger.info({ jid: updatedCreds.me!.id }, 'registered connection, restart server') - ev.emit('creds.update', updatedCreds) - ev.emit('connection.update', { isNewLogin: true, qr: undefined }) + ev.emit('creds.update', updatedCreds) + ev.emit('connection.update', { isNewLogin: true, qr: undefined }) - end(new Boom('Restart Required', { statusCode: DisconnectReason.restartRequired })) - } catch(error) { - logger.info({ trace: error.stack }, 'error in pairing') - end(error) - } - }) - // login complete - ws.on('CB:success', async() => { - if(!creds.serverHasPreKeys) { - await uploadPreKeys() - } - await sendPassiveIq('active') + end(new Boom('Restart Required', { statusCode: DisconnectReason.restartRequired })) + } catch(error) { + logger.info({ trace: error.stack }, 'error in pairing') + end(error) + } + }) + // login complete + ws.on('CB:success', async() => { + if(!creds.serverHasPreKeys) { + await uploadPreKeys() + } - logger.info('opened connection to WA') - clearTimeout(qrTimer) // will never happen in all likelyhood -- but just in case WA sends success on first try + await sendPassiveIq('active') - ev.emit('connection.update', { connection: 'open' }) - }) + logger.info('opened connection to WA') + clearTimeout(qrTimer) // will never happen in all likelyhood -- but just in case WA sends success on first try + + ev.emit('connection.update', { connection: 'open' }) + }) - ws.on('CB:ib,,offline', (node: BinaryNode) => { - const child = getBinaryNodeChild(node, 'offline') - const offlineCount = +child.attrs.count + ws.on('CB:ib,,offline', (node: BinaryNode) => { + const child = getBinaryNodeChild(node, 'offline') + const offlineCount = +child.attrs.count - logger.info(`got ${offlineCount} offline messages/notifications`) + logger.info(`got ${offlineCount} offline messages/notifications`) - ev.emit('connection.update', { receivedPendingNotifications: true }) - }) + ev.emit('connection.update', { receivedPendingNotifications: true }) + }) - ws.on('CB:stream:error', (node: BinaryNode) => { - logger.error({ error: node }, `stream errored out`) + ws.on('CB:stream:error', (node: BinaryNode) => { + logger.error({ error: node }, 'stream errored out') - const statusCode = +(node.attrs.code || DisconnectReason.restartRequired) - end(new Boom('Stream Errored', { statusCode, data: node })) - }) - // stream fail, possible logout - ws.on('CB:failure', (node: BinaryNode) => { - const reason = +(node.attrs.reason || 500) - end(new Boom('Connection Failure', { statusCode: reason, data: node.attrs })) - }) + const statusCode = +(node.attrs.code || DisconnectReason.restartRequired) + end(new Boom('Stream Errored', { statusCode, data: node })) + }) + // stream fail, possible logout + ws.on('CB:failure', (node: BinaryNode) => { + const reason = +(node.attrs.reason || 500) + end(new Boom('Connection Failure', { statusCode: reason, data: node.attrs })) + }) - ws.on('CB:ib,,downgrade_webclient', () => { - end(new Boom('Multi-device beta not joined', { statusCode: DisconnectReason.multideviceMismatch })) - }) + ws.on('CB:ib,,downgrade_webclient', () => { + end(new Boom('Multi-device beta not joined', { statusCode: DisconnectReason.multideviceMismatch })) + }) - process.nextTick(() => { - ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false, qr: undefined }) - }) - // update credentials when required - ev.on('creds.update', update => Object.assign(creds, update)) + process.nextTick(() => { + ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false, qr: undefined }) + }) + // update credentials when required + ev.on('creds.update', update => Object.assign(creds, update)) - if(printQRInTerminal) { + if(printQRInTerminal) { printQRIfNecessaryListener(ev, logger) } return { - type: 'md' as 'md', - ws, - ev, - authState: { - creds, - // add capability - keys: addTransactionCapability(authState.keys, logger) - }, - get user () { - return authState.creds.me - }, - assertingPreKeys, - generateMessageTag, - query, - waitForMessage, - waitForSocketOpen, + type: 'md' as 'md', + ws, + ev, + authState: { + creds, + // add capability + keys: addTransactionCapability(authState.keys, logger) + }, + get user() { + return authState.creds.me + }, + assertingPreKeys, + generateMessageTag, + query, + waitForMessage, + waitForSocketOpen, sendRawMessage, - sendNode, - logout, - end, - /** Waits for the connection to WA to reach a state */ - waitForConnectionUpdate: bindWaitForConnectionUpdate(ev) + sendNode, + logout, + end, + /** Waits for the connection to WA to reach a state */ + waitForConnectionUpdate: bindWaitForConnectionUpdate(ev) } } + export type Socket = ReturnType \ No newline at end of file diff --git a/src/Store/make-ordered-dictionary.ts b/src/Store/make-ordered-dictionary.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/Tests/test.media-download.ts b/src/Tests/test.media-download.ts index baa29d5..81e7b4a 100644 --- a/src/Tests/test.media-download.ts +++ b/src/Tests/test.media-download.ts @@ -1,7 +1,7 @@ -import { MediaType, DownloadableMessage } from '../Types' -import { downloadContentFromMessage } from '../Utils' -import { proto } from '../../WAProto' import { readFileSync } from 'fs' +import { proto } from '../../WAProto' +import { DownloadableMessage, MediaType } from '../Types' +import { downloadContentFromMessage } from '../Utils' jest.setTimeout(20_000) @@ -41,7 +41,7 @@ describe('Media Download Tests', () => { const readPipe = await downloadContentFromMessage(message, type) let buffer = Buffer.alloc(0) - for await(const read of readPipe) { + for await (const read of readPipe) { buffer = Buffer.concat([ buffer, read ]) } @@ -61,7 +61,7 @@ describe('Media Download Tests', () => { const readPipe = await downloadContentFromMessage(message, type, range) let buffer = Buffer.alloc(0) - for await(const read of readPipe) { + for await (const read of readPipe) { buffer = Buffer.concat([ buffer, read ]) } diff --git a/src/Types/Auth.ts b/src/Types/Auth.ts index cd88192..30cc1ce 100644 --- a/src/Types/Auth.ts +++ b/src/Types/Auth.ts @@ -1,5 +1,5 @@ -import type { Contact } from "./Contact" -import type { proto } from "../../WAProto" +import type { proto } from '../../WAProto' +import type { Contact } from './Contact' export type KeyPair = { public: Uint8Array, private: Uint8Array } export type SignedKeyPair = { keyPair: KeyPair, signature: Uint8Array, keyId: number } diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 06b7e50..3b98d84 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -1,4 +1,4 @@ -import type { proto } from "../../WAProto" +import type { proto } from '../../WAProto' /** set of statuses visible to other people; see updatePresence() in WhatsAppWeb.Send */ export type WAPresence = 'unavailable' | 'available' | 'composing' | 'recording' | 'paused' diff --git a/src/Types/Events.ts b/src/Types/Events.ts index dc7a4d0..039416c 100644 --- a/src/Types/Events.ts +++ b/src/Types/Events.ts @@ -1,12 +1,10 @@ -import type EventEmitter from "events" - +import type EventEmitter from 'events' import { AuthenticationCreds } from './Auth' import { Chat, PresenceData } from './Chat' import { Contact } from './Contact' -import { ConnectionState } from './State' - import { GroupMetadata, ParticipantAction } from './GroupMetadata' -import { MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageUpdate, WAMessageKey } from './Message' +import { MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageKey, WAMessageUpdate } from './Message' +import { ConnectionState } from './State' export type BaileysEventMap = { /** connection state has been updated -- WS closed, opened, connecting etc. */ diff --git a/src/Types/GroupMetadata.ts b/src/Types/GroupMetadata.ts index 276636f..c4c0ff7 100644 --- a/src/Types/GroupMetadata.ts +++ b/src/Types/GroupMetadata.ts @@ -1,4 +1,4 @@ -import { Contact } from "./Contact"; +import { Contact } from './Contact' export type GroupParticipant = (Contact & { isAdmin?: boolean; isSuperAdmin?: boolean, admin?: 'admin' | 'superadmin' | null }) diff --git a/src/Types/Legacy.ts b/src/Types/Legacy.ts index c30e006..ad86ca7 100644 --- a/src/Types/Legacy.ts +++ b/src/Types/Legacy.ts @@ -1,6 +1,6 @@ -import { CommonSocketConfig } from "./Socket" -import { CommonBaileysEventEmitter } from "./Events" -import { BinaryNode } from "../WABinary" +import { BinaryNode } from '../WABinary' +import { CommonBaileysEventEmitter } from './Events' +import { CommonSocketConfig } from './Socket' export interface LegacyAuthenticationCreds { clientID: string diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 277c00d..4ee130b 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -1,10 +1,9 @@ -import type { ReadStream } from "fs" -import type { Logger } from "pino" -import type { URL } from "url" -import type NodeCache from "node-cache" -import type { GroupMetadata } from "./GroupMetadata" -import type { Readable } from "stream" +import type NodeCache from 'node-cache' +import type { Logger } from 'pino' +import type { Readable } from 'stream' +import type { URL } from 'url' import { proto } from '../../WAProto' +import type { GroupMetadata } from './GroupMetadata' // export the WAMessage Prototypes export { proto as WAProto } diff --git a/src/Types/Socket.ts b/src/Types/Socket.ts index 8b2c403..aee0639 100644 --- a/src/Types/Socket.ts +++ b/src/Types/Socket.ts @@ -1,9 +1,9 @@ -import type { Agent } from "https" -import type { Logger } from "pino" -import type { URL } from "url" +import type { Agent } from 'https' import type NodeCache from 'node-cache' -import { MediaConnInfo } from "./Message" +import type { Logger } from 'pino' +import type { URL } from 'url' +import { MediaConnInfo } from './Message' export type WAVersion = [number, number, number] export type WABrowserDescription = [string, string, string] diff --git a/src/Types/State.ts b/src/Types/State.ts index e7f0cec..5774c50 100644 --- a/src/Types/State.ts +++ b/src/Types/State.ts @@ -1,4 +1,4 @@ -import { Contact } from "./Contact" +import { Contact } from './Contact' export type WAConnectionState = 'open' | 'connecting' | 'close' diff --git a/src/Types/index.ts b/src/Types/index.ts index c04d218..c0c0a11 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -9,9 +9,8 @@ export * from './Socket' export * from './Events' import type NodeCache from 'node-cache' - -import { AuthenticationState } from './Auth' import { proto } from '../../WAProto' +import { AuthenticationState } from './Auth' import { CommonSocketConfig } from './Socket' export type SocketConfig = CommonSocketConfig & { diff --git a/src/Utils/auth-utils.ts b/src/Utils/auth-utils.ts index 9230147..9013859 100644 --- a/src/Utils/auth-utils.ts +++ b/src/Utils/auth-utils.ts @@ -2,9 +2,9 @@ import { Boom } from '@hapi/boom' import { randomBytes } from 'crypto' import type { Logger } from 'pino' import { proto } from '../../WAProto' -import type { AuthenticationCreds, AuthenticationState, SignalDataTypeMap, SignalDataSet, SignalKeyStore, SignalKeyStoreWithTransaction } from "../Types" +import type { AuthenticationCreds, AuthenticationState, SignalDataSet, SignalDataTypeMap, SignalKeyStore, SignalKeyStoreWithTransaction } from '../Types' import { Curve, signedKeyPair } from './crypto' -import { generateRegistrationId, BufferJSON } from './generics' +import { BufferJSON, generateRegistrationId } from './generics' const KEY_MAP: { [T in keyof SignalDataTypeMap]: string } = { 'pre-key': 'preKeys', @@ -46,6 +46,7 @@ export const addTransactionCapability = (state: SignalKeyStore, logger: Logger): if(value) { dict[id] = value } + return dict }, { } ) @@ -55,7 +56,7 @@ export const addTransactionCapability = (state: SignalKeyStore, logger: Logger): }, set: data => { if(inTransaction) { - logger.trace({ types: Object.keys(data) }, `caching in transaction`) + logger.trace({ types: Object.keys(data) }, 'caching in transaction') for(const key in data) { transactionCache[key] = transactionCache[key] || { } Object.assign(transactionCache[key], data[key]) @@ -69,7 +70,7 @@ export const addTransactionCapability = (state: SignalKeyStore, logger: Logger): }, isInTransaction: () => inTransaction, prefetch: (type, ids) => { - logger.trace({ type, ids }, `prefetching`) + logger.trace({ type, ids }, 'prefetching') return prefetch(type, ids) }, transaction: async(work) => { @@ -128,17 +129,17 @@ export const useSingleFileAuthState = (filename: string, logger?: Logger): { sta ) } - if(existsSync(filename)) { - const result = JSON.parse( - readFileSync(filename, { encoding: 'utf-8' }), - BufferJSON.reviver - ) + if(existsSync(filename)) { + const result = JSON.parse( + readFileSync(filename, { encoding: 'utf-8' }), + BufferJSON.reviver + ) creds = result.creds keys = result.keys - } else { - creds = initAuthCreds() - keys = { } - } + } else { + creds = initAuthCreds() + keys = { } + } return { state: { @@ -153,8 +154,10 @@ export const useSingleFileAuthState = (filename: string, logger?: Logger): { sta if(type === 'app-state-sync-key') { value = proto.AppStateSyncKeyData.fromObject(value) } + dict[id] = value } + return dict }, { } ) @@ -165,6 +168,7 @@ export const useSingleFileAuthState = (filename: string, logger?: Logger): { sta keys[key] = keys[key] || { } Object.assign(keys[key], data[_key]) } + saveState() } } diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index fd2fc10..1ae606c 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -1,523 +1,541 @@ import { Boom } from '@hapi/boom' -import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./crypto" -import { WAPatchCreate, ChatMutation, WAPatchName, LTHashState, ChatModification, LastMessageList } from "../Types" import { proto } from '../../WAProto' -import { LT_HASH_ANTI_TAMPERING } from './lt-hash' +import { ChatModification, ChatMutation, LastMessageList, LTHashState, WAPatchCreate, WAPatchName } from '../Types' import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren } from '../WABinary' +import { aesDecrypt, aesEncrypt, hkdf, hmacSign } from './crypto' import { toNumber } from './generics' +import { LT_HASH_ANTI_TAMPERING } from './lt-hash' import { downloadContentFromMessage, } from './messages-media' type FetchAppStateSyncKey = (keyId: string) => Promise | proto.IAppStateSyncKeyData const mutationKeys = (keydata: Uint8Array) => { - const expanded = hkdf(keydata, 160, { info: 'WhatsApp Mutation Keys' }) - return { - indexKey: expanded.slice(0, 32), - valueEncryptionKey: expanded.slice(32, 64), - valueMacKey: expanded.slice(64, 96), - snapshotMacKey: expanded.slice(96, 128), - patchMacKey: expanded.slice(128, 160) - } + const expanded = hkdf(keydata, 160, { info: 'WhatsApp Mutation Keys' }) + return { + indexKey: expanded.slice(0, 32), + valueEncryptionKey: expanded.slice(32, 64), + valueMacKey: expanded.slice(64, 96), + snapshotMacKey: expanded.slice(96, 128), + patchMacKey: expanded.slice(128, 160) + } } const generateMac = (operation: proto.SyncdMutation.SyncdMutationSyncdOperation, data: Buffer, keyId: Uint8Array | string, key: Buffer) => { - const getKeyData = () => { - let r: number - switch (operation) { - case proto.SyncdMutation.SyncdMutationSyncdOperation.SET: - r = 0x01 - break - case proto.SyncdMutation.SyncdMutationSyncdOperation.REMOVE: - r = 0x02 - break - } - const buff = Buffer.from([r]) - return Buffer.concat([ buff, Buffer.from(keyId as any, 'base64') ]) - } - const keyData = getKeyData() + const getKeyData = () => { + let r: number + switch (operation) { + case proto.SyncdMutation.SyncdMutationSyncdOperation.SET: + r = 0x01 + break + case proto.SyncdMutation.SyncdMutationSyncdOperation.REMOVE: + r = 0x02 + break + } - const last = Buffer.alloc(8) // 8 bytes - last.set([ keyData.length ], last.length-1) + const buff = Buffer.from([r]) + return Buffer.concat([ buff, Buffer.from(keyId as any, 'base64') ]) + } - const total = Buffer.concat([ keyData, data, last ]) - const hmac = hmacSign(total, key, 'sha512') + const keyData = getKeyData() - return hmac.slice(0, 32) + const last = Buffer.alloc(8) // 8 bytes + last.set([ keyData.length ], last.length-1) + + const total = Buffer.concat([ keyData, data, last ]) + const hmac = hmacSign(total, key, 'sha512') + + return hmac.slice(0, 32) } -const to64BitNetworkOrder = function(e) { - const t = new ArrayBuffer(8) - new DataView(t).setUint32(4, e, !1) - return Buffer.from(t) +const to64BitNetworkOrder = (e: number) => { + const t = new ArrayBuffer(8) + new DataView(t).setUint32(4, e, !1) + return Buffer.from(t) } type Mac = { indexMac: Uint8Array, valueMac: Uint8Array, operation: proto.SyncdMutation.SyncdMutationSyncdOperation } const makeLtHashGenerator = ({ indexValueMap, hash }: Pick) => { - indexValueMap = { ...indexValueMap } - const addBuffs: ArrayBuffer[] = [] - const subBuffs: ArrayBuffer[] = [] + indexValueMap = { ...indexValueMap } + const addBuffs: ArrayBuffer[] = [] + const subBuffs: ArrayBuffer[] = [] - return { - mix: ({ indexMac, valueMac, operation }: Mac) => { - const indexMacBase64 = Buffer.from(indexMac).toString('base64') - const prevOp = indexValueMap[indexMacBase64] - if(operation === proto.SyncdMutation.SyncdMutationSyncdOperation.REMOVE) { - if(!prevOp) { - throw new Boom('tried remove, but no previous op', { data: { indexMac, valueMac } }) - } - // remove from index value mac, since this mutation is erased - delete indexValueMap[indexMacBase64] - } else { - addBuffs.push(new Uint8Array(valueMac).buffer) - // add this index into the history map - indexValueMap[indexMacBase64] = { valueMac } - } - if(prevOp) { - subBuffs.push(new Uint8Array(prevOp.valueMac).buffer) - } - }, - finish: () => { - const result = LT_HASH_ANTI_TAMPERING.subtractThenAdd(new Uint8Array(hash).buffer, addBuffs, subBuffs) - const buffer = Buffer.from(result) + return { + mix: ({ indexMac, valueMac, operation }: Mac) => { + const indexMacBase64 = Buffer.from(indexMac).toString('base64') + const prevOp = indexValueMap[indexMacBase64] + if(operation === proto.SyncdMutation.SyncdMutationSyncdOperation.REMOVE) { + if(!prevOp) { + throw new Boom('tried remove, but no previous op', { data: { indexMac, valueMac } }) + } - return { - hash: buffer, - indexValueMap - } - } - } + // remove from index value mac, since this mutation is erased + delete indexValueMap[indexMacBase64] + } else { + addBuffs.push(new Uint8Array(valueMac).buffer) + // add this index into the history map + indexValueMap[indexMacBase64] = { valueMac } + } + + if(prevOp) { + subBuffs.push(new Uint8Array(prevOp.valueMac).buffer) + } + }, + finish: () => { + const result = LT_HASH_ANTI_TAMPERING.subtractThenAdd(new Uint8Array(hash).buffer, addBuffs, subBuffs) + const buffer = Buffer.from(result) + + return { + hash: buffer, + indexValueMap + } + } + } } const generateSnapshotMac = (lthash: Uint8Array, version: number, name: WAPatchName, key: Buffer) => { - const total = Buffer.concat([ - lthash, - to64BitNetworkOrder(version), - Buffer.from(name, 'utf-8') - ]) - return hmacSign(total, key, 'sha256') + const total = Buffer.concat([ + lthash, + to64BitNetworkOrder(version), + Buffer.from(name, 'utf-8') + ]) + return hmacSign(total, key, 'sha256') } const generatePatchMac = (snapshotMac: Uint8Array, valueMacs: Uint8Array[], version: number, type: WAPatchName, key: Buffer) => { - const total = Buffer.concat([ - snapshotMac, - ...valueMacs, - to64BitNetworkOrder(version), - Buffer.from(type, 'utf-8') - ]) - return hmacSign(total, key) + const total = Buffer.concat([ + snapshotMac, + ...valueMacs, + to64BitNetworkOrder(version), + Buffer.from(type, 'utf-8') + ]) + return hmacSign(total, key) } export const newLTHashState = (): LTHashState => ({ version: 0, hash: Buffer.alloc(128), indexValueMap: {} }) export const encodeSyncdPatch = async( - { type, index, syncAction, apiVersion, operation }: WAPatchCreate, - myAppStateKeyId: string, - state: LTHashState, - getAppStateSyncKey: FetchAppStateSyncKey + { type, index, syncAction, apiVersion, operation }: WAPatchCreate, + myAppStateKeyId: string, + state: LTHashState, + getAppStateSyncKey: FetchAppStateSyncKey ) => { - const key = !!myAppStateKeyId ? await getAppStateSyncKey(myAppStateKeyId) : undefined - if(!key) { - throw new Boom(`myAppStateKey ("${myAppStateKeyId}") not present`, { statusCode: 404 }) - } - const encKeyId = Buffer.from(myAppStateKeyId, 'base64') + const key = !!myAppStateKeyId ? await getAppStateSyncKey(myAppStateKeyId) : undefined + if(!key) { + throw new Boom(`myAppStateKey ("${myAppStateKeyId}") not present`, { statusCode: 404 }) + } - state = { ...state, indexValueMap: { ...state.indexValueMap } } + const encKeyId = Buffer.from(myAppStateKeyId, 'base64') - const indexBuffer = Buffer.from(JSON.stringify(index)) - const dataProto = proto.SyncActionData.fromObject({ - index: indexBuffer, - value: syncAction, - padding: new Uint8Array(0), - version: apiVersion - }) - const encoded = proto.SyncActionData.encode(dataProto).finish() + state = { ...state, indexValueMap: { ...state.indexValueMap } } - const keyValue = mutationKeys(key!.keyData!) + const indexBuffer = Buffer.from(JSON.stringify(index)) + const dataProto = proto.SyncActionData.fromObject({ + index: indexBuffer, + value: syncAction, + padding: new Uint8Array(0), + version: apiVersion + }) + const encoded = proto.SyncActionData.encode(dataProto).finish() - const encValue = aesEncrypt(encoded, keyValue.valueEncryptionKey) - const valueMac = generateMac(operation, encValue, encKeyId, keyValue.valueMacKey) - const indexMac = hmacSign(indexBuffer, keyValue.indexKey) + const keyValue = mutationKeys(key!.keyData!) - // update LT hash - const generator = makeLtHashGenerator(state) - generator.mix({ indexMac, valueMac, operation }) - Object.assign(state, generator.finish()) + const encValue = aesEncrypt(encoded, keyValue.valueEncryptionKey) + const valueMac = generateMac(operation, encValue, encKeyId, keyValue.valueMacKey) + const indexMac = hmacSign(indexBuffer, keyValue.indexKey) - state.version += 1 + // update LT hash + const generator = makeLtHashGenerator(state) + generator.mix({ indexMac, valueMac, operation }) + Object.assign(state, generator.finish()) - const snapshotMac = generateSnapshotMac(state.hash, state.version, type, keyValue.snapshotMacKey) + state.version += 1 - const patch: proto.ISyncdPatch = { - patchMac: generatePatchMac(snapshotMac, [valueMac], state.version, type, keyValue.patchMacKey), - snapshotMac: snapshotMac, - keyId: { id: encKeyId }, - mutations: [ - { - operation: operation, - record: { - index: { - blob: indexMac - }, - value: { - blob: Buffer.concat([ encValue, valueMac ]) - }, - keyId: { id: encKeyId } - } - } - ] - } + const snapshotMac = generateSnapshotMac(state.hash, state.version, type, keyValue.snapshotMacKey) - const base64Index = indexMac.toString('base64') - state.indexValueMap[base64Index] = { valueMac } + const patch: proto.ISyncdPatch = { + patchMac: generatePatchMac(snapshotMac, [valueMac], state.version, type, keyValue.patchMacKey), + snapshotMac: snapshotMac, + keyId: { id: encKeyId }, + mutations: [ + { + operation: operation, + record: { + index: { + blob: indexMac + }, + value: { + blob: Buffer.concat([ encValue, valueMac ]) + }, + keyId: { id: encKeyId } + } + } + ] + } - return { patch, state } + const base64Index = indexMac.toString('base64') + state.indexValueMap[base64Index] = { valueMac } + + return { patch, state } } export const decodeSyncdMutations = async( - msgMutations: (proto.ISyncdMutation | proto.ISyncdRecord)[], - initialState: LTHashState, - getAppStateSyncKey: FetchAppStateSyncKey, - validateMacs: boolean + msgMutations: (proto.ISyncdMutation | proto.ISyncdRecord)[], + initialState: LTHashState, + getAppStateSyncKey: FetchAppStateSyncKey, + validateMacs: boolean ) => { - const keyCache: { [_: string]: ReturnType } = { } - const getKey = async(keyId: Uint8Array) => { - const base64Key = Buffer.from(keyId!).toString('base64') - let key = keyCache[base64Key] - if(!key) { - const keyEnc = await getAppStateSyncKey(base64Key) - if(!keyEnc) { - throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 404, data: { msgMutations } }) - } - const result = mutationKeys(keyEnc.keyData!) - keyCache[base64Key] = result - key = result - } - return key - } + const keyCache: { [_: string]: ReturnType } = { } + const getKey = async(keyId: Uint8Array) => { + const base64Key = Buffer.from(keyId!).toString('base64') + let key = keyCache[base64Key] + if(!key) { + const keyEnc = await getAppStateSyncKey(base64Key) + if(!keyEnc) { + throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 404, data: { msgMutations } }) + } - const ltGenerator = makeLtHashGenerator(initialState) + const result = mutationKeys(keyEnc.keyData!) + keyCache[base64Key] = result + key = result + } - const mutations: ChatMutation[] = [] - // indexKey used to HMAC sign record.index.blob - // valueEncryptionKey used to AES-256-CBC encrypt record.value.blob[0:-32] - // the remaining record.value.blob[0:-32] is the mac, it the HMAC sign of key.keyId + decoded proto data + length of bytes in keyId - for(const msgMutation of msgMutations!) { - // if it's a syncdmutation, get the operation property - // otherwise, if it's only a record -- it'll be a SET mutation - const operation = 'operation' in msgMutation ? msgMutation.operation : proto.SyncdMutation.SyncdMutationSyncdOperation.SET - const record = ('record' in msgMutation && !!msgMutation.record) ? msgMutation.record : msgMutation as proto.ISyncdRecord + return key + } + + const ltGenerator = makeLtHashGenerator(initialState) + + const mutations: ChatMutation[] = [] + // indexKey used to HMAC sign record.index.blob + // valueEncryptionKey used to AES-256-CBC encrypt record.value.blob[0:-32] + // the remaining record.value.blob[0:-32] is the mac, it the HMAC sign of key.keyId + decoded proto data + length of bytes in keyId + for(const msgMutation of msgMutations!) { + // if it's a syncdmutation, get the operation property + // otherwise, if it's only a record -- it'll be a SET mutation + const operation = 'operation' in msgMutation ? msgMutation.operation : proto.SyncdMutation.SyncdMutationSyncdOperation.SET + const record = ('record' in msgMutation && !!msgMutation.record) ? msgMutation.record : msgMutation as proto.ISyncdRecord - const key = await getKey(record.keyId!.id!) - const content = Buffer.from(record.value!.blob!) - const encContent = content.slice(0, -32) - const ogValueMac = content.slice(-32) - if(validateMacs) { - const contentHmac = generateMac(operation, encContent, record.keyId!.id!, key.valueMacKey) - if(Buffer.compare(contentHmac, ogValueMac) !== 0) { - throw new Boom('HMAC content verification failed') - } - } + const key = await getKey(record.keyId!.id!) + const content = Buffer.from(record.value!.blob!) + const encContent = content.slice(0, -32) + const ogValueMac = content.slice(-32) + if(validateMacs) { + const contentHmac = generateMac(operation, encContent, record.keyId!.id!, key.valueMacKey) + if(Buffer.compare(contentHmac, ogValueMac) !== 0) { + throw new Boom('HMAC content verification failed') + } + } - const result = aesDecrypt(encContent, key.valueEncryptionKey) - const syncAction = proto.SyncActionData.decode(result) + const result = aesDecrypt(encContent, key.valueEncryptionKey) + const syncAction = proto.SyncActionData.decode(result) - if(validateMacs) { - const hmac = hmacSign(syncAction.index, key.indexKey) - if(Buffer.compare(hmac, record.index!.blob) !== 0) { - throw new Boom('HMAC index verification failed') - } - } + if(validateMacs) { + const hmac = hmacSign(syncAction.index, key.indexKey) + if(Buffer.compare(hmac, record.index!.blob) !== 0) { + throw new Boom('HMAC index verification failed') + } + } - const indexStr = Buffer.from(syncAction.index).toString() - mutations.push({ - syncAction, - index: JSON.parse(indexStr), - }) - ltGenerator.mix({ - indexMac: record.index!.blob!, - valueMac: ogValueMac, - operation: operation - }) - } + const indexStr = Buffer.from(syncAction.index).toString() + mutations.push({ + syncAction, + index: JSON.parse(indexStr), + }) + ltGenerator.mix({ + indexMac: record.index!.blob!, + valueMac: ogValueMac, + operation: operation + }) + } - return { mutations, ...ltGenerator.finish() } + return { mutations, ...ltGenerator.finish() } } export const decodeSyncdPatch = async( - msg: proto.ISyncdPatch, - name: WAPatchName, - initialState: LTHashState, - getAppStateSyncKey: FetchAppStateSyncKey, - validateMacs: boolean + msg: proto.ISyncdPatch, + name: WAPatchName, + initialState: LTHashState, + getAppStateSyncKey: FetchAppStateSyncKey, + validateMacs: boolean ) => { - if(validateMacs) { - const base64Key = Buffer.from(msg.keyId!.id).toString('base64') - const mainKeyObj = await getAppStateSyncKey(base64Key) - const mainKey = mutationKeys(mainKeyObj.keyData!) - const mutationmacs = msg.mutations!.map(mutation => mutation.record!.value!.blob!.slice(-32)) + if(validateMacs) { + const base64Key = Buffer.from(msg.keyId!.id).toString('base64') + const mainKeyObj = await getAppStateSyncKey(base64Key) + const mainKey = mutationKeys(mainKeyObj.keyData!) + const mutationmacs = msg.mutations!.map(mutation => mutation.record!.value!.blob!.slice(-32)) - const patchMac = generatePatchMac(msg.snapshotMac, mutationmacs, toNumber(msg.version!.version), name, mainKey.patchMacKey) - if(Buffer.compare(patchMac, msg.patchMac) !== 0) { - throw new Boom('Invalid patch mac') - } - } + const patchMac = generatePatchMac(msg.snapshotMac, mutationmacs, toNumber(msg.version!.version), name, mainKey.patchMacKey) + if(Buffer.compare(patchMac, msg.patchMac) !== 0) { + throw new Boom('Invalid patch mac') + } + } - const result = await decodeSyncdMutations(msg!.mutations!, initialState, getAppStateSyncKey, validateMacs) - return result + const result = await decodeSyncdMutations(msg!.mutations!, initialState, getAppStateSyncKey, validateMacs) + return result } export const extractSyncdPatches = async(result: BinaryNode) => { - const syncNode = getBinaryNodeChild(result, 'sync') - const collectionNodes = getBinaryNodeChildren(syncNode, 'collection') + const syncNode = getBinaryNodeChild(result, 'sync') + const collectionNodes = getBinaryNodeChildren(syncNode, 'collection') - const final = { } as { [T in WAPatchName]: { patches: proto.ISyncdPatch[], hasMorePatches: boolean, snapshot?: proto.ISyncdSnapshot } } - await Promise.all( - collectionNodes.map( - async collectionNode => { - const patchesNode = getBinaryNodeChild(collectionNode, 'patches') + const final = { } as { [T in WAPatchName]: { patches: proto.ISyncdPatch[], hasMorePatches: boolean, snapshot?: proto.ISyncdSnapshot } } + await Promise.all( + collectionNodes.map( + async collectionNode => { + const patchesNode = getBinaryNodeChild(collectionNode, 'patches') - const patches = getBinaryNodeChildren(patchesNode || collectionNode, 'patch') - const snapshotNode = getBinaryNodeChild(collectionNode, 'snapshot') + const patches = getBinaryNodeChildren(patchesNode || collectionNode, 'patch') + const snapshotNode = getBinaryNodeChild(collectionNode, 'snapshot') - const syncds: proto.ISyncdPatch[] = [] - const name = collectionNode.attrs.name as WAPatchName + const syncds: proto.ISyncdPatch[] = [] + const name = collectionNode.attrs.name as WAPatchName - const hasMorePatches = collectionNode.attrs.has_more_patches == 'true' + const hasMorePatches = collectionNode.attrs.has_more_patches === 'true' - let snapshot: proto.ISyncdSnapshot | undefined = undefined - if(snapshotNode && !!snapshotNode.content) { - if(!Buffer.isBuffer(snapshotNode)) { - snapshotNode.content = Buffer.from(Object.values(snapshotNode.content)) - } - const blobRef = proto.ExternalBlobReference.decode( + let snapshot: proto.ISyncdSnapshot | undefined = undefined + if(snapshotNode && !!snapshotNode.content) { + if(!Buffer.isBuffer(snapshotNode)) { + snapshotNode.content = Buffer.from(Object.values(snapshotNode.content)) + } + + const blobRef = proto.ExternalBlobReference.decode( snapshotNode.content! as Buffer - ) - const data = await downloadExternalBlob(blobRef) - snapshot = proto.SyncdSnapshot.decode(data) - } + ) + const data = await downloadExternalBlob(blobRef) + snapshot = proto.SyncdSnapshot.decode(data) + } - for(let { content } of patches) { - if(content) { - if(!Buffer.isBuffer(content)) { - content = Buffer.from(Object.values(content)) - } - const syncd = proto.SyncdPatch.decode(content! as Uint8Array) - if(!syncd.version) { - syncd.version = { version: +collectionNode.attrs.version+1 } - } - syncds.push(syncd) - } - } + for(let { content } of patches) { + if(content) { + if(!Buffer.isBuffer(content)) { + content = Buffer.from(Object.values(content)) + } + + const syncd = proto.SyncdPatch.decode(content! as Uint8Array) + if(!syncd.version) { + syncd.version = { version: +collectionNode.attrs.version+1 } + } + + syncds.push(syncd) + } + } - final[name] = { patches: syncds, hasMorePatches, snapshot } - } - ) - ) + final[name] = { patches: syncds, hasMorePatches, snapshot } + } + ) + ) - return final + return final } export const downloadExternalBlob = async(blob: proto.IExternalBlobReference) => { - const stream = await downloadContentFromMessage(blob, 'md-app-state') + const stream = await downloadContentFromMessage(blob, 'md-app-state') let buffer = Buffer.from([]) - for await(const chunk of stream) { + for await (const chunk of stream) { buffer = Buffer.concat([buffer, chunk]) } - return buffer + + return buffer } export const downloadExternalPatch = async(blob: proto.IExternalBlobReference) => { - const buffer = await downloadExternalBlob(blob) + const buffer = await downloadExternalBlob(blob) const syncData = proto.SyncdMutations.decode(buffer) return syncData } export const decodeSyncdSnapshot = async( - name: WAPatchName, - snapshot: proto.ISyncdSnapshot, - getAppStateSyncKey: FetchAppStateSyncKey, - minimumVersionNumber: number | undefined, - validateMacs: boolean = true + name: WAPatchName, + snapshot: proto.ISyncdSnapshot, + getAppStateSyncKey: FetchAppStateSyncKey, + minimumVersionNumber: number | undefined, + validateMacs: boolean = true ) => { - const newState = newLTHashState() - newState.version = toNumber(snapshot.version!.version!) + const newState = newLTHashState() + newState.version = toNumber(snapshot.version!.version!) - let { hash, indexValueMap, mutations } = await decodeSyncdMutations(snapshot.records!, newState, getAppStateSyncKey, validateMacs) - newState.hash = hash - newState.indexValueMap = indexValueMap + const { hash, indexValueMap, mutations } = await decodeSyncdMutations(snapshot.records!, newState, getAppStateSyncKey, validateMacs) + newState.hash = hash + newState.indexValueMap = indexValueMap - if(validateMacs) { - const base64Key = Buffer.from(snapshot.keyId!.id!).toString('base64') - const keyEnc = await getAppStateSyncKey(base64Key) - if(!keyEnc) { - throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500 }) - } - const result = mutationKeys(keyEnc.keyData!) - const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey) - if(Buffer.compare(snapshot.mac!, computedSnapshotMac) !== 0) { - throw new Boom(`failed to verify LTHash at ${newState.version} of ${name} from snapshot`, { statusCode: 500 }) - } - } + if(validateMacs) { + const base64Key = Buffer.from(snapshot.keyId!.id!).toString('base64') + const keyEnc = await getAppStateSyncKey(base64Key) + if(!keyEnc) { + throw new Boom(`failed to find key "${base64Key}" to decode mutation`, { statusCode: 500 }) + } - const areMutationsRequired = typeof minimumVersionNumber === 'undefined' || newState.version > minimumVersionNumber - if(!areMutationsRequired) { - mutations = [] - } + const result = mutationKeys(keyEnc.keyData!) + const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey) + if(Buffer.compare(snapshot.mac!, computedSnapshotMac) !== 0) { + throw new Boom(`failed to verify LTHash at ${newState.version} of ${name} from snapshot`, { statusCode: 500 }) + } + } - return { - state: newState, - mutations - } + const areMutationsRequired = typeof minimumVersionNumber === 'undefined' || newState.version > minimumVersionNumber + if(!areMutationsRequired) { + // clear array + mutations.splice(0, mutations.length) + } + + return { + state: newState, + mutations + } } export const decodePatches = async( - name: WAPatchName, - syncds: proto.ISyncdPatch[], - initial: LTHashState, - getAppStateSyncKey: FetchAppStateSyncKey, - minimumVersionNumber?: number, - validateMacs: boolean = true + name: WAPatchName, + syncds: proto.ISyncdPatch[], + initial: LTHashState, + getAppStateSyncKey: FetchAppStateSyncKey, + minimumVersionNumber?: number, + validateMacs: boolean = true ) => { - const successfulMutations: ChatMutation[] = [] + const successfulMutations: ChatMutation[] = [] - const newState: LTHashState = { - ...initial, - indexValueMap: { ...initial.indexValueMap } - } + const newState: LTHashState = { + ...initial, + indexValueMap: { ...initial.indexValueMap } + } - for(const syncd of syncds) { - const { version, keyId, snapshotMac } = syncd - if(syncd.externalMutations) { - const ref = await downloadExternalPatch(syncd.externalMutations) - syncd.mutations.push(...ref.mutations) - } + for(const syncd of syncds) { + const { version, keyId, snapshotMac } = syncd + if(syncd.externalMutations) { + const ref = await downloadExternalPatch(syncd.externalMutations) + syncd.mutations.push(...ref.mutations) + } - const patchVersion = toNumber(version.version!) + const patchVersion = toNumber(version.version!) - newState.version = patchVersion + newState.version = patchVersion - const decodeResult = await decodeSyncdPatch(syncd, name, newState, getAppStateSyncKey, validateMacs) + const decodeResult = await decodeSyncdPatch(syncd, name, newState, getAppStateSyncKey, validateMacs) - newState.hash = decodeResult.hash - newState.indexValueMap = decodeResult.indexValueMap - if(typeof minimumVersionNumber === 'undefined' || patchVersion > minimumVersionNumber) { - successfulMutations.push(...decodeResult.mutations) - } + newState.hash = decodeResult.hash + newState.indexValueMap = decodeResult.indexValueMap + if(typeof minimumVersionNumber === 'undefined' || patchVersion > minimumVersionNumber) { + successfulMutations.push(...decodeResult.mutations) + } - if(validateMacs) { - const base64Key = Buffer.from(keyId!.id!).toString('base64') - const keyEnc = await getAppStateSyncKey(base64Key) - if(!keyEnc) { - throw new Boom(`failed to find key "${base64Key}" to decode mutation`) - } - const result = mutationKeys(keyEnc.keyData!) - const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey) - if(Buffer.compare(snapshotMac, computedSnapshotMac) !== 0) { - throw new Boom(`failed to verify LTHash at ${newState.version} of ${name}`) - } - } - } - return { - newMutations: successfulMutations, - state: newState - } + if(validateMacs) { + const base64Key = Buffer.from(keyId!.id!).toString('base64') + const keyEnc = await getAppStateSyncKey(base64Key) + if(!keyEnc) { + throw new Boom(`failed to find key "${base64Key}" to decode mutation`) + } + + const result = mutationKeys(keyEnc.keyData!) + const computedSnapshotMac = generateSnapshotMac(newState.hash, newState.version, name, result.snapshotMacKey) + if(Buffer.compare(snapshotMac, computedSnapshotMac) !== 0) { + throw new Boom(`failed to verify LTHash at ${newState.version} of ${name}`) + } + } + } + + return { + newMutations: successfulMutations, + state: newState + } } export const chatModificationToAppPatch = ( - mod: ChatModification, - jid: string + mod: ChatModification, + jid: string ) => { - const OP = proto.SyncdMutation.SyncdMutationSyncdOperation - const getMessageRange = (lastMessages: LastMessageList) => { - if(!lastMessages?.length) { - throw new Boom('Expected last message to be not from me', { statusCode: 400 }) - } - const lastMsg = lastMessages[lastMessages.length-1] - if(lastMsg.key.fromMe) { - throw new Boom('Expected last message in array to be not from me', { statusCode: 400 }) - } - const messageRange: proto.ISyncActionMessageRange = { - lastMessageTimestamp: lastMsg?.messageTimestamp, - messages: lastMessages - } - return messageRange - } - let patch: WAPatchCreate - if('mute' in mod) { - patch = { - syncAction: { - muteAction: { - muted: !!mod.mute, - muteEndTimestamp: mod.mute || undefined - } - }, - index: ['mute', jid], - type: 'regular_high', - apiVersion: 2, - operation: OP.SET - } - } else if('archive' in mod) { - patch = { - syncAction: { - archiveChatAction: { - archived: !!mod.archive, - messageRange: getMessageRange(mod.lastMessages) - } - }, - index: ['archive', jid], - type: 'regular_low', - apiVersion: 3, - operation: OP.SET - } - } else if('markRead' in mod) { - patch = { - syncAction: { - markChatAsReadAction: { - read: mod.markRead, - messageRange: getMessageRange(mod.lastMessages) - } - }, - index: ['markChatAsRead', jid], - type: 'regular_low', - apiVersion: 3, - operation: OP.SET - } - } else if('clear' in mod) { - if(mod.clear === 'all') { - throw new Boom('not supported') - } else { - const key = mod.clear.messages[0] - patch = { - syncAction: { - deleteMessageForMeAction: { - deleteMedia: false - } - }, - index: ['deleteMessageForMe', jid, key.id, key.fromMe ? '1' : '0', '0'], - type: 'regular_high', - apiVersion: 3, - operation: OP.SET - } - } - } else if('pin' in mod) { - patch = { - syncAction: { - pinAction: { - pinned: !!mod.pin - } - }, - index: ['pin_v1', jid], - type: 'regular_low', - apiVersion: 5, - operation: OP.SET - } - } else { - throw new Boom('not supported') - } + const OP = proto.SyncdMutation.SyncdMutationSyncdOperation + const getMessageRange = (lastMessages: LastMessageList) => { + if(!lastMessages?.length) { + throw new Boom('Expected last message to be not from me', { statusCode: 400 }) + } - patch.syncAction.timestamp = Date.now() + const lastMsg = lastMessages[lastMessages.length-1] + if(lastMsg.key.fromMe) { + throw new Boom('Expected last message in array to be not from me', { statusCode: 400 }) + } - return patch + const messageRange: proto.ISyncActionMessageRange = { + lastMessageTimestamp: lastMsg?.messageTimestamp, + messages: lastMessages + } + return messageRange + } + + let patch: WAPatchCreate + if('mute' in mod) { + patch = { + syncAction: { + muteAction: { + muted: !!mod.mute, + muteEndTimestamp: mod.mute || undefined + } + }, + index: ['mute', jid], + type: 'regular_high', + apiVersion: 2, + operation: OP.SET + } + } else if('archive' in mod) { + patch = { + syncAction: { + archiveChatAction: { + archived: !!mod.archive, + messageRange: getMessageRange(mod.lastMessages) + } + }, + index: ['archive', jid], + type: 'regular_low', + apiVersion: 3, + operation: OP.SET + } + } else if('markRead' in mod) { + patch = { + syncAction: { + markChatAsReadAction: { + read: mod.markRead, + messageRange: getMessageRange(mod.lastMessages) + } + }, + index: ['markChatAsRead', jid], + type: 'regular_low', + apiVersion: 3, + operation: OP.SET + } + } else if('clear' in mod) { + if(mod.clear === 'all') { + throw new Boom('not supported') + } else { + const key = mod.clear.messages[0] + patch = { + syncAction: { + deleteMessageForMeAction: { + deleteMedia: false + } + }, + index: ['deleteMessageForMe', jid, key.id, key.fromMe ? '1' : '0', '0'], + type: 'regular_high', + apiVersion: 3, + operation: OP.SET + } + } + } else if('pin' in mod) { + patch = { + syncAction: { + pinAction: { + pinned: !!mod.pin + } + }, + index: ['pin_v1', jid], + type: 'regular_low', + apiVersion: 5, + operation: OP.SET + } + } else { + throw new Boom('not supported') + } + + patch.syncAction.timestamp = Date.now() + + return patch } \ No newline at end of file diff --git a/src/Utils/crypto.ts b/src/Utils/crypto.ts index babffd0..81b4e74 100644 --- a/src/Utils/crypto.ts +++ b/src/Utils/crypto.ts @@ -1,5 +1,5 @@ -import * as curveJs from 'curve25519-js' import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes } from 'crypto' +import * as curveJs from 'curve25519-js' import { KeyPair } from '../Types' export const Curve = { @@ -23,70 +23,77 @@ export const Curve = { } export const signedKeyPair = (keyPair: KeyPair, keyId: number) => { - const signKeys = Curve.generateKeyPair() - const pubKey = new Uint8Array(33) - pubKey.set([5], 0) - pubKey.set(signKeys.public, 1) + const signKeys = Curve.generateKeyPair() + const pubKey = new Uint8Array(33) + pubKey.set([5], 0) + pubKey.set(signKeys.public, 1) - const signature = Curve.sign(keyPair.private, pubKey) + const signature = Curve.sign(keyPair.private, pubKey) - return { keyPair: signKeys, signature, keyId } + return { keyPair: signKeys, signature, keyId } } /** decrypt AES 256 CBC; where the IV is prefixed to the buffer */ export function aesDecrypt(buffer: Buffer, key: Buffer) { - return aesDecryptWithIV(buffer.slice(16, buffer.length), key, buffer.slice(0, 16)) + return aesDecryptWithIV(buffer.slice(16, buffer.length), key, buffer.slice(0, 16)) } + /** decrypt AES 256 CBC */ export function aesDecryptWithIV(buffer: Buffer, key: Buffer, IV: Buffer) { - const aes = createDecipheriv('aes-256-cbc', key, IV) - return Buffer.concat([aes.update(buffer), aes.final()]) + const aes = createDecipheriv('aes-256-cbc', key, IV) + return Buffer.concat([aes.update(buffer), aes.final()]) } + // encrypt AES 256 CBC; where a random IV is prefixed to the buffer export function aesEncrypt(buffer: Buffer | Uint8Array, key: Buffer) { - const IV = randomBytes(16) - const aes = createCipheriv('aes-256-cbc', key, IV) - return Buffer.concat([IV, aes.update(buffer), aes.final()]) // prefix IV to the buffer + const IV = randomBytes(16) + const aes = createCipheriv('aes-256-cbc', key, IV) + return Buffer.concat([IV, aes.update(buffer), aes.final()]) // prefix IV to the buffer } + // encrypt AES 256 CBC with a given IV export function aesEncrypWithIV(buffer: Buffer, key: Buffer, IV: Buffer) { - const aes = createCipheriv('aes-256-cbc', key, IV) - return Buffer.concat([aes.update(buffer), aes.final()]) // prefix IV to the buffer + const aes = createCipheriv('aes-256-cbc', key, IV) + return Buffer.concat([aes.update(buffer), aes.final()]) // prefix IV to the buffer } + // sign HMAC using SHA 256 export function hmacSign(buffer: Buffer | Uint8Array, key: Buffer | Uint8Array, variant: 'sha256' | 'sha512' = 'sha256') { - return createHmac(variant, key).update(buffer).digest() + return createHmac(variant, key).update(buffer).digest() } + export function sha256(buffer: Buffer) { - return createHash('sha256').update(buffer).digest() + return createHash('sha256').update(buffer).digest() } + // HKDF key expansion // from: https://github.com/benadida/node-hkdf export function hkdf(buffer: Uint8Array, expandedLength: number, { info, salt }: { salt?: Buffer, info?: string }) { - const hashAlg = 'sha256' - const hashLength = 32 - salt = salt || Buffer.alloc(hashLength) - // now we compute the PRK - const prk = createHmac(hashAlg, salt).update(buffer).digest() + const hashAlg = 'sha256' + const hashLength = 32 + salt = salt || Buffer.alloc(hashLength) + // now we compute the PRK + const prk = createHmac(hashAlg, salt).update(buffer).digest() - let prev = Buffer.from([]) - const buffers = [] - const num_blocks = Math.ceil(expandedLength / hashLength) + let prev = Buffer.from([]) + const buffers = [] + const num_blocks = Math.ceil(expandedLength / hashLength) - const infoBuff = Buffer.from(info || []) + const infoBuff = Buffer.from(info || []) - for (var i=0; i { - //const deviceIdentity = (stanza.content as BinaryNodeM[])?.find(m => m.tag === 'device-identity') - //const deviceIdentityBytes = deviceIdentity ? deviceIdentity.content as Buffer : undefined + //const deviceIdentity = (stanza.content as BinaryNodeM[])?.find(m => m.tag === 'device-identity') + //const deviceIdentityBytes = deviceIdentity ? deviceIdentity.content as Buffer : undefined - let msgType: MessageType - let chatId: string - let author: string + let msgType: MessageType + let chatId: string + let author: string - const msgId: string = stanza.attrs.id - const from: string = stanza.attrs.from - const participant: string | undefined = stanza.attrs.participant - const recipient: string | undefined = stanza.attrs.recipient + const msgId: string = stanza.attrs.id + const from: string = stanza.attrs.from + const participant: string | undefined = stanza.attrs.participant + const recipient: string | undefined = stanza.attrs.recipient - const isMe = (jid: string) => areJidsSameUser(jid, auth.creds.me!.id) + const isMe = (jid: string) => areJidsSameUser(jid, auth.creds.me!.id) - if(isJidUser(from)) { - if(recipient) { - if(!isMe(from)) { - throw new Boom('') - } - chatId = recipient - } else { - chatId = from - } - msgType = 'chat' - author = from - } else if(isJidGroup(from)) { - if(!participant) { - throw new Boom('No participant in group message') - } - msgType = 'group' - author = participant - chatId = from - } else if(isJidBroadcast(from)) { - if(!participant) { - throw new Boom('No participant in group message') - } - const isParticipantMe = isMe(participant) - if(isJidStatusBroadcast(from)) { - msgType = isParticipantMe ? 'direct_peer_status' : 'other_status' - } else { - msgType = isParticipantMe ? 'peer_broadcast' : 'other_broadcast' - } - chatId = from - author = participant - } + if(isJidUser(from)) { + if(recipient) { + if(!isMe(from)) { + throw new Boom('') + } - const sender = msgType === 'chat' ? author : chatId + chatId = recipient + } else { + chatId = from + } - const fromMe = isMe(stanza.attrs.participant || stanza.attrs.from) - const pushname = stanza.attrs.notify + msgType = 'chat' + author = from + } else if(isJidGroup(from)) { + if(!participant) { + throw new Boom('No participant in group message') + } + + msgType = 'group' + author = participant + chatId = from + } else if(isJidBroadcast(from)) { + if(!participant) { + throw new Boom('No participant in group message') + } + + const isParticipantMe = isMe(participant) + if(isJidStatusBroadcast(from)) { + msgType = isParticipantMe ? 'direct_peer_status' : 'other_status' + } else { + msgType = isParticipantMe ? 'peer_broadcast' : 'other_broadcast' + } + + chatId = from + author = participant + } + + const sender = msgType === 'chat' ? author : chatId + + const fromMe = isMe(stanza.attrs.participant || stanza.attrs.from) + const pushname = stanza.attrs.notify - const key: WAMessageKey = { - remoteJid: chatId, - fromMe, - id: msgId, - participant - } + const key: WAMessageKey = { + remoteJid: chatId, + fromMe, + id: msgId, + participant + } - const fullMessage: proto.IWebMessageInfo = { - key, - messageTimestamp: +stanza.attrs.t, - pushName: pushname - } + const fullMessage: proto.IWebMessageInfo = { + key, + messageTimestamp: +stanza.attrs.t, + pushName: pushname + } - if(key.fromMe) { - fullMessage.status = proto.WebMessageInfo.WebMessageInfoStatus.SERVER_ACK - } + if(key.fromMe) { + fullMessage.status = proto.WebMessageInfo.WebMessageInfoStatus.SERVER_ACK + } - if(Array.isArray(stanza.content)) { - for(const { tag, attrs, content } of stanza.content) { - if(tag !== 'enc') continue - if(!(content instanceof Uint8Array)) continue + if(Array.isArray(stanza.content)) { + for(const { tag, attrs, content } of stanza.content) { + if(tag !== 'enc') { + continue + } - let msgBuffer: Buffer + if(!(content instanceof Uint8Array)) { + continue + } - try { - const e2eType = attrs.type - switch(e2eType) { - case 'skmsg': - msgBuffer = await decryptGroupSignalProto(sender, author, content, auth) - break - case 'pkmsg': - case 'msg': - const user = isJidUser(sender) ? sender : author - msgBuffer = await decryptSignalProto(user, e2eType, content as Buffer, auth) - break - } - let msg: proto.IMessage = proto.Message.decode(unpadRandomMax16(msgBuffer)) - msg = msg.deviceSentMessage?.message || msg - if(msg.senderKeyDistributionMessage) { - await processSenderKeyMessage(author, msg.senderKeyDistributionMessage, auth) - } + let msgBuffer: Buffer - if(fullMessage.message) Object.assign(fullMessage.message, msg) - else fullMessage.message = msg - } catch(error) { - fullMessage.messageStubType = proto.WebMessageInfo.WebMessageInfoStubType.CIPHERTEXT - fullMessage.messageStubParameters = [error.message] - } - } - } + try { + const e2eType = attrs.type + switch (e2eType) { + case 'skmsg': + msgBuffer = await decryptGroupSignalProto(sender, author, content, auth) + break + case 'pkmsg': + case 'msg': + const user = isJidUser(sender) ? sender : author + msgBuffer = await decryptSignalProto(user, e2eType, content as Buffer, auth) + break + } - return fullMessage + let msg: proto.IMessage = proto.Message.decode(unpadRandomMax16(msgBuffer)) + msg = msg.deviceSentMessage?.message || msg + if(msg.senderKeyDistributionMessage) { + await processSenderKeyMessage(author, msg.senderKeyDistributionMessage, auth) + } + + if(fullMessage.message) { + Object.assign(fullMessage.message, msg) + } else { + fullMessage.message = msg + } + } catch(error) { + fullMessage.messageStubType = proto.WebMessageInfo.WebMessageInfoStubType.CIPHERTEXT + fullMessage.messageStubParameters = [error.message] + } + } + } + + return fullMessage } \ No newline at end of file diff --git a/src/Utils/generics.ts b/src/Utils/generics.ts index 54a37ff..566c377 100644 --- a/src/Utils/generics.ts +++ b/src/Utils/generics.ts @@ -2,217 +2,233 @@ import { Boom } from '@hapi/boom' import { randomBytes } from 'crypto' import { platform, release } from 'os' import { Logger } from 'pino' -import { ConnectionState } from '..' import { proto } from '../../WAProto' import { CommonBaileysEventEmitter, DisconnectReason } from '../Types' import { Binary } from '../WABinary' +import { ConnectionState } from '..' const PLATFORM_MAP = { - 'aix': 'AIX', - 'darwin': 'Mac OS', - 'win32': 'Windows', - 'android': 'Android' + 'aix': 'AIX', + 'darwin': 'Mac OS', + 'win32': 'Windows', + 'android': 'Android' } export const Browsers = { - ubuntu: browser => ['Ubuntu', browser, '18.04'] as [string, string, string], - macOS: browser => ['Mac OS', browser, '10.15.3'] as [string, string, string], - baileys: browser => ['Baileys', browser, '4.0.0'] as [string, string, string], - /** The appropriate browser based on your OS & release */ - appropriate: browser => [ PLATFORM_MAP[platform()] || 'Ubuntu', browser, release() ] as [string, string, string] + ubuntu: browser => ['Ubuntu', browser, '18.04'] as [string, string, string], + macOS: browser => ['Mac OS', browser, '10.15.3'] as [string, string, string], + baileys: browser => ['Baileys', browser, '4.0.0'] as [string, string, string], + /** The appropriate browser based on your OS & release */ + appropriate: browser => [ PLATFORM_MAP[platform()] || 'Ubuntu', browser, release() ] as [string, string, string] } export const BufferJSON = { - replacer: (k, value: any) => { - if(Buffer.isBuffer(value) || value instanceof Uint8Array || value?.type === 'Buffer') { - return { type: 'Buffer', data: Buffer.from(value?.data || value).toString('base64') } - } - return value - }, - reviver: (_, value: any) => { - if(typeof value === 'object' && !!value && (value.buffer === true || value.type === 'Buffer')) { - const val = value.data || value.value - return typeof val === 'string' ? Buffer.from(val, 'base64') : Buffer.from(val) - } - return value - } + replacer: (k, value: any) => { + if(Buffer.isBuffer(value) || value instanceof Uint8Array || value?.type === 'Buffer') { + return { type: 'Buffer', data: Buffer.from(value?.data || value).toString('base64') } + } + + return value + }, + reviver: (_, value: any) => { + if(typeof value === 'object' && !!value && (value.buffer === true || value.type === 'Buffer')) { + const val = value.data || value.value + return typeof val === 'string' ? Buffer.from(val, 'base64') : Buffer.from(val) + } + + return value + } } -export const writeRandomPadMax16 = function(e: Binary) { - function r(e: Binary, t: number) { - for (var r = 0; r < t; r++) - e.writeUint8(t) - } +export const writeRandomPadMax16 = (e: Binary) => { + function r(e: Binary, t: number) { + for(var r = 0; r < t; r++) { + e.writeUint8(t) + } + } - var t = randomBytes(1) - r(e, 1 + (15 & t[0])) - return e + var t = randomBytes(1) + r(e, 1 + (15 & t[0])) + return e } export const unpadRandomMax16 = (e: Uint8Array | Buffer) => { - const t = new Uint8Array(e); - if (0 === t.length) { - throw new Error('unpadPkcs7 given empty bytes'); - } + const t = new Uint8Array(e) + if(0 === t.length) { + throw new Error('unpadPkcs7 given empty bytes') + } - var r = t[t.length - 1]; - if (r > t.length) { - throw new Error(`unpad given ${t.length} bytes, but pad is ${r}`); - } + var r = t[t.length - 1] + if(r > t.length) { + throw new Error(`unpad given ${t.length} bytes, but pad is ${r}`) + } - return new Uint8Array(t.buffer, t.byteOffset, t.length - r); + return new Uint8Array(t.buffer, t.byteOffset, t.length - r) } export const encodeWAMessage = (message: proto.IMessage) => ( - Buffer.from( - writeRandomPadMax16( - new Binary(proto.Message.encode(message).finish()) - ).readByteArray() - ) + Buffer.from( + writeRandomPadMax16( + new Binary(proto.Message.encode(message).finish()) + ).readByteArray() + ) ) export const generateRegistrationId = () => ( - Uint16Array.from(randomBytes(2))[0] & 0x3fff + Uint16Array.from(randomBytes(2))[0] & 0x3fff ) export const encodeInt = (e: number, t: number) => { - for (var r = t, a = new Uint8Array(e), i = e - 1; i >= 0; i--) { - a[i] = 255 & r - r >>>= 8 - } - return a + for(var r = t, a = new Uint8Array(e), i = e - 1; i >= 0; i--) { + a[i] = 255 & r + r >>>= 8 + } + + return a } + export const encodeBigEndian = (e: number, t=4) => { - let r = e; - let a = new Uint8Array(t); - for (let i = t - 1; i >= 0; i--) { - a[i] = 255 & r - r >>>= 8 - } - return a + let r = e + const a = new Uint8Array(t) + for(let i = t - 1; i >= 0; i--) { + a[i] = 255 & r + r >>>= 8 + } + + return a } export const toNumber = (t: Long | number) => ((typeof t === 'object' && 'toNumber' in t) ? t.toNumber() : t) -export function shallowChanges (old: T, current: T, {lookForDeletedKeys}: {lookForDeletedKeys: boolean}): Partial { - let changes: Partial = {} - for (let key in current) { - if (old[key] !== current[key]) { - changes[key] = current[key] || null - } - } - if (lookForDeletedKeys) { - for (let key in old) { - if (!changes[key] && old[key] !== current[key]) { - changes[key] = current[key] || null - } - } - } - return changes +export function shallowChanges (old: T, current: T, { lookForDeletedKeys }: {lookForDeletedKeys: boolean}): Partial { + const changes: Partial = {} + for(const key in current) { + if(old[key] !== current[key]) { + changes[key] = current[key] || null + } + } + + if(lookForDeletedKeys) { + for(const key in old) { + if(!changes[key] && old[key] !== current[key]) { + changes[key] = current[key] || null + } + } + } + + return changes } + /** unix timestamp of a date in seconds */ export const unixTimestampSeconds = (date: Date = new Date()) => Math.floor(date.getTime()/1000) export type DebouncedTimeout = ReturnType export const debouncedTimeout = (intervalMs: number = 1000, task: () => void = undefined) => { - let timeout: NodeJS.Timeout - return { - start: (newIntervalMs?: number, newTask?: () => void) => { - task = newTask || task - intervalMs = newIntervalMs || intervalMs - timeout && clearTimeout(timeout) - timeout = setTimeout(task, intervalMs) - }, - cancel: () => { - timeout && clearTimeout(timeout) - timeout = undefined - }, - setTask: (newTask: () => void) => task = newTask, - setInterval: (newInterval: number) => intervalMs = newInterval - } + let timeout: NodeJS.Timeout + return { + start: (newIntervalMs?: number, newTask?: () => void) => { + task = newTask || task + intervalMs = newIntervalMs || intervalMs + timeout && clearTimeout(timeout) + timeout = setTimeout(task, intervalMs) + }, + cancel: () => { + timeout && clearTimeout(timeout) + timeout = undefined + }, + setTask: (newTask: () => void) => task = newTask, + setInterval: (newInterval: number) => intervalMs = newInterval + } } export const delay = (ms: number) => delayCancellable (ms).delay export const delayCancellable = (ms: number) => { - const stack = new Error().stack - let timeout: NodeJS.Timeout - let reject: (error) => void - const delay: Promise = new Promise((resolve, _reject) => { - timeout = setTimeout(resolve, ms) - reject = _reject - }) - const cancel = () => { - clearTimeout (timeout) - reject( - new Boom('Cancelled', { - statusCode: 500, - data: { - stack - } - }) - ) - } - return { delay, cancel } + const stack = new Error().stack + let timeout: NodeJS.Timeout + let reject: (error) => void + const delay: Promise = new Promise((resolve, _reject) => { + timeout = setTimeout(resolve, ms) + reject = _reject + }) + const cancel = () => { + clearTimeout (timeout) + reject( + new Boom('Cancelled', { + statusCode: 500, + data: { + stack + } + }) + ) + } + + return { delay, cancel } } + export async function promiseTimeout(ms: number, promise: (resolve: (v?: T)=>void, reject: (error) => void) => void) { - if (!ms) return new Promise (promise) - const stack = new Error().stack - // Create a promise that rejects in milliseconds - let {delay, cancel} = delayCancellable (ms) - const p = new Promise ((resolve, reject) => { - delay - .then(() => reject( - new Boom('Timed Out', { - statusCode: DisconnectReason.timedOut, - data: { - stack - } - }) - )) - .catch (err => reject(err)) + if(!ms) { + return new Promise (promise) + } + + const stack = new Error().stack + // Create a promise that rejects in milliseconds + const { delay, cancel } = delayCancellable (ms) + const p = new Promise ((resolve, reject) => { + delay + .then(() => reject( + new Boom('Timed Out', { + statusCode: DisconnectReason.timedOut, + data: { + stack + } + }) + )) + .catch (err => reject(err)) - promise (resolve, reject) - }) - .finally (cancel) - return p as Promise + promise (resolve, reject) + }) + .finally (cancel) + return p as Promise } + // generate a random ID to attach to a message export const generateMessageID = () => 'BAE5' + randomBytes(6).toString('hex').toUpperCase() export const bindWaitForConnectionUpdate = (ev: CommonBaileysEventEmitter) => ( - async(check: (u: Partial) => boolean, timeoutMs?: number) => { - let listener: (item: Partial) => void - await ( - promiseTimeout( - timeoutMs, - (resolve, reject) => { - listener = (update) => { - if(check(update)) { - resolve() - } else if(update.connection == 'close') { + async(check: (u: Partial) => boolean, timeoutMs?: number) => { + let listener: (item: Partial) => void + await ( + promiseTimeout( + timeoutMs, + (resolve, reject) => { + listener = (update) => { + if(check(update)) { + resolve() + } else if(update.connection === 'close') { reject(update.lastDisconnect?.error || new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed })) } } - ev.on('connection.update', listener) - } - ) - .finally(() => ( - ev.off('connection.update', listener) - )) - ) - } + + ev.on('connection.update', listener) + } + ) + .finally(() => ( + ev.off('connection.update', listener) + )) + ) + } ) export const printQRIfNecessaryListener = (ev: CommonBaileysEventEmitter, logger: Logger) => { - ev.on('connection.update', async({ qr }) => { - if(qr) { - const QR = await import('qrcode-terminal') - .catch(err => { - logger.error('QR code terminal not added as dependency') - }) - QR?.generate(qr, { small: true }) - } - }) + ev.on('connection.update', async({ qr }) => { + if(qr) { + const QR = await import('qrcode-terminal') + .catch(err => { + logger.error('QR code terminal not added as dependency') + }) + QR?.generate(qr, { small: true }) + } + }) } \ No newline at end of file diff --git a/src/Utils/history.ts b/src/Utils/history.ts index d53e84d..1caf4d5 100644 --- a/src/Utils/history.ts +++ b/src/Utils/history.ts @@ -1,17 +1,18 @@ -import { downloadContentFromMessage } from "./messages-media" -import { proto } from "../../WAProto" import { promisify } from 'util' -import { inflate } from "zlib" -import { Chat, Contact } from "../Types" +import { inflate } from 'zlib' +import { proto } from '../../WAProto' +import { Chat, Contact } from '../Types' +import { downloadContentFromMessage } from './messages-media' const inflatePromise = promisify(inflate) export const downloadHistory = async(msg: proto.IHistorySyncNotification) => { const stream = await downloadContentFromMessage(msg, 'history') let buffer = Buffer.from([]) - for await(const chunk of stream) { + for await (const chunk of stream) { buffer = Buffer.concat([buffer, chunk]) } + // decompress buffer buffer = await inflatePromise(buffer) @@ -24,45 +25,47 @@ export const processHistoryMessage = (item: proto.IHistorySync, historyCache: Se const messages: proto.IWebMessageInfo[] = [] const contacts: Contact[] = [] const chats: Chat[] = [] - switch(item.syncType) { - case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_BOOTSTRAP: - case proto.HistorySync.HistorySyncHistorySyncType.RECENT: - for(const chat of item.conversations) { - const contactId = `c:${chat.id}` - if(chat.name && !historyCache.has(contactId)) { - contacts.push({ - id: chat.id, - name: chat.name - }) - historyCache.add(contactId) - } + switch (item.syncType) { + case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_BOOTSTRAP: + case proto.HistorySync.HistorySyncHistorySyncType.RECENT: + for(const chat of item.conversations) { + const contactId = `c:${chat.id}` + if(chat.name && !historyCache.has(contactId)) { + contacts.push({ + id: chat.id, + name: chat.name + }) + historyCache.add(contactId) + } - for(const { message } of chat.messages || []) { - const uqId = `${message?.key.remoteJid}:${message.key.id}` - if(message && !historyCache.has(uqId)) { - messages.push(message) - historyCache.add(uqId) - } - } - - delete chat.messages - if(!historyCache.has(chat.id)) { - chats.push(chat) - historyCache.add(chat.id) + for(const { message } of chat.messages || []) { + const uqId = `${message?.key.remoteJid}:${message.key.id}` + if(message && !historyCache.has(uqId)) { + messages.push(message) + historyCache.add(uqId) } } - break - case proto.HistorySync.HistorySyncHistorySyncType.PUSH_NAME: - for(const c of item.pushnames) { - const contactId = `c:${c.id}` - if(historyCache.has(contactId)) { - contacts.push({ notify: c.pushname, id: c.id }) - historyCache.add(contactId) - } + + delete chat.messages + if(!historyCache.has(chat.id)) { + chats.push(chat) + historyCache.add(chat.id) } + } + break - case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_STATUS_V3: - // TODO + case proto.HistorySync.HistorySyncHistorySyncType.PUSH_NAME: + for(const c of item.pushnames) { + const contactId = `c:${c.id}` + if(historyCache.has(contactId)) { + contacts.push({ notify: c.pushname, id: c.id }) + historyCache.add(contactId) + } + } + + break + case proto.HistorySync.HistorySyncHistorySyncType.INITIAL_STATUS_V3: + // TODO break } diff --git a/src/Utils/legacy-msgs.ts b/src/Utils/legacy-msgs.ts index 590b65d..3c874da 100644 --- a/src/Utils/legacy-msgs.ts +++ b/src/Utils/legacy-msgs.ts @@ -1,75 +1,82 @@ import { Boom } from '@hapi/boom' import { randomBytes } from 'crypto' -import { decodeBinaryNodeLegacy, jidNormalizedUser } from "../WABinary" -import { aesDecrypt, hmacSign, hkdf, Curve } from "./crypto" +import { AuthenticationCreds, Contact, CurveKeyPair, DisconnectReason, LegacyAuthenticationCreds, WATag } from '../Types' +import { decodeBinaryNodeLegacy, jidNormalizedUser } from '../WABinary' +import { aesDecrypt, Curve, hkdf, hmacSign } from './crypto' import { BufferJSON } from './generics' -import { DisconnectReason, WATag, LegacyAuthenticationCreds, AuthenticationCreds, CurveKeyPair, Contact } from "../Types" export const newLegacyAuthCreds = () => ({ - clientID: randomBytes(16).toString('base64') + clientID: randomBytes(16).toString('base64') }) as LegacyAuthenticationCreds export const decodeWAMessage = ( - message: Buffer | string, - auth: { macKey: Buffer, encKey: Buffer }, - fromMe: boolean=false + message: Buffer | string, + auth: { macKey: Buffer, encKey: Buffer }, + fromMe: boolean=false ) => { - let commaIndex = message.indexOf(',') // all whatsapp messages have a tag and a comma, followed by the actual message - if (commaIndex < 0) throw new Boom('invalid message', { data: message }) // if there was no comma, then this message must be not be valid + let commaIndex = message.indexOf(',') // all whatsapp messages have a tag and a comma, followed by the actual message + if(commaIndex < 0) { + throw new Boom('invalid message', { data: message }) + } // if there was no comma, then this message must be not be valid - if (message[commaIndex+1] === ',') commaIndex += 1 - let data = message.slice(commaIndex+1, message.length) + if(message[commaIndex+1] === ',') { + commaIndex += 1 + } + + let data = message.slice(commaIndex+1, message.length) - // get the message tag. - // If a query was done, the server will respond with the same message tag we sent the query with - const messageTag: string = message.slice(0, commaIndex).toString() - let json: any - let tags: WATag - if(data.length) { - const possiblyEnc = (data.length > 32 && data.length % 16 === 0) - if(typeof data === 'string' || !possiblyEnc) { - json = JSON.parse(data.toString()) // parse the JSON - } else { - try { - json = JSON.parse(data.toString()) - } catch { - const { macKey, encKey } = auth || {} - if (!macKey || !encKey) { - throw new Boom('recieved encrypted buffer when auth creds unavailable', { data: message, statusCode: DisconnectReason.badSession }) - } - /* + // get the message tag. + // If a query was done, the server will respond with the same message tag we sent the query with + const messageTag: string = message.slice(0, commaIndex).toString() + let json: any + let tags: WATag + if(data.length) { + const possiblyEnc = (data.length > 32 && data.length % 16 === 0) + if(typeof data === 'string' || !possiblyEnc) { + json = JSON.parse(data.toString()) // parse the JSON + } else { + try { + json = JSON.parse(data.toString()) + } catch{ + const { macKey, encKey } = auth || {} + if(!macKey || !encKey) { + throw new Boom('recieved encrypted buffer when auth creds unavailable', { data: message, statusCode: DisconnectReason.badSession }) + } + + /* If the data recieved was not a JSON, then it must be an encrypted message. Such a message can only be decrypted if we're connected successfully to the servers & have encryption keys */ - if (fromMe) { - tags = [data[0], data[1]] - data = data.slice(2, data.length) - } + if(fromMe) { + tags = [data[0], data[1]] + data = data.slice(2, data.length) + } - const checksum = data.slice(0, 32) // the first 32 bytes of the buffer are the HMAC sign of the message - data = data.slice(32, data.length) // the actual message - const computedChecksum = hmacSign(data, macKey) // compute the sign of the message we recieved using our macKey + const checksum = data.slice(0, 32) // the first 32 bytes of the buffer are the HMAC sign of the message + data = data.slice(32, data.length) // the actual message + const computedChecksum = hmacSign(data, macKey) // compute the sign of the message we recieved using our macKey - if (checksum.equals(computedChecksum)) { - // the checksum the server sent, must match the one we computed for the message to be valid - const decrypted = aesDecrypt(data, encKey) // decrypt using AES - json = decodeBinaryNodeLegacy(decrypted, { index: 0 }) // decode the binary message into a JSON array - } else { - throw new Boom('Bad checksum', { - data: { - received: checksum.toString('hex'), - computed: computedChecksum.toString('hex'), - data: data.slice(0, 80).toString(), - tag: messageTag, - message: message.slice(0, 80).toString() - }, - statusCode: DisconnectReason.badSession - }) - } - } - } - } - return [messageTag, json, tags] as const + if(checksum.equals(computedChecksum)) { + // the checksum the server sent, must match the one we computed for the message to be valid + const decrypted = aesDecrypt(data, encKey) // decrypt using AES + json = decodeBinaryNodeLegacy(decrypted, { index: 0 }) // decode the binary message into a JSON array + } else { + throw new Boom('Bad checksum', { + data: { + received: checksum.toString('hex'), + computed: computedChecksum.toString('hex'), + data: data.slice(0, 80).toString(), + tag: messageTag, + message: message.slice(0, 80).toString() + }, + statusCode: DisconnectReason.badSession + }) + } + } + } + } + + return [messageTag, json, tags] as const } /** @@ -82,104 +89,110 @@ export const validateNewConnection = ( auth: LegacyAuthenticationCreds, curveKeys: CurveKeyPair ) => { - // set metadata: one's WhatsApp ID [cc][number]@s.whatsapp.net, name on WhatsApp, info about the phone - const onValidationSuccess = () => { + // set metadata: one's WhatsApp ID [cc][number]@s.whatsapp.net, name on WhatsApp, info about the phone + const onValidationSuccess = () => { const user: Contact = { - id: jidNormalizedUser(json.wid), - name: json.pushname - } + id: jidNormalizedUser(json.wid), + name: json.pushname + } return { user, auth, phone: json.phone } - } - if (!json.secret) { + } + + if(!json.secret) { // if we didn't get a secret, we don't need it, we're validated - if (json.clientToken && json.clientToken !== auth.clientToken) { + if(json.clientToken && json.clientToken !== auth.clientToken) { auth = { ...auth, clientToken: json.clientToken } } - if (json.serverToken && json.serverToken !== auth.serverToken) { + + if(json.serverToken && json.serverToken !== auth.serverToken) { auth = { ...auth, serverToken: json.serverToken } } + return onValidationSuccess() - } - const secret = Buffer.from(json.secret, 'base64') - if (secret.length !== 144) { + } + + const secret = Buffer.from(json.secret, 'base64') + if(secret.length !== 144) { throw new Error ('incorrect secret length received: ' + secret.length) - } + } - // generate shared key from our private key & the secret shared by the server - const sharedKey = Curve.sharedKey(curveKeys.private, secret.slice(0, 32)) - // expand the key to 80 bytes using HKDF - const expandedKey = hkdf(sharedKey as Buffer, 80, { }) + // generate shared key from our private key & the secret shared by the server + const sharedKey = Curve.sharedKey(curveKeys.private, secret.slice(0, 32)) + // expand the key to 80 bytes using HKDF + const expandedKey = hkdf(sharedKey as Buffer, 80, { }) - // perform HMAC validation. - const hmacValidationKey = expandedKey.slice(32, 64) - const hmacValidationMessage = Buffer.concat([secret.slice(0, 32), secret.slice(64, secret.length)]) + // perform HMAC validation. + const hmacValidationKey = expandedKey.slice(32, 64) + const hmacValidationMessage = Buffer.concat([secret.slice(0, 32), secret.slice(64, secret.length)]) - const hmac = hmacSign(hmacValidationMessage, hmacValidationKey) + const hmac = hmacSign(hmacValidationMessage, hmacValidationKey) - if (!hmac.equals(secret.slice(32, 64))) { + if(!hmac.equals(secret.slice(32, 64))) { // if the checksums didn't match throw new Boom('HMAC validation failed', { statusCode: 400 }) - } + } - // computed HMAC should equal secret[32:64] - // expandedKey[64:] + secret[64:] are the keys, encrypted using AES, that are used to encrypt/decrypt the messages recieved from WhatsApp - // they are encrypted using key: expandedKey[0:32] - const encryptedAESKeys = Buffer.concat([ + // computed HMAC should equal secret[32:64] + // expandedKey[64:] + secret[64:] are the keys, encrypted using AES, that are used to encrypt/decrypt the messages recieved from WhatsApp + // they are encrypted using key: expandedKey[0:32] + const encryptedAESKeys = Buffer.concat([ expandedKey.slice(64, expandedKey.length), secret.slice(64, secret.length), - ]) - const decryptedKeys = aesDecrypt(encryptedAESKeys, expandedKey.slice(0, 32)) - // set the credentials - auth = { + ]) + const decryptedKeys = aesDecrypt(encryptedAESKeys, expandedKey.slice(0, 32)) + // set the credentials + auth = { encKey: decryptedKeys.slice(0, 32), // first 32 bytes form the key to encrypt/decrypt messages macKey: decryptedKeys.slice(32, 64), // last 32 bytes from the key to sign messages clientToken: json.clientToken, serverToken: json.serverToken, clientID: auth.clientID, - } - return onValidationSuccess() + } + return onValidationSuccess() } export const computeChallengeResponse = (challenge: string, auth: LegacyAuthenticationCreds) => { const bytes = Buffer.from(challenge, 'base64') // decode the base64 encoded challenge string const signed = hmacSign(bytes, auth.macKey).toString('base64') // sign the challenge string with our macKey - return['admin', 'challenge', signed, auth.serverToken, auth.clientID] // prepare to send this signed string with the serverToken & clientID + return ['admin', 'challenge', signed, auth.serverToken, auth.clientID] // prepare to send this signed string with the serverToken & clientID } export const useSingleFileLegacyAuthState = (file: string) => { - // require fs here so that in case "fs" is not available -- the app does not crash + // require fs here so that in case "fs" is not available -- the app does not crash const { readFileSync, writeFileSync, existsSync } = require('fs') - let state: LegacyAuthenticationCreds + let state: LegacyAuthenticationCreds - if(existsSync(file)) { - state = JSON.parse( - readFileSync(file, { encoding: 'utf-8' }), - BufferJSON.reviver - ) - if(typeof state.encKey === 'string') { - state.encKey = Buffer.from(state.encKey, 'base64') - } - if(typeof state.macKey === 'string') { - state.macKey = Buffer.from(state.macKey, 'base64') - } - } else { - state = newLegacyAuthCreds() - } + if(existsSync(file)) { + state = JSON.parse( + readFileSync(file, { encoding: 'utf-8' }), + BufferJSON.reviver + ) + if(typeof state.encKey === 'string') { + state.encKey = Buffer.from(state.encKey, 'base64') + } - return { - state, - saveState: () => { - const str = JSON.stringify(state, BufferJSON.replacer, 2) - writeFileSync(file, str) - } - } + if(typeof state.macKey === 'string') { + state.macKey = Buffer.from(state.macKey, 'base64') + } + } else { + state = newLegacyAuthCreds() + } + + return { + state, + saveState: () => { + const str = JSON.stringify(state, BufferJSON.replacer, 2) + writeFileSync(file, str) + } + } } export const getAuthenticationCredsType = (creds: LegacyAuthenticationCreds | AuthenticationCreds) => { - if('clientID' in creds && !!creds.clientID) { - return 'legacy' - } - if('noiseKey' in creds && !!creds.noiseKey) { - return 'md' - } + if('clientID' in creds && !!creds.clientID) { + return 'legacy' + } + + if('noiseKey' in creds && !!creds.noiseKey) { + return 'md' + } } \ No newline at end of file diff --git a/src/Utils/lt-hash.ts b/src/Utils/lt-hash.ts index 0eeaaa4..bc9b057 100644 --- a/src/Utils/lt-hash.ts +++ b/src/Utils/lt-hash.ts @@ -6,7 +6,7 @@ import { hkdf } from './crypto' * if the same series of mutations was made sequentially. */ -const o = 128; +const o = 128 class d { @@ -16,41 +16,45 @@ class d { this.salt = e } add(e, t) { - var r = this; + var r = this for(const item of t) { e = r._addSingle(e, item) } + return e } subtract(e, t) { - var r = this; + var r = this for(const item of t) { e = r._subtractSingle(e, item) } + return e } subtractThenAdd(e, t, r) { - var n = this; + var n = this return n.add(n.subtract(e, r), t) } _addSingle(e, t) { - var r = this; - const n = new Uint8Array(hkdf(Buffer.from(t), o, { info: r.salt })).buffer; - return r.performPointwiseWithOverflow(e, n, ((e,t)=>e + t)) + var r = this + const n = new Uint8Array(hkdf(Buffer.from(t), o, { info: r.salt })).buffer + return r.performPointwiseWithOverflow(e, n, ((e, t) => e + t)) } _subtractSingle(e, t) { - var r = this; + var r = this - const n = new Uint8Array(hkdf(Buffer.from(t), o, { info: r.salt })).buffer; - return r.performPointwiseWithOverflow(e, n, ((e,t)=>e - t)) + const n = new Uint8Array(hkdf(Buffer.from(t), o, { info: r.salt })).buffer + return r.performPointwiseWithOverflow(e, n, ((e, t) => e - t)) } performPointwiseWithOverflow(e, t, r) { const n = new DataView(e) , i = new DataView(t) , a = new ArrayBuffer(n.byteLength) - , s = new DataView(a); - for (let e = 0; e < n.byteLength; e += 2) - s.setUint16(e, r(n.getUint16(e, !0), i.getUint16(e, !0)), !0); + , s = new DataView(a) + for(let e = 0; e < n.byteLength; e += 2) { + s.setUint16(e, r(n.getUint16(e, !0), i.getUint16(e, !0)), !0) + } + return a } } diff --git a/src/Utils/make-mutex.ts b/src/Utils/make-mutex.ts index 76f4148..8903b26 100644 --- a/src/Utils/make-mutex.ts +++ b/src/Utils/make-mutex.ts @@ -3,17 +3,20 @@ export default () => { let task = Promise.resolve() as Promise return { mutex(code: () => Promise):Promise { - task = (async () => { + task = (async() => { // wait for the previous task to complete // if there is an error, we swallow so as to not block the queue - try { await task } catch { } + try { + await task + } catch{ } + // execute the current task return code() - })() - // we replace the existing task, appending the new piece of execution to it - // so the next task will have to wait for this one to finish - return task + })() + // we replace the existing task, appending the new piece of execution to it + // so the next task will have to wait for this one to finish + return task }, } - } +} \ No newline at end of file diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index ab4a0c6..fab4930 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -1,303 +1,341 @@ -import type { Logger } from 'pino' -import type { IAudioMetadata } from 'music-metadata' import { Boom } from '@hapi/boom' -import * as Crypto from 'crypto' -import { Readable, Transform } from 'stream' -import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs' -import { exec } from 'child_process' -import { tmpdir } from 'os' -import { URL } from 'url' -import { join } from 'path' -import { once } from 'events' -import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType, DownloadableMessage, CommonSocketConfig, WAMediaUploadFunction, MediaConnInfo } from '../Types' -import { generateMessageID } from './generics' -import { hkdf } from './crypto' -import { DEFAULT_ORIGIN, MEDIA_PATH_MAP } from '../Defaults' import { AxiosRequestConfig } from 'axios' +import { exec } from 'child_process' +import * as Crypto from 'crypto' +import { once } from 'events' +import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs' +import type { IAudioMetadata } from 'music-metadata' +import { tmpdir } from 'os' +import { join } from 'path' +import type { Logger } from 'pino' +import { Readable, Transform } from 'stream' +import { URL } from 'url' +import { DEFAULT_ORIGIN, MEDIA_PATH_MAP } from '../Defaults' +import { CommonSocketConfig, DownloadableMessage, MediaConnInfo, MediaType, MessageType, WAGenericMediaMessage, WAMediaUpload, WAMediaUploadFunction, WAMessageContent, WAProto } from '../Types' +import { hkdf } from './crypto' +import { generateMessageID } from './generics' const getTmpFilesDirectory = () => tmpdir() const getImageProcessingLibrary = async() => { - const [jimp, sharp] = await Promise.all([ - (async() => { - const jimp = await ( - import('jimp') - .catch(() => { }) - ) - return jimp - })(), - (async() => { - const sharp = await ( - import('sharp') - .catch(() => { }) - ) - return sharp - })() - ]) - if(sharp) return { sharp } - if(jimp) return { jimp } + const [jimp, sharp] = await Promise.all([ + (async() => { + const jimp = await ( + import('jimp') + .catch(() => { }) + ) + return jimp + })(), + (async() => { + const sharp = await ( + import('sharp') + .catch(() => { }) + ) + return sharp + })() + ]) + if(sharp) { + return { sharp } + } - throw new Boom('No image processing library available') + if(jimp) { + return { jimp } + } + + throw new Boom('No image processing library available') } export const hkdfInfoKey = (type: MediaType) => { - let str: string = type - if(type === 'sticker') str = 'image' - if(type === 'md-app-state') str = 'App State' + let str: string = type + if(type === 'sticker') { + str = 'image' + } + + if(type === 'md-app-state') { + str = 'App State' + } - let hkdfInfo = str[0].toUpperCase() + str.slice(1) + const hkdfInfo = str[0].toUpperCase() + str.slice(1) return `WhatsApp ${hkdfInfo} Keys` } + /** generates all the keys required to encrypt/decrypt & sign a media message */ export function getMediaKeys(buffer, mediaType: MediaType) { - if (typeof buffer === 'string') { - buffer = Buffer.from(buffer.replace('data:;base64,', ''), 'base64') - } - // expand using HKDF to 112 bytes, also pass in the relevant app info - const expandedMediaKey = hkdf(buffer, 112, { info: hkdfInfoKey(mediaType) }) - return { - iv: expandedMediaKey.slice(0, 16), - cipherKey: expandedMediaKey.slice(16, 48), - macKey: expandedMediaKey.slice(48, 80), - } + if(typeof buffer === 'string') { + buffer = Buffer.from(buffer.replace('data:;base64,', ''), 'base64') + } + + // expand using HKDF to 112 bytes, also pass in the relevant app info + const expandedMediaKey = hkdf(buffer, 112, { info: hkdfInfoKey(mediaType) }) + return { + iv: expandedMediaKey.slice(0, 16), + cipherKey: expandedMediaKey.slice(16, 48), + macKey: expandedMediaKey.slice(48, 80), + } } + /** Extracts video thumb using FFMPEG */ -const extractVideoThumb = async ( - path: string, - destPath: string, - time: string, - size: { width: number; height: number }, -) => - new Promise((resolve, reject) => { - const cmd = `ffmpeg -ss ${time} -i ${path} -y -s ${size.width}x${size.height} -vframes 1 -f image2 ${destPath}` - exec(cmd, (err) => { - if (err) reject(err) - else resolve() - }) - }) as Promise +const extractVideoThumb = async( + path: string, + destPath: string, + time: string, + size: { width: number; height: number }, +) => new Promise((resolve, reject) => { + const cmd = `ffmpeg -ss ${time} -i ${path} -y -s ${size.width}x${size.height} -vframes 1 -f image2 ${destPath}` + exec(cmd, (err) => { + if(err) { + reject(err) + } else { + resolve() + } + }) +}) as Promise -export const extractImageThumb = async (bufferOrFilePath: Readable | Buffer | string) => { - if(bufferOrFilePath instanceof Readable) { - bufferOrFilePath = await toBuffer(bufferOrFilePath) - } - const lib = await getImageProcessingLibrary() - if('sharp' in lib) { - const result = await lib.sharp!.default(bufferOrFilePath) - .resize(32, 32) - .jpeg({ quality: 50 }) - .toBuffer() - return result - } else { - const { read, MIME_JPEG, RESIZE_BILINEAR } = lib.jimp +export const extractImageThumb = async(bufferOrFilePath: Readable | Buffer | string) => { + if(bufferOrFilePath instanceof Readable) { + bufferOrFilePath = await toBuffer(bufferOrFilePath) + } - const jimp = await read(bufferOrFilePath as any) - const result = await jimp - .quality(50) - .resize(32, 32, RESIZE_BILINEAR) - .getBufferAsync(MIME_JPEG) - return result - } + const lib = await getImageProcessingLibrary() + if('sharp' in lib) { + const result = await lib.sharp!.default(bufferOrFilePath) + .resize(32, 32) + .jpeg({ quality: 50 }) + .toBuffer() + return result + } else { + const { read, MIME_JPEG, RESIZE_BILINEAR } = lib.jimp + + const jimp = await read(bufferOrFilePath as any) + const result = await jimp + .quality(50) + .resize(32, 32, RESIZE_BILINEAR) + .getBufferAsync(MIME_JPEG) + return result + } } -export const generateProfilePicture = async (mediaUpload: WAMediaUpload) => { - let bufferOrFilePath: Buffer | string - if(Buffer.isBuffer(mediaUpload)) { - bufferOrFilePath = mediaUpload - } else if('url' in mediaUpload) { - bufferOrFilePath = mediaUpload.url.toString() - } else { - bufferOrFilePath = await toBuffer(mediaUpload.stream) - } - const lib = await getImageProcessingLibrary() - let img: Promise - if('sharp' in lib) { - img = lib.sharp!.default(bufferOrFilePath) - .resize(640, 640) - .jpeg({ - quality: 50, - }) - .toBuffer() - } else { - const { read, MIME_JPEG, RESIZE_BILINEAR } = lib.jimp - const jimp = await read(bufferOrFilePath as any) - const min = Math.min(jimp.getWidth(), jimp.getHeight()) - const cropped = jimp.crop(0, 0, min, min) +export const generateProfilePicture = async(mediaUpload: WAMediaUpload) => { + let bufferOrFilePath: Buffer | string + if(Buffer.isBuffer(mediaUpload)) { + bufferOrFilePath = mediaUpload + } else if('url' in mediaUpload) { + bufferOrFilePath = mediaUpload.url.toString() + } else { + bufferOrFilePath = await toBuffer(mediaUpload.stream) + } - img = cropped - .quality(50) - .resize(640, 640, RESIZE_BILINEAR) - .getBufferAsync(MIME_JPEG) - } + const lib = await getImageProcessingLibrary() + let img: Promise + if('sharp' in lib) { + img = lib.sharp!.default(bufferOrFilePath) + .resize(640, 640) + .jpeg({ + quality: 50, + }) + .toBuffer() + } else { + const { read, MIME_JPEG, RESIZE_BILINEAR } = lib.jimp + const jimp = await read(bufferOrFilePath as any) + const min = Math.min(jimp.getWidth(), jimp.getHeight()) + const cropped = jimp.crop(0, 0, min, min) + + img = cropped + .quality(50) + .resize(640, 640, RESIZE_BILINEAR) + .getBufferAsync(MIME_JPEG) + } - return { - img: await img, - } + return { + img: await img, + } } + /** gets the SHA256 of the given media message */ export const mediaMessageSHA256B64 = (message: WAMessageContent) => { - const media = Object.values(message)[0] as WAGenericMediaMessage - return media?.fileSha256 && Buffer.from(media.fileSha256).toString ('base64') + const media = Object.values(message)[0] as WAGenericMediaMessage + return media?.fileSha256 && Buffer.from(media.fileSha256).toString ('base64') } -export async function getAudioDuration (buffer: Buffer | string | Readable) { - const musicMetadata = await import('music-metadata') - let metadata: IAudioMetadata - if(Buffer.isBuffer(buffer)) { - metadata = await musicMetadata.parseBuffer(buffer, null, { duration: true }) - } else if(typeof buffer === 'string') { - const rStream = createReadStream(buffer) - metadata = await musicMetadata.parseStream(rStream, null, { duration: true }) - rStream.close() - } else { - metadata = await musicMetadata.parseStream(buffer, null, { duration: true }) - } - return metadata.format.duration; + +export async function getAudioDuration(buffer: Buffer | string | Readable) { + const musicMetadata = await import('music-metadata') + let metadata: IAudioMetadata + if(Buffer.isBuffer(buffer)) { + metadata = await musicMetadata.parseBuffer(buffer, null, { duration: true }) + } else if(typeof buffer === 'string') { + const rStream = createReadStream(buffer) + metadata = await musicMetadata.parseStream(rStream, null, { duration: true }) + rStream.close() + } else { + metadata = await musicMetadata.parseStream(buffer, null, { duration: true }) + } + + return metadata.format.duration } + export const toReadable = (buffer: Buffer) => { - const readable = new Readable({ read: () => {} }) - readable.push(buffer) - readable.push(null) - return readable + const readable = new Readable({ read: () => {} }) + readable.push(buffer) + readable.push(null) + return readable } + export const toBuffer = async(stream: Readable) => { - let buff = Buffer.alloc(0) - for await(const chunk of stream) { - buff = Buffer.concat([ buff, chunk ]) - } - return buff + let buff = Buffer.alloc(0) + for await (const chunk of stream) { + buff = Buffer.concat([ buff, chunk ]) + } + + return buff } -export const getStream = async (item: WAMediaUpload) => { - if(Buffer.isBuffer(item)) return { stream: toReadable(item), type: 'buffer' } - if('stream' in item) return { stream: item.stream, type: 'readable' } - if(item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) { - return { stream: await getHttpStream(item.url), type: 'remote' } - } - return { stream: createReadStream(item.url), type: 'file' } + +export const getStream = async(item: WAMediaUpload) => { + if(Buffer.isBuffer(item)) { + return { stream: toReadable(item), type: 'buffer' } + } + + if('stream' in item) { + return { stream: item.stream, type: 'readable' } + } + + if(item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) { + return { stream: await getHttpStream(item.url), type: 'remote' } + } + + return { stream: createReadStream(item.url), type: 'file' } } + /** generates a thumbnail for a given media, if required */ export async function generateThumbnail( - file: string, - mediaType: 'video' | 'image', - options: { + file: string, + mediaType: 'video' | 'image', + options: { logger?: Logger } ) { - let thumbnail: string - if(mediaType === 'image') { - const buff = await extractImageThumb(file) - thumbnail = buff.toString('base64') - } else if(mediaType === 'video') { - const imgFilename = join(getTmpFilesDirectory(), generateMessageID() + '.jpg') - try { - await extractVideoThumb(file, imgFilename, '00:00:00', { width: 32, height: 32 }) - const buff = await fs.readFile(imgFilename) - thumbnail = buff.toString('base64') + let thumbnail: string + if(mediaType === 'image') { + const buff = await extractImageThumb(file) + thumbnail = buff.toString('base64') + } else if(mediaType === 'video') { + const imgFilename = join(getTmpFilesDirectory(), generateMessageID() + '.jpg') + try { + await extractVideoThumb(file, imgFilename, '00:00:00', { width: 32, height: 32 }) + const buff = await fs.readFile(imgFilename) + thumbnail = buff.toString('base64') - await fs.unlink(imgFilename) - } catch (err) { - options.logger?.debug('could not generate video thumb: ' + err) - } - } + await fs.unlink(imgFilename) + } catch(err) { + options.logger?.debug('could not generate video thumb: ' + err) + } + } - return thumbnail + return thumbnail } + export const getHttpStream = async(url: string | URL, options: AxiosRequestConfig & { isStream?: true } = {}) => { - const { default: axios } = await import('axios') - const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' }) - return fetched.data as Readable -} + const { default: axios } = await import('axios') + const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' }) + return fetched.data as Readable +} + export const encryptedStream = async( - media: WAMediaUpload, - mediaType: MediaType, - saveOriginalFileIfRequired = true, - logger?: Logger + media: WAMediaUpload, + mediaType: MediaType, + saveOriginalFileIfRequired = true, + logger?: Logger ) => { - const { stream, type } = await getStream(media) + const { stream, type } = await getStream(media) - logger?.debug('fetched media stream') + logger?.debug('fetched media stream') - const mediaKey = Crypto.randomBytes(32) - const {cipherKey, iv, macKey} = getMediaKeys(mediaKey, mediaType) - // random name - //const encBodyPath = join(getTmpFilesDirectory(), mediaType + generateMessageID() + '.enc') - // const encWriteStream = createWriteStream(encBodyPath) - const encWriteStream = new Readable({ read: () => {} }) + const mediaKey = Crypto.randomBytes(32) + const { cipherKey, iv, macKey } = getMediaKeys(mediaKey, mediaType) + // random name + //const encBodyPath = join(getTmpFilesDirectory(), mediaType + generateMessageID() + '.enc') + // const encWriteStream = createWriteStream(encBodyPath) + const encWriteStream = new Readable({ read: () => {} }) - let bodyPath: string - let writeStream: WriteStream - let didSaveToTmpPath = false - if(type === 'file') { - bodyPath = (media as any).url - } else if(saveOriginalFileIfRequired) { - bodyPath = join(getTmpFilesDirectory(), mediaType + generateMessageID()) - writeStream = createWriteStream(bodyPath) - didSaveToTmpPath = true - } + let bodyPath: string + let writeStream: WriteStream + let didSaveToTmpPath = false + if(type === 'file') { + bodyPath = (media as any).url + } else if(saveOriginalFileIfRequired) { + bodyPath = join(getTmpFilesDirectory(), mediaType + generateMessageID()) + writeStream = createWriteStream(bodyPath) + didSaveToTmpPath = true + } - let fileLength = 0 - const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv) - let hmac = Crypto.createHmac('sha256', macKey).update(iv) - let sha256Plain = Crypto.createHash('sha256') - let sha256Enc = Crypto.createHash('sha256') + let fileLength = 0 + const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv) + let hmac = Crypto.createHmac('sha256', macKey).update(iv) + let sha256Plain = Crypto.createHash('sha256') + let sha256Enc = Crypto.createHash('sha256') - const onChunk = (buff: Buffer) => { - sha256Enc = sha256Enc.update(buff) - hmac = hmac.update(buff) - encWriteStream.push(buff) - } + const onChunk = (buff: Buffer) => { + sha256Enc = sha256Enc.update(buff) + hmac = hmac.update(buff) + encWriteStream.push(buff) + } - try { - for await(const data of stream) { - fileLength += data.length - sha256Plain = sha256Plain.update(data) - if(writeStream) { - if(!writeStream.write(data)) await once(writeStream, 'drain') - } - onChunk(aes.update(data)) - } - onChunk(aes.final()) + try { + for await (const data of stream) { + fileLength += data.length + sha256Plain = sha256Plain.update(data) + if(writeStream) { + if(!writeStream.write(data)) { + await once(writeStream, 'drain') + } + } + + onChunk(aes.update(data)) + } + + onChunk(aes.final()) - const mac = hmac.digest().slice(0, 10) - sha256Enc = sha256Enc.update(mac) + const mac = hmac.digest().slice(0, 10) + sha256Enc = sha256Enc.update(mac) - const fileSha256 = sha256Plain.digest() - const fileEncSha256 = sha256Enc.digest() + const fileSha256 = sha256Plain.digest() + const fileEncSha256 = sha256Enc.digest() - encWriteStream.push(mac) - encWriteStream.push(null) + encWriteStream.push(mac) + encWriteStream.push(null) - writeStream && writeStream.end() - stream.destroy() + writeStream && writeStream.end() + stream.destroy() - logger?.debug('encrypted data successfully') + logger?.debug('encrypted data successfully') - return { - mediaKey, - encWriteStream, - bodyPath, - mac, - fileEncSha256, - fileSha256, - fileLength, - didSaveToTmpPath - } - } catch(error) { - encWriteStream.destroy(error) - writeStream.destroy(error) - aes.destroy(error) - hmac.destroy(error) - sha256Plain.destroy(error) - sha256Enc.destroy(error) - stream.destroy(error) + return { + mediaKey, + encWriteStream, + bodyPath, + mac, + fileEncSha256, + fileSha256, + fileLength, + didSaveToTmpPath + } + } catch(error) { + encWriteStream.destroy(error) + writeStream.destroy(error) + aes.destroy(error) + hmac.destroy(error) + sha256Plain.destroy(error) + sha256Enc.destroy(error) + stream.destroy(error) - throw error - } + throw error + } } const DEF_HOST = 'mmg.whatsapp.net' const AES_CHUNK_SIZE = 16 const toSmallestChunkSize = (num: number) => { - return Math.floor(num / AES_CHUNK_SIZE) * AES_CHUNK_SIZE + return Math.floor(num / AES_CHUNK_SIZE) * AES_CHUNK_SIZE } type MediaDownloadOptions = { @@ -306,103 +344,106 @@ type MediaDownloadOptions = { } export const downloadContentFromMessage = async( - { mediaKey, directPath, url }: DownloadableMessage, - type: MediaType, - { startByte, endByte }: MediaDownloadOptions = { } + { mediaKey, directPath, url }: DownloadableMessage, + type: MediaType, + { startByte, endByte }: MediaDownloadOptions = { } ) => { - const downloadUrl = url || `https://${DEF_HOST}${directPath}` - let bytesFetched = 0 - let startChunk = 0 - let firstBlockIsIV = false - // if a start byte is specified -- then we need to fetch the previous chunk as that will form the IV - if(startByte) { - const chunk = toSmallestChunkSize(startByte || 0) - if(chunk) { - startChunk = chunk-AES_CHUNK_SIZE - bytesFetched = chunk + const downloadUrl = url || `https://${DEF_HOST}${directPath}` + let bytesFetched = 0 + let startChunk = 0 + let firstBlockIsIV = false + // if a start byte is specified -- then we need to fetch the previous chunk as that will form the IV + if(startByte) { + const chunk = toSmallestChunkSize(startByte || 0) + if(chunk) { + startChunk = chunk-AES_CHUNK_SIZE + bytesFetched = chunk - firstBlockIsIV = true - } - } - const endChunk = endByte ? toSmallestChunkSize(endByte || 0)+AES_CHUNK_SIZE : undefined + firstBlockIsIV = true + } + } - const headers: { [_: string]: string } = { - Origin: DEFAULT_ORIGIN, - } - if(startChunk || endChunk) { - headers.Range = `bytes=${startChunk}-` - if(endChunk) headers.Range += endChunk - } + const endChunk = endByte ? toSmallestChunkSize(endByte || 0)+AES_CHUNK_SIZE : undefined - // download the message - const fetched = await getHttpStream( - downloadUrl, - { - headers, - maxBodyLength: Infinity, - maxContentLength: Infinity, - } - ) + const headers: { [_: string]: string } = { + Origin: DEFAULT_ORIGIN, + } + if(startChunk || endChunk) { + headers.Range = `bytes=${startChunk}-` + if(endChunk) { + headers.Range += endChunk + } + } - let remainingBytes = Buffer.from([]) - const { cipherKey, iv } = getMediaKeys(mediaKey, type) + // download the message + const fetched = await getHttpStream( + downloadUrl, + { + headers, + maxBodyLength: Infinity, + maxContentLength: Infinity, + } + ) - let aes: Crypto.Decipher + let remainingBytes = Buffer.from([]) + const { cipherKey, iv } = getMediaKeys(mediaKey, type) - const pushBytes = (bytes: Buffer, push: (bytes: Buffer) => void) => { - if(startByte || endByte) { - const start = bytesFetched >= startByte ? undefined : Math.max(startByte-bytesFetched, 0) - const end = bytesFetched+bytes.length < endByte ? undefined : Math.max(endByte-bytesFetched, 0) + let aes: Crypto.Decipher + + const pushBytes = (bytes: Buffer, push: (bytes: Buffer) => void) => { + if(startByte || endByte) { + const start = bytesFetched >= startByte ? undefined : Math.max(startByte-bytesFetched, 0) + const end = bytesFetched+bytes.length < endByte ? undefined : Math.max(endByte-bytesFetched, 0) - push(bytes.slice(start, end)) + push(bytes.slice(start, end)) - bytesFetched += bytes.length - } else { - push(bytes) - } - } + bytesFetched += bytes.length + } else { + push(bytes) + } + } - const output = new Transform({ - transform(chunk, _, callback) { - let data = Buffer.concat([remainingBytes, chunk]) + const output = new Transform({ + transform(chunk, _, callback) { + let data = Buffer.concat([remainingBytes, chunk]) - const decryptLength = toSmallestChunkSize(data.length) - remainingBytes = data.slice(decryptLength) - data = data.slice(0, decryptLength) + const decryptLength = toSmallestChunkSize(data.length) + remainingBytes = data.slice(decryptLength) + data = data.slice(0, decryptLength) - if(!aes) { - let ivValue = iv - if(firstBlockIsIV) { - ivValue = data.slice(0, AES_CHUNK_SIZE) - data = data.slice(AES_CHUNK_SIZE) - } + if(!aes) { + let ivValue = iv + if(firstBlockIsIV) { + ivValue = data.slice(0, AES_CHUNK_SIZE) + data = data.slice(AES_CHUNK_SIZE) + } - aes = Crypto.createDecipheriv("aes-256-cbc", cipherKey, ivValue) - // if an end byte that is not EOF is specified - // stop auto padding (PKCS7) -- otherwise throws an error for decryption - if(endByte) { - aes.setAutoPadding(false) - } + aes = Crypto.createDecipheriv('aes-256-cbc', cipherKey, ivValue) + // if an end byte that is not EOF is specified + // stop auto padding (PKCS7) -- otherwise throws an error for decryption + if(endByte) { + aes.setAutoPadding(false) + } - } + } - try { - pushBytes(aes.update(data), b => this.push(b)) - callback() - } catch(error) { - callback(error) - } - }, - final(callback) { - try { - pushBytes(aes.final(), b => this.push(b)) - callback() - } catch(error) { - callback(error) - } - }, - }) - return fetched.pipe(output, { end: true }) + try { + pushBytes(aes.update(data), b => this.push(b)) + callback() + } catch(error) { + callback(error) + } + }, + final(callback) { + try { + pushBytes(aes.final(), b => this.push(b)) + callback() + } catch(error) { + callback(error) + } + }, + }) + return fetched.pipe(output, { end: true }) } /** @@ -410,121 +451,130 @@ export const downloadContentFromMessage = async( * @param message the media message you want to decode */ export async function decryptMediaMessageBuffer(message: WAMessageContent): Promise { - /* + /* One can infer media type from the key in the message it is usually written as [mediaType]Message. Eg. imageMessage, audioMessage etc. */ - const type = Object.keys(message)[0] as MessageType - if( + const type = Object.keys(message)[0] as MessageType + if( !type || type === 'conversation' || type === 'extendedTextMessage' ) { - throw new Boom(`no media message for "${type}"`, { statusCode: 400 }) - } - if (type === 'locationMessage' || type === 'liveLocationMessage') { - const buffer = Buffer.from(message[type].jpegThumbnail) - const readable = new Readable({ read: () => {} }) - readable.push(buffer) - readable.push(null) - return readable - } - let messageContent: WAGenericMediaMessage - if (message.productMessage) { - const product = message.productMessage.product?.productImage - if (!product) throw new Boom('product has no image', { statusCode: 400 }) - messageContent = product - } else { - messageContent = message[type] - } - return downloadContentFromMessage(messageContent, type.replace('Message', '') as MediaType) + throw new Boom(`no media message for "${type}"`, { statusCode: 400 }) + } + + if(type === 'locationMessage' || type === 'liveLocationMessage') { + const buffer = Buffer.from(message[type].jpegThumbnail) + const readable = new Readable({ read: () => {} }) + readable.push(buffer) + readable.push(null) + return readable + } + + let messageContent: WAGenericMediaMessage + if(message.productMessage) { + const product = message.productMessage.product?.productImage + if(!product) { + throw new Boom('product has no image', { statusCode: 400 }) + } + + messageContent = product + } else { + messageContent = message[type] + } + + return downloadContentFromMessage(messageContent, type.replace('Message', '') as MediaType) } + export function extensionForMediaMessage(message: WAMessageContent) { - const getExtension = (mimetype: string) => mimetype.split(';')[0].split('/')[1] - const type = Object.keys(message)[0] as MessageType - let extension: string - if( + const getExtension = (mimetype: string) => mimetype.split(';')[0].split('/')[1] + const type = Object.keys(message)[0] as MessageType + let extension: string + if( type === 'locationMessage' || type === 'liveLocationMessage' || type === 'productMessage' ) { - extension = '.jpeg' - } else { - const messageContent = message[type] as + extension = '.jpeg' + } else { + const messageContent = message[type] as | WAProto.VideoMessage | WAProto.ImageMessage | WAProto.AudioMessage | WAProto.DocumentMessage - extension = getExtension (messageContent.mimetype) - } - return extension + extension = getExtension (messageContent.mimetype) + } + + return extension } export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger }: CommonSocketConfig, refreshMediaConn: (force: boolean) => Promise): WAMediaUploadFunction => { - return async(stream, { mediaType, fileEncSha256B64, timeoutMs }) => { + return async(stream, { mediaType, fileEncSha256B64, timeoutMs }) => { const { default: axios } = await import('axios') - // send a query JSON to obtain the url & auth token to upload our media + // send a query JSON to obtain the url & auth token to upload our media let uploadInfo = await refreshMediaConn(false) let urls: { mediaUrl: string, directPath: string } - const hosts = [ ...customUploadHosts, ...uploadInfo.hosts ] + const hosts = [ ...customUploadHosts, ...uploadInfo.hosts ] - let chunks: Buffer[] = [] - for await(const chunk of stream) { - chunks.push(chunk) - } + const chunks: Buffer[] = [] + for await (const chunk of stream) { + chunks.push(chunk) + } - let reqBody = Buffer.concat(chunks) + let reqBody = Buffer.concat(chunks) - for (let { hostname, maxContentLengthBytes } of hosts) { - logger.debug(`uploading to "${hostname}"`) + for(const { hostname, maxContentLengthBytes } of hosts) { + logger.debug(`uploading to "${hostname}"`) const auth = encodeURIComponent(uploadInfo.auth) // the auth token const url = `https://${hostname}${MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}` let result: any try { - if(maxContentLengthBytes && reqBody.length > maxContentLengthBytes) { - throw new Boom(`Body too large for "${hostname}"`, { statusCode: 413 }) - } + if(maxContentLengthBytes && reqBody.length > maxContentLengthBytes) { + throw new Boom(`Body too large for "${hostname}"`, { statusCode: 413 }) + } const body = await axios.post( - url, - reqBody, + url, + reqBody, { headers: { 'Content-Type': 'application/octet-stream', 'Origin': DEFAULT_ORIGIN }, httpsAgent: fetchAgent, - timeout: timeoutMs, - responseType: 'json', - maxBodyLength: Infinity, - maxContentLength: Infinity, + timeout: timeoutMs, + responseType: 'json', + maxBodyLength: Infinity, + maxContentLength: Infinity, } ) - result = body.data + result = body.data if(result?.url || result?.directPath) { - urls = { - mediaUrl: result.url, - directPath: result.direct_path - } - break - } else { + urls = { + mediaUrl: result.url, + directPath: result.direct_path + } + break + } else { uploadInfo = await refreshMediaConn(true) throw new Error(`upload failed, reason: ${JSON.stringify(result)}`) } - } catch (error) { - if(axios.isAxiosError(error)) { - result = error.response?.data - } + } catch(error) { + if(axios.isAxiosError(error)) { + result = error.response?.data + } const isLast = hostname === hosts[uploadInfo.hosts.length-1]?.hostname logger.warn({ trace: error.stack, uploadResult: result }, `Error in uploading to ${hostname} ${isLast ? '' : ', retrying...'}`) } } - // clear buffer just to be sure we're releasing the memory - reqBody = undefined + + // clear buffer just to be sure we're releasing the memory + reqBody = undefined if(!urls) { throw new Boom( diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 31655f0..9b4cc0a 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -1,11 +1,12 @@ import { Boom } from '@hapi/boom' -import { promises as fs } from "fs" +import { promises as fs } from 'fs' import { proto } from '../../WAProto' -import { MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from "../Defaults" +import { MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from '../Defaults' import { AnyMediaMessageContent, AnyMessageContent, MediaGenerationOptions, + MediaType, MessageContentGenerationOptions, MessageGenerationOptions, MessageGenerationOptionsFromContent, @@ -13,13 +14,11 @@ import { WAMediaUpload, WAMessage, WAMessageContent, + WAMessageStatus, WAProto, - WATextMessage, - MediaType, - WAMessageStatus -} from "../Types" -import { generateMessageID, unixTimestampSeconds } from "./generics" -import { encryptedStream, generateThumbnail, getAudioDuration } from "./messages-media" + WATextMessage } from '../Types' +import { generateMessageID, unixTimestampSeconds } from './generics' +import { encryptedStream, generateThumbnail, getAudioDuration } from './messages-media' type MediaUploadData = { media: WAMediaUpload @@ -33,20 +32,20 @@ type MediaUploadData = { } const MIMETYPE_MAP: { [T in MediaType]: string } = { - image: 'image/jpeg', - video: 'video/mp4', - document: 'application/pdf', - audio: 'audio/ogg; codecs=opus', - sticker: 'image/webp', + image: 'image/jpeg', + video: 'video/mp4', + document: 'application/pdf', + audio: 'audio/ogg; codecs=opus', + sticker: 'image/webp', history: 'application/x-protobuf', - "md-app-state": 'application/x-protobuf', + 'md-app-state': 'application/x-protobuf', } const MessageTypeProto = { - 'image': WAProto.ImageMessage, - 'video': WAProto.VideoMessage, - 'audio': WAProto.AudioMessage, - 'sticker': WAProto.StickerMessage, + 'image': WAProto.ImageMessage, + 'video': WAProto.VideoMessage, + 'audio': WAProto.AudioMessage, + 'sticker': WAProto.StickerMessage, 'document': WAProto.DocumentMessage, } as const @@ -64,6 +63,7 @@ export const prepareWAMessageMedia = async( mediaType = key } } + const uploadData: MediaUploadData = { ...message, media: message[mediaType] @@ -74,13 +74,14 @@ export const prepareWAMessageMedia = async( ('url' in uploadData.media) && !!uploadData.media.url && !!options.mediaCache && ( - // generate the key - mediaType + ':' + uploadData.media.url!.toString() - ) + // generate the key + mediaType + ':' + uploadData.media.url!.toString() + ) if(mediaType === 'document' && !uploadData.fileName) { uploadData.fileName = 'file' } + if(!uploadData.mimetype) { uploadData.mimetype = MIMETYPE_MAP[mediaType] } @@ -89,7 +90,7 @@ export const prepareWAMessageMedia = async( if(cacheableKey) { const mediaBuff: Buffer = options.mediaCache!.get(cacheableKey) if(mediaBuff) { - logger?.debug({ cacheableKey }, `got media cache hit`) + logger?.debug({ cacheableKey }, 'got media cache hit') const obj = WAProto.Message.decode(mediaBuff) const key = `${mediaType}Message` @@ -117,9 +118,9 @@ export const prepareWAMessageMedia = async( // url safe Base64 encode the SHA256 hash of the body const fileEncSha256B64 = encodeURIComponent( fileEncSha256.toString('base64') - .replace(/\+/g, '-') - .replace(/\//g, '_') - .replace(/\=+$/, '') + .replace(/\+/g, '-') + .replace(/\//g, '_') + .replace(/\=+$/, '') ) const [{ mediaUrl, directPath }] = await Promise.all([ @@ -128,34 +129,35 @@ export const prepareWAMessageMedia = async( encWriteStream, { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs } ) - logger?.debug(`uploaded media`) + logger?.debug('uploaded media') return result })(), (async() => { try { if(requiresThumbnailComputation) { uploadData.jpegThumbnail = await generateThumbnail(bodyPath, mediaType as any, options) - logger?.debug(`generated thumbnail`) + logger?.debug('generated thumbnail') } - if (requiresDurationComputation) { + + if(requiresDurationComputation) { uploadData.seconds = await getAudioDuration(bodyPath) - logger?.debug(`computed audio duration`) + logger?.debug('computed audio duration') } - } catch (error) { + } catch(error) { logger?.warn({ trace: error.stack }, 'failed to obtain extra info') } })(), ]) - .finally( - async() => { - encWriteStream.destroy() - // remove tmp files - if(didSaveToTmpPath && bodyPath) { - await fs.unlink(bodyPath) - logger?.debug('removed tmp files') + .finally( + async() => { + encWriteStream.destroy() + // remove tmp files + if(didSaveToTmpPath && bodyPath) { + await fs.unlink(bodyPath) + logger?.debug('removed tmp files') + } } - } - ) + ) delete uploadData.media @@ -175,12 +177,13 @@ export const prepareWAMessageMedia = async( }) if(cacheableKey) { - logger.debug({ cacheableKey }, `set cache`) + logger.debug({ cacheableKey }, 'set cache') options.mediaCache!.set(cacheableKey, WAProto.Message.encode(obj).finish()) } return obj } + export const prepareDisappearingMessageSettingContent = (ephemeralExpiration?: number) => { ephemeralExpiration = ephemeralExpiration || 0 const content: WAMessageContent = { @@ -195,6 +198,7 @@ export const prepareDisappearingMessageSettingContent = (ephemeralExpiration?: n } return WAProto.Message.fromObject(content) } + /** * Generate forwarded message content like WA does * @param message the message to forward @@ -205,7 +209,10 @@ export const generateForwardMessageContent = ( forceForward?: boolean ) => { let content = message.message - if (!content) throw new Boom('no content in message', { statusCode: 400 }) + if(!content) { + throw new Boom('no content in message', { statusCode: 400 }) + } + // hacky copy content = proto.Message.decode(proto.Message.encode(message.message).finish()) @@ -213,17 +220,22 @@ export const generateForwardMessageContent = ( let score = content[key].contextInfo?.forwardingScore || 0 score += message.key.fromMe && !forceForward ? 0 : 1 - if (key === 'conversation') { + if(key === 'conversation') { content.extendedTextMessage = { text: content[key] } delete content.conversation key = 'extendedTextMessage' } - if (score > 0) content[key].contextInfo = { forwardingScore: score, isForwarded: true } - else content[key].contextInfo = {} + + if(score > 0) { + content[key].contextInfo = { forwardingScore: score, isForwarded: true } + } else { + content[key].contextInfo = {} + } return content } + export const generateWAMessageContent = async( message: AnyMessageContent, options: MessageContentGenerationOptions @@ -231,7 +243,7 @@ export const generateWAMessageContent = async( let m: WAMessageContent = {} if('text' in message) { const extContent = { ...message } as WATextMessage - if (!!options.getUrlInfo && message.text.match(URL_REGEX)) { + if(!!options.getUrlInfo && message.text.match(URL_REGEX)) { try { const data = await options.getUrlInfo(message.text) extContent.canonicalUrl = data['canonical-url'] @@ -240,16 +252,18 @@ export const generateWAMessageContent = async( extContent.description = data.description extContent.title = data.title extContent.previewType = 0 - } catch (error) { // ignore if fails + } catch(error) { // ignore if fails options.logger?.warn({ trace: error.stack }, 'url generation failed') } } + m.extendedTextMessage = extContent } else if('contacts' in message) { const contactLen = message.contacts.contacts.length if(!contactLen) { throw new Boom('require atleast 1 contact', { statusCode: 400 }) - } + } + if(contactLen === 1) { m.contactMessage = WAProto.ContactMessage.fromObject(message.contacts.contacts[0]) } else { @@ -269,8 +283,8 @@ export const generateWAMessageContent = async( ) } else if('disappearingMessagesInChat' in message) { const exp = typeof message.disappearingMessagesInChat === 'boolean' ? - (message.disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : - message.disappearingMessagesInChat + (message.disappearingMessagesInChat ? WA_DEFAULT_EPHEMERAL : 0) : + message.disappearingMessagesInChat m = prepareDisappearingMessageSettingContent(exp) } else { m = await prepareWAMessageMedia( @@ -278,6 +292,7 @@ export const generateWAMessageContent = async( options ) } + if('buttons' in message && !!message.buttons) { const buttonsMessage: proto.IButtonsMessage = { buttons: message.buttons!.map(b => ({ ...b, type: proto.Button.ButtonType.RESPONSE })) @@ -289,13 +304,14 @@ export const generateWAMessageContent = async( if('caption' in message) { buttonsMessage.contentText = message.caption } + const type = Object.keys(m)[0].replace('Message', '').toUpperCase() buttonsMessage.headerType = ButtonType[type] Object.assign(buttonsMessage, m) } - if ('footer' in message && !!message.footer) { + if('footer' in message && !!message.footer) { buttonsMessage.footerText = message.footer } @@ -325,7 +341,7 @@ export const generateWAMessageContent = async( m = { templateMessage } } - if ('sections' in message && !!message.sections) { + if('sections' in message && !!message.sections) { const listMessage: proto.IListMessage = { sections: message.sections, buttonText: message.buttonText, @@ -341,19 +357,24 @@ export const generateWAMessageContent = async( if('viewOnce' in message && !!message.viewOnce) { m = { viewOnceMessage: { message: m } } } + if('mentions' in message && message.mentions?.length) { const [messageType] = Object.keys(m) m[messageType].contextInfo = m[messageType] || { } m[messageType].contextInfo.mentionedJid = message.mentions } + return WAProto.Message.fromObject(m) } + export const generateWAMessageFromContent = ( jid: string, message: WAMessageContent, options: MessageGenerationOptionsFromContent ) => { - if(!options.timestamp) options.timestamp = new Date() // set timestamp to now + if(!options.timestamp) { + options.timestamp = new Date() + } // set timestamp to now const key = Object.keys(message)[0] const timestamp = unixTimestampSeconds(options.timestamp) @@ -373,6 +394,7 @@ export const generateWAMessageFromContent = ( message[key].contextInfo.remoteJid = quoted.key.remoteJid } } + if( // if we want to send a disappearing message !!options?.ephemeralExpiration && @@ -409,6 +431,7 @@ export const generateWAMessageFromContent = ( } return WAProto.WebMessageInfo.fromObject(messageJSON) } + export const generateWAMessage = async( jid: string, content: AnyMessageContent, @@ -434,6 +457,7 @@ export const getContentType = (content: WAProto.IMessage | undefined) => { return key as keyof typeof content } } + /** * Extract the true message content from a message * Eg. extracts the inner message from a disappearing message/view once message @@ -447,17 +471,18 @@ export const extractMessageContent = (content: WAMessageContent | undefined | nu if(content?.buttonsMessage) { const { buttonsMessage } = content if(buttonsMessage.imageMessage) { - return { imageMessage: buttonsMessage.imageMessage } + return { imageMessage: buttonsMessage.imageMessage } } else if(buttonsMessage.documentMessage) { - return { documentMessage: buttonsMessage.documentMessage } + return { documentMessage: buttonsMessage.documentMessage } } else if(buttonsMessage.videoMessage) { - return { videoMessage: buttonsMessage.videoMessage } + return { videoMessage: buttonsMessage.videoMessage } } else if(buttonsMessage.locationMessage) { - return { locationMessage: buttonsMessage.locationMessage } + return { locationMessage: buttonsMessage.locationMessage } } else { - return { conversation: buttonsMessage.contentText } + return { conversation: buttonsMessage.contentText } } } + return content } @@ -465,6 +490,6 @@ export const extractMessageContent = (content: WAMessageContent | undefined | nu * Returns the device predicted by message ID */ export const getDevice = (id: string) => { - const deviceType = id.length > 21 ? 'android' : id.substring(0, 2) == '3A' ? 'ios' : 'web' - return deviceType + const deviceType = id.length > 21 ? 'android' : id.substring(0, 2) === '3A' ? 'ios' : 'web' + return deviceType } diff --git a/src/Utils/noise-handler.ts b/src/Utils/noise-handler.ts index 28039cf..def4be1 100644 --- a/src/Utils/noise-handler.ts +++ b/src/Utils/noise-handler.ts @@ -1,15 +1,15 @@ -import { sha256, Curve, hkdf } from "./crypto"; -import { Binary } from "../WABinary"; -import { createCipheriv, createDecipheriv } from "crypto"; -import { NOISE_MODE, NOISE_WA_HEADER } from "../Defaults"; -import { KeyPair } from "../Types"; -import { BinaryNode, decodeBinaryNode } from "../WABinary"; -import { Boom } from "@hapi/boom"; +import { Boom } from '@hapi/boom' +import { createCipheriv, createDecipheriv } from 'crypto' import { proto } from '../../WAProto' +import { NOISE_MODE, NOISE_WA_HEADER } from '../Defaults' +import { KeyPair } from '../Types' +import { Binary } from '../WABinary' +import { BinaryNode, decodeBinaryNode } from '../WABinary' +import { Curve, hkdf, sha256 } from './crypto' const generateIV = (counter: number) => { - const iv = new ArrayBuffer(12); - new DataView(iv).setUint32(8, counter); + const iv = new ArrayBuffer(12) + new DataView(iv).setUint32(8, counter) return new Uint8Array(iv) } @@ -18,9 +18,10 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key const authenticate = (data: Uint8Array) => { if(!isFinished) { - hash = sha256( Buffer.from(Binary.build(hash, data).readByteArray()) ) + hash = sha256(Buffer.from(Binary.build(hash, data).readByteArray())) } } + const encrypt = (plaintext: Uint8Array) => { const authTagLength = 128 >> 3 const cipher = createCipheriv('aes-256-gcm', encKey, generateIV(writeCounter), { authTagLength }) @@ -33,6 +34,7 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key authenticate(result) return result } + const decrypt = (ciphertext: Uint8Array) => { // before the handshake is finished, we use the same counter // after handshake, the counters are different @@ -48,16 +50,21 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key const result = Buffer.concat([cipher.update(enc), cipher.final()]) - if(isFinished) readCounter += 1 - else writeCounter += 1 + if(isFinished) { + readCounter += 1 + } else { + writeCounter += 1 + } authenticate(ciphertext) return result } + const localHKDF = (data: Uint8Array) => { const key = hkdf(Buffer.from(data), 64, { salt, info: '' }) return [key.slice(0, 32), key.slice(32)] } + const mixIntoKey = (data: Uint8Array) => { const [write, read] = localHKDF(data) salt = write @@ -66,15 +73,16 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key readCounter = 0 writeCounter = 0 } + const finishInit = () => { - const [write, read] = localHKDF(new Uint8Array(0)) - encKey = write + const [write, read] = localHKDF(new Uint8Array(0)) + encKey = write decKey = read hash = Buffer.from([]) readCounter = 0 writeCounter = 0 isFinished = true - } + } const data = Binary.build(NOISE_MODE).readBuffer() let hash = Buffer.from(data.byteLength === 32 ? data : sha256(Buffer.from(data))) @@ -123,11 +131,12 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key if(isFinished) { data = encrypt(data) } + const introSize = sentIntro ? 0 : NOISE_WA_HEADER.length outBinary.ensureAdditionalCapacity(introSize + 3 + data.byteLength) - if (!sentIntro) { + if(!sentIntro) { outBinary.writeByteArray(NOISE_WA_HEADER) sentIntro = true } @@ -146,6 +155,7 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key const getBytesSize = () => { return (inBinary.readUint8() << 16) | inBinary.readUint16() } + const peekSize = () => { return !(inBinary.size() < 3) && getBytesSize() <= inBinary.size() } @@ -159,8 +169,10 @@ export const makeNoiseHandler = ({ public: publicKey, private: privateKey }: Key const unpacked = new Binary(result).decompressed() frame = decodeBinaryNode(unpacked) } + onFrame(frame) } + inBinary.peek(peekSize) } } diff --git a/src/Utils/signal.ts b/src/Utils/signal.ts index 88533d8..7b0dfa2 100644 --- a/src/Utils/signal.ts +++ b/src/Utils/signal.ts @@ -1,10 +1,10 @@ import * as libsignal from 'libsignal' -import { encodeBigEndian } from "./generics" -import { Curve } from "./crypto" -import { SenderKeyDistributionMessage, GroupSessionBuilder, SenderKeyRecord, SenderKeyName, GroupCipher } from '../../WASignalGroup' -import { SignalIdentity, SignalKeyStore, SignedKeyPair, KeyPair, SignalAuthState, AuthenticationCreds } from "../Types/Auth" -import { assertNodeErrorFree, BinaryNode, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildUInt, jidDecode, JidWithDevice, getBinaryNodeChildren } from "../WABinary" -import { proto } from "../../WAProto" +import { proto } from '../../WAProto' +import { GroupCipher, GroupSessionBuilder, SenderKeyDistributionMessage, SenderKeyName, SenderKeyRecord } from '../../WASignalGroup' +import { AuthenticationCreds, KeyPair, SignalAuthState, SignalIdentity, SignalKeyStore, SignedKeyPair } from '../Types/Auth' +import { assertNodeErrorFree, BinaryNode, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildren, getBinaryNodeChildUInt, jidDecode, JidWithDevice } from '../WABinary' +import { Curve } from './crypto' +import { encodeBigEndian } from './generics' export const generateSignalPubKey = (pubKey: Uint8Array | Buffer) => { const newPub = Buffer.alloc(33) @@ -38,12 +38,13 @@ export const getPreKeys = async({ get }: SignalKeyStore, min: number, limit: num for(let id = min; id < limit;id++) { idList.push(id.toString()) } + return get('pre-key', idList) } export const generateOrGetPreKeys = (creds: AuthenticationCreds, range: number) => { const avaliable = creds.nextPreKeyId - creds.firstUnuploadedPreKeyId - const remaining = range - avaliable + const remaining = range - avaliable const lastPreKeyId = creds.nextPreKeyId + remaining - 1 const newPreKeys: { [id: number]: KeyPair } = { } if(remaining > 0) { @@ -51,6 +52,7 @@ export const generateOrGetPreKeys = (creds: AuthenticationCreds, range: number) newPreKeys[i] = Curve.generateKeyPair() } } + return { newPreKeys, lastPreKeyId, @@ -83,7 +85,7 @@ export const xmppPreKey = (pair: KeyPair, id: number): BinaryNode => ( ) export const signalStorage = ({ creds, keys }: SignalAuthState) => ({ - loadSession: async (id: string) => { + loadSession: async(id: string) => { const { [id]: sess } = await keys.get('session', [id]) if(sess) { return libsignal.SessionRecord.deserialize(sess) @@ -115,7 +117,9 @@ export const signalStorage = ({ creds, keys }: SignalAuthState) => ({ }, loadSenderKey: async(keyId: string) => { const { [keyId]: key } = await keys.get('sender-key', [keyId]) - if(key) return new SenderKeyRecord(key) + if(key) { + return new SenderKeyRecord(key) + } }, storeSenderKey: async(keyId, key) => { await keys.set({ 'sender-key': { [keyId]: key.serialize() } }) @@ -144,7 +148,7 @@ export const processSenderKeyMessage = async( item: proto.ISenderKeyDistributionMessage, auth: SignalAuthState ) => { - const builder = new GroupSessionBuilder(signalStorage(auth)) + const builder = new GroupSessionBuilder(signalStorage(auth)) const senderName = jidToSignalSenderKeyName(item.groupId, authorJid) const senderMsg = new SenderKeyDistributionMessage(null, null, null, null, item.axolotlSenderKeyDistributionMessage) @@ -153,6 +157,7 @@ export const processSenderKeyMessage = async( const record = new SenderKeyRecord() await auth.keys.set({ 'sender-key': { [senderName]: record } }) } + await builder.process(senderName, senderMsg) } @@ -160,14 +165,15 @@ export const decryptSignalProto = async(user: string, type: 'pkmsg' | 'msg', msg const addr = jidToSignalProtocolAddress(user) const session = new libsignal.SessionCipher(signalStorage(auth), addr) let result: Buffer - switch(type) { - case 'pkmsg': - result = await session.decryptPreKeyWhisperMessage(msg) + switch (type) { + case 'pkmsg': + result = await session.decryptPreKeyWhisperMessage(msg) break - case 'msg': - result = await session.decryptWhisperMessage(msg) + case 'msg': + result = await session.decryptWhisperMessage(msg) break } + return result } @@ -205,17 +211,18 @@ export const encryptSenderKeyMsgSignalProto = async(group: string, data: Uint8Ar export const parseAndInjectE2ESessions = async(node: BinaryNode, auth: SignalAuthState) => { const extractKey = (key: BinaryNode) => ( key ? ({ - keyId: getBinaryNodeChildUInt(key, 'id', 3), - publicKey: generateSignalPubKey( + keyId: getBinaryNodeChildUInt(key, 'id', 3), + publicKey: generateSignalPubKey( getBinaryNodeChildBuffer(key, 'value') ), - signature: getBinaryNodeChildBuffer(key, 'signature'), - }) : undefined + signature: getBinaryNodeChildBuffer(key, 'signature'), + }) : undefined ) const nodes = getBinaryNodeChildren(getBinaryNodeChild(node, 'list'), 'user') for(const node of nodes) { assertNodeErrorFree(node) } + await Promise.all( nodes.map( async node => { @@ -264,5 +271,6 @@ export const extractDeviceJids = (result: BinaryNode, myJid: string, excludeZero } } } + return extracted } \ No newline at end of file diff --git a/src/Utils/validate-connection.ts b/src/Utils/validate-connection.ts index 88468b8..8656493 100644 --- a/src/Utils/validate-connection.ts +++ b/src/Utils/validate-connection.ts @@ -1,152 +1,152 @@ import { Boom } from '@hapi/boom' import { proto } from '../../WAProto' -import type { SocketConfig, AuthenticationCreds, SignalCreds } from "../Types" +import type { AuthenticationCreds, SignalCreds, SocketConfig } from '../Types' +import { Binary, BinaryNode, getAllBinaryNodeChildren, jidDecode, S_WHATSAPP_NET } from '../WABinary' import { Curve, hmacSign } from './crypto' import { encodeInt } from './generics' -import { BinaryNode, S_WHATSAPP_NET, jidDecode, Binary, getAllBinaryNodeChildren } from '../WABinary' import { createSignalIdentity } from './signal' const ENCODED_VERSION = 'S9Kdc4pc4EJryo21snc5cg==' const getUserAgent = ({ version, browser }: Pick) => ({ - appVersion: { - primary: version[0], - secondary: version[1], - tertiary: version[2], - }, - platform: 14, - releaseChannel: 0, - mcc: "000", - mnc: "000", - osVersion: browser[2], - manufacturer: "", - device: browser[1], - osBuildNumber: "0.1", - localeLanguageIso6391: 'en', - localeCountryIso31661Alpha2: 'en', + appVersion: { + primary: version[0], + secondary: version[1], + tertiary: version[2], + }, + platform: 14, + releaseChannel: 0, + mcc: '000', + mnc: '000', + osVersion: browser[2], + manufacturer: '', + device: browser[1], + osBuildNumber: '0.1', + localeLanguageIso6391: 'en', + localeCountryIso31661Alpha2: 'en', }) export const generateLoginNode = (userJid: string, config: Pick) => { - const { user, device } = jidDecode(userJid) - const payload = { - passive: true, - connectType: 1, - connectReason: 1, - userAgent: getUserAgent(config), - webInfo: { webSubPlatform: 0 }, - username: parseInt(user, 10), - device: device, - } - return proto.ClientPayload.encode(payload).finish() + const { user, device } = jidDecode(userJid) + const payload = { + passive: true, + connectType: 1, + connectReason: 1, + userAgent: getUserAgent(config), + webInfo: { webSubPlatform: 0 }, + username: parseInt(user, 10), + device: device, + } + return proto.ClientPayload.encode(payload).finish() } export const generateRegistrationNode = ( - { registrationId, signedPreKey, signedIdentityKey }: SignalCreds, - config: Pick + { registrationId, signedPreKey, signedIdentityKey }: SignalCreds, + config: Pick ) => { - const appVersionBuf = new Uint8Array(Buffer.from(ENCODED_VERSION, "base64")); + const appVersionBuf = new Uint8Array(Buffer.from(ENCODED_VERSION, 'base64')) - const companion = { - os: config.browser[0], - version: { - primary: 10, - secondary: undefined, - tertiary: undefined, - }, - platformType: 1, - requireFullSync: false, - }; + const companion = { + os: config.browser[0], + version: { + primary: 10, + secondary: undefined, + tertiary: undefined, + }, + platformType: 1, + requireFullSync: false, + } - const companionProto = proto.CompanionProps.encode(companion).finish() + const companionProto = proto.CompanionProps.encode(companion).finish() - const registerPayload = { - connectReason: 1, - connectType: 1, - passive: false, - regData: { - buildHash: appVersionBuf, - companionProps: companionProto, - eRegid: encodeInt(4, registrationId), - eKeytype: encodeInt(1, 5), - eIdent: signedIdentityKey.public, - eSkeyId: encodeInt(3, signedPreKey.keyId), - eSkeyVal: signedPreKey.keyPair.public, - eSkeySig: signedPreKey.signature, - }, - userAgent: getUserAgent(config), - webInfo: { - webSubPlatform: 0, - }, - } + const registerPayload = { + connectReason: 1, + connectType: 1, + passive: false, + regData: { + buildHash: appVersionBuf, + companionProps: companionProto, + eRegid: encodeInt(4, registrationId), + eKeytype: encodeInt(1, 5), + eIdent: signedIdentityKey.public, + eSkeyId: encodeInt(3, signedPreKey.keyId), + eSkeyVal: signedPreKey.keyPair.public, + eSkeySig: signedPreKey.signature, + }, + userAgent: getUserAgent(config), + webInfo: { + webSubPlatform: 0, + }, + } - return proto.ClientPayload.encode(registerPayload).finish() + return proto.ClientPayload.encode(registerPayload).finish() } export const configureSuccessfulPairing = ( - stanza: BinaryNode, - { advSecretKey, signedIdentityKey, signalIdentities }: Pick + stanza: BinaryNode, + { advSecretKey, signedIdentityKey, signalIdentities }: Pick ) => { - const [pair] = getAllBinaryNodeChildren(stanza) - const pairContent = Array.isArray(pair.content) ? pair.content : [] + const [pair] = getAllBinaryNodeChildren(stanza) + const pairContent = Array.isArray(pair.content) ? pair.content : [] - const msgId = stanza.attrs.id - const deviceIdentity = pairContent.find(m => m.tag === 'device-identity')?.content - const businessName = pairContent.find(m => m.tag === 'biz')?.attrs?.name - const verifiedName = businessName || '' - const jid = pairContent.find(m => m.tag === 'device')?.attrs?.jid + const msgId = stanza.attrs.id + const deviceIdentity = pairContent.find(m => m.tag === 'device-identity')?.content + const businessName = pairContent.find(m => m.tag === 'biz')?.attrs?.name + const verifiedName = businessName || '' + const jid = pairContent.find(m => m.tag === 'device')?.attrs?.jid - const { details, hmac } = proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentity as Buffer) + const { details, hmac } = proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentity as Buffer) - const advSign = hmacSign(details, Buffer.from(advSecretKey, 'base64')) + const advSign = hmacSign(details, Buffer.from(advSecretKey, 'base64')) - if (Buffer.compare(hmac, advSign) !== 0) { - throw new Boom('Invalid pairing') - } + if(Buffer.compare(hmac, advSign) !== 0) { + throw new Boom('Invalid pairing') + } - const account = proto.ADVSignedDeviceIdentity.decode(details) - const { accountSignatureKey, accountSignature } = account + const account = proto.ADVSignedDeviceIdentity.decode(details) + const { accountSignatureKey, accountSignature } = account - const accountMsg = Binary.build(new Uint8Array([6, 0]), account.details, signedIdentityKey.public).readByteArray() - if (!Curve.verify(accountSignatureKey, accountMsg, accountSignature)) { - throw new Boom('Failed to verify account signature') - } + const accountMsg = Binary.build(new Uint8Array([6, 0]), account.details, signedIdentityKey.public).readByteArray() + if(!Curve.verify(accountSignatureKey, accountMsg, accountSignature)) { + throw new Boom('Failed to verify account signature') + } - const deviceMsg = Binary.build(new Uint8Array([6, 1]), account.details, signedIdentityKey.public, account.accountSignatureKey).readByteArray() - account.deviceSignature = Curve.sign(signedIdentityKey.private, deviceMsg) + const deviceMsg = Binary.build(new Uint8Array([6, 1]), account.details, signedIdentityKey.public, account.accountSignatureKey).readByteArray() + account.deviceSignature = Curve.sign(signedIdentityKey.private, deviceMsg) - const identity = createSignalIdentity(jid, accountSignatureKey) + const identity = createSignalIdentity(jid, accountSignatureKey) - const keyIndex = proto.ADVDeviceIdentity.decode(account.details).keyIndex + const keyIndex = proto.ADVDeviceIdentity.decode(account.details).keyIndex - const accountEnc = proto.ADVSignedDeviceIdentity.encode({ - ...account.toJSON(), - accountSignatureKey: undefined - }).finish() + const accountEnc = proto.ADVSignedDeviceIdentity.encode({ + ...account.toJSON(), + accountSignatureKey: undefined + }).finish() - const reply: BinaryNode = { - tag: 'iq', - attrs: { - to: S_WHATSAPP_NET, - type: 'result', - id: msgId, - }, - content: [ - { - tag: 'pair-device-sign', - attrs: { }, - content: [ - { tag: 'device-identity', attrs: { 'key-index': `${keyIndex}` }, content: accountEnc } - ] - } - ] - } + const reply: BinaryNode = { + tag: 'iq', + attrs: { + to: S_WHATSAPP_NET, + type: 'result', + id: msgId, + }, + content: [ + { + tag: 'pair-device-sign', + attrs: { }, + content: [ + { tag: 'device-identity', attrs: { 'key-index': `${keyIndex}` }, content: accountEnc } + ] + } + ] + } - const authUpdate: Partial = { - account, - me: { id: jid, verifiedName }, - signalIdentities: [...(signalIdentities || []), identity] - } - return { - creds: authUpdate, - reply - } + const authUpdate: Partial = { + account, + me: { id: jid, verifiedName }, + signalIdentities: [...(signalIdentities || []), identity] + } + return { + creds: authUpdate, + reply + } } \ No newline at end of file diff --git a/src/WABinary/Legacy/index.ts b/src/WABinary/Legacy/index.ts index 945eed0..b73cf28 100644 --- a/src/WABinary/Legacy/index.ts +++ b/src/WABinary/Legacy/index.ts @@ -3,214 +3,239 @@ import { BinaryNode } from '../types' import { DoubleByteTokens, SingleByteTokens, Tags } from './constants' export const isLegacyBinaryNode = (buffer: Buffer) => { - switch(buffer[0]) { - case Tags.LIST_EMPTY: - case Tags.LIST_8: - case Tags.LIST_16: - return true - default: - return false + switch (buffer[0]) { + case Tags.LIST_EMPTY: + case Tags.LIST_8: + case Tags.LIST_16: + return true + default: + return false } } function decode(buffer: Buffer, indexRef: { index: number }): BinaryNode { - const checkEOS = (length: number) => { - if (indexRef.index + length > buffer.length) { - throw new Error('end of stream') - } - } - const next = () => { - const value = buffer[indexRef.index] - indexRef.index += 1 - return value - } - const readByte = () => { - checkEOS(1) - return next() - } - const readStringFromChars = (length: number) => { - checkEOS(length) - const value = buffer.slice(indexRef.index, indexRef.index + length) + const checkEOS = (length: number) => { + if(indexRef.index + length > buffer.length) { + throw new Error('end of stream') + } + } - indexRef.index += length - return value.toString('utf-8') - } - const readBytes = (n: number) => { - checkEOS(n) - const value = buffer.slice(indexRef.index, indexRef.index + n) - indexRef.index += n - return value - } - const readInt = (n: number, littleEndian = false) => { - checkEOS(n) - let val = 0 - for (let i = 0; i < n; i++) { - const shift = littleEndian ? i : n - 1 - i - val |= next() << (shift * 8) - } - return val - } - const readInt20 = () => { - checkEOS(3) - return ((next() & 15) << 16) + (next() << 8) + next() - } - const unpackHex = (value: number) => { - if (value >= 0 && value < 16) { - return value < 10 ? '0'.charCodeAt(0) + value : 'A'.charCodeAt(0) + value - 10 - } - throw new Error('invalid hex: ' + value) - } - const unpackNibble = (value: number) => { - if (value >= 0 && value <= 9) { - return '0'.charCodeAt(0) + value - } - switch (value) { - case 10: - return '-'.charCodeAt(0) - case 11: - return '.'.charCodeAt(0) - case 15: - return '\0'.charCodeAt(0) - default: - throw new Error('invalid nibble: ' + value) - } - } - const unpackByte = (tag: number, value: number) => { - if (tag === Tags.NIBBLE_8) { - return unpackNibble(value) - } else if (tag === Tags.HEX_8) { - return unpackHex(value) - } else { - throw new Error('unknown tag: ' + tag) - } - } - const readPacked8 = (tag: number) => { - const startByte = readByte() - let value = '' + const next = () => { + const value = buffer[indexRef.index] + indexRef.index += 1 + return value + } - for (let i = 0; i < (startByte & 127); i++) { - const curByte = readByte() - value += String.fromCharCode(unpackByte(tag, (curByte & 0xf0) >> 4)) - value += String.fromCharCode(unpackByte(tag, curByte & 0x0f)) - } - if (startByte >> 7 !== 0) { - value = value.slice(0, -1) - } - return value - } - const isListTag = (tag: number) => { - return tag === Tags.LIST_EMPTY || tag === Tags.LIST_8 || tag === Tags.LIST_16 - } - const readListSize = (tag: number) => { - switch (tag) { - case Tags.LIST_EMPTY: - return 0 - case Tags.LIST_8: - return readByte() - case Tags.LIST_16: - return readInt(2) - default: - throw new Error('invalid tag for list size: ' + tag) - } - } - const getToken = (index: number) => { - if (index < 3 || index >= SingleByteTokens.length) { - throw new Error('invalid token index: ' + index) - } - return SingleByteTokens[index] - } - const readString = (tag: number) => { - if (tag >= 3 && tag <= 235) { - const token = getToken(tag) - return token// === 's.whatsapp.net' ? 'c.us' : token - } + const readByte = () => { + checkEOS(1) + return next() + } - switch (tag) { - case Tags.DICTIONARY_0: - case Tags.DICTIONARY_1: - case Tags.DICTIONARY_2: - case Tags.DICTIONARY_3: - return getTokenDouble(tag - Tags.DICTIONARY_0, readByte()) - case Tags.LIST_EMPTY: - return null - case Tags.BINARY_8: - return readStringFromChars(readByte()) - case Tags.BINARY_20: - return readStringFromChars(readInt20()) - case Tags.BINARY_32: - return readStringFromChars(readInt(4)) - case Tags.JID_PAIR: - const i = readString(readByte()) - const j = readString(readByte()) - if (typeof i === 'string' && j) { - return i + '@' + j - } - throw new Error('invalid jid pair: ' + i + ', ' + j) - case Tags.HEX_8: - case Tags.NIBBLE_8: - return readPacked8(tag) - default: - throw new Error('invalid string with tag: ' + tag) - } - } - const readList = (tag: number) => ( - [...new Array(readListSize(tag))].map(() => decode(buffer, indexRef)) - ) - const getTokenDouble = (index1: number, index2: number) => { - const n = 256 * index1 + index2 - if (n < 0 || n > DoubleByteTokens.length) { - throw new Error('invalid double token index: ' + n) - } - return DoubleByteTokens[n] - } + const readStringFromChars = (length: number) => { + checkEOS(length) + const value = buffer.slice(indexRef.index, indexRef.index + length) - const listSize = readListSize(readByte()) - const descrTag = readByte() - if (descrTag === Tags.STREAM_END) { - throw new Error('unexpected stream end') - } - const header = readString(descrTag) + indexRef.index += length + return value.toString('utf-8') + } + + const readBytes = (n: number) => { + checkEOS(n) + const value = buffer.slice(indexRef.index, indexRef.index + n) + indexRef.index += n + return value + } + + const readInt = (n: number, littleEndian = false) => { + checkEOS(n) + let val = 0 + for(let i = 0; i < n; i++) { + const shift = littleEndian ? i : n - 1 - i + val |= next() << (shift * 8) + } + + return val + } + + const readInt20 = () => { + checkEOS(3) + return ((next() & 15) << 16) + (next() << 8) + next() + } + + const unpackHex = (value: number) => { + if(value >= 0 && value < 16) { + return value < 10 ? '0'.charCodeAt(0) + value : 'A'.charCodeAt(0) + value - 10 + } + + throw new Error('invalid hex: ' + value) + } + + const unpackNibble = (value: number) => { + if(value >= 0 && value <= 9) { + return '0'.charCodeAt(0) + value + } + + switch (value) { + case 10: + return '-'.charCodeAt(0) + case 11: + return '.'.charCodeAt(0) + case 15: + return '\0'.charCodeAt(0) + default: + throw new Error('invalid nibble: ' + value) + } + } + + const unpackByte = (tag: number, value: number) => { + if(tag === Tags.NIBBLE_8) { + return unpackNibble(value) + } else if(tag === Tags.HEX_8) { + return unpackHex(value) + } else { + throw new Error('unknown tag: ' + tag) + } + } + + const readPacked8 = (tag: number) => { + const startByte = readByte() + let value = '' + + for(let i = 0; i < (startByte & 127); i++) { + const curByte = readByte() + value += String.fromCharCode(unpackByte(tag, (curByte & 0xf0) >> 4)) + value += String.fromCharCode(unpackByte(tag, curByte & 0x0f)) + } + + if(startByte >> 7 !== 0) { + value = value.slice(0, -1) + } + + return value + } + + const isListTag = (tag: number) => { + return tag === Tags.LIST_EMPTY || tag === Tags.LIST_8 || tag === Tags.LIST_16 + } + + const readListSize = (tag: number) => { + switch (tag) { + case Tags.LIST_EMPTY: + return 0 + case Tags.LIST_8: + return readByte() + case Tags.LIST_16: + return readInt(2) + default: + throw new Error('invalid tag for list size: ' + tag) + } + } + + const getToken = (index: number) => { + if(index < 3 || index >= SingleByteTokens.length) { + throw new Error('invalid token index: ' + index) + } + + return SingleByteTokens[index] + } + + const readString = (tag: number) => { + if(tag >= 3 && tag <= 235) { + const token = getToken(tag) + return token// === 's.whatsapp.net' ? 'c.us' : token + } + + switch (tag) { + case Tags.DICTIONARY_0: + case Tags.DICTIONARY_1: + case Tags.DICTIONARY_2: + case Tags.DICTIONARY_3: + return getTokenDouble(tag - Tags.DICTIONARY_0, readByte()) + case Tags.LIST_EMPTY: + return null + case Tags.BINARY_8: + return readStringFromChars(readByte()) + case Tags.BINARY_20: + return readStringFromChars(readInt20()) + case Tags.BINARY_32: + return readStringFromChars(readInt(4)) + case Tags.JID_PAIR: + const i = readString(readByte()) + const j = readString(readByte()) + if(typeof i === 'string' && j) { + return i + '@' + j + } + + throw new Error('invalid jid pair: ' + i + ', ' + j) + case Tags.HEX_8: + case Tags.NIBBLE_8: + return readPacked8(tag) + default: + throw new Error('invalid string with tag: ' + tag) + } + } + + const readList = (tag: number) => ( + [...new Array(readListSize(tag))].map(() => decode(buffer, indexRef)) + ) + const getTokenDouble = (index1: number, index2: number) => { + const n = 256 * index1 + index2 + if(n < 0 || n > DoubleByteTokens.length) { + throw new Error('invalid double token index: ' + n) + } + + return DoubleByteTokens[n] + } + + const listSize = readListSize(readByte()) + const descrTag = readByte() + if(descrTag === Tags.STREAM_END) { + throw new Error('unexpected stream end') + } + + const header = readString(descrTag) const attrs: BinaryNode['attrs'] = { } let data: BinaryNode['content'] - if (listSize === 0 || !header) { - throw new Error('invalid node') - } - // read the attributes in + if(listSize === 0 || !header) { + throw new Error('invalid node') + } + // read the attributes in - const attributesLength = (listSize - 1) >> 1 - for (let i = 0; i < attributesLength; i++) { - const key = readString(readByte()) - const b = readByte() + const attributesLength = (listSize - 1) >> 1 + for(let i = 0; i < attributesLength; i++) { + const key = readString(readByte()) + const b = readByte() - attrs[key] = readString(b) - } + attrs[key] = readString(b) + } + + if(listSize % 2 === 0) { + const tag = readByte() + if(isListTag(tag)) { + data = readList(tag) + } else { + let decoded: Buffer | string + switch (tag) { + case Tags.BINARY_8: + decoded = readBytes(readByte()) + break + case Tags.BINARY_20: + decoded = readBytes(readInt20()) + break + case Tags.BINARY_32: + decoded = readBytes(readInt(4)) + break + default: + decoded = readString(tag) + break + } - if (listSize % 2 === 0) { - const tag = readByte() - if (isListTag(tag)) { - data = readList(tag) - } else { - let decoded: Buffer | string - switch (tag) { - case Tags.BINARY_8: - decoded = readBytes(readByte()) - break - case Tags.BINARY_20: - decoded = readBytes(readInt20()) - break - case Tags.BINARY_32: - decoded = readBytes(readInt(4)) - break - default: - decoded = readString(tag) - break - } data = decoded - } - } + } + } - return { + return { tag: header, attrs, content: data @@ -221,85 +246,97 @@ const encode = ({ tag, attrs, content }: BinaryNode, buffer: number[] = []) => { const pushByte = (value: number) => buffer.push(value & 0xff) - const pushInt = (value: number, n: number, littleEndian=false) => { - for (let i = 0; i < n; i++) { - const curShift = littleEndian ? i : n - 1 - i - buffer.push((value >> (curShift * 8)) & 0xff) - } - } - const pushBytes = (bytes: Uint8Array | Buffer | number[]) => ( + const pushInt = (value: number, n: number, littleEndian=false) => { + for(let i = 0; i < n; i++) { + const curShift = littleEndian ? i : n - 1 - i + buffer.push((value >> (curShift * 8)) & 0xff) + } + } + + const pushBytes = (bytes: Uint8Array | Buffer | number[]) => ( bytes.forEach (b => buffer.push(b)) ) - const pushInt20 = (value: number) => ( + const pushInt20 = (value: number) => ( pushBytes([(value >> 16) & 0x0f, (value >> 8) & 0xff, value & 0xff]) ) - const writeByteLength = (length: number) => { - if (length >= 4294967296) throw new Error('string too large to encode: ' + length) + const writeByteLength = (length: number) => { + if(length >= 4294967296) { + throw new Error('string too large to encode: ' + length) + } - if (length >= 1 << 20) { - pushByte(Tags.BINARY_32) - pushInt(length, 4) // 32 bit integer - } else if (length >= 256) { - pushByte(Tags.BINARY_20) - pushInt20(length) - } else { - pushByte(Tags.BINARY_8) - pushByte(length) - } - } - const writeStringRaw = (str: string) => { - const bytes = Buffer.from (str, 'utf-8') - writeByteLength(bytes.length) - pushBytes(bytes) - } - const writeToken = (token: number) => { - if (token < 245) { - pushByte(token) - } else if (token <= 500) { - throw new Error('invalid token') - } - } - const writeString = (token: string, i?: boolean) => { - if (token === 'c.us') token = 's.whatsapp.net' + if(length >= 1 << 20) { + pushByte(Tags.BINARY_32) + pushInt(length, 4) // 32 bit integer + } else if(length >= 256) { + pushByte(Tags.BINARY_20) + pushInt20(length) + } else { + pushByte(Tags.BINARY_8) + pushByte(length) + } + } + + const writeStringRaw = (str: string) => { + const bytes = Buffer.from (str, 'utf-8') + writeByteLength(bytes.length) + pushBytes(bytes) + } + + const writeToken = (token: number) => { + if(token < 245) { + pushByte(token) + } else if(token <= 500) { + throw new Error('invalid token') + } + } + + const writeString = (token: string, i?: boolean) => { + if(token === 'c.us') { + token = 's.whatsapp.net' + } - const tokenIndex = SingleByteTokens.indexOf(token) - if (!i && token === 's.whatsapp.net') { - writeToken(tokenIndex) - } else if (tokenIndex >= 0) { - if (tokenIndex < Tags.SINGLE_BYTE_MAX) { - writeToken(tokenIndex) - } else { - const overflow = tokenIndex - Tags.SINGLE_BYTE_MAX - const dictionaryIndex = overflow >> 8 - if (dictionaryIndex < 0 || dictionaryIndex > 3) { - throw new Error('double byte dict token out of range: ' + token + ', ' + tokenIndex) - } - writeToken(Tags.DICTIONARY_0 + dictionaryIndex) - writeToken(overflow % 256) - } - } else if (token) { - const jidSepIndex = token.indexOf('@') - if (jidSepIndex <= 0) { - writeStringRaw(token) - } else { - writeJid(token.slice(0, jidSepIndex), token.slice(jidSepIndex + 1, token.length)) - } - } - } - const writeJid = (left: string, right: string) => { - pushByte(Tags.JID_PAIR) - left && left.length > 0 ? writeString(left) : writeToken(Tags.LIST_EMPTY) - writeString(right) - } - const writeListStart = (listSize: number) => { - if (listSize === 0) { - pushByte(Tags.LIST_EMPTY) - } else if (listSize < 256) { - pushBytes([Tags.LIST_8, listSize]) - } else { - pushBytes([Tags.LIST_16, listSize]) - } - } + const tokenIndex = SingleByteTokens.indexOf(token) + if(!i && token === 's.whatsapp.net') { + writeToken(tokenIndex) + } else if(tokenIndex >= 0) { + if(tokenIndex < Tags.SINGLE_BYTE_MAX) { + writeToken(tokenIndex) + } else { + const overflow = tokenIndex - Tags.SINGLE_BYTE_MAX + const dictionaryIndex = overflow >> 8 + if(dictionaryIndex < 0 || dictionaryIndex > 3) { + throw new Error('double byte dict token out of range: ' + token + ', ' + tokenIndex) + } + + writeToken(Tags.DICTIONARY_0 + dictionaryIndex) + writeToken(overflow % 256) + } + } else if(token) { + const jidSepIndex = token.indexOf('@') + if(jidSepIndex <= 0) { + writeStringRaw(token) + } else { + writeJid(token.slice(0, jidSepIndex), token.slice(jidSepIndex + 1, token.length)) + } + } + } + + const writeJid = (left: string, right: string) => { + pushByte(Tags.JID_PAIR) + left && left.length > 0 ? writeString(left) : writeToken(Tags.LIST_EMPTY) + writeString(right) + } + + const writeListStart = (listSize: number) => { + if(listSize === 0) { + pushByte(Tags.LIST_EMPTY) + } else if(listSize < 256) { + pushBytes([Tags.LIST_8, listSize]) + } else { + pushBytes([Tags.LIST_16, listSize]) + } + } + const validAttributes = Object.keys(attrs).filter(k => ( typeof attrs[k] !== 'undefined' && attrs[k] !== null )) @@ -308,25 +345,27 @@ const encode = ({ tag, attrs, content }: BinaryNode, buffer: number[] = []) => { writeString(tag) validAttributes.forEach((key) => { - if(typeof attrs[key] === 'string') { - writeString(key) - writeString(attrs[key]) - } + if(typeof attrs[key] === 'string') { + writeString(key) + writeString(attrs[key]) + } }) - if (typeof content === 'string') { + if(typeof content === 'string') { writeString(content, true) - } else if (Buffer.isBuffer(content)) { + } else if(Buffer.isBuffer(content)) { writeByteLength(content.length) pushBytes(content) - } else if (Array.isArray(content)) { + } else if(Array.isArray(content)) { writeListStart(content.length) for(const item of content) { - if(item) encode(item, buffer) + if(item) { + encode(item, buffer) + } } } else if(typeof content === 'undefined' || content === null) { - } else { + } else { throw new Error(`invalid children for header "${tag}": ${content} (${typeof content})`) } diff --git a/src/WABinary/generic-utils.ts b/src/WABinary/generic-utils.ts new file mode 100644 index 0000000..82d601c --- /dev/null +++ b/src/WABinary/generic-utils.ts @@ -0,0 +1,81 @@ +import { Boom } from '@hapi/boom' +import { proto } from '../../WAProto' +import { BinaryNode } from './types' + +// some extra useful utilities + +export const getBinaryNodeChildren = ({ content }: BinaryNode, childTag: string) => { + if(Array.isArray(content)) { + return content.filter(item => item.tag === childTag) + } + + return [] +} + +export const getAllBinaryNodeChildren = ({ content }: BinaryNode) => { + if(Array.isArray(content)) { + return content + } + + return [] +} + +export const getBinaryNodeChild = ({ content }: BinaryNode, childTag: string) => { + if(Array.isArray(content)) { + return content.find(item => item.tag === childTag) + } +} + +export const getBinaryNodeChildBuffer = (node: BinaryNode, childTag: string) => { + const child = getBinaryNodeChild(node, childTag)?.content + if(Buffer.isBuffer(child) || child instanceof Uint8Array) { + return child + } +} + +export const getBinaryNodeChildUInt = (node: BinaryNode, childTag: string, length: number) => { + const buff = getBinaryNodeChildBuffer(node, childTag) + if(buff) { + return bufferToUInt(buff, length) + } +} + +export const assertNodeErrorFree = (node: BinaryNode) => { + const errNode = getBinaryNodeChild(node, 'error') + if(errNode) { + throw new Boom(errNode.attrs.text || 'Unknown error', { data: +errNode.attrs.code }) + } +} + +export const reduceBinaryNodeToDictionary = (node: BinaryNode, tag: string) => { + const nodes = getBinaryNodeChildren(node, tag) + const dict = nodes.reduce( + (dict, { attrs }) => { + dict[attrs.name || attrs.config_code] = attrs.value || attrs.config_value + return dict + }, { } as { [_: string]: string } + ) + return dict +} + +export const getBinaryNodeMessages = ({ content }: BinaryNode) => { + const msgs: proto.WebMessageInfo[] = [] + if(Array.isArray(content)) { + for(const item of content) { + if(item.tag === 'message') { + msgs.push(proto.WebMessageInfo.decode(item.content as Buffer)) + } + } + } + + return msgs +} + +function bufferToUInt(e: Uint8Array | Buffer, t: number) { + let a = 0 + for(let i = 0; i < t; i++) { + a = 256 * a + e[i] + } + + return a +} \ No newline at end of file diff --git a/src/WABinary/index.ts b/src/WABinary/index.ts index 0633c4f..3595df2 100644 --- a/src/WABinary/index.ts +++ b/src/WABinary/index.ts @@ -319,6 +319,7 @@ export const getBinaryNodeMessages = ({ content }: BinaryNode) => { return msgs } +export * from './generic-utils' export * from './jid-utils' export { Binary } from '../../WABinary/Binary' export * from './types' diff --git a/src/WABinary/jid-utils.ts b/src/WABinary/jid-utils.ts index 5b09c00..266482f 100644 --- a/src/WABinary/jid-utils.ts +++ b/src/WABinary/jid-utils.ts @@ -1,7 +1,7 @@ export const S_WHATSAPP_NET = '@s.whatsapp.net' export const OFFICIAL_BIZ_JID = '16505361212@c.us' export const SERVER_JID = 'server@c.us' -export const PSA_WID = '0@c.us'; +export const PSA_WID = '0@c.us' export const STORIES_JID = 'status@broadcast' export type JidServer = 'c.us' | 'g.us' | 'broadcast' | 's.whatsapp.net' | 'call' @@ -12,30 +12,32 @@ export type JidWithDevice = { } export const jidEncode = (user: string | number | null, server: JidServer, device?: number, agent?: number) => { - return `${user || ''}${!!agent ? `_${agent}` : ''}${!!device ? `:${device}` : ''}@${server}` + return `${user || ''}${!!agent ? `_${agent}` : ''}${!!device ? `:${device}` : ''}@${server}` } export const jidDecode = (jid: string) => { - let sepIdx = typeof jid === 'string' ? jid.indexOf('@') : -1 - if(sepIdx < 0) { - return undefined - } - const server = jid.slice(sepIdx+1) - const userCombined = jid.slice(0, sepIdx) + const sepIdx = typeof jid === 'string' ? jid.indexOf('@') : -1 + if(sepIdx < 0) { + return undefined + } - const [userAgent, device] = userCombined.split(':') - const [user, agent] = userAgent.split('_') + const server = jid.slice(sepIdx+1) + const userCombined = jid.slice(0, sepIdx) - return { - server, - user, - agent: agent ? +agent : undefined, - device: device ? +device : undefined - } + const [userAgent, device] = userCombined.split(':') + const [user, agent] = userAgent.split('_') + + return { + server, + user, + agent: agent ? +agent : undefined, + device: device ? +device : undefined + } } + /** is the jid a user */ export const areJidsSameUser = (jid1: string, jid2: string) => ( - jidDecode(jid1)?.user === jidDecode(jid2)?.user + jidDecode(jid1)?.user === jidDecode(jid2)?.user ) /** is the jid a user */ export const isJidUser = (jid: string) => (jid?.endsWith('@s.whatsapp.net')) @@ -47,6 +49,6 @@ export const isJidGroup = (jid: string) => (jid?.endsWith('@g.us')) export const isJidStatusBroadcast = (jid: string) => jid === 'status@broadcast' export const jidNormalizedUser = (jid: string) => { - const { user, server } = jidDecode(jid) - return jidEncode(user, server === 'c.us' ? 's.whatsapp.net' : server as JidServer) + const { user, server } = jidDecode(jid) + return jidEncode(user, server === 'c.us' ? 's.whatsapp.net' : server as JidServer) } \ No newline at end of file diff --git a/src/WABinary/types.ts b/src/WABinary/types.ts index 96e35d4..66714f9 100644 --- a/src/WABinary/types.ts +++ b/src/WABinary/types.ts @@ -5,7 +5,7 @@ * This is done for easy serialization, to prevent running into issues with prototypes & * to maintain functional code structure * */ - export type BinaryNode = { +export type BinaryNode = { tag: string attrs: { [key: string]: string } content?: BinaryNode[] | string | Uint8Array diff --git a/src/index.ts b/src/index.ts index 8139a9f..d52f14b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ -import makeWASocket from './Socket' import makeWALegacySocket from './LegacySocket' +import makeWASocket from './Socket' export * from '../WAProto' export * from './Utils' diff --git a/yarn.lock b/yarn.lock index dbeb44b..950ff72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,23 @@ # yarn lockfile v1 +"@adiwajshing/eslint-config@git+https://github.com/adiwajshing/eslint-config": + version "1.0.0" + resolved "git+https://github.com/adiwajshing/eslint-config#db16c7427bd6dcf8fba20e0aaa526724e46c83aa" + dependencies: + "@typescript-eslint/eslint-plugin" "^4.33.0" + "@typescript-eslint/parser" "^4.33.0" + eslint-plugin-react "^7.26.1" + eslint-plugin-simple-import-sort "^7.0.0" + eslint-plugin-unused-imports "^1.1.5" + +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" @@ -146,6 +163,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + "@babel/helper-validator-option@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" @@ -160,6 +182,15 @@ "@babel/traverse" "^7.14.5" "@babel/types" "^7.14.5" +"@babel/highlight@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.7.tgz#81a01d7d675046f0d96f82450d9d9578bdfd6b0b" + integrity sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/highlight@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" @@ -321,6 +352,21 @@ dependencies: "@cspotcode/source-map-consumer" "0.8.0" +"@eslint/eslintrc@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" + integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + "@hapi/boom@^9.1.3": version "9.1.3" resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.3.tgz#22cad56e39b7a4819161a99b1db19eaaa9b6cc6e" @@ -333,6 +379,20 @@ resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug== +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -819,6 +879,27 @@ "@babel/runtime" "^7.7.2" regenerator-runtime "^0.13.3" +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -992,6 +1073,11 @@ jest-diff "^26.0.0" pretty-format "^26.0.0" +"@types/json-schema@^7.0.7": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + "@types/long@^4.0.0", "@types/long@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" @@ -1091,6 +1177,76 @@ dependencies: "@types/yargs-parser" "*" +"@typescript-eslint/eslint-plugin@^4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" + integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg== + dependencies: + "@typescript-eslint/experimental-utils" "4.33.0" + "@typescript-eslint/scope-manager" "4.33.0" + debug "^4.3.1" + functional-red-black-tree "^1.0.1" + ignore "^5.1.8" + regexpp "^3.1.0" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/experimental-utils@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd" + integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q== + dependencies: + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/parser@^4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899" + integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA== + dependencies: + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" + debug "^4.3.1" + +"@typescript-eslint/scope-manager@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3" + integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ== + dependencies: + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/visitor-keys" "4.33.0" + +"@typescript-eslint/types@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" + integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ== + +"@typescript-eslint/typescript-estree@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609" + integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA== + dependencies: + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/visitor-keys" "4.33.0" + debug "^4.3.1" + globby "^11.0.3" + is-glob "^4.0.1" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd" + integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg== + dependencies: + "@typescript-eslint/types" "4.33.0" + eslint-visitor-keys "^2.0.0" + abab@^2.0.3, abab@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" @@ -1104,6 +1260,11 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" +acorn-jsx@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + acorn-walk@^7.1.1: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" @@ -1114,7 +1275,7 @@ acorn-walk@^8.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^7.1.1: +acorn@^7.1.1, acorn@^7.4.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== @@ -1136,6 +1297,31 @@ agent-base@6: dependencies: debug "4" +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.1: + version "8.9.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.9.0.tgz#738019146638824dea25edcf299dcba1b0e7eb18" + integrity sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + ansi-escapes@^4.2.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" @@ -1215,6 +1401,36 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +array-includes@^3.1.3, array-includes@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" + integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + get-intrinsic "^1.1.1" + is-string "^1.0.7" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array.prototype.flatmap@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446" + integrity sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.19.0" + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1390,6 +1606,14 @@ buffer@^5.2.0, buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1565,7 +1789,7 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-spawn@^7.0.3: +cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -1612,6 +1836,13 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: dependencies: ms "2.1.2" +debug@^4.0.1: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + decimal.js@^10.2.1: version "10.3.1" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" @@ -1634,6 +1865,11 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -1644,6 +1880,13 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1679,6 +1922,27 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + dom-walk@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" @@ -1713,6 +1977,48 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +es-abstract@^1.19.0, es-abstract@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.1" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -1728,6 +2034,11 @@ escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escodegen@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" @@ -1740,11 +2051,159 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" +eslint-plugin-react@^7.26.1: + version "7.28.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz#8f3ff450677571a659ce76efc6d80b6a525adbdf" + integrity sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw== + dependencies: + array-includes "^3.1.4" + array.prototype.flatmap "^1.2.5" + doctrine "^2.1.0" + estraverse "^5.3.0" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.0.4" + object.entries "^1.1.5" + object.fromentries "^2.0.5" + object.hasown "^1.1.0" + object.values "^1.1.5" + prop-types "^15.7.2" + resolve "^2.0.0-next.3" + semver "^6.3.0" + string.prototype.matchall "^4.0.6" + +eslint-plugin-simple-import-sort@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-7.0.0.tgz#a1dad262f46d2184a90095a60c66fef74727f0f8" + integrity sha512-U3vEDB5zhYPNfxT5TYR7u01dboFZp+HNpnGhkDB2g/2E4wZ/g1Q9Ton8UwCLfRV9yAKyYqDh62oHOamvkFxsvw== + +eslint-plugin-unused-imports@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-1.1.5.tgz#a2b992ef0faf6c6c75c3815cc47bde76739513c2" + integrity sha512-TeV8l8zkLQrq9LBeYFCQmYVIXMjfHgdRQLw7dEZp4ZB3PeR10Y5Uif11heCsHRmhdRIYMoewr1d9ouUHLbLHew== + dependencies: + eslint-rule-composer "^0.3.0" + +eslint-rule-composer@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" + integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint@^7.0.0: + version "7.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" + integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.3" + "@humanwhocodes/config-array" "^0.5.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.1.2" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.9" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + estraverse@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" @@ -1797,12 +2256,28 @@ expect@^27.0.6: jest-message-util "^27.0.6" jest-regex-util "^27.0.6" +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= @@ -1817,6 +2292,13 @@ fast-safe-stringify@^2.0.8: resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz#dc2af48c46cf712b683e849b2bbd446b32de936f" integrity sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag== +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + fb-watchman@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" @@ -1824,6 +2306,13 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + file-type@^16.5.0: version "16.5.1" resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.1.tgz#dd697dc5c3a2f4db63af746f38a6322e5e7bc6a5" @@ -1853,11 +2342,24 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + flatstr@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931" integrity sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw== +flatted@^3.1.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2" + integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw== + follow-redirects@^1.14.4: version "1.14.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd" @@ -1911,6 +2413,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -1935,6 +2442,15 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -1945,6 +2461,14 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + gifwrap@^0.9.2: version "0.9.2" resolved "https://registry.yarnpkg.com/gifwrap/-/gifwrap-0.9.2.tgz#348e286e67d7cf57942172e1e6f05a71cee78489" @@ -1958,6 +2482,13 @@ github-from-package@0.0.0: resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" @@ -1983,6 +2514,25 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globals@^13.6.0, globals@^13.9.0: + version "13.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e" + integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg== + dependencies: + type-fest "^0.20.2" + +globby@^11.0.3: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" @@ -2000,6 +2550,11 @@ handlebars@^4.7.7: optionalDependencies: uglify-js "^3.1.4" +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -2010,6 +2565,18 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -2068,11 +2635,29 @@ ieee754@^1.1.13, ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.8, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + image-q@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/image-q/-/image-q-1.1.1.tgz#fc84099664460b90ca862d9300b6bfbbbfbf8056" integrity sha1-/IQJlmRGC5DKhi2TALa/u7+/gFY= +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-local@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" @@ -2104,6 +2689,15 @@ ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + interpret@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" @@ -2114,6 +2708,26 @@ is-arrayish@^0.3.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + is-ci@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994" @@ -2128,6 +2742,18 @@ is-core-module@^2.2.0: dependencies: has "^1.0.3" +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -2150,6 +2776,25 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== +is-glob@^4.0.0, is-glob@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-negative-zero@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -2160,16 +2805,50 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== + is-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-weakref@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -2661,7 +3340,7 @@ jpeg-js@0.4.2: resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.2.tgz#8b345b1ae4abde64c2da2fe67ea216a114ac279d" integrity sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw== -js-tokens@^4.0.0: +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== @@ -2712,6 +3391,21 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + json5@2.x, json5@^2.1.2, json5@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" @@ -2728,6 +3422,14 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +"jsx-ast-utils@^2.4.1 || ^3.0.0": + version "3.2.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz#720b97bfe7d901b927d87c3773637ae8ea48781b" + integrity sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA== + dependencies: + array-includes "^3.1.3" + object.assign "^4.1.2" + kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" @@ -2738,6 +3440,14 @@ leven@^3.1.0: resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -2774,6 +3484,16 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + lodash@4.x, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -2784,6 +3504,13 @@ long@^4.0.0: resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== +loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -2837,6 +3564,11 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + micromatch@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" @@ -3006,11 +3738,66 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== -object-assign@^4.1.0: +object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.entries@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" + integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +object.fromentries@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" + integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +object.hasown@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5" + integrity sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.19.1" + +object.values@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" + integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + omggif@^1.0.10, omggif@^1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" @@ -3049,6 +3836,18 @@ optionator@^0.8.1: type-check "~0.3.2" word-wrap "~1.2.3" +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + p-each-series@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" @@ -3078,6 +3877,13 @@ pako@^1.0.5: resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + parse-bmfont-ascii@^1.0.3: version "1.0.6" resolved "https://registry.yarnpkg.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz#11ac3c3ff58f7c2020ab22769079108d4dfa0285" @@ -3126,6 +3932,11 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + peek-readable@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.0.0.tgz#b024ef391c86136eba0ae9df3ff4f966a09e9a7e" @@ -3203,6 +4014,11 @@ prebuild-install@^7.0.0: tar-fs "^2.0.0" tunnel-agent "^0.6.0" +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -3238,7 +4054,7 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -progress@^2.0.3: +progress@^2.0.0, progress@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== @@ -3251,6 +4067,15 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" +prop-types@^15.7.2: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + protobufjs@6.8.8: version "6.8.8" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" @@ -3302,7 +4127,7 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.1: +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -3312,6 +4137,11 @@ qrcode-terminal@^0.12.0: resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819" integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + quick-format-unescaped@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.3.tgz#6d6b66b8207aa2b35eef12be1421bb24c428f652" @@ -3327,6 +4157,11 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" @@ -3373,11 +4208,29 @@ regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== +regexp.prototype.flags@^1.3.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" + integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +regexpp@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" @@ -3385,6 +4238,11 @@ resolve-cwd@^3.0.0: dependencies: resolve-from "^5.0.0" +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-from@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" @@ -3398,13 +4256,33 @@ resolve@^1.1.6, resolve@^1.20.0: is-core-module "^2.2.0" path-parse "^1.0.6" -rimraf@^3.0.0: +resolve@^2.0.0-next.3: + version "2.0.0-next.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" + integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -3432,7 +4310,7 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" -semver@7.x, semver@^7.3.2, semver@^7.3.5: +semver@7.x, semver@^7.2.1, semver@^7.3.2, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -3493,6 +4371,15 @@ shiki@^0.9.3: onigasm "^2.2.5" vscode-textmate "5.2.0" +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + signal-exit@^3.0.0: version "3.0.6" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" @@ -3534,6 +4421,15 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + sonic-boom@^1.0.2: version "1.4.1" resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.4.1.tgz#d35d6a74076624f12e6f917ade7b9d75e918f53e" @@ -3594,7 +4490,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2 || 3 || 4": +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -3612,6 +4508,36 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" +string.prototype.matchall@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz#5abb5dabc94c7b0ea2380f65ba610b3a544b15fa" + integrity sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + get-intrinsic "^1.1.1" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + regexp.prototype.flags "^1.3.1" + side-channel "^1.0.4" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -3657,6 +4583,11 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -3703,6 +4634,17 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +table@^6.0.9: + version "6.8.0" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca" + integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA== + dependencies: + ajv "^8.0.1" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + tar-fs@^2.0.0, tar-fs@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" @@ -3741,6 +4683,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + throat@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" @@ -3831,6 +4778,18 @@ ts-node@^10.0.0: make-error "^1.1.1" yn "3.1.1" +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -3838,6 +4797,13 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -3850,6 +4816,11 @@ type-detect@4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" @@ -3894,6 +4865,16 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.10.tgz#a6bd0d28d38f592c3adb6b180ea6e07e1e540a8d" integrity sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg== +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" @@ -3904,6 +4885,13 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + utif@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/utif/-/utif-2.0.1.tgz#9e1582d9bbd20011a6588548ed3266298e711759" @@ -3916,6 +4904,11 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + v8-to-istanbul@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz#4229f2a99e367f3f018fa1d5c2b8ec684667c69c" @@ -3982,6 +4975,17 @@ whatwg-url@^8.0.0, whatwg-url@^8.5.0: tr46 "^2.1.0" webidl-conversions "^6.1.0" +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -3996,7 +5000,7 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2 || 3 || 4" -word-wrap@~1.2.3: +word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== From fb66733b61ddb1a0c851d621de59ee251770eb47 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 19 Jan 2022 21:35:59 +0530 Subject: [PATCH 300/311] feat: implement in memory store 1. the store works as a temporary store for connection data such as chats, messages & contacts 2. the store is primarily meant to illustrate the usage of the event emitter as a way to construct the state of the connection. This will likely be very inefficient to perform well at scale 3. the store is meant to be a quick way to have some visibility of data while testing 4. the store works for both legacy & MD connections --- .gitignore | 1 + Example/example-legacy.ts | 12 +- Example/example.ts | 13 +- package.json | 4 +- src/Store/index.ts | 2 + src/Store/make-in-memory-store.ts | 374 +++++++++++++++++++++++++++ src/Store/make-ordered-dictionary.ts | 86 ++++++ src/index.ts | 2 +- yarn.lock | 5 + 9 files changed, 495 insertions(+), 4 deletions(-) create mode 100644 src/Store/index.ts create mode 100644 src/Store/make-in-memory-store.ts diff --git a/.gitignore b/.gitignore index ee4cfa5..b96baf0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules auth_info*.json +baileys_store*.json output.csv */.DS_Store .DS_Store diff --git a/Example/example-legacy.ts b/Example/example-legacy.ts index 76bb044..dc4c8fe 100644 --- a/Example/example-legacy.ts +++ b/Example/example-legacy.ts @@ -1,6 +1,15 @@ import P from "pino" import { Boom } from "@hapi/boom" -import { makeWALegacySocket, DisconnectReason, AnyMessageContent, delay, useSingleFileLegacyAuthState } from '../src' +import { makeWALegacySocket, DisconnectReason, AnyMessageContent, delay, useSingleFileLegacyAuthState, makeInMemoryStore } from '../src' + +// the store maintains the data of the WA connection in memory +// can be written out to a file & read from it +const store = makeInMemoryStore({ logger: P().child({ level: 'debug', stream: 'store' }) }) +store.readFromFile('./baileys_store.json') + +setInterval(() => { + store.writeToFile('./baileys_store.json') +}, 10_000) const { state, saveState } = useSingleFileLegacyAuthState('./auth_info.json') @@ -12,6 +21,7 @@ const startSock = () => { printQRInTerminal: true, auth: state }) + store.bind(sock.ev) const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { await sock.presenceSubscribe(jid) diff --git a/Example/example.ts b/Example/example.ts index 7dcc2be..ab69d13 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -1,6 +1,15 @@ import P from "pino" import { Boom } from "@hapi/boom" -import makeWASocket, { DisconnectReason, AnyMessageContent, delay, useSingleFileAuthState } from '../src' +import makeWASocket, { DisconnectReason, AnyMessageContent, delay, useSingleFileAuthState, makeInMemoryStore } from '../src' + +// the store maintains the data of the WA connection in memory +// can be written out to a file & read from it +const store = makeInMemoryStore({ logger: P().child({ level: 'debug', stream: 'store' }) }) +store.readFromFile('./baileys_store.json') + +setInterval(() => { + store.writeToFile('./baileys_store.json') +}, 10_000) const { state, saveState } = useSingleFileAuthState('./auth_info_multi.json') @@ -19,6 +28,8 @@ const startSock = () => { } }) + store.bind(sock.ev) + const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { await sock.presenceSubscribe(jid) await delay(500) diff --git a/package.json b/package.json index 50d112b..c7622c2 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,8 @@ "peerDependencies": { "jimp": "^0.16.1", "qrcode-terminal": "^0.12.0", - "sharp": "^0.29.3" + "sharp": "^0.29.3", + "@adiwajshing/keyed-db": "^0.2.4" }, "files": [ "lib/*", @@ -58,6 +59,7 @@ ], "devDependencies": { "@adiwajshing/eslint-config": "git+https://github.com/adiwajshing/eslint-config", + "@adiwajshing/keyed-db": "^0.2.4", "@types/got": "^9.6.11", "@types/jest": "^26.0.24", "@types/node": "^14.6.2", diff --git a/src/Store/index.ts b/src/Store/index.ts new file mode 100644 index 0000000..f744671 --- /dev/null +++ b/src/Store/index.ts @@ -0,0 +1,2 @@ +import makeInMemoryStore from './make-in-memory-store' +export { makeInMemoryStore } \ No newline at end of file diff --git a/src/Store/make-in-memory-store.ts b/src/Store/make-in-memory-store.ts new file mode 100644 index 0000000..5a3be5e --- /dev/null +++ b/src/Store/make-in-memory-store.ts @@ -0,0 +1,374 @@ +import type KeyedDB from '@adiwajshing/keyed-db' +import type { Comparable } from '@adiwajshing/keyed-db/lib/Types' +import type { Logger } from 'pino' +import { proto } from '../../WAProto' +import { DEFAULT_CONNECTION_CONFIG } from '../Defaults' +import type makeLegacySocket from '../LegacySocket' +import type makeMDSocket from '../Socket' +import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, MessageInfo, PresenceData, WAMessage, WAMessageCursor, WAMessageKey } from '../Types' +import { toNumber } from '../Utils' +import { jidNormalizedUser } from '../WABinary' +import makeOrderedDictionary from './make-ordered-dictionary' + +type LegacyWASocket = ReturnType +type AnyWASocket = ReturnType + +export const waChatKey = (pin: boolean) => ({ + key: (c: Chat) => (pin ? (c.pin ? '1' : '0') : '') + (c.archive ? '0' : '1') + c.conversationTimestamp.toString(16).padStart(8, '0') + c.id, + compare: (k1: string, k2: string) => k2.localeCompare (k1) +}) + +export const waMessageID = (m: WAMessage) => m.key.id + +export type BaileysInMemoryStoreConfig = { + chatKey?: Comparable + logger?: Logger +} + +const makeMessagesDictionary = () => makeOrderedDictionary(waMessageID) + +export default ( + { logger, chatKey }: BaileysInMemoryStoreConfig +) => { + logger = logger || DEFAULT_CONNECTION_CONFIG.logger.child({ stream: 'in-mem-store' }) + chatKey = chatKey || waChatKey(true) + const KeyedDB = require('@adiwajshing/keyed-db').default as new (...args: any[]) => KeyedDB + + const chats = new KeyedDB(chatKey, c => c.id) + const messages: { [_: string]: ReturnType } = { } + const contacts: { [_: string]: Contact } = { } + const groupMetadata: { [_: string]: GroupMetadata } = { } + const messageInfos: { [id: string]: MessageInfo } = { } + const presences: { [id: string]: { [participant: string]: PresenceData } } = { } + const state: ConnectionState = { connection: 'close' } + + const assertMessageList = (jid: string) => { + if(!messages[jid]) { + messages[jid] = makeMessagesDictionary() + } + + return messages[jid] + } + + const contactsUpsert = (newContacts: Contact[]) => { + const oldContacts = new Set(Object.keys(contacts)) + for(const contact of newContacts) { + oldContacts.delete(contact.id) + contacts[contact.id] = Object.assign( + contacts[contact.id] || {}, + contact + ) + } + + return oldContacts + } + + /** + * binds to a BaileysEventEmitter. + * It listens to all events and constructs a state that you can query accurate data from. + * Eg. can use the store to fetch chats, contacts, messages etc. + * @param ev typically the event emitter from the socket connection + */ + const bind = (ev: BaileysEventEmitter) => { + ev.on('connection.update', update => { + Object.assign(state, update) + }) + ev.on('chats.set', ({ chats: newChats, isLatest }) => { + if(isLatest) { + chats.clear() + } + + const chatsAdded = chats.insertIfAbsent(...newChats).length + logger.debug({ chatsAdded }, 'synced chats') + }) + ev.on('contacts.set', ({ contacts: newContacts }) => { + const oldContacts = contactsUpsert(newContacts) + for(const jid of oldContacts) { + delete contacts[jid] + } + + logger.debug({ deletedContacts: oldContacts.size, newContacts }, 'synced contacts') + }) + ev.on('messages.set', ({ messages: newMessages, isLatest }) => { + if(isLatest) { + for(const id in messages) { + delete messages[id] + } + } + + for(const msg of newMessages) { + const jid = msg.key.remoteJid! + const list = assertMessageList(jid) + list.upsert(msg, 'prepend') + } + + logger.debug({ messages: newMessages.length }, 'synced messages') + }) + ev.on('contacts.update', updates => { + for(const update of updates) { + if(contacts[update.id!]) { + Object.assign(contacts[update.id!], update) + } else { + logger.debug({ update }, 'got update for non-existant contact') + } + } + }) + ev.on('chats.upsert', newChats => { + chats.upsert(...newChats) + }) + ev.on('chats.update', updates => { + for(const update of updates) { + const result = chats.update(update.id!, chat => { + if(update.unreadCount > 0) { + update.unreadCount = chat.unreadCount + update.unreadCount + } + + Object.assign(chat, update) + }) + if(!result) { + logger.debug({ update }, 'got update for non-existant chat') + } + } + }) + ev.on('presence.update', ({ id, presences: update }) => { + presences[id] = presences[id] || {} + Object.assign(presences[id], update) + }) + ev.on('chats.delete', deletions => { + for(const item of deletions) { + chats.deleteById(item) + } + }) + ev.on('messages.upsert', ({ messages: newMessages, type }) => { + switch (type) { + case 'append': + case 'notify': + for(const msg of newMessages) { + const jid = jidNormalizedUser(msg.key.remoteJid!) + const list = assertMessageList(jid) + list.upsert(msg, 'append') + + if(type === 'notify') { + if(!chats.get(jid)) { + ev.emit('chats.upsert', [ + { + id: jid, + conversationTimestamp: toNumber(msg.messageTimestamp), + unreadCount: 1 + } + ]) + } + + // add message infos if required + messageInfos[msg.key.id!] = messageInfos[msg.key.id!] || { reads: {}, deliveries: {} } + } + } + + break + } + }) + ev.on('messages.update', updates => { + for(const { update, key } of updates) { + const list = assertMessageList(key.remoteJid) + const result = list.updateAssign(key.id, update) + if(!result) { + logger.debug({ update }, 'got update for non-existent message') + } + } + }) + ev.on('messages.delete', item => { + if('all' in item) { + const list = messages[item.jid] + list?.clear() + } else { + const jid = item.keys[0].remoteJid + const list = messages[jid] + if(list) { + const idSet = new Set(item.keys.map(k => k.id)) + list.filter(m => !idSet.has(m.key.id)) + } + } + }) + + ev.on('groups.update', updates => { + for(const update of updates) { + if(groupMetadata[update.id]) { + Object.assign(groupMetadata[update.id!], update) + } else { + logger.debug({ update }, 'got update for non-existant group metadata') + } + } + }) + + ev.on('group-participants.update', ({ id, participants, action }) => { + const metadata = groupMetadata[id] + if(metadata) { + switch (action) { + case 'add': + metadata.participants.push(...participants.map(id => ({ id, isAdmin: false, isSuperAdmin: false }))) + break + case 'demote': + case 'promote': + for(const participant of metadata.participants) { + if(participants.includes(participant.id)) { + participant.isAdmin = action === 'promote' + } + } + + break + case 'remove': + metadata.participants = metadata.participants.filter(p => !participants.includes(p.id)) + break + } + } + }) + + ev.on('message-info.update', updates => { + for(const { key, update } of updates) { + const obj = messageInfos[key.id!] + if(obj) { + // add reads/deliveries + for(const key in update) { + Object.assign(obj[key], update[key]) + } + } + } + }) + } + + const toJSON = () => ({ + chats, + contacts, + messages + }) + + const fromJSON = (json: { chats: Chat[], contacts: { [id: string]: Contact }, messages: { [id: string]: WAMessage[] } }) => { + chats.upsert(...json.chats) + contactsUpsert(Object.values(contacts)) + for(const jid in json.messages) { + const list = assertMessageList(jid) + for(const msg of json.messages[jid]) { + list.upsert(proto.WebMessageInfo.fromObject(msg), 'append') + } + } + } + + + return { + chats, + contacts, + messages, + groupMetadata, + messageInfos, + state, + presences, + bind, + loadMessages: async(jid: string, count: number, cursor: WAMessageCursor, sock: LegacyWASocket | undefined) => { + const list = assertMessageList(jid) + const retrieve = async(count: number, cursor: WAMessageCursor) => { + const result = await sock?.fetchMessagesFromWA(jid, count, cursor) + return result || [] + } + + const mode = !cursor || 'before' in cursor ? 'before' : 'after' + const cursorKey = !!cursor ? ('before' in cursor ? cursor.before : cursor.after) : undefined + const cursorValue = cursorKey ? list.get(cursorKey.id) : undefined + + let messages: WAMessage[] + if(list && mode === 'before' && (!cursorKey || cursorValue)) { + if(cursorValue) { + const msgIdx = list.array.findIndex(m => m.key.id === cursorKey.id) + messages = list.array.slice(0, msgIdx) + } else { + messages = list.array + } + + const diff = count - messages.length + if(diff < 0) { + messages = messages.slice(-count) // get the last X messages + } else if(diff > 0) { + const [fMessage] = messages + const cursor = { before: fMessage?.key || cursorKey } + const extra = await retrieve (diff, cursor) + // add to DB + for(let i = extra.length-1; i >= 0;i--) { + list.upsert(extra[i], 'prepend') + } + + messages.splice(0, 0, ...extra) + } + } else { + messages = await retrieve(count, cursor) + } + + return messages + }, + loadMessage: async(jid: string, id: string, sock: LegacyWASocket | undefined) => { + let message = messages[jid]?.get(id) + if(!message) { + message = await sock?.loadMessageFromWA(jid, id) + } + + return message + }, + mostRecentMessage: async(jid: string, sock: LegacyWASocket | undefined) => { + let message = messages[jid]?.array.slice(-1)[0] + if(!message) { + const [result] = await sock?.fetchMessagesFromWA(jid, 1, undefined) + message = result + } + + return message + }, + fetchImageUrl: async(jid: string, sock: AnyWASocket | undefined) => { + const contact = contacts[jid] + if(!contact) { + return sock?.profilePictureUrl(jid) + } + + if(typeof contact.imgUrl === 'undefined') { + contact.imgUrl = await sock?.profilePictureUrl(jid) + } + + return contact.imgUrl + }, + fetchGroupMetadata: async(jid: string, sock: AnyWASocket | undefined) => { + if(!groupMetadata[jid]) { + groupMetadata[jid] = await sock?.groupMetadata(jid) + } + + return groupMetadata[jid] + }, + fetchBroadcastListInfo: async(jid: string, sock: LegacyWASocket | undefined) => { + if(!groupMetadata[jid]) { + groupMetadata[jid] = await sock?.getBroadcastListInfo(jid) + } + + return groupMetadata[jid] + }, + fetchMessageInfo: async({ remoteJid, id }: WAMessageKey, sock: LegacyWASocket | undefined) => { + if(!messageInfos[id!]) { + messageInfos[id!] = await sock?.messageInfo(remoteJid, id) + } + + return messageInfos[id!] + }, + toJSON, + fromJSON, + writeToFile: (path: string) => { + // require fs here so that in case "fs" is not available -- the app does not crash + const { writeFileSync } = require('fs') + writeFileSync(path, JSON.stringify(toJSON())) + }, + readFromFile: (path: string) => { + // require fs here so that in case "fs" is not available -- the app does not crash + const { readFileSync, existsSync } = require('fs') + if(existsSync(path)) { + logger.debug({ path }, 'reading from file') + const jsonStr = readFileSync(path, { encoding: 'utf-8' }) + const json = JSON.parse(jsonStr) + fromJSON(json) + } + } + } +} \ No newline at end of file diff --git a/src/Store/make-ordered-dictionary.ts b/src/Store/make-ordered-dictionary.ts index e69de29..b66d760 100644 --- a/src/Store/make-ordered-dictionary.ts +++ b/src/Store/make-ordered-dictionary.ts @@ -0,0 +1,86 @@ +function makeOrderedDictionary(idGetter: (item: T) => string) { + const array: T[] = [] + const dict: { [_: string]: T } = { } + + const get = (id: string) => dict[id] + + const update = (item: T) => { + const id = idGetter(item) + const idx = array.findIndex(i => idGetter(i) === id) + if(idx >= 0) { + array[idx] = item + dict[id] = item + } + + return false + } + + const upsert = (item: T, mode: 'append' | 'prepend') => { + const id = idGetter(item) + if(get(id)) { + update(item) + } else { + if(mode === 'append') { + array.push(item) + } else { + array.splice(0, 0, item) + } + + dict[id] = item + } + } + + const remove = (item: T) => { + const id = idGetter(item) + const idx = array.findIndex(i => idGetter(i) === id) + if(idx >= 0) { + array.splice(idx, 1) + delete dict[id] + return true + } + + return false + } + + return { + array, + get, + upsert, + update, + remove, + updateAssign: (id: string, update: Partial) => { + const item = get(id) + if(item) { + Object.assign(item, update) + delete dict[id] + dict[idGetter(item)] = item + return true + } + + return false + }, + clear: () => { + array.splice(0, array.length) + Object.keys(dict).forEach(key => { + delete dict[key] + }) + }, + filter: (contain: (item: T) => boolean) => { + let i = 0 + while(i < array.length) { + if(!contain(array[i])) { + delete dict[idGetter(array[i])] + array.splice(i, 1) + } else { + i += 1 + } + } + }, + toJSON: () => array, + fromJSON: (newItems: T[]) => { + array.splice(0, array.length, ...newItems) + } + } +} + +export default makeOrderedDictionary \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index d52f14b..4fcdeb2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,7 @@ import makeWASocket from './Socket' export * from '../WAProto' export * from './Utils' export * from './Types' -//export * from './Store' +export * from './Store' export * from './Defaults' export * from './WABinary' diff --git a/yarn.lock b/yarn.lock index 950ff72..54b0e73 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,6 +12,11 @@ eslint-plugin-simple-import-sort "^7.0.0" eslint-plugin-unused-imports "^1.1.5" +"@adiwajshing/keyed-db@^0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@adiwajshing/keyed-db/-/keyed-db-0.2.4.tgz#2a09e88fce20b2672deb60a7750c5fe3ab0dfd99" + integrity sha512-yprSnAtj80/VKuDqRcFFLDYltoNV8tChNwFfIgcf6PGD4sjzWIBgs08pRuTqGH5mk5wgL6PBRSsMCZqtZwzFEw== + "@babel/code-frame@7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" From 1fb52de9587972e32a5c29387980520fc16416b3 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 19 Jan 2022 22:38:04 +0530 Subject: [PATCH 301/311] docs: update readme about store --- Example/example-legacy.ts | 2 +- Example/example.ts | 2 +- README.md | 48 ++++++++++++++++++++++++++++--- src/Store/make-in-memory-store.ts | 1 + 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/Example/example-legacy.ts b/Example/example-legacy.ts index dc4c8fe..0b4b388 100644 --- a/Example/example-legacy.ts +++ b/Example/example-legacy.ts @@ -6,7 +6,7 @@ import { makeWALegacySocket, DisconnectReason, AnyMessageContent, delay, useSing // can be written out to a file & read from it const store = makeInMemoryStore({ logger: P().child({ level: 'debug', stream: 'store' }) }) store.readFromFile('./baileys_store.json') - +// save every 10s setInterval(() => { store.writeToFile('./baileys_store.json') }, 10_000) diff --git a/Example/example.ts b/Example/example.ts index ab69d13..5b964e7 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -6,7 +6,7 @@ import makeWASocket, { DisconnectReason, AnyMessageContent, delay, useSingleFile // can be written out to a file & read from it const store = makeInMemoryStore({ logger: P().child({ level: 'debug', stream: 'store' }) }) store.readFromFile('./baileys_store.json') - +// save every 10s setInterval(() => { store.writeToFile('./baileys_store.json') }, 10_000) diff --git a/README.md b/README.md index 3f30ac0..2372dfd 100644 --- a/README.md +++ b/README.md @@ -76,12 +76,13 @@ If the connection is successful, you will see a QR code printed on your terminal **Note:** install `qrcode-terminal` using `yarn add qrcode-terminal` to auto-print the QR to the terminal. -## Notable Differences Between Baileys Web & MD +## Notable Differences Between Baileys v3 & v4 1. Baileys has been written from the ground up to have a more "functional" structure. This is done primarily for simplicity & more testability -2. Baileys no longer maintains an internal state of chats/contacts/messages. You must take this on your own, simply because your state in MD is its own source of truth & there is no one-size-fits-all way to handle the storage for this. -3. A baileys "socket" is meant to be a temporary & disposable object -- this is done to maintain simplicity & prevent bugs. I felt the entire Baileys object became too bloated as it supported too many configurations. You're encouraged to write your own implementation to handle missing functionality. -4. Moreover, Baileys does not offer an inbuilt reconnect mechanism anymore (though it's super easy to set one up on your own with your own rules, check the example script) +2. The Baileys event emitter will emit all events and be used to generate a source of truth for the connected user's account. Access the event emitter using (`sock.ev`) +3. Baileys no longer maintains an internal state of chats/contacts/messages. You should ideally take this on your own, simply because your state in MD is its own source of truth & there is no one-size-fits-all way to handle the storage for this. However, a simple storage extension has been provided. This also serves as a good demonstration of how to use the Baileys event emitter to construct a source of truth. +4. A baileys "socket" is meant to be a temporary & disposable object -- this is done to maintain simplicity & prevent bugs. I felt the entire Baileys object became too bloated as it supported too many configurations. You're encouraged to write your own implementation to handle missing functionality. +5. Moreover, Baileys does not offer an inbuilt reconnect mechanism anymore (though it's super easy to set one up on your own with your own rules, check the example script) ## Configuring the Connection @@ -225,6 +226,45 @@ sock.ev.on('messages.upsert', ({ messages }) => { ``` +## Implementing a Data Store + +As mentioned earlier, Baileys does not come with a defacto storage for chats, contacts, messages. However, a simple in-memory implementation has been provided. The store listens for chat updates, new messages, message updates etc. to always have an up to date version of the data. + +It can be used as follows: + +``` ts +import makeWASocket, { makeInMemoryStore } from '@adiwajshing/baileys-md' +// the store maintains the data of the WA connection in memory +// can be written out to a file & read from it +const store = makeInMemoryStore({ logger: P().child({ level: 'debug', stream: 'store' }) }) +// can be read from a file +store.readFromFile('./baileys_store.json') +// saves the state to a file every 10s +setInterval(() => { + store.writeToFile('./baileys_store.json') +}, 10_000) + +const sock = makeWASocket({ }) +// will listen from this socket +// the store can listen from a new socket once the current socket outlives its lifetime +store.bind(sock.ev) + +sock.ev.on('chats.set', () => { + // can use "store.chats" however you want, even after the socket dies out + // "chats" => a KeyedDB instance + console.log('got chats', store.chats.all()) +}) + +sock.ev.on('contacts.set', () => { + console.log('got contacts', Object.values(store.contacts)) +}) + +``` + +The store also provides some simple functions such as `loadMessages` that utilize the store to speed up data retrieval. + +**Note:** I highly recommend building your own data store especially for MD connections, as storing someone's entire chat history in memory is a terrible waste of RAM. + ## Sending Messages **Send all types of messages with a single function:** diff --git a/src/Store/make-in-memory-store.ts b/src/Store/make-in-memory-store.ts index 5a3be5e..0f55933 100644 --- a/src/Store/make-in-memory-store.ts +++ b/src/Store/make-in-memory-store.ts @@ -263,6 +263,7 @@ export default ( state, presences, bind, + /** loads messages from the store, if not found -- uses the legacy connection */ loadMessages: async(jid: string, count: number, cursor: WAMessageCursor, sock: LegacyWASocket | undefined) => { const list = assertMessageList(jid) const retrieve = async(count: number, cursor: WAMessageCursor) => { From d8cc38608f7cb7c21d5d881f8a642ece7ea31eea Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 19 Jan 2022 22:52:12 +0530 Subject: [PATCH 302/311] chore: update package name --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c7622c2..6c4f581 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "@adiwajshing/baileys-md", + "name": "@adiwajshing/baileys", "version": "4.0.0", - "description": "WhatsApp Multi-Device API", + "description": "WhatsApp API", "homepage": "https://github.com/adiwajshing/Baileys", "main": "lib/index.js", "types": "lib/index.d.ts", From 05191ddb72aded31a2e7e30df2802861d3db685a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 19 Jan 2022 22:52:25 +0530 Subject: [PATCH 303/311] docs: add info about using legacy version --- README.md | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2372dfd..d94d396 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# Baileys MD - Typescript/Javascript WhatsApp Web API +# Baileys - Typescript/Javascript WhatsApp Web API - Early Multi-Device Edition. Breaks completely from master. - Baileys does not require Selenium or any other browser to be interface with WhatsApp Web, it does so directly using a **WebSocket**. Not running Selenium or Chromimum saves you like **half a gig** of ram :/ - Thank you to [@pokearaujo](https://github.com/pokearaujo/multidevice) for writing his observations on the workings of WhatsApp Multi-Device. + Baileys supports interacting with the multi-device & web versions of WhatsApp. + + Thank you to [@pokearaujo](https://github.com/pokearaujo/multidevice) for writing his observations on the workings of WhatsApp Multi-Device. Also, thank you to [@Sigalor](https://github.com/sigalor/whatsapp-web-reveng) for writing his observations on the workings of WhatsApp Web and thanks to [@Rhymen](https://github.com/Rhymen/go-whatsapp/) for the __go__ implementation. Baileys is type-safe, extensible and simple to use. If you require more functionality than provided, it'll super easy for you to write an extension. More on this [here](#WritingCustomFunctionality). @@ -19,8 +19,10 @@ Do check out & run [example.ts](Example/example.ts) to see example usage of the The script covers most common use cases. To run the example script, download or clone the repo and then type the following in terminal: 1. ``` cd path/to/Baileys ``` -2. ``` yarn``` -3. ``` yarn example ``` +2. ``` yarn ``` +3. + - ``` yarn example ``` for the multi-device edition + - ``` yarn example:legacy ``` for the legacy web edition ## Install @@ -236,7 +238,7 @@ It can be used as follows: import makeWASocket, { makeInMemoryStore } from '@adiwajshing/baileys-md' // the store maintains the data of the WA connection in memory // can be written out to a file & read from it -const store = makeInMemoryStore({ logger: P().child({ level: 'debug', stream: 'store' }) }) +const store = makeInMemoryStore({ }) // can be read from a file store.readFromFile('./baileys_store.json') // saves the state to a file every 10s @@ -265,6 +267,34 @@ The store also provides some simple functions such as `loadMessages` that utiliz **Note:** I highly recommend building your own data store especially for MD connections, as storing someone's entire chat history in memory is a terrible waste of RAM. +## Using the Legacy Version + +The API for the legacy and MD versions has been made as similar as possible so ya'll can switch between them seamlessly. + +Example on using the eg. version: +``` ts +import P from "pino" +import { Boom } from "@hapi/boom" +import { makeWALegacySocket } from '@adiwajshing/baileys-md' + +// store can be used with legacy version as well +const store = makeInMemoryStore({ logger: P().child({ level: 'debug', stream: 'store' }) }) + +const sock = makeWALegacySocket({ + logger: P({ level: 'debug' }), + printQRInTerminal: true, + auth: state +}) +// bind to the socket +store.bind(sock.ev) +``` + +If you need a type representing either the legacy or MD version: +``` ts +// this type can have any of the socket types underneath +import { AnyWASocket } from '@adiwajshing/baileys-md' +``` + ## Sending Messages **Send all types of messages with a single function:** From 34d934d7624886d6e56340b1dd1828f94a80c6b2 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 19 Jan 2022 22:54:43 +0530 Subject: [PATCH 304/311] chore: update memory store location --- Example/example.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/example.ts b/Example/example.ts index 5b964e7..4d4b289 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -5,10 +5,10 @@ import makeWASocket, { DisconnectReason, AnyMessageContent, delay, useSingleFile // the store maintains the data of the WA connection in memory // can be written out to a file & read from it const store = makeInMemoryStore({ logger: P().child({ level: 'debug', stream: 'store' }) }) -store.readFromFile('./baileys_store.json') +store.readFromFile('./baileys_store_multi.json') // save every 10s setInterval(() => { - store.writeToFile('./baileys_store.json') + store.writeToFile('./baileys_store_multi.json') }, 10_000) const { state, saveState } = useSingleFileAuthState('./auth_info_multi.json') From 5270b8482de0bebd9d731b15f5f52cfb3dd27297 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 19 Jan 2022 22:55:04 +0530 Subject: [PATCH 305/311] chore: update pino --- package.json | 4 +- yarn.lock | 136 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 82 insertions(+), 58 deletions(-) diff --git a/package.json b/package.json index 6c4f581..5f03ecb 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "libsignal": "git+https://github.com/adiwajshing/libsignal-node", "music-metadata": "^7.4.1", "node-cache": "^5.1.2", - "pino": "^6.7.0", + "pino": "^7.0.0", "protobufjs": "^6.10.1", "ws": "^8.0.0" }, @@ -63,7 +63,7 @@ "@types/got": "^9.6.11", "@types/jest": "^26.0.24", "@types/node": "^14.6.2", - "@types/pino": "^6.3.2", + "@types/pino": "^7.0.0", "@types/sharp": "^0.29.4", "@types/ws": "^8.0.0", "eslint": "^7.0.0", diff --git a/yarn.lock b/yarn.lock index 54b0e73..2b197cf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1103,29 +1103,12 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.5.tgz#b59daf6a7ffa461b5648456ca59050ba8e40ed54" integrity sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA== -"@types/pino-pretty@*": - version "4.7.1" - resolved "https://registry.yarnpkg.com/@types/pino-pretty/-/pino-pretty-4.7.1.tgz#2ce3f56f3cf4f9632374419d616ae2e6c933b935" - integrity sha512-l1ntNXdpVWsnPYUk5HyO5Lxfr38zLCgxVfEn/9Zhhm+nGF04/BiIou/m8XPwvoVZLV+livUo79VdHXMJPfUYxA== +"@types/pino@^7.0.0": + version "7.0.5" + resolved "https://registry.yarnpkg.com/@types/pino/-/pino-7.0.5.tgz#1c84a81b924a6a9e263dbb581dffdbad7a3c60c4" + integrity sha512-wKoab31pknvILkxAF8ss+v9iNyhw5Iu/0jLtRkUD74cNfOOLJNnqfFKAv0r7wVaTQxRZtWrMpGfShwwBjOcgcg== dependencies: - "@types/pino" "*" - -"@types/pino-std-serializers@*": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@types/pino-std-serializers/-/pino-std-serializers-2.4.1.tgz#f8bd52a209c8b3c97d1533b1ba27f57c816382bf" - integrity sha512-17XcksO47M24IVTVKPeAByWUd3Oez7EbIjXpSbzMPhXVzgjGtrOa49gKBwxH9hb8dKv58OelsWQ+A1G1l9S3wQ== - dependencies: - "@types/node" "*" - -"@types/pino@*", "@types/pino@^6.3.2": - version "6.3.9" - resolved "https://registry.yarnpkg.com/@types/pino/-/pino-6.3.9.tgz#dbbbd4a9a6b99935f5ed286c3d998ab83d260482" - integrity sha512-2/XV6adNNCLWnT2lJqcSn/OXrCxRFOY6yXYoofrLy5Ts5e8RHTJP1M4XEcCarQQMa6H6JISaa4GkrlGZwIP5aQ== - dependencies: - "@types/node" "*" - "@types/pino-pretty" "*" - "@types/pino-std-serializers" "*" - "@types/sonic-boom" "*" + pino "*" "@types/prettier@^2.1.5": version "2.3.2" @@ -1139,13 +1122,6 @@ dependencies: "@types/node" "*" -"@types/sonic-boom@*": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@types/sonic-boom/-/sonic-boom-0.7.0.tgz#38337036293992a1df65dd3161abddf8fb9b7176" - integrity sha512-AfqR0fZMoUXUNwusgXKxcE9DPlHNDHQp6nKYUd4PSRpLobF5CCevSpyTEBcVZreqaWKCnGBr9KI1fHMTttoB7A== - dependencies: - "@types/node" "*" - "@types/stack-utils@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" @@ -1960,6 +1936,16 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" +duplexify@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.2.tgz#18b4f8d28289132fa0b9573c898d9f903f81c7b0" + integrity sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw== + dependencies: + end-of-stream "^1.4.1" + inherits "^2.0.3" + readable-stream "^3.1.1" + stream-shift "^1.0.0" + electron-to-chromium@^1.3.723: version "1.3.779" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.779.tgz#de55492a756deec63424f89fbe62aec9776f0e6d" @@ -2292,11 +2278,6 @@ fast-redact@^3.0.0: resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.0.1.tgz#d6015b971e933d03529b01333ba7f22c29961e92" integrity sha512-kYpn4Y/valC9MdrISg47tZOpYBNoTXKgT9GYXFpHN/jYFs+lFkPoisY+LcBODdKVMY96ATzvzsWv+ES/4Kmufw== -fast-safe-stringify@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz#dc2af48c46cf712b683e849b2bbd446b32de936f" - integrity sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag== - fastq@^1.6.0: version "1.13.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" @@ -2355,11 +2336,6 @@ flat-cache@^3.0.4: flatted "^3.1.0" rimraf "^3.0.2" -flatstr@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931" - integrity sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw== - flatted@^3.1.0: version "3.2.4" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2" @@ -3808,6 +3784,11 @@ omggif@^1.0.10, omggif@^1.0.9: resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw== +on-exit-leak-free@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" + integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== + once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -3957,22 +3938,34 @@ picomatch@^2.0.4, picomatch@^2.2.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== -pino-std-serializers@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz#b56487c402d882eb96cd67c257868016b61ad671" - integrity sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg== +pino-abstract-transport@v0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz#4b54348d8f73713bfd14e3dc44228739aa13d9c0" + integrity sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ== + dependencies: + duplexify "^4.1.2" + split2 "^4.0.0" -pino@^6.7.0: - version "6.12.0" - resolved "https://registry.yarnpkg.com/pino/-/pino-6.12.0.tgz#2281521620d70eeff519039467352d656f46735e" - integrity sha512-5NGopOcUusGuklGHVVv9az0Hv/Dj3urHhD3G+zhl5pBGIRYAeGCi/Ej6YCl16Q2ko28cmYiJz+/qRoJiwy62Rw== +pino-std-serializers@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz#1791ccd2539c091ae49ce9993205e2cd5dbba1e2" + integrity sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q== + +pino@*, pino@^7.0.0: + version "7.6.3" + resolved "https://registry.yarnpkg.com/pino/-/pino-7.6.3.tgz#47841acd2b83d2b0c929966433a5b4abd7299f8e" + integrity sha512-TCUDiN0QmzruJ5UE4mIFkTcfCSROV7IVRp5SEUH77UnjDHbeoFntj9jQexvYZhCHp1yhjYCH6vZ8rV85L04KaA== dependencies: fast-redact "^3.0.0" - fast-safe-stringify "^2.0.8" - flatstr "^1.0.12" - pino-std-serializers "^3.1.0" + on-exit-leak-free "^0.2.0" + pino-abstract-transport v0.5.0 + pino-std-serializers "^4.0.0" + process-warning "^1.0.0" quick-format-unescaped "^4.0.3" - sonic-boom "^1.0.2" + real-require "^0.1.0" + safe-stable-stringify "^2.1.0" + sonic-boom "^2.2.1" + thread-stream "^0.13.0" pirates@^4.0.1: version "4.0.1" @@ -4054,6 +4047,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process-warning@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-1.0.0.tgz#980a0b25dc38cd6034181be4b7726d89066b4616" + integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== + process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" @@ -4201,6 +4199,11 @@ readable-web-to-node-stream@^3.0.0: dependencies: readable-stream "^3.6.0" +real-require@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.1.0.tgz#736ac214caa20632847b7ca8c1056a0767df9381" + integrity sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg== + rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -4298,6 +4301,11 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-stable-stringify@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz#ab67cbe1fe7d40603ca641c5e765cb942d04fc73" + integrity sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg== + "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -4435,13 +4443,12 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -sonic-boom@^1.0.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.4.1.tgz#d35d6a74076624f12e6f917ade7b9d75e918f53e" - integrity sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg== +sonic-boom@^2.2.1: + version "2.6.0" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-2.6.0.tgz#8786fc78be07c18a90381acd816d1d4afe3537a2" + integrity sha512-6xYZFRmDEtxGqfOKcDQ4cPLrNa0SPEDI+wlzDAHowXE6YV42NeXqg9mP2KkiM8JVu3lHfZ2iQKYlGOz+kTpphg== dependencies: atomic-sleep "^1.0.0" - flatstr "^1.0.12" source-map-support@^0.5.6: version "0.5.19" @@ -4466,6 +4473,11 @@ source-map@^0.7.3: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +split2@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.1.0.tgz#101907a24370f85bb782f08adaabe4e281ecf809" + integrity sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -4478,6 +4490,11 @@ stack-utils@^2.0.3: dependencies: escape-string-regexp "^2.0.0" +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -4693,6 +4710,13 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +thread-stream@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-0.13.0.tgz#c68054bdea250c5d8d400caa3233a150d5461cca" + integrity sha512-kTMZeX4Dzlb1zZ00/01aerGaTw2i8NE4sWF0TvF1uXewRhCiUjCvatQkvxIvFqauWG2ADFS2Wpd3qBeYL9i3dg== + dependencies: + real-require "^0.1.0" + throat@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" From 1ff4ff3aa65fcd3064b855446b50cd3b803d7acd Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 20 Jan 2022 11:17:22 +0530 Subject: [PATCH 306/311] chore: update version --- src/Defaults/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 1d247f9..f596479 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -18,7 +18,7 @@ export const NOISE_WA_HEADER = new Uint8Array([87, 65, 5, 2]) // last is "DICT_V export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi const BASE_CONNECTION_CONFIG: CommonSocketConfig = { - version: [2, 2147, 16], + version: [2, 2149, 4], browser: Browsers.baileys('Chrome'), waWebSocketUrl: 'wss://web.whatsapp.com/ws/chat', From c4eea6fd69368b3f94613ab1fbdf3b5fb087f9f3 Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Thu, 20 Jan 2022 11:18:10 +0530 Subject: [PATCH 307/311] minor spelling typo (#1167) Signed-off-by: Prince Mendiratta --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d94d396..123a792 100644 --- a/README.md +++ b/README.md @@ -382,7 +382,7 @@ const listMessage = { text: "This is a list", footer: "nice footer, link: https://google.com", title: "Amazing boldfaced list title", - buttonText: "Required, text on the button to vie the list", + buttonText: "Required, text on the button to view the list", sections } From 284c7e781288671aab43d9f3fd3fdecfc5d0bb5f Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Thu, 20 Jan 2022 12:28:56 +0530 Subject: [PATCH 308/311] fix: do not mutate update object reference --- src/Store/make-in-memory-store.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Store/make-in-memory-store.ts b/src/Store/make-in-memory-store.ts index 0f55933..ef41f87 100644 --- a/src/Store/make-in-memory-store.ts +++ b/src/Store/make-in-memory-store.ts @@ -117,9 +117,10 @@ export default ( chats.upsert(...newChats) }) ev.on('chats.update', updates => { - for(const update of updates) { + for(let update of updates) { const result = chats.update(update.id!, chat => { if(update.unreadCount > 0) { + update = { ...update } update.unreadCount = chat.unreadCount + update.unreadCount } From 92587bd46a5b43f448412553147c6c9b8099a47d Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 22 Jan 2022 00:27:00 +0530 Subject: [PATCH 309/311] refactor: use the proto UserReceipt instead of custom MessageInfo --- src/LegacySocket/messages.ts | 39 ++++++++++++++++++++----------- src/Store/make-in-memory-store.ts | 39 +++++++++++++++++-------------- src/Types/Events.ts | 4 ++-- src/Types/Message.ts | 8 ++----- 4 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/LegacySocket/messages.ts b/src/LegacySocket/messages.ts index f9b8a8d..2316ddd 100644 --- a/src/LegacySocket/messages.ts +++ b/src/LegacySocket/messages.ts @@ -1,7 +1,7 @@ import { Boom } from '@hapi/boom' import { proto } from '../../WAProto' import { WA_DEFAULT_EPHEMERAL } from '../Defaults' -import { AnyMessageContent, Chat, GroupMetadata, LegacySocketConfig, MediaConnInfo, MessageInfo, MessageInfoUpdate, MessageUpdateType, MiscMessageGenerationOptions, ParticipantAction, WAFlag, WAMessage, WAMessageCursor, WAMessageKey, WAMessageStatus, WAMessageStubType, WAMessageUpdate, WAMetric, WAUrlInfo } from '../Types' +import { AnyMessageContent, Chat, GroupMetadata, LegacySocketConfig, MediaConnInfo, MessageUpdateType, MessageUserReceipt, MessageUserReceiptUpdate, MiscMessageGenerationOptions, ParticipantAction, WAFlag, WAMessage, WAMessageCursor, WAMessageKey, WAMessageStatus, WAMessageStubType, WAMessageUpdate, WAMetric, WAUrlInfo } from '../Types' import { decryptMediaMessageBuffer, extractMessageContent, generateWAMessage, getWAUploadToServer, toNumber } from '../Utils' import { areJidsSameUser, BinaryNode, getBinaryNodeMessages, isJidGroup, jidNormalizedUser } from '../WABinary' import makeChatsSocket from './chats' @@ -353,13 +353,16 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { ids = [ids] } - let updateKey: keyof MessageInfoUpdate['update'] + let updateKey: keyof MessageUserReceipt switch (attributes.ack.toString()) { case '2': - updateKey = 'deliveries' + updateKey = 'receiptTimestamp' break case '3': - updateKey = 'reads' + updateKey = 'readTimestamp' + break + case '4': + updateKey = 'playedTimestamp' break default: logger.warn({ attributes }, 'received unknown message info update') @@ -370,13 +373,17 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { remoteJid: jidNormalizedUser(attributes.to), fromMe: areJidsSameUser(attributes.from, state.legacy?.user?.id || ''), } - const updates = ids.map(id => ({ + + const userJid = jidNormalizedUser(attributes.participant || attributes.to) + + const updates = ids.map(id => ({ key: { ...keyPartial, id }, - update: { - [updateKey]: { [jidNormalizedUser(attributes.participant || attributes.to)]: new Date(+attributes.t) } + receipt: { + userJid, + [updateKey]: +attributes.t } })) - ev.emit('message-info.update', updates) + ev.emit('message-receipt.update', updates) // for individual messages // it means the message is marked read/delivered if(!isJidGroup(keyPartial.remoteJid)) { @@ -384,7 +391,7 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { { key: { ...keyPartial, id }, update: { - status: updateKey === 'deliveries' ? WAMessageStatus.DELIVERY_ACK : WAMessageStatus.READ + status: updateKey === 'receiptTimestamp' ? WAMessageStatus.DELIVERY_ACK : WAMessageStatus.READ } } ))) @@ -416,24 +423,28 @@ const makeMessagesSocket = (config: LegacySocketConfig) => { expect200: true, requiresPhoneConnection: true }) - const info: MessageInfo = { reads: {}, deliveries: {} } + const info: { [jid: string]: MessageUserReceipt } = { } if(Array.isArray(content)) { for(const { tag, content: innerData } of content) { const [{ attrs }] = (innerData as BinaryNode[]) + const jid = jidNormalizedUser(attrs.jid) - const date = new Date(+attrs.t * 1000) + const recp = info[jid] || { userJid: jid } + const date = +attrs.t switch (tag) { case 'read': - info.reads[jid] = date + recp.readTimestamp = date break case 'delivery': - info.deliveries[jid] = date + recp.receiptTimestamp = date break } + + info[jid] = recp } } - return info + return Object.values(info) }, downloadMediaMessage: async(message: WAMessage, type: 'buffer' | 'stream' = 'buffer') => { const downloadMediaMessage = async() => { diff --git a/src/Store/make-in-memory-store.ts b/src/Store/make-in-memory-store.ts index ef41f87..90a766d 100644 --- a/src/Store/make-in-memory-store.ts +++ b/src/Store/make-in-memory-store.ts @@ -5,7 +5,7 @@ import { proto } from '../../WAProto' import { DEFAULT_CONNECTION_CONFIG } from '../Defaults' import type makeLegacySocket from '../LegacySocket' import type makeMDSocket from '../Socket' -import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, MessageInfo, PresenceData, WAMessage, WAMessageCursor, WAMessageKey } from '../Types' +import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, PresenceData, WAMessage, WAMessageCursor, WAMessageKey } from '../Types' import { toNumber } from '../Utils' import { jidNormalizedUser } from '../WABinary' import makeOrderedDictionary from './make-ordered-dictionary' @@ -38,7 +38,6 @@ export default ( const messages: { [_: string]: ReturnType } = { } const contacts: { [_: string]: Contact } = { } const groupMetadata: { [_: string]: GroupMetadata } = { } - const messageInfos: { [id: string]: MessageInfo } = { } const presences: { [id: string]: { [participant: string]: PresenceData } } = { } const state: ConnectionState = { connection: 'close' } @@ -159,9 +158,6 @@ export default ( } ]) } - - // add message infos if required - messageInfos[msg.key.id!] = messageInfos[msg.key.id!] || { reads: {}, deliveries: {} } } } @@ -224,13 +220,17 @@ export default ( } }) - ev.on('message-info.update', updates => { - for(const { key, update } of updates) { - const obj = messageInfos[key.id!] - if(obj) { - // add reads/deliveries - for(const key in update) { - Object.assign(obj[key], update[key]) + ev.on('message-receipt.update', updates => { + for(const { key, receipt } of updates) { + const obj = messages[key.remoteJid!] + const msg = obj?.get(key.id) + if(msg) { + msg.userReceipt = msg.userReceipt || [] + const recp = msg.userReceipt.find(m => m.userJid === receipt.userJid) + if(recp) { + Object.assign(recp, receipt) + } else { + msg.userReceipt.push(receipt) } } } @@ -260,7 +260,6 @@ export default ( contacts, messages, groupMetadata, - messageInfos, state, presences, bind, @@ -348,12 +347,18 @@ export default ( return groupMetadata[jid] }, - fetchMessageInfo: async({ remoteJid, id }: WAMessageKey, sock: LegacyWASocket | undefined) => { - if(!messageInfos[id!]) { - messageInfos[id!] = await sock?.messageInfo(remoteJid, id) + fetchMessageReceipts: async({ remoteJid, id }: WAMessageKey, sock: LegacyWASocket | undefined) => { + const list = messages[remoteJid] + const msg = list?.get(id) + let receipts = msg.userReceipt + if(!receipts) { + receipts = await sock?.messageInfo(remoteJid, id) + if(msg) { + msg.userReceipt = receipts + } } - return messageInfos[id!] + return receipts }, toJSON, fromJSON, diff --git a/src/Types/Events.ts b/src/Types/Events.ts index 039416c..889040d 100644 --- a/src/Types/Events.ts +++ b/src/Types/Events.ts @@ -3,7 +3,7 @@ import { AuthenticationCreds } from './Auth' import { Chat, PresenceData } from './Chat' import { Contact } from './Contact' import { GroupMetadata, ParticipantAction } from './GroupMetadata' -import { MessageInfoUpdate, MessageUpdateType, WAMessage, WAMessageKey, WAMessageUpdate } from './Message' +import { MessageUpdateType, MessageUserReceiptUpdate, WAMessage, WAMessageKey, WAMessageUpdate } from './Message' import { ConnectionState } from './State' export type BaileysEventMap = { @@ -37,7 +37,7 @@ export type BaileysEventMap = { * */ 'messages.upsert': { messages: WAMessage[], type: MessageUpdateType } - 'message-info.update': MessageInfoUpdate[] + 'message-receipt.update': MessageUserReceiptUpdate[] 'groups.upsert': GroupMetadata[] 'groups.update': Partial[] diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 4ee130b..5cbf760 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -166,14 +166,10 @@ export type MessageGenerationOptions = MessageContentGenerationOptions & Message export type MessageUpdateType = 'append' | 'notify' | 'replace' -export type MessageInfoEventMap = { [jid: string]: Date } -export interface MessageInfo { - reads: MessageInfoEventMap - deliveries: MessageInfoEventMap -} +export type MessageUserReceipt = proto.IUserReceipt export type WAMessageUpdate = { update: Partial, key: proto.IMessageKey } export type WAMessageCursor = { before: WAMessageKey | undefined } | { after: WAMessageKey | undefined } -export type MessageInfoUpdate = { key: proto.IMessageKey, update: Partial } +export type MessageUserReceiptUpdate = { key: proto.IMessageKey, receipt: MessageUserReceipt } From 57d6ab62a157eb7807b42a741ef7756818e0bd16 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 22 Jan 2022 11:37:26 +0530 Subject: [PATCH 310/311] feat: use message receipt on MD --- src/Socket/messages-recv.ts | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 7146431..8dd4e65 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -1,7 +1,7 @@ import { proto } from '../../WAProto' import { KEY_BUNDLE_TYPE } from '../Defaults' -import { Chat, GroupMetadata, ParticipantAction, SocketConfig, WAMessageStubType } from '../Types' +import { Chat, GroupMetadata, MessageUserReceipt, ParticipantAction, SocketConfig, WAMessageStubType } from '../Types' import { decodeMessageStanza, downloadAndProcessHistorySyncNotification, encodeBigEndian, generateSignalPubKey, toNumber, xmppPreKey, xmppSignedPreKey } from '../Utils' import { areJidsSameUser, BinaryNode, BinaryNodeAttributes, getAllBinaryNodeChildren, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser } from '../WABinary' import { makeChatsSocket } from './chats' @@ -438,10 +438,28 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { !isNodeFromMe ) ) { - ev.emit('messages.update', ids.map(id => ({ - key: { ...key, id }, - update: { status } - }))) + if(isJidGroup(remoteJid)) { + const updateKey: keyof MessageUserReceipt = status === proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp' + ev.emit( + 'message-receipt.update', + ids.map(id => ({ + key: { ...key, id }, + receipt: { + userJid: jidNormalizedUser(attrs.participant), + [updateKey]: +attrs.t + } + })) + ) + } else { + ev.emit( + 'messages.update', + ids.map(id => ({ + key: { ...key, id }, + update: { status } + })) + ) + } + } if(attrs.type === 'retry') { From e954fc00539a38c99bb62a3551be0d744f679f18 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 22 Jan 2022 11:37:39 +0530 Subject: [PATCH 311/311] lint: examples --- Example/example-legacy.ts | 96 ++++++++++++++++----------------- Example/example.ts | 111 +++++++++++++++++++------------------- 2 files changed, 104 insertions(+), 103 deletions(-) diff --git a/Example/example-legacy.ts b/Example/example-legacy.ts index 0b4b388..bae2b89 100644 --- a/Example/example-legacy.ts +++ b/Example/example-legacy.ts @@ -1,6 +1,6 @@ -import P from "pino" -import { Boom } from "@hapi/boom" -import { makeWALegacySocket, DisconnectReason, AnyMessageContent, delay, useSingleFileLegacyAuthState, makeInMemoryStore } from '../src' +import { Boom } from '@hapi/boom' +import P from 'pino' +import { AnyMessageContent, delay, DisconnectReason, makeInMemoryStore, makeWALegacySocket, useSingleFileLegacyAuthState } from '../src' // the store maintains the data of the WA connection in memory // can be written out to a file & read from it @@ -8,7 +8,7 @@ const store = makeInMemoryStore({ logger: P().child({ level: 'debug', stream: 's store.readFromFile('./baileys_store.json') // save every 10s setInterval(() => { - store.writeToFile('./baileys_store.json') + store.writeToFile('./baileys_store.json') }, 10_000) const { state, saveState } = useSingleFileLegacyAuthState('./auth_info.json') @@ -16,61 +16,61 @@ const { state, saveState } = useSingleFileLegacyAuthState('./auth_info.json') // start a connection const startSock = () => { - const sock = makeWALegacySocket({ - logger: P({ level: 'debug' }), - printQRInTerminal: true, - auth: state - }) - store.bind(sock.ev) + const sock = makeWALegacySocket({ + logger: P({ level: 'debug' }), + printQRInTerminal: true, + auth: state + }) + store.bind(sock.ev) - const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { - await sock.presenceSubscribe(jid) - await delay(500) + const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { + await sock.presenceSubscribe(jid) + await delay(500) - await sock.sendPresenceUpdate('composing', jid) - await delay(2000) + await sock.sendPresenceUpdate('composing', jid) + await delay(2000) - await sock.sendPresenceUpdate('paused', jid) + await sock.sendPresenceUpdate('paused', jid) - await sock.sendMessage(jid, msg) - } + await sock.sendMessage(jid, msg) + } - sock.ev.on('messages.upsert', async m => { - if(m.type === 'append' || m.type === 'notify') { - console.log(JSON.stringify(m, undefined, 2)) - } + sock.ev.on('messages.upsert', async m => { + if(m.type === 'append' || m.type === 'notify') { + console.log(JSON.stringify(m, undefined, 2)) + } - const msg = m.messages[0] - if(!msg.key.fromMe && m.type === 'notify') { - console.log('replying to', m.messages[0].key.remoteJid) - await sock!.chatRead(msg.key, 1) - await sendMessageWTyping({ text: 'Hello there!' }, msg.key.remoteJid) - } + const msg = m.messages[0] + if(!msg.key.fromMe && m.type === 'notify') { + console.log('replying to', m.messages[0].key.remoteJid) + await sock!.chatRead(msg.key, 1) + await sendMessageWTyping({ text: 'Hello there!' }, msg.key.remoteJid) + } - }) + }) - sock.ev.on('messages.update', m => console.log(JSON.stringify(m, undefined, 2))) - sock.ev.on('presence.update', m => console.log(m)) - sock.ev.on('chats.update', m => console.log(m)) - sock.ev.on('contacts.update', m => console.log(m)) + sock.ev.on('messages.update', m => console.log(JSON.stringify(m, undefined, 2))) + sock.ev.on('presence.update', m => console.log(m)) + sock.ev.on('chats.update', m => console.log(m)) + sock.ev.on('contacts.update', m => console.log(m)) - sock.ev.on('connection.update', (update) => { - const { connection, lastDisconnect } = update - if(connection === 'close') { - // reconnect if not logged out - if((lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut) { - startSock() - } else { - console.log('connection closed') - } - } + sock.ev.on('connection.update', (update) => { + const { connection, lastDisconnect } = update + if(connection === 'close') { + // reconnect if not logged out + if((lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut) { + startSock() + } else { + console.log('connection closed') + } + } - console.log('connection update', update) - }) - // listen for when the auth credentials is updated - sock.ev.on('creds.update', saveState) + console.log('connection update', update) + }) + // listen for when the auth credentials is updated + sock.ev.on('creds.update', saveState) - return sock + return sock } startSock() \ No newline at end of file diff --git a/Example/example.ts b/Example/example.ts index 4d4b289..2a89d22 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -1,6 +1,6 @@ -import P from "pino" -import { Boom } from "@hapi/boom" -import makeWASocket, { DisconnectReason, AnyMessageContent, delay, useSingleFileAuthState, makeInMemoryStore } from '../src' +import { Boom } from '@hapi/boom' +import P from 'pino' +import makeWASocket, { AnyMessageContent, delay, DisconnectReason, makeInMemoryStore, useSingleFileAuthState } from '../src' // the store maintains the data of the WA connection in memory // can be written out to a file & read from it @@ -8,7 +8,7 @@ const store = makeInMemoryStore({ logger: P().child({ level: 'debug', stream: 's store.readFromFile('./baileys_store_multi.json') // save every 10s setInterval(() => { - store.writeToFile('./baileys_store_multi.json') + store.writeToFile('./baileys_store_multi.json') }, 10_000) const { state, saveState } = useSingleFileAuthState('./auth_info_multi.json') @@ -16,70 +16,71 @@ const { state, saveState } = useSingleFileAuthState('./auth_info_multi.json') // start a connection const startSock = () => { - const sock = makeWASocket({ - logger: P({ level: 'trace' }), - printQRInTerminal: true, - auth: state, - // implement to handle retries - getMessage: async key => { - return { - conversation: 'hello' - } - } - }) + const sock = makeWASocket({ + logger: P({ level: 'trace' }), + printQRInTerminal: true, + auth: state, + // implement to handle retries + getMessage: async key => { + return { + conversation: 'hello' + } + } + }) - store.bind(sock.ev) + store.bind(sock.ev) - const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { - await sock.presenceSubscribe(jid) - await delay(500) + const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => { + await sock.presenceSubscribe(jid) + await delay(500) - await sock.sendPresenceUpdate('composing', jid) - await delay(2000) + await sock.sendPresenceUpdate('composing', jid) + await delay(2000) - await sock.sendPresenceUpdate('paused', jid) + await sock.sendPresenceUpdate('paused', jid) - await sock.sendMessage(jid, msg) - } + await sock.sendMessage(jid, msg) + } - sock.ev.on('chats.set', item => console.log(`recv ${item.chats.length} chats (is latest: ${item.isLatest})`)) - sock.ev.on('messages.set', item => console.log(`recv ${item.messages.length} messages (is latest: ${item.isLatest})`)) - sock.ev.on('contacts.set', item => console.log(`recv ${item.contacts.length} contacts`)) + sock.ev.on('chats.set', item => console.log(`recv ${item.chats.length} chats (is latest: ${item.isLatest})`)) + sock.ev.on('messages.set', item => console.log(`recv ${item.messages.length} messages (is latest: ${item.isLatest})`)) + sock.ev.on('contacts.set', item => console.log(`recv ${item.contacts.length} contacts`)) - sock.ev.on('messages.upsert', async m => { - console.log(JSON.stringify(m, undefined, 2)) + sock.ev.on('messages.upsert', async m => { + console.log(JSON.stringify(m, undefined, 2)) - const msg = m.messages[0] - if(!msg.key.fromMe && m.type === 'notify') { - console.log('replying to', m.messages[0].key.remoteJid) - await sock!.sendReadReceipt(msg.key.remoteJid, msg.key.participant, [msg.key.id]) - await sendMessageWTyping({ text: 'Hello there!' }, msg.key.remoteJid) - } + const msg = m.messages[0] + if(!msg.key.fromMe && m.type === 'notify') { + console.log('replying to', m.messages[0].key.remoteJid) + await sock!.sendReadReceipt(msg.key.remoteJid, msg.key.participant, [msg.key.id]) + await sendMessageWTyping({ text: 'Hello there!' }, msg.key.remoteJid) + } - }) + }) - sock.ev.on('messages.update', m => console.log(m)) - sock.ev.on('presence.update', m => console.log(m)) - sock.ev.on('chats.update', m => console.log(m)) - sock.ev.on('contacts.upsert', m => console.log(m)) + sock.ev.on('messages.update', m => console.log(m)) + sock.ev.on('message-receipt.update', m => console.log(m)) + sock.ev.on('presence.update', m => console.log(m)) + sock.ev.on('chats.update', m => console.log(m)) + sock.ev.on('contacts.upsert', m => console.log(m)) - sock.ev.on('connection.update', (update) => { - const { connection, lastDisconnect } = update - if(connection === 'close') { - // reconnect if not logged out - if((lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut) { - startSock() - } else { - console.log('connection closed') - } - } + sock.ev.on('connection.update', (update) => { + const { connection, lastDisconnect } = update + if(connection === 'close') { + // reconnect if not logged out + if((lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut) { + startSock() + } else { + console.log('connection closed') + } + } - console.log('connection update', update) - }) - // listen for when the auth credentials is updated - sock.ev.on('creds.update', saveState) + console.log('connection update', update) + }) + // listen for when the auth credentials is updated + sock.ev.on('creds.update', saveState) - return sock + return sock } startSock() \ No newline at end of file