Slack Examples cannot be installed
martibi opened this issue · 10 comments
Both the express
and restify
examples cannot be installed into a Slack workspace using Slack Button
. Slack Button generates the following:
https://slack.com/oauth/authorize?scope=bot&client_id=client_id
After the above is called, and the authorization is given, the OAuth process fails with the following output:
Bot is listening...
error: Response not OK: missing_scope
@martibi Hello!
Are you sure that bot
is the only scope your bot uses ? Can you verify that ?
Yes I am using both the examples in your project https://github.com/suttna/botbuilder-slack/tree/master/example/src
The OAuth process tries to install the bot but the URL gets redirected to onOAuthErrorRedirectUrl
.
I modified the example bot to use the function below instead of listenOAuth()
and it works, so there is something wrong with botbuilder-slack
's listenOAuth
function:
// This route handles get request to a /oauth endpoint. We'll use this endpoint for handling the logic of the Slack oAuth process behind our app.
app.get('/slack/oauth', function(req, res) {
// When a user authorizes an app, a code query parameter is passed on the oAuth endpoint. If that code is not there, we respond with an error message
if (!req.query.code) {
res.status(500);
res.send({"Error": "Looks like we're not getting code."});
console.log("Looks like we're not getting code.");
} else {
// If it's there...
// We'll do a GET call to Slack's `oauth.access` endpoint, passing our app's client ID, client secret, and the code we just got as query parameters.
request({
url: 'https://slack.com/api/oauth.access', //URL to hit
qs: {code: req.query.code, client_id: process.env.SLACK_CLIENT_ID,
client_secret: process.env.SLACK_CLIENT_SECRET}, //Query string data
method: 'GET', //Specify the method
}, function (error, response, body) {
if (error) {
console.log(error);
} else {
res.json(body);
}
})
}
});
@martibi Can you show the code you are using and a screenshot of the slack permissions page ? That will help us troubleshoot a potential issue.
- I'm using the examples in your botbuilder-slack project. I did not modify anything.
- I just did one small modification to package.json to use botbuilder-slack directly:
{
"dependencies": {
"botbuilder-slack": "^2.0.0"
}
}
- Started
ngrok
withngrok http 1234
to obtain ngrok address. - Added Slack application, and Slack bot user named "botbuilder".
- Obtained the CLIENT_ID, CLIENT_SECRET from Slack.
- Setup OAuth Redirect URL on Slack to point to ngrok address:
- Setup OAuth Scope:
-
Install this Slack App and authorize it.
-
Next I started the
express
example with this script:
#!/bin/bash
export SLACK_BOT_NAME="botbuilder"
export SLACK_VERIFICATION_TOKEN="xyz"
export SLACK_CLIENT_ID="xyz"
export SLACK_CLIENT_SECRET="xyz"
export SLACK_OAUTH_REDIRECT_URL="https://foobar.ngrok.io/slack/oauth" #matched to ngrok address obtained above
export SLACK_OAUTH_ON_SUCCESS_REDIRECT_URL="https://example.com/success"
export SLACK_OAUTH_ON_ERROR_REDIRECT_URL="https://example.com/error"
export SLACK_OAUTH_ON_ACCESS_DENIED_REDIRECT_URL="https://example.com/redirect"
export PORT=1234
npx ts-node src/express.ts
- Proceed to
https://api.slack.com/docs/slack-button
and selected this app and "commands, bot". - Click on "Add to Slack" button.
- Output is shown:
error: Response not OK: missing_scope
As mentioned, after I modified the express.ts
to the following the installation from "Add to Slack" button worked:
import * as express from "express"
import * as bodyParser from "body-parser"
import { SlackConnector } from "botbuilder-slack"
import { createBot, BotCache } from "./bot"
import * as request from "request"
const port = process.env.PORT || 3000
const botsCache: BotCache = {}
const connectorSettings = {
botLookup: (teamId: string) => {
const botEntry = botsCache[teamId]
if (botEntry) {
return Promise.resolve([botEntry.token, botEntry.identity.id] as [string, string])
} else {
return Promise.reject(new Error('Bot not found'))
}
},
botName: process.env.SLACK_BOT_NAME,
verificationToken: process.env.SLACK_VERIFICATION_TOKEN,
clientId: process.env.SLACK_CLIENT_ID,
clientSecret: process.env.SLACK_CLIENT_SECRET,
redirectUrl: process.env.SLACK_OAUTH_REDIRECT_URL,
onOAuthSuccessRedirectUrl: process.env.SLACK_OAUTH_ON_SUCCESS_REDIRECT_URL,
onOAuthErrorRedirectUrl: process.env.SLACK_OAUTH_ON_ERROR_REDIRECT_URL,
onOAuthAccessDeniedRedirectUrl: process.env.SLACK_OAUTH_ON_ACCESS_DENIED_REDIRECT_URL
}
const connector = new SlackConnector(connectorSettings)
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded())
app.listen(port, () => {
console.log(`Bot is listening on port ${port}`)
})
// This route handles get request to a /oauth endpoint. We'll use this endpoint for handling the logic of the Slack oAuth process behind our app.
app.get('/slack/oauth', function(req, res) {
// When a user authorizes an app, a code query parameter is passed on the oAuth endpoint. If that code is not there, we respond with an error message
if (!req.query.code) {
res.status(500);
res.send({"Error": "Looks like we're not getting code."});
console.log("Looks like we're not getting code.");
} else {
// If it's there...
// We'll do a GET call to Slack's `oauth.access` endpoint, passing our app's client ID, client secret, and the code we just got as query parameters.
request({
url: 'https://slack.com/api/oauth.access', //URL to hit
qs: {code: req.query.code, client_id: process.env.SLACK_CLIENT_ID,
client_secret: process.env.SLACK_CLIENT_SECRET}, //Query string data
method: 'GET', //Specify the method
}, function (error, response, body) {
if (error) {
console.log(error);
} else {
res.json(body);
}
})
}
});
app.post('/slack/events', connector.listenEvents())
app.post('/slack/interactive', connector.listenInteractiveMessages())
app.post('/slack/command', connector.listenCommands())
//app.get('/slack/oauth', connector.listenOAuth())
createBot(connector, botsCache)
@martibi What version of botbuilder
are you using ? Can you show the url that the Slack Button redirects you please ?
Thanks
I am using botbuilder 3.9.1
as in the example, but when I updated to 3.15.1
the error still occurs.
The URL that is being redirected by the Slack Button is: https://slack.com/oauth/authorize?scope=commands,bot&client_id=xyzabc
Can you try changing scope=commands,bot
for scope=commands+bot
?
Using scope=commands+bot
returns the same error:
error: Response not OK: missing_scope
Error: missing_scope
at handleHttpResponse (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/@slack/client/lib/clients/transports/call-transport.js:103:17)
at handleTransportResponse (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/@slack/client/lib/clients/transports/call-transport.js:153:19)
at apply (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/lodash/lodash.js:478:17)
at wrapper (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/lodash/lodash.js:5323:16)
at Request.handleRequestTranportRes (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/@slack/client/lib/clients/transports/request.js:21:5)
at apply (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/lodash/lodash.js:478:17)
at Request.wrapper [as _callback] (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/lodash/lodash.js:5323:16)
at Request.self.callback (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/@slack/client/node_modules/request/request.js:186:22)
at Request.emit (events.js:182:13)
at Request.EventEmitter.emit (domain.js:442:20)
at Request.<anonymous> (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/@slack/client/node_modules/request/request.js:1060:10)
at Request.emit (events.js:182:13)
at Request.EventEmitter.emit (domain.js:442:20)
at IncomingMessage.<anonymous> (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/@slack/client/node_modules/request/request.js:980:12)
at Object.onceWrapper (events.js:273:13)
at IncomingMessage.emit (events.js:187:15) 'Error: missing_scope\n at handleHttpResponse (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/@slack/client/lib/clients/transports/call-transport.js:103:17)\n at handleTransportResponse (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/@slack/client/lib/clients/transports/call-transport.js:153:19)\n at apply (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/lodash/lodash.js:478:17)\n at wrapper (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/lodash/lodash.js:5323:16)\n at Request.handleRequestTranportRes (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/@slack/client/lib/clients/transports/request.js:21:5)\n at apply (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/lodash/lodash.js:478:17)\n at Request.wrapper [as _callback] (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/lodash/lodash.js:5323:16)\n at Request.self.callback (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/@slack/client/node_modules/request/request.js:186:22)\n at Request.emit (events.js:182:13)\n at Request.EventEmitter.emit (domain.js:442:20)\n at Request.<anonymous> (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/@slack/client/node_modules/request/request.js:1060:10)\n at Request.emit (events.js:182:13)\n at Request.EventEmitter.emit (domain.js:442:20)\n at IncomingMessage.<anonymous> (botbuilder-slack/example/node_modules/botbuilder-slack/node_modules/@slack/client/node_modules/request/request.js:980:12)\n at Object.onceWrapper (events.js:273:13)\n at IncomingMessage.emit (events.js:187:15)'