Alternative of ctx.updateSubTypes Telgraf 4 - telegram-bot

That end point was removed with new version of telgraf
https://github.com/telegraf/telegraf/releases/tag/v4.0.0#:~:text=ctx.updateSubTypes
How we can detect the message type with new API
this is the old ctx retrun

This is an alternative usage to ctx.updatesubtypes AKA getting message type in telegraf 3.
bot.use((ctx, next) => {
console.log(`Message Type is: ${getMessageType(ctx.message)}`);
// Message Type is: STICKER or Message Type is: TEXT
});
const getMessageType = (message) => {
var keys = Object.keys(message);
var messageType = keys.pop();
console.log(messageType);
return messageType.toUpperCase();
};
source is: https://stackoverflow.com/a/58052712/10694425

A good alternative to using ctx.updatesubtypes in 4.6.0 is:
bot.use((ctx, next) => {
let message_type = "";
let keys = Object.keys(ctx.message);
if (keys.includes("text")) {
message_type = "text";
} else if (keys.includes("sticker")) {
message_type = "sticker";
} else if (keys.includes("photo")) {
message_type = "photo";
}
console.log(`Message Type is: ${message_type}`);
next();
});

Related

How can I refresh datatable in Wire using refreshApex

#wire(_getContacts,{recordId:'$recordId'}) wiredContacts({error,data}){
this.dataToRefresh = data;
if (data) {
this.contacts = this.dataToRefresh.recordList;
this.ContactsRecords = this.dataToRefresh.cList;
this.contactsSize = " Case Contacts (" + this.contacts.length + ")";
}else{
//
}
};
relateContacts() {
this.showSpinner = true;
this.showtable=false;
relateContacts({contacts: this.selected, recordId: this.recordId})
.then(data => {
this.showSpinner=false;
this.showtable=true;
this.showSuccessMessage();
refreshApex(this.dataToRefresh);
//location.reload();
this.isShowModal = false;
})
.catch(error => {
console.log(error);
this.showSpinner=false;
const evt = new ShowToastEvent({
title: 'Application Error',
message: error.body.message,
variant: 'error',
mode: 'sticky'
});
this.dispatchEvent(evt);
this.showSpinner = false;
});
}
For this code, I tried refreshApex with all possible ways. but I'm not sure the miss here. I've Checked all the blogs but everywhere, the solution is mentioned.
Tried refreshApex like below :
#wire(_getContacts,{recordId:'$recordId'}) wiredContacts({data}){
this.dataToRefresh = data;
But this also does not work
Ah that is a fun one ! Your issue is using destructuring in wiredContacts as the parameter.
(The {data} or {data,error} normally works as a parameter to the function being called back, except if you have to do refresh) Try this instead.
#wire(_getContacts,{recordId:'$recordId'}) wiredContacts(value){
this.dataToRefresh = value;
const {data, error} = value;
//Rest of you code now with data and error
}
Then in your other method you can do:
method(){
refreshApex(this.dataToRefresh);
}
Salesforce does show doing this in their example code, but it’s easy to miss and experience the fun you have been having with this.
https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.apex_result_caching
See the last example on their page.

Getting "spc message cannot be null" as response

Getting "spc message cannot be null" as response every time while providing implementation of Shaka player to play fairplay content on safari browser.Tried many ways to provide spc message in body and header also and we are actually sending it that i can see in network tab nut still cant find a solution. Here is the code below.
if (this.platform.getBrowserPlatform() === Constants.PLATFORMS.SAFARI_WEB) {
this.shakaPlayer.configure({
drm: {
servers: {
'com.apple.fps.1_0': `${this.config.baseUrl}${Constants.DRM_FAIRPLAY_LICENSE}`,
},
advanced: {
'com.apple.fps.1_0': {
serverCertificate: cert,
},
},
},
});
let that = this //,licenseUri;
this.shakaPlayer.configure('drm.initDataTransform', (initData) => {
const skdUri = shaka.util.StringUtils.fromBytesAutoDetect(initData);
var contentId = skdUri.substring(skdUri.indexOf('skd://') + 6);
// licenseUri = skdUri.replace('skd://', 'https://');
const url = new URL(contentId);
const urlParams = new URLSearchParams(url.search);
const cert = that.shakaPlayer.drmInfo().serverCertificate;
let id = urlParams.get('contentId');
that.id = id;
return shaka.util.FairPlayUtils.initDataTransform(initData, id, cert);
// let skdUrl = shaka.util.StringUtils.fromBytesAutoDetect(initData);
// licenseUri = skdUrl.replace('skd://', 'https://');
// const cert = that.shakaPlayer.drmInfo().serverCertificate;
// return shaka.util.FairPlayUtils.initDataTransform(initData, licenseUri, cert);
});
this.shakaPlayer.getNetworkingEngine().registerRequestFilter((type, request) => {
if (type != shaka.net.NetworkingEngine.RequestType.LICENSE) {
return;
}
let token = localStorage.getItem('auth');
let testToken = JSON.parse(token);
const originalPayload = new Uint8Array(request.body);
const base64Payload = shaka.util.Uint8ArrayUtils.toBase64(originalPayload);
const params = `{ "spc": "${base64Payload}", "assetId":"${that.id}"}`;
request.body = shaka.util.StringUtils.toUTF8(params);
request.headers['Content-Type'] = 'application/json';
request.headers['Authorization'] = `JWT ${testToken.access_token}`
console.log("request.body", request.body)
});
this.shakaPlayer.getNetworkingEngine().registerResponseFilter((type, response) => {
if (type != shaka.net.NetworkingEngine.RequestType.LICENSE) {
return;
}
console.log("license passed")
let responseText = shaka.util.StringUtils.fromUTF8(response.data);
responseText = responseText.trim();
if (responseText.substr(0, 5) === '<ckc>' &&
responseText.substr(-6) === '</ckc>') {
responseText = responseText.slice(5, -6);
}
response.data = shaka.util.Uint8ArrayUtils.fromBase64(responseText).buffer;
});
this.shakaPlayer.load(this.getProgramUrl(channel, program, restart)).then(() => {
console.log('1', this.shakaPlayer.isTextTrackVisible());
console.log('2', this.shakaPlayer.getTextTracks());
console.log('3', this.shakaPlayer.getTextLanguages());
}).catch((error) => {
console.log(error);
});
Smooth play of fairplay content on safari or some advise what can i do in this case

Cloudflare ESI worker / TypeError: Body has already been used

I'm trying to use a CloudFlare worker to manage my backend ESI fragments but i get an error:
Uncaught (in promise) TypeError: Body has already been used. It can only be used once. Use tee() first if you need to read it twice.
Uncaught (in response) TypeError: Body has already been used. It can only be used once. Use tee() first if you need to read it twice.
I don't find where the body has already been used
The process is:
get a response with the parts
Transform the body by replacing parts fragments with sub Backend calls (streamTransformBody function)
return the response
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request))
});
const esiHeaders = {
"user-agent": "cloudflare"
}
async function handleRequest(request) {
// get cookies from the request
if(cookie = request.headers.get("Cookie")) {
esiHeaders["Cookie"] = cookie
console.log(cookie)
}
// Clone the request so that it's no longer immutable
newRequest = new Request(request)
// remove cookie from request
newRequest.headers.delete('Cookie')
// Add header to get <esi>
newRequest.headers.set("Surrogate-Capability", "abc=ESI/1.0")
console.log(newRequest.url);
const response = await fetch(newRequest);
let contentType = response.headers.get('content-type')
if (!contentType || !contentType.startsWith("text/")) {
return response
}
// Clone the response so that it's no longer immutable
const newResponse = new Response(response.body, response);
let { readable, writable } = new TransformStream()
streamTransformBody(newResponse.body, writable)
newResponse.headers.append('x-workers-hello', 'Hello from
Cloudflare Workers');
return newResponse;
}
async function streamTransformBody(readable, writable) {
const startTag = "<".charCodeAt(0);
const endTag = ">".charCodeAt(0);
let reader = readable.getReader();
let writer = writable.getWriter();
let templateChunks = null;
while (true) {
let { done, value } = await reader.read();
if (done) break;
while (value.byteLength > 0) {
if (templateChunks) {
let end = value.indexOf(endTag);
if (end === -1) {
templateChunks.push(value);
break;
} else {
templateChunks.push(value.subarray(0, end));
await writer.write(await translate(templateChunks));
templateChunks = null;
value = value.subarray(end + 1);
}
}
let start = value.indexOf(startTag);
if (start === -1) {
await writer.write(value);
break;
} else {
await writer.write(value.subarray(0, start));
value = value.subarray(start + 1);
templateChunks = [];
}
}
}
await writer.close();
}
async function translate(chunks) {
const decoder = new TextDecoder();
let templateKey = chunks.reduce(
(accumulator, chunk) =>
accumulator + decoder.decode(chunk, { stream: true }),
""
);
templateKey += decoder.decode();
return handleTemplate(new TextEncoder(), templateKey);
}
async function handleTemplate(encoder, templateKey) {
const linkRegex = /(esi:include.*src="(.*?)".*\/)/gm
let result = linkRegex.exec(templateKey);
let esi
if (!result) {
return encoder.encode(`<${templateKey}>`);
}
if (result[2]) {
esi = await subRequests(result[2]);
}
return encoder.encode(
`${esi}`
);
}
async function subRequests(target){
target = esiHost + target
const init = {
method: 'GET',
headers: esiHeaders
}
let response = await fetch(target, init)
if (!response.ok) {
return ''
}
let text = await response.text()
return '<!--esi-->' + text + '<!--/esi-->'
}

Discord.JS Purge.js command issue

Ok so my bot got rebuilt with a somewhat different code.
I'm using a somewhat more simplified fs command and events handler. My command works as intended.
But I'm wanting to add the amount pruned into the fields for the richEmbed and it keeps erroring out.
Here is my purge.js file
const Discord = require('discord.js')
module.exports = {
name: 'purge',
description: 'Purge up to 99 messages.',
execute(message, args) {
console.log("purging messages")
const embed = new Discord.RichEmbed()
.setTitle("Success")
.setColor(0x00AE86)
.setFooter("Guardian", "https://raw.githubusercontent.com/phantomdev-github/Resources/master/Discord%20Bots/Guardian/src/avatar.png")
.setThumbnail("https://raw.githubusercontent.com/phantomdev-github/Resources/master/Discord%20Bots/Guardian/src/avatar.png")
.setTimestamp()
.setURL("https://github.com/phantomdev-github/Resources/tree/master/Discord%20Bots/Guardian")
.addField("Bot Messages Purged", "missing code here", false)
.addField("User Pins Purged", "missing code here", false)
.addField("User Messages Purged", "missing code here", false)
.addField("Total Messages Purged", "missing code here", false)
message.channel.send({ embed });
const amount = parseInt(args[0]) + 1;
if (isNaN(amount)) {
return message.reply('that doesn\'t seem to be a valid number.');
} else if (amount <= 1 || amount > 100) {
return message.reply('you need to input a number between 1 and 99.');
}
message.channel.bulkDelete(amount, true).catch(err => {
console.error(err);
message.channel.send('there was an error trying to prune messages in this channel!');
});
},
};
If it helps this i my index.js
const fs = require('fs');
const Discord = require('discord.js');
const client = new Discord.Client();
const { token } = require('./token.json');
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
client.commands.set(command.name, command);
console.log(file,command)
}
fs.readdir('./events/', (err, files) => {
if (err) return console.error(err);
files.forEach(file => {
if(!file.endsWith('.js')) return;
const eventFunction = require(`./events/${file}`);
console.log(eventFunction)
eventFunction.execute(client)
});
});
client.login(token);
and this is my message.js
const { prefix } = require('./prefix.json');
module.exports = {
name: 'message',
description: '',
execute:function(client) {
client.on('message',message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if (!client.commands.has(command)) return;
try {
client.commands.get(command).execute(message, args);
} catch (error) {
console.error(error);
message.reply('there was an error trying to execute that command!');
}
})
}};
Basically I'm trying to figure out what to place into the "missing code here" sections. Also any way to lock it to people with Administrator permissions only would be useful as well. I attempted that but it failed to work with the embed.
If I understand you right you want to know how to get the amount of the purged pins, bot msgs and user msgs. For this you need to put your embed after you deleted the messages.
purge.js
const Discord = require('discord.js')
module.exports = {
name: 'purge',
description: 'Purge up to 99 messages.',
execute(message, args) {
console.log("purging messages")
const amount = parseInt(args[0]) + 1;
if (isNaN(amount)) {
return message.reply('that doesn\'t seem to be a valid number.');
} else if (amount <= 1 || amount > 100) {
return message.reply('you need to input a number between 1 and 99.');
}
message.channel.bulkDelete(amount, true).then(deletedMessages => {
// Filter the deleted messages with .filter()
var botMessages = deletedMessages.filter(m => m.author.bot);
var userPins = deletedMessages.filter(m => m.pinned);
var userMessages = deletedMessages.filter(m => !m.author.bot);
const embed = new Discord.RichEmbed()
.setTitle("Success")
.setColor(0x00AE86)
.setFooter("Guardian", "https://raw.githubusercontent.com/phantomdev-github/Resources/master/Discord%20Bots/Guardian/src/avatar.png")
.setThumbnail("https://raw.githubusercontent.com/phantomdev-github/Resources/master/Discord%20Bots/Guardian/src/avatar.png")
.setTimestamp()
.setURL("https://github.com/phantomdev-github/Resources/tree/master/Discord%20Bots/Guardian")
.addField("Bot Messages Purged", botMessages.size, false)
.addField("User Pins Purged", userPins.size, false)
.addField("User Messages Purged", userMessages.size, false)
.addField("Total Messages Purged", deletedMessages.size, false);
message.channel.send(embed);
}).catch(err => {
console.error(err);
message.channel.send('there was an error trying to prune messages in this channel!');
});
},
};

Discord.JS Announce Command Issue

I'm trying to build an announce command for my bot using a rich embed.
Here is my announce.js file:
const Discord = require('discord.js');
module.exports = {
name: 'announce',
description: 'Send an announcement.',
guildOnly: true,
execute(message, args) {
console.log("embedding")
const embed = new Discord.RichEmbed()
.setTitle("Announcement")
.setDescription("A Staff member has sent an announcement")
.setColor(0x00AE86)
.setFooter("Guardian", "https://raw.githubusercontent.com/phantomdev-github/Resources/master/Discord%20Bots/Guardian/src/avatar.png")
.setThumbnail("https://raw.githubusercontent.com/phantomdev-github/Resources/master/Discord%20Bots/Guardian/src/avatar.png")
.setTimestamp()
.setURL("https://github.com/phantomdev-github/Resources/tree/master/Discord%20Bots/Guardian")
.addBlankField(true)
.addField("Announcement", "message contents here", false))
message.channel.send({ embed });
}
};
I rebuilt it since the post it and took me a while to get back to this post. I'm trying to rebuild all of my messages from my bot into rich embeds. Thus the different code. I've also simplified my fs command and events handler.
indexjs
const fs = require('fs');
const Discord = require('discord.js');
const client = new Discord.Client();
const { token } = require('./token.json');
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
client.commands.set(command.name, command);
console.log(file,command)
}
fs.readdir('./events/', (err, files) => {
if (err) return console.error(err);
files.forEach(file => {
if(!file.endsWith('.js')) return;
const eventFunction = require(`./events/${file}`);
console.log(eventFunction)
eventFunction.execute(client)
});
});
client.login(token);
message.js
const { prefix } = require('./prefix.json');
module.exports = {
name: 'message',
description: 'client message event.',
execute:function(client) {
client.on('message',message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if (!client.commands.has(command)) return;
try {
client.commands.get(command).execute(message, args);
} catch (error) {
console.error(error);
message.reply('there was an error trying to execute that command!');
}
})
}};
Basically I need to know what to put for "message contents here" to make it post the message typed into the #announcements channel.
My question is how to I make it place the announcement message into the .addField section of the richEmbed?
Would it be something along the lines of this?
const Discord = require('discord.js');
module.exports = {
name: 'announce',
description: 'Send an announcement to the specified channel.',
guildOnly: true,
execute(message, args) {
console.log("embedding")
enter code here
if(args.length < 2) return /* error message */;
let channel = message.mentions.channels.first();
if(!channel) return ;
let announcement = args.slice(1).join(" ");
const embed = new Discord.RichEmbed()
.setTitle("Notice!")
.setDescription("Announcememnt from PhantomDEV Staff!")
.setColor(0x00AE86)
.setFooter("Guardian", "https://raw.githubusercontent.com/phantomdev-github/Resources/master/Discord%20Bots/Guardian/src/avatar.png")
.setThumbnail("https://raw.githubusercontent.com/phantomdev-github/Resources/master/Discord%20Bots/Guardian/src/avatar.png")
.setTimestamp()
.setURL("https://github.com/phantomdev-github/Resources/tree/master/Discord%20Bots/Guardian")
.addBlankField(true)
.addField("Message", "", false);
message.channel.send({ embed });
.catch(console.error);
};
At the end of your message event, use this line to call the execution of the command...
command.execute(message, args);
Define your execute function to use the args parameter that you need. Also, Collection.first() is the method you're looking for when declaring channel. Your function should look like so...
execute: function(message, args) {
if (args.length < 2) return /* error message */;
// Careful using this; if just an announcement is provided
// and it mentions a channel, that channel will be used.
let channel = message.mentions.channels.first();
if (!channel) return /* error message */;
let announcement = args.slice(1).join(" ");
channel.send(announcement)
.catch(console.error);
}
There's no need to check that the command is "announce" in the execution function, because it'll only be called if it is.