Start an Azure WebJobs from Javascript code - javascript

Is there any node package or something else to start (Run) an Azure Webjob from JS? I'm an automation guy and I want to start an Azure Webjob to change some statuses in the app. Manually I just press "Run", but I want to start the job using code. An option is to login in UI and press the run button using automation, but is not looking professional for me to do it from UI.
I saw some infos there, in Webjob properties like webhook, user, password. Maybe I can use somehow those things to trigger using code.
Thank you!

If you want to manage Azure WebJob with node, we can use the package azure-arm-website. The package provides the method runTriggeredWebJobWithHttpOperationResponse to run a trigger WebJob and the method startContinuousWebJobWithHttpOperationResponse to continuous WebJob.
For example
Create a service pricipal
az login
az account set --subscription "SUBSCRIPTION_ID"
az ad sp create-for-rbac --role "Contributor" --scopes "/subscriptions/<subscription_id>"
Code
const {
ApplicationTokenCredentials,
AzureEnvironment,
} = require("ms-rest-azure");
const { WebSiteManagementClient } = require("azure-arm-website");
const clientId = "<the sp appId>";
const tenant = "<you AD tenant domain>";
const clientSecret = "<the sp password>";
const subscriptionId = "";
const creds = new ApplicationTokenCredentials(clientId, tenant, clientSecret, {
environment: AzureEnvironment.Azure,
});
const client = new WebSiteManagementClient(creds, subscriptionId);
const rgName = "rg-webapp-demo";
const webName = "demo-200925164220";
const jobName = "test";
client.webApps
.runTriggeredWebJobWithHttpOperationResponse(rgName, webName, jobName)
.then((res) => {
console.log(res.response.statusMessage);
console.log(res.response.statusCode);
})
.catch((err) => {
throw err;
});
client.webApps.startContinuousWebJob

Related

Telegram Bot run commands from outside

I'm quite new to working with telegram bots, but I managed well so far with some basic bot. Now I want to improve a bit things and let my site "feed" the bot.
This is the scenario
I have a Google spreadsheet that make some calculation and then sends a message to the bot with the classic URL. Something like this...
var optionsUG = {
'method' : 'post',
'payload' : formDataUG,
'muteHttpExceptions':true
};
var optionsLG = {
'method' : 'post',
'payload' : formDataLG
};
//SpreadsheetApp.getUi().alert('UrlFetchApp options ['+options+"]");
//UrlFetchApp.fetch('https://api.telegram.org/bot'+token+'/sendMessage?chat_id='+channelNumber+'&text='+text);
var result = UrlFetchApp.fetch('https://api.telegram.org/bot'+token+'/sendMessage',optionsUG);
Utilities.sleep(5 * 1000);
result = UrlFetchApp.fetch('https://api.telegram.org/bot'+token+'/sendMessage',optionsLG);
now I would like to make something like but, instead of sendMessage I would like to call a method of my bot
I use JavaScript Telegraf framework ATM, but I can change is not a problem.
I want to achieve something like:
var result = UrlFetchApp.fetch('https://api.telegram.org/bot'+token+'/register',optionsUG);
here is the bot currently configured
const serverPath = "/home/bots/PlatoonAdvisor/telegram";
const commands = require(serverPath+'/package/modules/commands.js');
const config = require(serverPath+'/config.json');
var helpText = require(serverPath+'/package/help.txt');
const token = config.TELEGRAM_BOT_SECRET;
const Telegraf = require('telegraf');
const bot = new Telegraf(token);
const REGISTER_COM = 'register';
const HELP_COM = 'help';
const REQUIREMENTS_COM = 'requirements';
const CAHT_ID_COM = 'chatid';
const getCommandParameters = function (text, command) {
var reg = "/\/"+command+" (.*)/g";
var arr = text.match(reg);
return arr;
}
/*
bot.on('text', message=> {
return message.reply('I am Grooth');
})
*/
bot.command(HELP_COM, ctx=> {
return ctx.reply(helpText);
});
bot.command(REGISTER_COM, ctx=> {
var replyMsg;
var param = getCommandParameters(ctx.message.text, REGISTER_COM);
var player_name, allycode;
if (param != null) {
try {
var params = param.split(",");
if (params.length < 2) {
replyMsg = "Missing parameters, try /help if you need help :)";
throw replyMsg;
}
player_name = params[1];
allycode = params[0];
var channel = ctx.chat.id;
commands.registerTPlayer(player_name, allycode, channel);
replyMsg = "Successfully registered player ${player_name} with allycode ${allycode}!"
} catch (ex) {
console.log (ex);
}
}
return ctx.reply(replyMsg);
});
bot.command(REQUIREMENTS_COM, ctx=> {
var param = getCommandParameters(ctx.message.text, REQUIREMENTS_COM);
var params = param.split(",");
var json = ctx.chat.id;
return ctx.reply(json);
});
bot.command(CAHT_ID_COM, ctx=> {
var id = ctx.chat.id;
var msg = "The chat id requested is ${id}";
return ctx.reply(msg);
});
bot.startPolling();
is that even possible? I'm looking over the internet for a while now and was not able to find any clue about.
EDIT: Doing some more digging I found webhooks to send content to a web server when something happens in the bot but not vice versa. I'm getting frustrated.
My goal is to update the local database with information the spreadsheet have but the bot still don't so users can later ask to the bot to retrieve those information.
I mean I could make an ajax call if it were a real web server, but it is just a spreadsheet which doesn't act as a server.
Ok I forgot to answer this question with the solution I found.
there is no way indeed to call a specific function of the bot from the outside because it is not a real function, it is a parsed string that a user type and the bot interpret as a command.
So I had to be creative and expose a RestServer from the bot itself (the NodeJS express library did the trick) which I was then able to call from the script.
Here an handy guide for Express.js
This is my solution which is working great now.

How to have collections populated in a module for use inside events/commands

I know that to have a collection populated such as guilds and channels, the bot must have logged in already, i.e. it can be used inside command files as well as inside events. What I have is a module that will display my logs inside my control discord server, and I want to be able to reference this module inside my events as well as my commands.
I have tried importing the module inside of the events, as well as other options that would make sense.
This is the code inside my module
const Discord = require('discord.js')
const bot = new Discord.Client()
const CC = '../settings/control-center.json'
const CCFile = require(CC)
const GUILD = bot.guilds.get(CCFile.GUILD)
const STARTUP = bot.channels.get(CCFile.STARTUP)
const INFO = bot.channels.get(CCFile.INFO)
const ERRORS = bot.channels.get(CCFile.ERRORS)
const RESTART = bot.channels.get(CCFile.RESTART)
const EXECUTABLES = bot.channels.get(CCFile.EXECUTABLES)
class Control {
/**
* Implement control center logging
* #param {string} message - What to send to the startup channel
* #return {string} The final product being sent to the startup channel
*/
STARTUP(message) {
return STARTUP.send(`${message}`)
}
}
module.exports = Control
I want to be able to globally use this module/the functions inside, so that my code can be more compact. So how can I have it so that this code is only loaded once the bot is logged in?
In your module code, you are creating a new Discord client instance, and never calling the login method.
A better approach would be to pass the bot object in your method
module file
const CC = '../settings/control-center.json';
const CCFile = require(CC);
const GUILD = CCFile.GUILD;
const STARTUP = CCFile.STARTUP;
const INFO = CCFile.INFO;
const ERRORS = CCFile.ERRORS;
const RESTART = CCFile.RESTART;
const EXECUTABLES = CCFile.EXECUTABLES;
class Control {
startup(bot, message) {
return bot.channels.get(STARTUP).send(message);
}
}
module.exports = Control
app file
// Use the bot here
const Discord = require('discord.js')
const bot = new Discord.Client()
const control = require('path/to/control.js');
[...]
// to send a message when ready, try something like this
bot.on('ready', () => {
control.startup(bot, 'bot is ready');
});
// don't forget to login
bot.login('YOUR-TOKEN-HERE');

JS SDK, Thrift error code 12 when getting SharedNotebooksList

It's the first time that I work with evernote,
Like the example given in the JS SDK, I create my client with the token that I get from the OAuth and I get all the notebooks of my current user so it was good for me.
But I'm facing a problem that I can't understand, when I use any method of my shared store it throw an Thrift exception with error code 12 and giving the shard id in the message.
I know that 12 error code is that the shard is temporary unavailable..
But I know that it's another thing because it's not temporary...
I have a full access api key, it work with the note store, did I miss something ?
// This is the example in the JS SDK
var linkedNotebook = noteStore.listLinkedNotebooks()
.then(function(linkedNotebooks) {
// just pick the first LinkedNotebook for this example
return client.getSharedNoteStore(linkedNotebooks[0]);
}).then(function(sharedNoteStore) {
// /!\ There is the problem, throw Thrift exception !
return sharedNoteStore.listNotebooks().then(function(notebooks) {
return sharedNoteStore.listTagsByNotebook(notebooks[0].guid);
}).then(function(tags) {
// tags here is a list of Tag objects
});
});
this seems to be an error with the SDK. I created a PR (https://github.com/evernote/evernote-sdk-js/pull/90).
You can work around this by using authenticateToSharedNotebook yourself.
const client = new Evernote.Client({ token, sandbox });
const noteStore = client.getNoteStore();
const notebooks = await noteStore
.listLinkedNotebooks()
.catch(err => console.error(err));
const notebook = notebooks.find(x => x.guid === guid);
const { authenticationToken } = await client
.getNoteStore(notebook.noteStoreUrl)
.authenticateToSharedNotebook(notebook.sharedNotebookGlobalId);
const client2 = new Evernote.Client({
token: authenticationToken,
sandbox
});
const noteStore2 = client2.getNoteStore();
const [notebook2] = await noteStore2.listNotebooks();
noteStore2.listTagsByNotebook(notebook2.guid)

Generating Twillio Access Tokens using Node JS

I'm developing an application that uses Twillios Programmable Video API.
I'm new to using Node JS, but the documentation has been fairly straightforward, however I still have a few questions.
Here's code I am referencing.
const AccessToken = require('twilio').jwt.AccessToken;
const VideoGrant = AccessToken.VideoGrant;
// Used when generating any kind of tokens
const twilioAccountSid = 'ACxxxxxxxxxx';
const twilioApiKey = 'SKxxxxxxxxxx';
const twilioApiSecret = 'xxxxxxxxxxxx';
const identity = 'user';
// Create Video Grant
const videoGrant = new VideoGrant({
room: 'cool room'
});
// Create an access token which we will sign and return to the client,
// containing the grant we just created
const token = new AccessToken(twilioAccountSid, twilioApiKey, twilioApiSecret);
token.addGrant(videoGrant);
token.identity = identity;
// Serialize the token to a JWT string
console.log(token.toJwt());
In this specific example provided by Twillio, the video grant which I assume is mandatory is explicitly referenced, however that would mean for this specific token generator, the users can only enter rooms of that name.
I was wondering if it was possible to reference the room before configuring the token. Something similar to how the identity is a variable that's entered into the function before the token is output.
In addition, are there any required dependencies or libraries when creating tokens outside of Twillios own function environment?
Any answers, suggestions, or references are greatly appreciated.
Twilio developer evangelist here.
It is possible to supply the room name as a variable too. You might want to create a function that can take an identity and room name as arguments and returns an access token. Something like this:
const AccessToken = require('twilio').jwt.AccessToken;
const VideoGrant = AccessToken.VideoGrant;
// Used when generating any kind of tokens
const twilioAccountSid = 'ACxxxxxxxxxx';
const twilioApiKey = 'SKxxxxxxxxxx';
const twilioApiSecret = 'xxxxxxxxxxxx';
function generateToken(identity, roomName) {
const videoGrant = new VideoGrant({
room: roomName
});
const token = new AccessToken(twilioAccountSid, twilioApiKey, twilioApiSecret);
token.addGrant(videoGrant);
token.identity = identity;
return token.toJwt();
}
Then you can use the function like:
const token = generateToken("Stefan", "StefansRoom");
Let me know if that helps at all.

How to Play Audio File Into Channel?

How do you play an audio file from a Discord bot? Needs to play a local file, be in JS, and upon a certain message being sent it will join the user who typed the message, and will play the file to that channel.
GitHub Project: LINK
In order to do this there are a few things you have to make sure of first.
Have FFMPEG installed & the environment path set for it in Windows [link]
Have Microsoft Visual Studio (VS) installed [link]
Have Node.js installed.[link]
Have Discord.js installed in VS.
From there the steps are quite simple. After making your project index.js you will start typing some code. Here are the steps:
Add the Discord.js dependency to the project;
var Discord = require('discord.js');
Create out client variable called bot;
var bot = new Discord.Client();
3. Create a Boolean variable to make sure that the system doesn't overload of requests;
var isReady = true;
Next make the function to intercept the correct message;
bot.on('message', message =>{ENTER CODE HERE});
Create an if statement to check if the message is correct & if the bot is ready;
if (isReady && message.content === 'MESSAGE'){ENTER CODE HERE}
Set the bot to unready so that it cannot process events until it finishes;
isReady = false;
Create a variable for the channel that the message-sender is currently in;
var voiceChannel = message.member.voice.channel;
Join that channel and keep track of all errors;
voiceChannel.join().then(connection =>{ENTER CODE HERE}).catch(err => console.log(err));
Create a refrence to and play the audio file;
const dispatcher = connection.play('./audiofile.mp3');
Slot to wait until the audio file is done playing;
dispatcher.on("end", end => {ENTER CODE HERE});
Leave channel after audio is done playing;
voiceChannel.leave();
Login to the application;
bot.login('CLIENT TOKEN HERE');
After you are all finished with this, make sure to check for any un-closed brackets or parentheses. i made this because it took my hours until I finally found a good solution so I just wanted to share it with anybody who is out there looking for something like this.
thanks so much!
One thing I will say to help anyone else, is things like where it says ENTER CODE HERE on step 10, you put the code from step 11 IE:
dispatcher.on("end", end => voiceChannel.leave());
As a complete example, this is how I have used it in my message command IF block:
if (command === "COMMAND") {
var VC = message.member.voiceChannel;
if (!VC)
return message.reply("MESSAGE IF NOT IN A VOICE CHANNEL")
VC.join()
.then(connection => {
const dispatcher = connection.playFile('c:/PAtH/TO/MP3/FILE.MP3');
dispatcher.on("end", end => {VC.leave()});
})
.catch(console.error);
};
I went ahead an included Nicholas Johnson's Github bot code here, but I made slight modifications.
He appears to be creating a lock; so I created a LockableClient that extends the Discord Client.
Never include an authorization token in the code
auth.json
{
"token" : "your-token-here"
}
lockable-client.js
const { Client } = require('discord.js')
/**
* A lockable client that can interact with the Discord API.
* #extends {Client}
*/
class LockableClient extends Client {
constructor(options) {
super(options)
this.locked = false
}
lock() {
this.setLocked(true)
}
unlock() {
this.setLocked(false)
}
setLocked(locked) {
return this.locked = locked
}
isLocked {
return this.locked
}
}
module.exports = LockableClient;
index.js
const auth = require('./auth.json')
const { LockableClient } = require('./lockable-client.js')
const bot = new LockableClient()
bot.on('message', message => {
if (!bot.isLocked() && message.content === 'Gotcha Bitch') {
bot.lock()
var voiceChannel = message.member.voiceChannel
voiceChannel.join().then(connection => {
const dispatcher = connection.playFile('./assets/audio/gab.mp3')
dispatcher.on('end', end => voiceChannel.leave());
}).catch(err => console.log(err))
bot.unlock()
}
})
bot.login(auth.token)
This is an semi old thread but I'm going to add code here that will hopefully help someone out and save them time. It took me way too long to figure this out but dispatcher.on('end') didn't work for me. I think in later versions of discord.js they changed it from end to finish
var voiceChannel = msg.member.voice.channel;
voiceChannel.join()
.then(connection => {
const dispatcher = connection.play(fileName);
dispatcher.on("finish", end => {
voiceChannel.leave();
deleteFile(fileName);
});
})
.catch(console.error);
Note that fileName is a string path for example: fileName = "/example.mp3". Hopefully that helps someone out there :)
Update: If you want to detect if the Audio has stopped, you must subscribe to the speaking event.
voiceChannel
.join()
.then((connection) => {
const dispatcher = connection.play("./audio_files/file.mp3");
dispatcher.on("speaking", (speaking) => {
if (!speaking) {
voiceChannel.leave();
}
});
})

Categories

Resources