Request scopes from Slack for messages - slack-api

i have a Slack app and until yesterday only the primary owner could send the message. I asked the Slack team on how to solve this issue to allow all users to be able to send messages on Slack. The answer was to first use the Sign in with Slack button to log them in. Then another button but with different scopes.
My question here is, I was able to send messages as users using the button as follows :
<input type="button" value="Authenticate again to send Message" class="btn btn-warning" onclick="location.href = 'https://slack.com/oauth/authorize?scope=incoming-webhook,im:write,chat:write:user&client_id=xxyyzz'"/>
Now, I am trying to do the same extra scopes request in the background by displaying a view that says" Please wait"
Attaching the code below:
<script>
$.ajax({
method: "GET",
dataType: "json",
url: "#Url.Action(MenuItem, "SetupSlack")",
//data: { code: 'Model.Code' },
data: { code: '#Model' },
success: function(rsp) {
window.location.replace(rsp.redirect);
},
error: function() {
// Show error.
}
});
</script>
And the controller code is as follows:
public ActionResult SetupSlack(string code)
{
SlackAuthToken slackToken = slackService.GetAccessToken( clientId, clientSecret, code);
string redirectUrl;
if (slackToken.IsAuthenticated && slackToken.HasWrite)
{
Alert("Slack setup successfully!!!!", AlertLevel.Success);
redirectUrl = Url.Action(MenuItem, "Index");
}
else if (slackToken.IsAuthenticated)
{
redirectUrl = "https://slack.com/oauth/authorize?scope=incoming-webhook,im:write,chat:write:user&client_id=aabbcc";
}
else
{
Alert("Slack setup failed. Please try again, if the problem persists please contact support.", AlertLevel.Success);
redirectUrl = Url.Action(MenuItem, "Index");
}
return JsonNet(new { redirect = redirectUrl });
}
It is not leading to the post message authentication page.Also, the other error that am getting it "code already used" as one of the responses in the OAuth flow.
Can anyone help me here.
I made the button work fine, but this should work as well.

Let me try to give a more complete answer to your problem as I understand it.
Requirements
You have a website and you want users from your Slack team to be able to send messages to Slack from it.
Messages must be sent on behalf of the user, not from the app
Solution
To authenticate and get the slack user ID users need to log into your website using "Sign-in with Slack"
When the user wants to send a message, your website checks its database for the access token belonging to the current user (the slack user ID is the key) and then uses that token to send a the slack message via API with chat.postMessage
If the website can not find a token for the current user in its database, the token needs to be created. For that the user is presented with a button that starts an Oauth flow with Slack requesting the required permissions (e.g. "Grant permissions to website"). After the token has been created it is stored in the database of the website, so this process has to be run once per user only. The user can then sent his message.
Notes
The Oauth process in step 3 is basically the same as installing the Slack app for each individual user. It is called configurations. This only works though if the admins of your Slack team have granted all users the right to install this particular Slack app
The Oauth process in step 3 and can NOT be run the background as you suggested in your question since it requires direct user interaction. It will always require the user to first login and then approve the requested permissions for your Slack app.

This can not work. The button is triggering the installation of your Slack app by a user via Oauth 2.0. By definition the Oauth process can not be run in the background, but requires the user to follow the redirect to the login-page from Slack and approve the permissions requested for your Slack app.

Related

How to link slack user with github account?

I am creating a slack bot and want to be able to link the slack user with the github account.
Is there a way I can link the 2 either via slack or github API's?
I was thinking if of storing users slack username and github username in a JSON object, i.e.:
{
"slack_username": "JoeBlogs",
"github_username": "JoeBlogs123"
}
In order to do this, I would need to retrieve the users' username from slack API when the user authorises the app / bot.
I was thinking if I add a redirect_url to my slack app then it would redirect user to http://example.com/redirect if the users data is sent along to this redirect url, I would be able save it in a database of sorts.
If I then did the same with the github API then I could reference database in order to find slack users JoeBlogs github account and vice versa.
Is it possible to use the redirect_url like this? I couldn't see any user data being sent to but maybe it is nested somewhere I couldn't see it?
Is there a better way to link the 2 accounts?
Assuming you are using Install button to install your Slack app into the workspace, this is a payload which will be sent to your response_url:
{
"access_token": "xoxp-XXXXXXXX-XXXXXXXX-XXXXX",
"scope": "incoming-webhook,commands,bot",
"team_name": "Team Installing Your Hook",
"team_id": "XXXXXXXXXX",
"incoming_webhook": {
"url": "https://hooks.slack.com/TXXXXX/BXXXXX/XXXXXXXXXX",
"channel": "#channel-it-will-post-to",
"configuration_url": "https://teamname.slack.com/services/BXXXXX"
},
"bot":{
"bot_user_id":"UTTTTTTTTTTR",
"bot_access_token":"xoxb-XXXXXXXXXXXX-TTTTTTTTTTTTTT"
}
}
See for details.
Then, using access_token in combination with users.identity API method you will get basic information about Slack user (playing with the scopes you requested during the install process you can get different fields of Slack user identity).

Slack API Opening a New DM (Scopes and Permissions)

I am attempting to open a DM (Direct Message) with an arbitrary user using the im.open Slack API call. I am sending it a user's user_id that I obtain through their clicking of a consent button in order to begin a series of questions. I am sending data to the Slack API successfully along with receiving data. I am getting the following response...
{
"ok": false,
"error": "missing_scope",
"needed": "im:write",
"provided": "identify,incoming-webhook,chat:write:user,files:write:user",
}
I have went into the application's page and changed the scope of the app (I am not the owner, but have been given collaborator permissions by my team lead (the owner)). These are the current permissions...
I apologize for the poor quality of the image. The scopes are as follows...
identify
incoming-webhook
chat:write:user
files:write:user
im:write
After this change, I am still getting the same response from the Slack API. The following is what I am sending them (it's my user_id, and I don't mind).
{
"user": "U94155Z43"
}
Any help is appreciated. Thanks.
I needed to use the bot token "xoxb" instead of the user token "xoxp" which I had used for all other slack api calls.

Request to onedrive permission returning wrong information

POST https://graph.microsoft.com/v1.0/drives/{driveId}/items/{itemId}/invite
Request Body:
{
"recipients":[{"email":"some_valid#ID.com"}],
"message":"",
"requireSignIn":true,
"sendInvitation":false,
"roles":["write"]
}
Response Body:
{
"#odata.context":"https://graph.microsoft.com/v1.0/$metadata#Collection(permission)",
"value":[{
"#odata.type":"#microsoft.graph.permission",
"grantedTo":{"user":{"displayName":"some_valid#ID.com"}},
"id":"<PERMISSION_ID>",
"roles":["write"]
}]
}
I'm getting proper response with 200 ("OK") status code. But I'm not able to access the sharepoint folder with "some_valid#ID.com" account. Also when I'm checking the permissions on the folder in the sharepoint, the "some_valid#ID.com" id is not listed in manage access list.
This is a combination of 'By Design' and a bug. The 'By Design' part is that if you choose to not send the email invite, the user will not be able to access the document. The user typically needs to redeem the link in the invite before they get access. The bug is that the API response should still show that the user was granted access(although the invitation never got sent out, the invitation link however could be shared at a later time) . We are working on a fix. Thanks for bringing it up.

.NET - Update status (tweet) to Twitter without PIN or real Callback url?

I'm trying to write an app that can tweet using an 'application' I registered with Twitter. I am using TweetSharp and have tried to get my TwitterService set up as follows:
public Twitter(string consumerKey, string consumerSecret)
{
this.twitterService = new TwitterService(consumerKey, consumerSecret);
OAuthRequestToken oAuthRequestToken = this.twitterService.GetRequestToken();
Uri uri = this.twitterService.GetAuthorizationUri(oAuthRequestToken);
Process.Start(uri.ToString());
OAuthAccessToken oAuthAccessToken =
this.twitterService.GetAccessToken(oAuthRequestToken);
this.twitterService
.AuthenticateWith(oAuthAccessToken.Token, oAuthAccessToken.TokenSecret);
}
It gets to the OAuthAccessToken line and then takes me to the Authorize [my app] to use your account? page on the Twitter website. Before I specified a phony callback url, it displayed a page with the PIN that my user is supposed to enter when I clicked the 'Authorize app' button. Then when I added a phony callback url, it would attempt to go to that page and my code would blow to smithereens with the following error:
The remote server returned an error: (401) Unauthorized.
What I want to know is: can I tweet programatically without the need to enter a PIN or have a legitimate callback url?
Tweets must be sent in the context of a user. (Ref: POST statuses/update.) Therefore, your app must get the user's authorization (an OAuth access token) in order to send a Tweet. Since you can't get an access token without using either PIN-based authentication or a callback URL, I'm afraid that what you are asking simply cannot be done.
If, however, you just want to avoid prompting your users to enter the PIN each time they start your app, then the answer is simple: Once you have a valid access token, save it somewhere (e.g. to a file) and then reload it next time your app runs. For my WinForms app, I use .NET's built-in per-user Settings mechanism to store the Access Token and Access Token Secret. A web app would probably be better off using a database or similar to persist access tokens.
Note: If you do this, you'll also need to check the validity of the stored access token, and repeat the authorization process if it's no longer valid. The Twitter API documentation suggests using the GET account/verify_credentials method for this purpose.

Twitter #anywhere login having issues

I'm using the new twitter #anywhere api for logging in on the client using a popup. The api docs are here
https://dev.twitter.com/docs/anywhere/welcome#auth-events
Ive created a very simple example of their api, but after hitting "connect" on the popup, twitter just says "Something is technically wrong" as seen here in this screenshot
http://cl.ly/0A321R1Z2W1o3v0P0t0z
Here is my setup for doing this (note ive already created my app on twitter)
var api = "http://platform.twitter.com/anywhere.js?id={MY_API_KEY}&v=1";
$.getScript(api,function() {
twttr.anywhere(function (tw) {
console.log("tw",tw);
// bind auth compelte event
tw.bind("authComplete", function (e, user) {
console.log("tw auth complete",e,user);
});
// calling sign in triggeers the above event
tw.signIn();
});
});
So it opens the popup, lets me sign into twitter, and then when I hit connect, i get that odd error from twitter.
Any ideas what could be going wrong?
Thanks!
Update - I found this page of people having similar problems, but the solution they offered didn't change anything.
https://dev.twitter.com/discussions/1286
And it might be important to note the domain I'm using is http://changeup.dev its a local domain. I have it setup in my hosts file already.
SO, i Figured it out. You NEED to have a callback URL for your app, (on the developer page) even though it says you don't. The callback URL needs to match your authorized domain as well.
Then, in your app, the URL that the callback is calling, NEEDS to include the twitter api. THEN, and only THEN will the window automatically close and execute the authComplete callback.
I did this on the same page I was logging in from
if(location.hash && location.hash.indexOf("oauth_access_token") != -1) {

Resources