Bot framework v3 unauthorized - botframework

I'm trying to use MS botframework V3 to create a basic bot using the nodejs tutorial code, but I keep getting 401 Unauthorized using the emulator. Please help?
AppId / Secret are set in env variables and definitely correct in emulator.
Code below
var restify = require('restify');
var builder = require('botbuilder');
//=========================================================
// Bot Setup
//=========================================================
// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url);
});
// Create chat bot
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
var bot = new builder.UniversalBot(connector);
server.post('/api/messages', connector.listen());
//=========================================================
// Bots Dialogs
//=========================================================
bot.dialog('/', function (session) {
session.send("Hello World");
});

try changing the appId and appSecret to MicrosoftAppId and MicrosoftAppPassword respectively
As stated on botframework website
In V1, the authentication properties were stored with these keys:
AppId
AppSecret
In V3, to reflect changes to the underlying auth model, these keys have been changed to:
MicrosoftAppId
MicrosoftAppPassword
Edit:
So, from a post on github by Steven the actual values are
appId
appPassword
These values won't work with the emulator due to an issue with node sdk however they should work when deployed.
Link:
https://github.com/Microsoft/BotBuilder/issues/625

While using the emulator for the first time, i was giving an appid and password on my own. I learnt that no app id and no password also works fine in local.
:Removing the appid and password in the web.config in the bot application and in the emulator resolved my error. Hope it helps. Cheers!

I am having the same the issue, but I can get the above solution to work. It appears to suggest, you can put in any values for id and pw. If they are not found, then authorization is turned off? Is this correct?
I tried this
var connector = new builder.ChatConnector({appId:'999', appPassword: 'xxxx'});
And I still get a 401.

Related

How to use graph api on outlook add-ins?

According to documentation I created simple authentication in my outlook add-in https://learn.microsoft.com/en-us/graph/tutorials/javascript?tabs=aad&tutorial-step=3
But i get an error: DeviceCodeCredentials is not supported in the browser; when i try to create auth provider in my outlook add-in. Which authentication I should use to successfully create 'graph client instance'? Or better solutions exists?
`
const graph = require('#microsoft/microsoft-graph-client');
const authProviders =
require('#microsoft/microsoft-graph-client/authProviders/azureTokenCredentials');
_deviceCodeCredential = new azure.DeviceCodeCredential({
clientId: settings.clientId,
tenantId: settings.tenantId,
userPromptCallback: deviceCodePrompt
});
const authProvider = new authProviders.TokenCredentialAuthenticationProvider(
_deviceCodeCredential, {
scopes: settings.graphUserScopes
});
_userClient = graph.Client.initWithMiddleware({
authProvider: authProvider
});
`
I also tried other auth methods, but all they didn't work. How I can auth my user in outlook add in? Maybe there are some ways to auth without azure?

Stripe returns a "No such token" error (Plaid Integration)

I am getting this error from Stripe when I try to create a new source for the selected bank account. I am using the new (beta) version of the Plaid Node SDK. Here is my code:
let user;
const mode = "sandbox";
const dsService = new CaspioDsService();
// Load the user if not already loaded by cognitoAuth
if (!req.user) {
user = new User(
dsService,
new CaspioRefDataService(),
new AuthUserService({
organizationId: res.locals.organization.Organization_ID,
isAuthenticated: res.locals.isAuthenticated,
})
);
await user.load(req.params.userId);
} else {
user = req.user.userObject;
}
const configuration = new Configuration({
basePath: PlaidEnvironments[mode],
baseOptions: {
headers: {
"PLAID-CLIENT-ID": config.plaid.clientId,
"PLAID-SECRET": mode === "sandbox" ? config.plaid.secretSandbox : config.plaid.secretProduction,
"Plaid-Version": "2020-09-14",
},
},
});
const plaidClient = new PlaidApi(configuration);
console.log(configuration.basePath); // https://sandbox.plaid.com
// Exchange the public token for the Plaid access token
const plaidTokenRes = await plaidClient.itemPublicTokenExchange({
public_token: req.body.publicToken,
});
const accessToken = plaidTokenRes.data.access_token;
console.log(accessToken); // access-sandbox-d92396c2-1f49-4780-9ae9-23d50645f364
// Get the Stripe bank account token from Plaid
const stripeTokenRes = await plaidClient.processorStripeBankAccountTokenCreate({
access_token: accessToken,
account_id: req.body.accountId
});
const bankAccountToken = stripeTokenRes.data.stripe_bank_account_token;
console.log(bankAccountToken); // btok_1JFMGwGq7ejZoSiwGmM8WSSm
let stripeCustomerId = user.getStripeToken();
const stripeClient = await StripeHelper.getStripeClient(mode); // Get Stripe client in sandbox mode
console.log(stripeCustomerId); // cus_Jt7AWZjC8rHPzt
// Add the source to the Stripe customer and get the bank account info
const bankAccount = await stripeClient.customers.createSource(stripeCustomerId, {
source: bankAccountToken,
}); // Error: No such token: 'btok_1JFMGwGq7ejZoSiwGmM8WSSm'
Any ideas what I might be doing wrong? I expect the issue is with my code, or possibly Plaid (I don't think it is a Stripe problem).
It sounds like you're getting a token from Plaid, but Stripe is rejecting it, which suggests a problem with the relationship between your Plaid and Stripe setups. Are you sure that you enabled the Plaid/Stripe integration in the Plaid dashboard and that the client id / secret you're using matches the Plaid account where the integration is enabled? The Plaid docs also suggest that this error can be caused by using a mismatched set of environments (e.g. using Production with Stripe but Sandbox with Plaid).
The problem was that we had the wrong Stripe account connected. Silly one, but I'm posting this in case anyone else makes the same mistake.

guildmemberupdate event only occurs when bot gets updated

This only picks up when the actual bot gets updated and not when other users update
client.on('guildMemberUpdate' ,(oldMember,newMember) => {
console.log(oldMember['_roles'])
console.log(newMember['_roles'])
});
https://discordjs.guide/popular-topics/intents.html
Read through this page - You need to use intents when connecting to the gateway
so
const client = new Discord.Client({ ws: { intents: Discord.Intents.ALL } })
And enable intents on your application's Page (https://i.imgur.com/XtKjFyY.png) enable both.

Xamarin.Auth doesn't work with Linkedin V2 API

I'm actually trying to do a simple login with Linkedin and the new API V2 with Xamarin.Auth extension. I do get the token like this
var auth = new OAuth2Authenticator(
clientId: *****,
clientSecret: *****,
scope: "r_liteprofile",
authorizeUrl: new Uri("https://www.linkedin.com/oauth/v2/authorization"),
redirectUrl: new Uri(*****),
accessTokenUrl: new Uri("https://www.linkedin.com/oauth/v2/accessToken")
);
but when I try to make a request it fails with an {"serviceErrorCode":100,"message":"Unpermitted fields present in PARAMETER: Data Processing Exception while processing fields [/access_token, /format]","status":403}. Code for these error:
var request = new OAuth2Request(
"GET",
new System.Uri("https://api.linkedin.com/v2/me?"
+ "format=json"
+ "&oauth2_access_token="
+ e.Account.Properties["access_token"]),
null,
e.Account
);
var linkedinResponse = await request.GetResponseAsync();
var json = linkedinResponse.GetResponseText();
Console.WriteLine(json);
If I take out the fields, it fails because of empty access token: {"serviceErrorCode":65604,"message":"Empty oauth2 access token","status":401} Code for these error:
var request = new OAuth2Request(
"GET",
new System.Uri("https://api.linkedin.com/v2/me"),
null,
e.Account
);
var linkedinResponse = await request.GetResponseAsync();
var json = linkedinResponse.GetResponseText();
Console.WriteLine(json);
I've confirmed that I've recieved the token. Looking for a solution I found that the token must be in a header but I can't change or add any header. Can anyone help me please?
Thank you very much.
PD: Forgot to say this code is for Android but I needed to do it for iOS aswell.
Hi finally I found the solution to this.
In Linkedin API V2 you have to change your AccessTokenparameterName.
yourOauth2Request.AccessTokenParameterName = "oauth2_access_token";
Hope I can help somebody to not get mad like me.

In Bot Framework Web Chat, how do I connect to my bot server?

All the tutorial are connecting to direct line, what about using my own bot server? How do I connect in javascript?
I already setup server side:
// Setup BotFramework
var connector = new Builder.ChatConnector({
appId: "a8...",
appPassword: "ko...",
openIdMetadata: process.env.BotOpenIdMetadata
});
// Setup Bot
var bot = new Builder.UniversalBot(connector);
bot.set('storage', new Builder.MemoryBotStorage());
// Setup Server
var server = Restify.createServer();
server.listen(process.env.port || process.env.PORT || 4000, function () {
console.log("Listening on port "+(process.env.port || process.env.PORT || 4000));
});
server.post('/api/messages', connector.listen());
On the client side, here is what I currently got using direct line:
<script src="https://cdn.botframework.com/botframework-webchat/latest/botchat.js"></script>
<script src="https://cdn.botframework.com/botframework-webchat/latest/CognitiveServices.js"></script>
<script>
const params = BotChat.queryParams(location.search);
const speechOptions = {
speechRecognizer: new BotChat.Speech.BrowserSpeechRecognizer(),
speechSynthesizer: new BotChat.Speech.BrowserSpeechSynthesizer()
};
BotChat.App({
showUploadButton: false,
directLine: { secret: '_bm...' },
bot: { id: 'a8...' },
locale: params['locale'],
resize: 'detect',
speechOptions: speechOptions,
user: {
id: 'WebChatDemoUser',
name: 'You'
},
}, document.getElementById('ChatBot'));
var header = document.getElementsByClassName("wc-header");
header[0].innerHTML = "<span>Chat</span>"
</script>
So this work, but it connect directly to the bot framework, I need to connect to my server like this:
http://localhost:4000/api/messages
Or on production would be like this:
http://myserver.com:4000/api/messages
Basically, similar to how Bot Emulator connect:
DirectLineJs will call the Direct Line Connector Service by default. The connector service then calls your bot, and the bot calls back to the connector service with responses (or proactive messages). DirectLineJs does provide a domain parameter you can supply to override the default:
const dl = new DirectLine({
secret: /* put your Direct Line secret here */,
token: /* or put your Direct Line token here (supply secret OR token, not both) */,
domain: /* optional: if you are not using the default Direct Line endpoint, e.g. if you are using a region-specific endpoint, put its full URL here */
webSocket: /* optional: false if you want to use polling GET to receive messages. Defaults to true (use WebSocket). */,
pollingInterval: /* optional: set polling interval in milliseconds. Default to 1000 */,
});
However, there is a lot more involved in hosting your own Direct Line Connector Service. The SDK code will use the activity's serviceUrl property to send messages back to the connector service. The bot is expecting endpoints such as those in this MockChannelController: https://github.com/Microsoft/BotFramework-Samples/blob/master/blog-samples/CSharp/MockChannel/Controllers/MockChannelController.cs
More details are explained in this Load Testing blog post: https://blog.botframework.com/2017/06/19/load-testing-a-bot/
There's also this limited node example: offline-directline

Resources