wechaty-puppet-service
Version:
Puppet Service for Wechaty
1,093 lines (1,092 loc) • 61.6 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PuppetService = void 0;
/**
* Wechaty Open Source Software - https://github.com/wechaty
*
* @copyright 2016 Huan LI (李卓桓) <https://github.com/huan>, and
* Wechaty Contributors <https://github.com/wechaty>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const util_1 = __importDefault(require("util"));
const PUPPET = __importStar(require("wechaty-puppet"));
const wechaty_grpc_1 = require("wechaty-grpc");
const wechaty_redux_1 = require("wechaty-redux");
const ducks_1 = require("ducks");
// import type { Subscription } from 'rxjs'
/**
* Deprecated. Will be removed after Dec 31, 2022
*/
const mod_js_1 = require("../deprecated/mod.js");
const serialize_file_box_js_1 = require("../deprecated/serialize-file-box.js");
const timestamp_js_1 = require("../pure-functions/timestamp.js");
const mod_js_2 = require("../file-box-helper/mod.js");
const config_js_1 = require("../config.js");
const event_type_rev_js_1 = require("../event-type-rev.js");
const package_json_js_1 = require("../package-json.js");
const grpc_manager_js_1 = require("./grpc-manager.js");
const payload_store_js_1 = require("./payload-store.js");
class PuppetService extends PUPPET.Puppet {
options;
static VERSION = config_js_1.VERSION;
_cleanupCallbackList;
_payloadStore;
/**
* Wechaty Redux
*/
_ducks;
_store;
_grpcManager;
get grpcManager() {
if (!this._grpcManager) {
throw new Error('no grpc manager');
}
return this._grpcManager;
}
/**
* UUIDify:
* We need to clone a FileBox
* to set uuid loader/saver with this grpc client
*/
FileBoxUuid;
constructor(options = {}) {
super(options);
this.options = options;
this._payloadStore = new payload_store_js_1.PayloadStore({
token: config_js_1.envVars.WECHATY_PUPPET_SERVICE_TOKEN(this.options.token),
});
this.hookPayloadStore();
this._ducks = new ducks_1.Ducks({ puppet: wechaty_redux_1.Duck });
this._store = this._ducks.configureStore();
this._cleanupCallbackList = [];
this.FileBoxUuid = (0, mod_js_2.uuidifyFileBoxGrpc)(() => this.grpcManager.client);
}
async serializeFileBox(fileBox) {
/**
* 1. if the fileBox is one of type `Url`, `QRCode`, `Uuid`, etc,
* then it can be serialized by `fileBox.toString()`
* 2. if the fileBox is one of type `Stream`, `Buffer`, `File`, etc,
* then it need to be convert to type `Uuid`
* before serialized by `fileBox.toString()`
*/
const normalizedFileBox = await (0, mod_js_2.normalizeFileBoxUuid)(this.FileBoxUuid)(fileBox);
return JSON.stringify(normalizedFileBox);
}
name() {
return package_json_js_1.packageJson.name || 'wechaty-puppet-service';
}
version() {
return package_json_js_1.packageJson.version || '0.0.0';
}
async onStart() {
config_js_1.log.verbose('PuppetService', 'onStart()');
if (this._grpcManager) {
config_js_1.log.warn('PuppetService', 'onStart() found this.grpc is already existed. dropped.');
this._grpcManager = undefined;
}
config_js_1.log.verbose('PuppetService', 'start() instanciating GrpcManager ...');
const grpcManager = new grpc_manager_js_1.GrpcManager(this.options);
config_js_1.log.verbose('PuppetService', 'start() instanciating GrpcManager ... done');
/**
* Huan(202108): when we started the event stream,
* the `this.grpc` need to be available for all listeners.
*/
this._grpcManager = grpcManager;
config_js_1.log.verbose('PuppetService', 'start() setting up bridge grpc event stream ...');
this.bridgeGrpcEventStream(grpcManager);
config_js_1.log.verbose('PuppetService', 'start() setting up bridge grpc event stream ... done');
config_js_1.log.verbose('PuppetService', 'start() starting grpc manager...');
await grpcManager.start();
config_js_1.log.verbose('PuppetService', 'start() starting grpc manager... done');
/**
* Ducks management
*/
const subscription = (0, wechaty_redux_1.puppet$)(this)
.subscribe(this._store.dispatch);
this._cleanupCallbackList.push(() => subscription.unsubscribe());
config_js_1.log.verbose('PuppetService', 'onStart() ... done');
}
async onStop() {
config_js_1.log.verbose('PuppetService', 'onStop()');
this._cleanupCallbackList.map(setImmediate);
this._cleanupCallbackList.length = 0;
if (this._grpcManager) {
config_js_1.log.verbose('PuppetService', 'onStop() stopping grpc manager ...');
const grpcManager = this._grpcManager;
this._grpcManager = undefined;
await grpcManager.stop();
config_js_1.log.verbose('PuppetService', 'onStop() stopping grpc manager ... done');
}
config_js_1.log.verbose('PuppetService', 'onStop() ... done');
}
hookPayloadStore() {
config_js_1.log.verbose('PuppetService', 'hookPayloadStore()');
this.on('login', async ({ contactId }) => {
try {
config_js_1.log.verbose('PuppetService', 'hookPayloadStore() this.on(login) contactId: "%s"', contactId);
await this._payloadStore.start(contactId);
}
catch (e) {
config_js_1.log.verbose('PuppetService', 'hookPayloadStore() this.on(login) rejection "%s"', e.message);
}
});
this.on('logout', async ({ contactId }) => {
config_js_1.log.verbose('PuppetService', 'hookPayloadStore() this.on(logout) contactId: "%s"', contactId);
try {
await this._payloadStore.stop();
}
catch (e) {
config_js_1.log.verbose('PuppetService', 'hookPayloadStore() this.on(logout) rejection "%s"', e.message);
}
});
}
bridgeGrpcEventStream(client) {
config_js_1.log.verbose('PuppetService', 'bridgeGrpcEventStream(client)');
client
.on('data', this.onGrpcStreamEvent.bind(this))
.on('end', () => {
config_js_1.log.verbose('PuppetService', 'bridgeGrpcEventStream() eventStream.on(end)');
})
.on('error', (e) => {
this.emit('error', e);
// https://github.com/wechaty/wechaty-puppet-service/issues/16
// log.verbose('PuppetService', 'bridgeGrpcEventStream() eventStream.on(error) %s', e)
// const reason = 'bridgeGrpcEventStream() eventStream.on(error) ' + e
/**
* Huan(202110): simple reset puppet when grpc client has error? (or not?)
*/
// this.wrapAsync(this.reset())
// /**
// * The `Puppet` class have a throttleQueue for receiving the `reset` events
// * and it's the `Puppet` class's duty for call the `puppet.reset()` to reset the puppet.
// */
// if (this.state.on()) {
// this.emit('reset', { data: reason })
// }
})
.on('cancel', (...args) => {
config_js_1.log.verbose('PuppetService', 'bridgeGrpcEventStream() eventStream.on(cancel), %s', JSON.stringify(args));
});
}
onGrpcStreamEvent(event) {
const type = event.getType();
const payload = event.getPayload();
config_js_1.log.verbose('PuppetService', 'onGrpcStreamEvent({type:%s(%s), payload(len:%s)})', event_type_rev_js_1.EventTypeRev[type], type, payload.length);
config_js_1.log.silly('PuppetService', 'onGrpcStreamEvent({type:%s(%s), payload:"%s"})', event_type_rev_js_1.EventTypeRev[type], type, payload);
if (type !== wechaty_grpc_1.puppet.EventType.EVENT_TYPE_HEARTBEAT) {
this.emit('heartbeat', {
data: `onGrpcStreamEvent(${event_type_rev_js_1.EventTypeRev[type]})`,
});
}
switch (type) {
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_DONG:
this.emit('dong', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_ERROR:
this.emit('error', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_HEARTBEAT:
this.emit('heartbeat', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_FRIENDSHIP:
this.emit('friendship', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_LOGIN:
{
const loginPayload = JSON.parse(payload);
(async () => this.login(loginPayload.contactId))().catch(e => config_js_1.log.error('PuppetService', 'onGrpcStreamEvent() this.login() rejection %s', e.message));
}
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_LOGOUT:
{
const logoutPayload = JSON.parse(payload);
(async () => this.logout(logoutPayload.data))().catch(e => config_js_1.log.error('PuppetService', 'onGrpcStreamEvent() this.logout() rejection %s', e.message));
}
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_DIRTY:
this.emit('dirty', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_MESSAGE:
this.emit('message', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_POST:
this.emit('post', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_READY:
this.emit('ready', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_ROOM_INVITE:
this.emit('room-invite', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_ROOM_JOIN:
this.emit('room-join', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_ROOM_LEAVE:
this.emit('room-leave', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_ROOM_TOPIC:
this.emit('room-topic', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_SCAN:
this.emit('scan', JSON.parse(payload));
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_RESET:
config_js_1.log.warn('PuppetService', 'onGrpcStreamEvent() got an EventType.EVENT_TYPE_RESET ?');
// the `reset` event should be dealed not send out
break;
case wechaty_grpc_1.puppet.EventType.EVENT_TYPE_UNSPECIFIED:
config_js_1.log.error('PuppetService', 'onGrpcStreamEvent() got an EventType.EVENT_TYPE_UNSPECIFIED ?');
break;
default:
// Huan(202003): in default, the `type` type should be `never`, please check.
throw new Error('eventType ' + type + ' unsupported! (code should not reach here)');
}
}
async logout(reason) {
config_js_1.log.verbose('PuppetService', 'logout(%s)', reason ? `"${reason}"` : '');
await super.logout(reason);
try {
await util_1.default.promisify(this.grpcManager.client.logout
.bind(this.grpcManager.client))(new wechaty_grpc_1.puppet.LogoutRequest());
}
catch (e) {
config_js_1.log.silly('PuppetService', 'logout() no grpc client');
}
}
ding(data) {
config_js_1.log.silly('PuppetService', 'ding(%s)', data);
const request = new wechaty_grpc_1.puppet.DingRequest();
request.setData(data || '');
this.grpcManager.client.ding(request, (error, _response) => {
if (error) {
config_js_1.log.error('PuppetService', 'ding() rejection: %s', error);
}
});
}
/**
*
* Huan(202111) Issue #158 - Refactoring the 'dirty' event, dirtyPayload(),
* and XXXPayloadDirty() methods logic & spec
*
* @see https://github.com/wechaty/puppet/issues/158
*
*/
async dirtyPayload(type, id) {
config_js_1.log.verbose('PuppetService', 'dirtyPayload(%s, %s)', type, id);
const request = new wechaty_grpc_1.puppet.DirtyPayloadRequest();
request.setId(id);
request.setType(type);
try {
await util_1.default.promisify(this.grpcManager.client.dirtyPayload
.bind(this.grpcManager.client))(request);
}
catch (e) {
config_js_1.log.error('PuppetService', 'dirtyPayload() rejection: %s', e && e.message);
throw e;
}
}
/**
* `onDirty()` is called when the puppet emit `dirty` event.
* the event listener will be registered in `start()` from the `PuppetAbstract` class
*/
onDirty({ payloadType, payloadId, }) {
config_js_1.log.verbose('PuppetService', 'onDirty(%s<%s>, %s)', PUPPET.types.Dirty[payloadType], payloadType, payloadId);
const dirtyMap = {
[PUPPET.types.Dirty.Contact]: async (id) => this._payloadStore.contact?.delete(id),
[PUPPET.types.Dirty.Friendship]: async (_) => { },
[PUPPET.types.Dirty.Message]: async (_) => { },
[PUPPET.types.Dirty.Post]: async (_) => { },
[PUPPET.types.Dirty.Room]: async (id) => this._payloadStore.room?.delete(id),
[PUPPET.types.Dirty.RoomMember]: async (id) => this._payloadStore.roomMember?.delete(id),
[PUPPET.types.Dirty.Unspecified]: async (id) => { throw new Error('Unspecified type with id: ' + id); },
};
const dirtyFuncSync = this.wrapAsync(dirtyMap[payloadType]);
dirtyFuncSync(payloadId);
/**
* We need to call `super.onDirty()` to clean the `PuppetAbstract` LRUCache
*/
super.onDirty({ payloadId, payloadType });
}
async contactAlias(contactId, alias) {
config_js_1.log.verbose('PuppetService', 'contactAlias(%s, %s)', contactId, alias);
/**
* Get alias
*/
if (typeof alias === 'undefined') {
const request = new wechaty_grpc_1.puppet.ContactAliasRequest();
request.setId(contactId);
const response = await util_1.default.promisify(this.grpcManager.client.contactAlias
.bind(this.grpcManager.client))(request);
const result = response.getAlias();
if (result) {
return result;
}
{
// DEPRECATED, will be removed after Dec 31, 2022
const aliasWrapper = response.getAliasStringValueDeprecated();
if (!aliasWrapper) {
throw new Error('can not get aliasWrapper');
}
return aliasWrapper.getValue();
}
}
/**
* Set alias
*/
const request = new wechaty_grpc_1.puppet.ContactAliasRequest();
request.setId(contactId);
request.setAlias(alias || ''); // null -> '', in server, we treat '' as null
{
// DEPRECATED, will be removed after Dec 31, 2022
const aliasWrapper = new wechaty_grpc_1.StringValue();
aliasWrapper.setValue(alias || ''); // null -> '', in server, we treat '' as null
request.setAliasStringValueDeprecated(aliasWrapper);
}
await util_1.default.promisify(this.grpcManager.client.contactAlias
.bind(this.grpcManager.client))(request);
}
async contactPhone(contactId, phoneList) {
config_js_1.log.verbose('PuppetService', 'contactPhone(%s, %s)', contactId, phoneList);
const request = new wechaty_grpc_1.puppet.ContactPhoneRequest();
request.setContactId(contactId);
request.setPhonesList(phoneList);
await util_1.default.promisify(this.grpcManager.client.contactPhone
.bind(this.grpcManager.client))(request);
}
async contactCorporationRemark(contactId, corporationRemark) {
config_js_1.log.verbose('PuppetService', 'contactCorporationRemark(%s, %s)', contactId, corporationRemark);
const request = new wechaty_grpc_1.puppet.ContactCorporationRemarkRequest();
request.setContactId(contactId);
if (corporationRemark) {
request.setCorporationRemark(corporationRemark);
}
{
// DEPRECATED, will be removed after Dec 31, 2022
const corporationRemarkWrapper = new wechaty_grpc_1.StringValue();
if (corporationRemark) {
corporationRemarkWrapper.setValue(corporationRemark);
request.setCorporationRemarkStringValueDeprecated(corporationRemarkWrapper);
}
}
await util_1.default.promisify(this.grpcManager.client.contactCorporationRemark
.bind(this.grpcManager.client))(request);
}
async contactDescription(contactId, description) {
config_js_1.log.verbose('PuppetService', 'contactDescription(%s, %s)', contactId, description);
const request = new wechaty_grpc_1.puppet.ContactDescriptionRequest();
request.setContactId(contactId);
if (description) {
request.setDescription(description);
}
{
// DEPRECATED, will be removed after Dec 31, 2022
const descriptionWrapper = new wechaty_grpc_1.StringValue();
if (description) {
descriptionWrapper.setValue(description);
request.setDescriptionStringValueDeprecated(descriptionWrapper);
}
}
await util_1.default.promisify(this.grpcManager.client.contactDescription
.bind(this.grpcManager.client))(request);
}
async contactList() {
config_js_1.log.verbose('PuppetService', 'contactList()');
const response = await util_1.default.promisify(this.grpcManager.client.contactList
.bind(this.grpcManager.client))(new wechaty_grpc_1.puppet.ContactListRequest());
return response.getIdsList();
}
async contactAvatar(contactId, fileBox) {
config_js_1.log.verbose('PuppetService', 'contactAvatar(%s)', contactId);
/**
* 1. set
*/
if (fileBox) {
const request = new wechaty_grpc_1.puppet.ContactAvatarRequest();
request.setId(contactId);
const serializedFileBox = await this.serializeFileBox(fileBox);
request.setFileBox(serializedFileBox);
{
// DEPRECATED, will be removed after Dec 31, 2022
const fileboxWrapper = new wechaty_grpc_1.StringValue();
fileboxWrapper.setValue(await (0, serialize_file_box_js_1.serializeFileBox)(fileBox));
request.setFileboxStringValueDeprecated(fileboxWrapper);
}
await util_1.default.promisify(this.grpcManager.client.contactAvatar
.bind(this.grpcManager.client))(request);
return;
}
/**
* 2. get
*/
const request = new wechaty_grpc_1.puppet.ContactAvatarRequest();
request.setId(contactId);
const response = await util_1.default.promisify(this.grpcManager.client.contactAvatar
.bind(this.grpcManager.client))(request);
let jsonText;
jsonText = response.getFileBox();
{
// DEPRECATED, will be removed after Dec 31, 2022
const deprecated = true;
void deprecated;
if (!jsonText) {
const textWrapper = response.getFileboxStringValueDeprecated();
if (!textWrapper) {
throw new Error('can not get textWrapper');
}
jsonText = textWrapper.getValue();
}
}
return this.FileBoxUuid.fromJSON(jsonText);
}
async contactRawPayload(id) {
config_js_1.log.verbose('PuppetService', 'contactRawPayload(%s)', id);
const cachedPayload = await this._payloadStore.contact?.get(id);
if (cachedPayload) {
config_js_1.log.silly('PuppetService', 'contactRawPayload(%s) cache HIT', id);
return cachedPayload;
}
const request = new wechaty_grpc_1.puppet.ContactPayloadRequest();
request.setId(id);
const response = await util_1.default.promisify(this.grpcManager.client.contactPayload
.bind(this.grpcManager.client))(request);
const payload = {
address: response.getAddress(),
alias: response.getAlias(),
avatar: response.getAvatar(),
city: response.getCity(),
corporation: response.getCorporation(),
coworker: response.getCoworker(),
description: response.getDescription(),
friend: response.getFriend(),
gender: response.getGender(),
id: response.getId(),
name: response.getName(),
phone: response.getPhonesList(),
province: response.getProvince(),
signature: response.getSignature(),
star: response.getStar(),
title: response.getTitle(),
type: response.getType(),
weixin: response.getWeixin(),
};
await this._payloadStore.contact?.set(id, payload);
config_js_1.log.silly('PuppetService', 'contactRawPayload(%s) cache SET', id);
return payload;
}
async contactRawPayloadParser(payload) {
// log.silly('PuppetService', 'contactRawPayloadParser({id:%s})', payload.id)
// passthrough
return payload;
}
async contactSelfName(name) {
config_js_1.log.verbose('PuppetService', 'contactSelfName(%s)', name);
const request = new wechaty_grpc_1.puppet.ContactSelfNameRequest();
request.setName(name);
await util_1.default.promisify(this.grpcManager.client.contactSelfName
.bind(this.grpcManager.client))(request);
}
async contactSelfQRCode() {
config_js_1.log.verbose('PuppetService', 'contactSelfQRCode()');
const response = await util_1.default.promisify(this.grpcManager.client.contactSelfQRCode
.bind(this.grpcManager.client))(new wechaty_grpc_1.puppet.ContactSelfQRCodeRequest());
return response.getQrcode();
}
async contactSelfSignature(signature) {
config_js_1.log.verbose('PuppetService', 'contactSelfSignature(%s)', signature);
const request = new wechaty_grpc_1.puppet.ContactSelfSignatureRequest();
request.setSignature(signature);
await util_1.default.promisify(this.grpcManager.client.contactSelfSignature
.bind(this.grpcManager.client))(request);
}
/**
*
* Conversation
*
*/
conversationReadMark(conversationId, hasRead = true) {
config_js_1.log.verbose('PuppetService', 'conversationMarkRead(%s, %s)', conversationId, hasRead);
return PUPPET.throwUnsupportedError('not implemented. See https://github.com/wechaty/wechaty-puppet/pull/132');
}
/**
*
* Message
*
*/
async messageMiniProgram(messageId) {
config_js_1.log.verbose('PuppetService', 'messageMiniProgram(%s)', messageId);
const request = new wechaty_grpc_1.puppet.MessageMiniProgramRequest();
request.setId(messageId);
const response = await util_1.default.promisify(this.grpcManager.client.messageMiniProgram
.bind(this.grpcManager.client))(request);
let miniProgramPayload = response.getMiniProgram()?.toObject();
if (!miniProgramPayload) {
/**
* Deprecated: will be removed after Dec 22, 2022
*/
const jsonText = response.getMiniProgramDeprecated();
miniProgramPayload = JSON.parse(jsonText);
}
const payload = {
...miniProgramPayload,
};
return payload;
}
async messageLocation(messageId) {
config_js_1.log.verbose('PuppetService', 'messageLocation(%s)', messageId);
const request = new wechaty_grpc_1.puppet.MessageLocationRequest();
request.setId(messageId);
const response = await util_1.default.promisify(this.grpcManager.client.messageLocation
.bind(this.grpcManager.client))(request);
const locationPayload = response.getLocation();
const payload = {
accuracy: 0,
address: 'NOADDRESS',
latitude: 0,
longitude: 0,
name: 'NONAME',
...locationPayload,
};
return payload;
}
async messageImage(messageId, imageType) {
config_js_1.log.verbose('PuppetService', 'messageImage(%s, %s[%s])', messageId, imageType, PUPPET.types.Image[imageType]);
try {
const request = new wechaty_grpc_1.puppet.MessageImageRequest();
request.setId(messageId);
request.setType(imageType);
const response = await util_1.default.promisify(this.grpcManager.client.messageImage
.bind(this.grpcManager.client))(request);
const jsonText = response.getFileBox();
if (jsonText) {
return this.FileBoxUuid.fromJSON(jsonText);
}
}
catch (e) {
config_js_1.log.verbose('PuppetService', 'messageImage() rejection %s', e.message);
}
{
// Deprecated. Will be removed after Dec 31, 2022
const request = new wechaty_grpc_1.puppet.MessageImageStreamRequest();
request.setId(messageId);
request.setType(imageType);
const pbStream = this.grpcManager.client.messageImageStream(request);
const fileBox = await (0, mod_js_1.unpackFileBoxFromPb)(pbStream);
// const fileBoxChunkStream = unpackFileBoxChunk(stream)
// return unpackFileBox(fileBoxChunkStream)
return fileBox;
}
}
async messageContact(messageId) {
config_js_1.log.verbose('PuppetService', 'messageContact(%s)', messageId);
const request = new wechaty_grpc_1.puppet.MessageContactRequest();
request.setId(messageId);
const response = await util_1.default.promisify(this.grpcManager.client.messageContact
.bind(this.grpcManager.client))(request);
const contactId = response.getId();
return contactId;
}
async messageSendMiniProgram(conversationId, miniProgramPayload) {
config_js_1.log.verbose('PuppetService', 'messageSendMiniProgram(%s, "%s")', conversationId, JSON.stringify(miniProgramPayload));
const request = new wechaty_grpc_1.puppet.MessageSendMiniProgramRequest();
request.setConversationId(conversationId);
const pbMiniProgramPayload = new wechaty_grpc_1.puppet.MiniProgramPayload();
if (miniProgramPayload.appid) {
pbMiniProgramPayload.setAppid(miniProgramPayload.appid);
}
if (miniProgramPayload.description) {
pbMiniProgramPayload.setDescription(miniProgramPayload.description);
}
if (miniProgramPayload.iconUrl) {
pbMiniProgramPayload.setIconUrl(miniProgramPayload.iconUrl);
}
if (miniProgramPayload.pagePath) {
pbMiniProgramPayload.setPagePath(miniProgramPayload.pagePath);
}
if (miniProgramPayload.shareId) {
pbMiniProgramPayload.setShareId(miniProgramPayload.shareId);
}
if (miniProgramPayload.thumbKey) {
pbMiniProgramPayload.setThumbKey(miniProgramPayload.thumbKey);
}
if (miniProgramPayload.thumbUrl) {
pbMiniProgramPayload.setThumbUrl(miniProgramPayload.thumbUrl);
}
if (miniProgramPayload.title) {
pbMiniProgramPayload.setTitle(miniProgramPayload.title);
}
if (miniProgramPayload.username) {
pbMiniProgramPayload.setUsername(miniProgramPayload.username);
}
request.setMiniProgram(pbMiniProgramPayload);
/**
* Deprecated: will be removed after Dec 31, 2022
*/
request.setMiniProgramDeprecated(JSON.stringify(miniProgramPayload));
const response = await util_1.default.promisify(this.grpcManager.client.messageSendMiniProgram
.bind(this.grpcManager.client))(request);
const messageId = response.getId();
if (messageId) {
return messageId;
}
{
/**
* Huan(202110): Deprecated: will be removed after Dec 31, 2022
*/
const messageIdWrapper = response.getIdStringValueDeprecated();
if (messageIdWrapper) {
return messageIdWrapper.getValue();
}
}
}
async messageSendLocation(conversationId, locationPayload) {
config_js_1.log.verbose('PuppetService', 'messageSendLocation(%s)', conversationId, JSON.stringify(locationPayload));
const request = new wechaty_grpc_1.puppet.MessageSendLocationRequest();
request.setConversationId(conversationId);
const pbLocationPayload = new wechaty_grpc_1.puppet.LocationPayload();
pbLocationPayload.setAccuracy(locationPayload.accuracy);
pbLocationPayload.setAddress(locationPayload.address);
pbLocationPayload.setLatitude(locationPayload.latitude);
pbLocationPayload.setLongitude(locationPayload.longitude);
pbLocationPayload.setName(locationPayload.name);
request.setLocation(pbLocationPayload);
const response = await util_1.default.promisify(this.grpcManager.client.messageSendLocation
.bind(this.grpcManager.client))(request);
const id = response.getId();
if (id) {
return id;
}
}
async messageRecall(messageId) {
config_js_1.log.verbose('PuppetService', 'messageRecall(%s)', messageId);
const request = new wechaty_grpc_1.puppet.MessageRecallRequest();
request.setId(messageId);
const response = await util_1.default.promisify(this.grpcManager.client.messageRecall
.bind(this.grpcManager.client))(request);
return response.getSuccess();
}
async messageFile(id) {
config_js_1.log.verbose('PuppetService', 'messageFile(%s)', id);
try {
const request = new wechaty_grpc_1.puppet.MessageFileRequest();
request.setId(id);
const response = await util_1.default.promisify(this.grpcManager.client.messageFile
.bind(this.grpcManager.client))(request);
const jsonText = response.getFileBox();
if (jsonText) {
return this.FileBoxUuid.fromJSON(jsonText);
}
}
catch (e) {
config_js_1.log.warn('PuppetService', 'messageFile() rejection: %s', e.message);
config_js_1.log.warn('PuppetService', [
'This might because you are using Wechaty v1.x with a Puppet Service v0.x',
'Contact your Wechaty Puppet Service provided to report this problem',
'Related issues:',
' - https://github.com/wechaty/puppet-service/issues/179',
' - https://github.com/wechaty/puppet-service/pull/170',
].join('\n'));
}
{
// Deprecated. `MessageFileStream` Will be removed after Dec 31, 2022
const request = new wechaty_grpc_1.puppet.MessageFileStreamRequest();
request.setId(id);
const pbStream = this.grpcManager.client.messageFileStream(request);
// const fileBoxChunkStream = unpackFileBoxChunk(pbStream)
// return unpackFileBox(fileBoxChunkStream)
const fileBox = await (0, mod_js_1.unpackFileBoxFromPb)(pbStream);
return fileBox;
}
}
async messageForward(conversationId, messageId) {
config_js_1.log.verbose('PuppetService', 'messageForward(%s, %s)', conversationId, messageId);
const request = new wechaty_grpc_1.puppet.MessageForwardRequest();
request.setConversationId(conversationId);
request.setMessageId(messageId);
const response = await util_1.default.promisify(this.grpcManager.client.messageForward
.bind(this.grpcManager.client))(request);
const forwardedMessageId = response.getId();
if (forwardedMessageId) {
return forwardedMessageId;
}
{
/**
* Huan(202110): Deprecated: will be removed after Dec 31, 2022
*/
const messageIdWrapper = response.getIdStringValueDeprecated();
if (messageIdWrapper) {
return messageIdWrapper.getValue();
}
}
}
async messageRawPayload(id) {
config_js_1.log.verbose('PuppetService', 'messageRawPayload(%s)', id);
// const cachedPayload = await this.payloadStore.message?.get(id)
// if (cachedPayload) {
// log.silly('PuppetService', 'messageRawPayload(%s) cache HIT', id)
// return cachedPayload
// }
const request = new wechaty_grpc_1.puppet.MessagePayloadRequest();
request.setId(id);
const response = await util_1.default.promisify(this.grpcManager.client.messagePayload
.bind(this.grpcManager.client))(request);
let timestamp;
const receiveTime = response.getReceiveTime();
if (receiveTime) {
timestamp = (0, timestamp_js_1.millisecondsFromTimestamp)(receiveTime);
}
else {
// Deprecated: will be removed after Dec 31, 2022
timestamp = response.getTimestampDeprecated();
}
const payload = {
filename: response.getFilename(),
id: response.getId(),
listenerId: response.getListenerId(),
mentionIdList: response.getMentionIdsList(),
roomId: response.getRoomId(),
talkerId: response.getTalkerId(),
text: response.getText(),
timestamp,
type: response.getType(),
};
// log.silly('PuppetService', 'messageRawPayload(%s) cache SET', id)
// await this.payloadStore.message?.set(id, payload)
return payload;
}
async messageRawPayloadParser(payload) {
// log.silly('PuppetService', 'messagePayload({id:%s})', payload.id)
// passthrough
return payload;
}
async messageSendText(conversationId, text, mentionIdList) {
config_js_1.log.verbose('PuppetService', 'messageSend(%s, %s)', conversationId, text);
const request = new wechaty_grpc_1.puppet.MessageSendTextRequest();
request.setConversationId(conversationId);
request.setText(text);
if (typeof mentionIdList !== 'undefined') {
request.setMentionalIdsList(mentionIdList);
}
const response = await util_1.default.promisify(this.grpcManager.client.messageSendText
.bind(this.grpcManager.client))(request);
const messageId = response.getId();
if (messageId) {
return messageId;
}
{
/**
* Huan(202110): Deprecated: will be removed after Dec 31, 2022
*/
const messageIdWrapper = response.getIdStringValueDeprecated();
if (messageIdWrapper) {
return messageIdWrapper.getValue();
}
}
}
async messageSendFile(conversationId, fileBox) {
config_js_1.log.verbose('PuppetService', 'messageSendFile(%s, %s)', conversationId, fileBox);
try {
const request = new wechaty_grpc_1.puppet.MessageSendFileRequest();
request.setConversationId(conversationId);
const serializedFileBox = await this.serializeFileBox(fileBox);
request.setFileBox(serializedFileBox);
const response = await util_1.default.promisify(this.grpcManager.client.messageSendFile
.bind(this.grpcManager.client))(request);
const messageId = response.getId();
if (messageId) {
return messageId;
}
else {
/**
* Huan(202110): Deprecated: will be removed after Dec 31, 2022
*/
const messageIdWrapper = response.getIdStringValueDeprecated();
if (messageIdWrapper) {
return messageIdWrapper.getValue();
}
}
return; // void
}
catch (e) {
config_js_1.log.verbose('PuppetService', 'messageSendFile() rejection: %s', e.message);
}
/**
* Huan(202110): Deprecated: will be removed after Dec 31, 2022
* The old server will not support `Upload` gRPC method,
* which I'm expecting the above code will throw a exception,
* then the below code will be executed.
*/
return this.messageSendFileStream(conversationId, fileBox);
}
async messageSendContact(conversationId, contactId) {
config_js_1.log.verbose('PuppetService', 'messageSend("%s", %s)', conversationId, contactId);
const request = new wechaty_grpc_1.puppet.MessageSendContactRequest();
request.setConversationId(conversationId);
request.setContactId(contactId);
const response = await util_1.default.promisify(this.grpcManager.client.messageSendContact
.bind(this.grpcManager.client))(request);
const messageId = response.getId();
if (messageId) {
return messageId;
}
{
/**
* Huan(202110): Deprecated: will be removed after Dec 31, 2022
*/
const messageIdWrapper = response.getIdStringValueDeprecated();
if (messageIdWrapper) {
return messageIdWrapper.getValue();
}
}
}
async messageSendUrl(conversationId, urlLinkPayload) {
config_js_1.log.verbose('PuppetService', 'messageSendUrl("%s", %s)', conversationId, JSON.stringify(urlLinkPayload));
const request = new wechaty_grpc_1.puppet.MessageSendUrlRequest();
request.setConversationId(conversationId);
const pbUrlLinkPayload = new wechaty_grpc_1.puppet.UrlLinkPayload();
pbUrlLinkPayload.setUrl(urlLinkPayload.url);
pbUrlLinkPayload.setTitle(urlLinkPayload.title);
if (urlLinkPayload.description) {
pbUrlLinkPayload.setDescription(urlLinkPayload.description);
}
if (urlLinkPayload.thumbnailUrl) {
pbUrlLinkPayload.setThumbnailUrl(urlLinkPayload.thumbnailUrl);
}
request.setUrlLink(pbUrlLinkPayload);
// Deprecated: will be removed after Dec 31, 2022
request.setUrlLinkDeprecated(JSON.stringify(urlLinkPayload));
const response = await util_1.default.promisify(this.grpcManager.client.messageSendUrl
.bind(this.grpcManager.client))(request);
const messageId = response.getId();
if (messageId) {
return messageId;
}
{
/**
* Huan(202110): Deprecated: will be removed after Dec 31, 2022
*/
const messageIdWrapper = response.getIdStringValueDeprecated();
if (messageIdWrapper) {
return messageIdWrapper.getValue();
}
}
}
async messageUrl(messageId) {
config_js_1.log.verbose('PuppetService', 'messageUrl(%s)', messageId);
const request = new wechaty_grpc_1.puppet.MessageUrlRequest();
request.setId(messageId);
const response = await util_1.default.promisify(this.grpcManager.client.messageUrl
.bind(this.grpcManager.client))(request);
let pbUrlLinkPayload = response.getUrlLink()?.toObject();
if (!pbUrlLinkPayload) {
// Deprecated: will be removed after Dec 31, 2022
const jsonText = response.getUrlLinkDeprecated();
pbUrlLinkPayload = JSON.parse(jsonText);
}
const payload = {
title: 'NOTITLE',
url: 'NOURL',
...pbUrlLinkPayload,
};
return payload;
}
/**
*
* Room
*
*/
async roomRawPayload(id) {
config_js_1.log.verbose('PuppetService', 'roomRawPayload(%s)', id);
const cachedPayload = await this._payloadStore.room?.get(id);
if (cachedPayload) {
config_js_1.log.silly('PuppetService', 'roomRawPayload(%s) cache HIT', id);
return cachedPayload;
}
const request = new wechaty_grpc_1.puppet.RoomPayloadRequest();
request.setId(id);
const response = await util_1.default.promisify(this.grpcManager.client.roomPayload
.bind(this.grpcManager.client))(request);
const payload = {
adminIdList: response.getAdminIdsList(),
avatar: response.getAvatar(),
id: response.getId(),
memberIdList: response.getMemberIdsList(),
ownerId: response.getOwnerId(),
topic: response.getTopic(),
};
await this._payloadStore.room?.set(id, payload);
config_js_1.log.silly('PuppetService', 'roomRawPayload(%s) cache SET', id);
return payload;
}
async roomRawPayloadParser(payload) {
// log.silly('PuppetService', 'roomRawPayloadParser({id:%s})', payload.id)
// passthrough
return payload;
}
async roomList() {
config_js_1.log.verbose('PuppetService', 'roomList()');
const response = await util_1.default.promisify(this.grpcManager.client.roomList
.bind(this.grpcManager.client))(new wechaty_grpc_1.puppet.RoomListRequest());
return response.getIdsList();
}
async roomDel(roomId, contactId) {
config_js_1.log.verbose('PuppetService', 'roomDel(%s, %s)', roomId, contactId);
const request = new wechaty_grpc_1.puppet.RoomDelRequest();
request.setId(roomId);
request.setContactId(contactId);
await util_1.default.promisify(this.grpcManager.client.roomDel
.bind(this.grpcManager.client))(request);
}
async roomAvatar(roomId) {
config_js_1.log.verbose('PuppetService', 'roomAvatar(%s)', roomId);
const request = new wechaty_grpc_1.puppet.RoomAvatarRequest();
request.setId(roomId);
const response = await util_1.default.promisify(this.grpcManager.client.roomAvatar
.bind(this.grpcManager.client))(request);
const jsonText = response.getFileBox();
return this.FileBoxUuid.fromJSON(jsonText);
}
async roomAdd(roomId, contactId, inviteOnly) {
config_js_1.log.verbose('PuppetService', 'roomAdd(%s, %s)', roomId, contactId);
const request = new wechaty_grpc_1.puppet.RoomAddRequest();
request.setId(roomId);
request.setContactId(contactId);
request.setInviteOnly(inviteOnly);
await util_1.default.promisify(this.grpcManager.client.roomAdd
.bind(this.grpcManager.client))(request);
}
async roomTopic(roomId, topic) {
config_js_1.log.verbose('PuppetService', 'roomTopic(%s, %s)', roomId, topic);
/**
* Get
*/
if (typeof topic === 'undefined') {
const request = new wechaty_grpc_1.puppet.RoomTopicRequest();
request.setId(roomId);
const response = await util_1.default.promisify(this.grpcManager.client.roomTopic
.bind(this.grpcManager.client))(request);
const result = response.getTopic();
if (result) {
return result;
}
{
// DEPRECATED, will be removed after Dec 31, 2022
const topicWrapper = response.getTopicStringValueDeprecated();
if (topicWrapper) {
return topicWrapper.getValue();
}
}
return '';
}
/**
* Set
*/
const request = new wechaty_grpc_1.puppet.RoomTopicRequest();
request.setId(roomId);
request.setTopic(topic);
{
// DEPRECATED, will be removed after Dec 31, 2022
const topicWrapper = new wechaty_grpc_1.StringValue();
topicWrapper.setValue(topic);
request.setTopicStringValueDeprecated(topicWrapper);
}
await util_1.default.promisify(this.grpcManager.client.roomTopic
.bind(this.grpcManager.client))(request);
}
async roomCreate(contactIdList, topic) {
config_js_1.log.verbose('PuppetService', 'roomCreate(%s, %s)', contactIdList, topic);
const request = new wechaty_grpc_1.puppet.RoomCreateRequest();
request.setContactIdsList(contactIdList);
request.setTopic(topic);
const response = await util_1.default.promisify(this.grpcManager.client.roomCreate
.bind(this.grpcManager.client))(request);
return response.getId();
}
async roomQuit(roomId) {
config_js_1.log.verbose('PuppetService', 'roomQuit(%s)', roomId);
const request = new wechaty_grpc_1.puppet.RoomQuitRequest();
request.setId(roomId);
await util_1.default.promisify(this.grpcManager.client.roomQuit
.bind(this.grpcManager.client))(request);
}
async roomQRCode(roomId) {
config_js_1.log.verbose('PuppetService', 'roomQRCode(%s)', roomId);
const request = new wechaty_grpc_1.puppet.RoomQRCodeRequest();
request.setId(roomId);
const response = await util_1.default.promisify(this.grpcManager.client.roomQRCode
.bind(this.grpcManager.client))(request);
return response.getQrcode();
}
async roomMemberList(roomId) {
config_js_1.log.verbose('PuppetService', 'roomMemberList(%s)', roomId);
const request = new wechaty_grpc_1.puppet.RoomMemberListRequest();
request.setId(roomId);
const response = await util_1.default.promisify(this.grpcManager.client.roomMemberList
.bind(this.grpcManager.client))(request);
return response.getMemberIdsList();
}
async roomMemberRawPayload(roomId, contactId) {
config_js_1.log.verbose('PuppetService', 'roomMemberRawPayload(%s, %s)', roomId, contactId);
const cachedPayload = await this._payloadStore.roomMember?.get(roomId);
const cachedRoomMemberPayload = cachedPayload && cachedPayload[contactId];
if (cachedRoomMemberPayload) {
config_js_1.log.silly('PuppetService', 'roomMemberRawPayload(%s, %s) cache HIT', roomId, contactId);
return cachedRoomMemberPayload;
}
const request = new wechaty_grpc_1.puppet.RoomMemberPayloadRequest();
request.setId(roomId);
request.setMemberId(contactId);
const response = await util_1.default.promisify(this.grpcManager.client.roomMemberPayload
.bind(this.grpcManager.client))(request);
const payload = {
avatar: response.getAvatar(),
id: response.getId(),
inviterId: response.getInviterId(),
name: response.getName(),
roomAlias: response.getRoomAlias(),
};
await this._payloadStore.roomMember?.set(roomId, {
...cachedPayload,
contactId: payload,
});
config_js_1.log.silly('PuppetService', 'roomMemberRawPayload(%s, %s) cache SET', roomId, contactId);
return payload;
}
async roomMemberRawPayloadParser(payload) {