Read Information for incoming slack webhooks via api - slack

Following the steps for creating incoming webhooks via add to slack button. The final response will look like this:
{
"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"
},
....
}
This provides access to team_name, channel the webhook will post to, and a url for configuration.
While this is working great and after initially storing the 'configuration' to my own webapp it displays correctly. But after a someone uses the 'configuration_url' link from the response these previous values like the channel could become obsolete. For example the webhook could be deleted from this link.
My Question is:
Is there a way to reflect this changes in my external app? As far as I can see there is no way to query information for 'incoming webhooks' via an api call from an external web application?
I also could not find any api calls that could change webhook configuration directly without using the provided link.

Its not possible to change the webhook configuration after it is created. The only possible change is that the workspace that installed your Slack app (which contains the webhook) is uninstalled.
If that happens the webhook will no longer work and you will get an error in response.
You can also get notified when you app is uninstalled by listening to the app_uninstalled event.
Or you can also test if your app and webhook is still valid by checking the token you received during the Add to Slack process. Just call the API method auth.test with that token. If it returns the following error than the webhook is no longer valid:
{
"ok": false,
"error": "invalid_auth"
}

Related

Cannot get refresh token for Chrome Web Store API to publish Chrome extension

I'm trying to upload and publish my Chrome Extension using Chrome Web Store API in Azure DevOps. I've been referencing the official Google guide but the problem is that it looks like it's outdated now. I'm failing at the step
To create the client ID and client secret, click on Create New Client ID, select Installed Application, and Other under Installed application type.
When I do this, I don't see option for "Other" in Application Type dropdown.
I've tried the following:
Choosing Web Application as Application Type
With this I'm not able to get an access code with this link:
https://accounts.google.com/o/oauth2/auth?response_type=code&scope=https://www.googleapis.com/auth/chromewebstore&client_id=$CLIENT_ID&redirect_uri=urn:ietf:wg:oauth:2.0:oob
it's resulting in "Error 400: redirect_uri_mismatch". If I add an authorized redirect URI in my Client ID settings, like 'localhost', and replace 'urn:ietf:wg:oauth:2.0:oob' in URL above with it, I'm able to invoke authorization process and get the code from URL. But when I try to make a curl request to https://accounts.google.com/o/oauth2/token to get the refresh token I don't receive a refresh token, I only get this:
{
"access_token": "",
"expires_in": 3599,
"scope": "https://www.googleapis.com/auth/chromewebstore",
"token_type": "Bearer"
}
Choosing Chrome App as Application Type
Pretty much the same happens here as in previous attempt, except I don't have to substitute the redirect URI in request for access code, but I also don't have Client Secret for this application type, so I just omit it. Anyways, it results in the same response that doesn't have refresh token.
When I enable Chrome Web Store API in dev console and try to create new credentials, it suggests to create API key instead of Cliend ID. But it doesn't look like this API can actually work with this key, I've tried sending it as query param, as a header, and I always get 401 result with "Login Required" message. But when I try to send a request with (invalid) token in a header I get meaningful response (smth like Invalid Credentials).
Apparently I do need to have access token to work with Chrome Web Store API but without refresh token I need to manually authorize my permissions and that's not acceptable because I need to use in my CI/CD pipeline. It looks like Google removed the option to just generate this info for such application types.
So, the question is, how can I get the refresh token to actually be able to continuously deploy the chrome extension?
Ok, so the trick here was to add two params to the request that you use to get the access code (not token):
&access_type=offline&approval_prompt=force
And so the link should be:
https://accounts.google.com/o/oauth2/auth?response_type=code&scope=https://www.googleapis.com/auth/chromewebstore&client_id=$CLIENT_ID&redirect_uri=urn:ietf:wg:oauth:2.0:oob&access_type=offline&approval_prompt=force
And Google should do better job in updating their docs.

Try this API for Logging API returns "PERMISSION_DENIED"

I am trying to test the Google Cloud Logging API on the "Try this API" feature that Google Cloud Platform has on their documentation, but I get this response back:
{
"error": {
"code": 403,
"message": "The caller does not have permission",
"status": "PERMISSION_DENIED"
}
}
I know that my response body is correct because it works with OAuth 2.0 but fails when I use API Key.
Auth 2.0:
Working request using OAuth 2.0
API Key:
Non-Working request using API Key
Google docs says that they generate their own API Key for this "Try this API" feature. https://developers.google.com/explorer-help/
Since Google is using their own API Key, I do not understand why I am getting a response status of PERMISSION_DENIED.
Edit:
Here is a link to the Try this API feature in Google Cloud Platform if you would like to give it a try. https://cloud.google.com/logging/docs/reference/v2/rest/v2/entries/write?apix_params=%7B%22resource%22%3A%7B%22entries%22%3A%5B%7B%22logName%22%3A%22projects%2F%5BPROJECT_ID%5D%2Flogs%2Frequests%22%2C%22resource%22%3A%7B%22type%22%3A%22http_load_balancer%22%2C%22labels%22%3A%7B%7D%7D%7D%5D%7D%7D
Here is the python request that I am using in my code to create an entry:
import requests
entry = {
"entries": [
{
"logName": "projects/[PROJECT_ID]/logs/requests",
"resource": {
"type": "http_load_balancer",
"labels": {}
}
}
]
}
requests.post('https://logging.googleapis.com/v2/entries:write?key=[YOUR_API_KEY]', data=json.dumps(entry))
The API key was created from my user that has "logs writer", "logs viewer", and "logging admin" permissions. This theoretically should be all the permissions I need to make the post request. However, it is still returning a "PERMISSION_DENIED" status.
Any help would be much appreciated. Thank you in advance.
It looks like you are making a request to write data which isn't publicly writable. API Keys have no concept of user, they are only identifying you are allowed to call an API. So it looks like your API key request is working to the extent it can, but the response is telling you: I don't know who you are so I can't let you do this.
OAuth 2.0 is the solution here, as it acts on behalf of your account (you have to give consent), allowing the API to verify you have permission to take this action.
Service accounts are another option, to act on behalf of your project instead of your user, but they aren't practical from a web UI.

How to send direct messages to a user as app in app channel

How is it possible to send message in slack directly to the user, by user.id as application.
this application has scope: bot,channels:write,emoji:read,users:read,users:read.email
I find how to send message only as DM or by webhooks, but there is no scope for that. Any one has idea?
If I understand your question correctly, you want to send direct messages to users in the app channel instead of the standard slackbot channel.
In order to do that you need to
Your app needs the bot scope and a bot user
Open a direct message channel from your app with the user with conversations.open. You get back a direct message ID.
Send a message with chat.postMessage to the the direct message channel ID
Make sure to use your bot access token (not the user access token) from your Slack app.
The bot scope gives you all permissions needed to open and send DMs to users from your bot channel. No other scopes are required.
You can also use the new conversations methods, which work for all kind of channel types to do the same.
See also this question on the same topic.
There is an alternative way to solve this, which can be more suitable if your app uses a bot to operate with Slack API.
You need to call chat.postMessage API method and specify channel argument equal to the user ID (e.g. U0G9QF9C6) you want to message and as_user argument is true.
Important detail - ensure you are using bot access token (learn here how to obtain it).
Example:
curl -X POST "https://slack.com/api/chat.postMessage" -H "accept: application/json" -d token=BOT_ACCESS_TOKEN -d channel=U0G9QF3C6 -d text=Hello -d as_user=true
In this way, your message will be always sent on behalf (name and icon) of your bot and will be display like a direct message in the app channel (YourAppChannel in the Slack sidebar).
Compared to the approach of #ErikKalkoken you have no need to create a channel in advance and as a result, keep track of its ID (it may be good or bad depending on your needs).
For those who is still searching for detailed answer:
First of all you need to make call to this endpoint.
You need to make call with bot token and provide into users param value of user you want to send message.
Also you need set prevent_creation and return_im to true.
Example:
Authorization: Bearer {your_bot_token}
{
"users": "U12345679",
"prevent_creation": true,
"return_im": true
}
After that you will have your channel id to which you want to send message.
Example response:
{
"ok": true,
"no_op": true,
"already_open": true,
"channel": {
"id": "D123456789", <-- this is your id
...
"unread_count": 0,
"unread_count_display": 0,
"is_open": true,
"priority": 0
}
}
and then with same bot token and user id send message with help of this one
Blockquote I keep getting {"ok":false,"error":"not_in_channel"} do i need to manually add the bot to a channel?? –
Abhijeet Bajracharya
Feb 4 '20 at 8:04
you need to get scope that allow to send messages like this
There is no need to use the conversation.info, you can post message (DM), by using the users.list endpoint and fetch the user id, which then you can use in chat.postMessage

Outlook Push Notifications REST API fails in subscriptions registration

My application uses Outlook Push Notifications REST API to get updates for a set of users.
The code I use to make the registration is like following:
HTTP POST to:
https://outlook.office.com/api/v2.0/users/<user email>/subscriptions
POST data = {
'#odata.type': '#Microsoft.OutlookServices.PushSubscription',
'Resource': 'https://outlook.office.com/api/v2.0/me/messages',
'NotificationURL': 'https://<my_valid_hostname>/api/subscriptions',
'ChangeType': 'Created, Deleted',
'ClientState': <user UUID>,
}
This code always worked fine, but since Sep 26 it stopped to work for mostly of users. The HTTP request to make a registration to web notification returns HTTP 403 error:
HTTP 403 Error: https://outlook.office.com/api/v2.0/users/<user email>/subscriptions
{
"error": {
"code": "ErrorAccessDenied",
"message":"Access is denied. Check credentials and try again."
}
}
This application is a backend aplication registered in Azure AAD portal and uses a token which allow me to do the requests on behalf of the users.
My token credentials are working fine. I use the same token for Graph API and Outlook API without errors. I refreshed it to see if the error go away, but it doesn't work. The error comes for fresh tokens anyway.
For some users I get no error, it always work. The subscription is created fine and I get the subscription data in JSON returned, as usual.
This make me think that it may be a problem in Microsoft side, but I have no way to check this.
So how can I fix this error for the affected users?
First thing that comes in my mind is that did you forgot to renew your calendar subscriptions? It's something like max. 14 days those are alive. Anytime before expiration you can renew subscriptions and after that you still can revive subscriptions.
In fact now I tested new subscription with my app and I get only 7 days to expiration date.
At this point I got that you are getting error when creating new subscription.. are you sure your access_token is still valid?
For future SO users,
POST https://outlook.office.com/api/v2.0/me/subscriptions
Content-Type: application/json
Authorization: Bearer <access_token>
{
"#odata.type":"#Microsoft.OutlookServices.PushSubscription",
"Resource": "https://outlook.office.com/api/v2.0/<Outlook-Resource>",
"NotificationURL": "<My-Endpoint-Url>",
"ChangeType": "Created,Updated,Deleted"
}
Optional ClientState in body, allows the listener to check the legitimacy of the notification.
Check out the docs for more info.

"400: Unsupported service specified, INVALID_ARGUMENT" from Google Cloud Logging API

I am trying to manually write a log entry using Google Cloud Logging API.
Before doing this via code, I am first trying to do it using the Google APIs Explorer. Here is a screen shot of the request I've built using this tool:
In projectsId I have the Google Project Id that I've copied from the
Google Developer Console.
Likewise for metadata.projectId.
In metadata.userId I have the Client Id of the same Service account that I'm using to authenticate (OAuth2) against the Google Logging API.
Google Logging API is enabled for the project.
The Service account belong to the project and has the "Can edit" permission.
I'm 99% sure that I've setup OAuth2 correctly for the request.
When I execute this request, I get the following response:
{
"error":
{
"code": 400,
"message": "Unsupported service specified",
"status": "INVALID_ARGUMENT"
}
}
Why? and how can I fix this?
The error message was actually telling me exactly which argument was invalid - The serviceName I supplied was bogus ("test").
As soon as I set the serviceName to be "compute.googleapis.com", the problem went away and I received a 200 status code indicating success.

Resources