How to use Slack Incoming Webhooks to send a message to a direct user (from the bot, not through the app creator private channel to that user)? - slack

My username is "Charlie", and I'm the admin of a Slack environtment.
I create my incoming webhook following the steps:
https://api.slack.com/messaging/webhooks
And I create a bot called "Bot" with all the "write" scopes.
Then, I add a Webhook URL to be able to send direct messages to username "Peter".
When I use the typical curl method to send a test:
curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/xxxxxxxxxxx/xxxxxxxxxxx/xxxxxxxxxxxxxxx
Peter receives a message from Bot ... that's ok !!
But I see in my private messages with Peter that notification also.
That's to say, it's like Bot has written to Peter as me ... in my private channel with Peter.
What I want is Bot to write DIRECTLY to Peter, not in my private channel with that person.
Thank you!

Unfortunately, incoming webhooks won't be able to post a DM to a user on behalf of the bot. This type of functionality requires additional permissions and therefore can only be accomplished using a Slack WebAPI methods via a bot token.
To post a DM to a user with a Slack API app you will have to:
Add a bot user to your app. The bot token will appear in your OAuth and Permissions page after you install the app.
Make a call to the chat.postMessage api method and pass the id for the channel/conversation your want to post to. https://api.slack.com/methods/chat.postMessage
To get a list of all channel and conversations in your workspace including DMs make a call to conversations.list https://api.slack.com/methods/conversations.list
To open a DM with a user you can call conversations.open https://api.slack.com/methods/conversations.open

Related

How to use Google Oauth2.0 to authenticate user via Telegram Bot

This is my first time interacting with Google API and I'm using python3.9 with this library Python Telegram Bot
I want to access a user Google API Calendar via a telegram bot and I can't seem to find any article to guide me through it. My key problem (I think) is redirecting the success authorization flow back to telegram bot.
This is what I have in mind:
In the telegram app, user send '/send' to bot
Bot receive message and return a google an authorization link to user
User clink on authorization link and allow access
Bot receive authorization access and completes the Oauth flow
The problem lies betweeen step 3 and 4. A standard authorization link is
https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=<clientid>&redirect_uri=<redirect_uri>&scope=<scope>&state<state>&access_type=offline
How do I send the authorization link back to my telegram bot? Should I create another API endpoint to receive that authorization link? Or can I send telegram api send_message() in the <redirect_uri> to redirect the success message to my bot.
Update 1
Thanks to CallMeStag, I manage to figure out a way to complete the oauth process. For people who faced the same problem, this is what I did
Pre-requisite: Credentials is created in google console api - Web application. redirect_uri set as localhost:8000 (During development phase)
User send '/send' to bot
Bot receive message and return an authorization link https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=<clientid>&redirect_uri=http://localhost:8000/&scope=<scope>&state<state>&access_type=offline
User click on link to authenticate and it will redirect to http://localhost:8000. Used fastapi as a webhook to receive the message. Capture the authorization code, use google.oauthlib.flow to complete the authorization process. Next, redirect user back to telegram link https://t.me/<botname>
Start using user google calendar
It's currently indeed not very straight forward for a PTB-application to listen for external updates (the auth verification in this cas) - see also this issue. Currently it might be easiest for you to set up a custom webhook application that runs in parallel to the Updater - e.g. using flask/django/starlette/fastapi/…. Alternatively, if you're using webhooks for your bot anyway, you can patch the Updater to do the job for you. Although that requires some manual work - see here for an example.
Once you are able to listen to updates coming from Google, handling them can be done via PTBs usual handler setup, specifically via the TypeHandler or even a custom Handler subclass - see this FAQ entry.
Regarding the redirect url: You'll want to redirect your user back to your bot, so you'll have to provide a link that does that. Bot.link should probably do the trick.
Disclaimer: I'm currently the maintainer of python-telegram-bot.

Can a slack bot join automatically a channel?

I am building a slack application.
I added "incoming-webhook" to oauth scopes that let me choose the channel I want the App to post messages. However unless I ping the app in the channel to add it. I get a "channel not found" error.
Is it possible to add the app to a channel when installing app via oauth ? Without adding it manually by #app-name or /invite app-name ?
When you add an incoming-webhookscope to your app, the option to add a channel during authentication is specific to incoming webhooks not bot messages. So any messages you send via the incoming webhook will send to the channel you selected during authentication. Messages sent via [chat.postMessage][1] will require your bot to be a member of the destination channel, via invite. Incoming webhooks can only be linked to a single channel. You will have to create a new webhook for every channel you want to post to using webhooks. For that reason, I'd recommend using chat.postMessage instead. If you request the chat:write.public scope your bot will be able to post into any public channel without invitation.

How to message a user in a slack App via API?

When creating a slack app, it creates a new "channel" in the left hand menu. I want to be able to send a message to specific users and not to all users in a workspace who have integrated with the app.
For example, if I make the following request:
curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/ABxxx/CDxxx/EFxxxxxx
It will send a message to all users who have integrated with my app with the text "Hello World".
But I only want to send a message to user A without User B being notified.
I don't want to message a user directly and it to appear to come from slack bot. I want the message to appear to come from my bot / app.
How can this be achieved via slack API?
I found this quite hard to explain so please let me know if you'd like me to clarify anything.
The problem of your request that you are using a hook URL which is bound to a particular channel (you pick it during Slack App installation).
To send a direct message to the user on behalf of your bot, you need to consider the following things (this is not the single way to achieve it, but works for me):
Ensure you have a bot registered for your Slack App.
Ask for bot and chat:write:bot permissions during App installation process (example for Slack Install button and here).
Store the bot access token on successful installation (see for details).
Now using the bot access token you can send Slack API requests.
To achieve what you need, use chat.postMessage API method. channel argument can be user ID (e.g. U0G9QF9C6). By setting up as_user argument to true, your message will be always sent on behalf (name and icon) of your bot (seems for bot tokens it's always like this, but it's recommend it to specify it explicitly).
Hope it helps. Feel free to ask for details.

Slack Events API not working for normal users

I'm using slack api to send reply whenever there is any direct message to authenticated user. So I created app, enabled events api and verified webhook url and subscribed to messages.im event
I use regular oauth flow with scope(chat:write:user,users:read) to get the access token.
First I tried with the admin of the workspace and everything worked fine. Whenever there is a direct message between admin user and any other user, i'm receiving events to my callback.
NOW
when I tried same with normal user(user2) i'm not receiving any events back when there is direct message between user2 and some other user. I followed the same steps above.
User2 went through same oauth flow with same scopes and got the access token of his own. As I subscribed to events api, I should be able to received event callbacks to the url I mentioned.
Is there any issue here? Is this not how things work?
This is not supposed to work.
Your Slack app will only receive message events from channels / conversations, which the installing user is a member of (e.g. the admin is member of the direct messaging conversation between him and others). But it's not possible to get direct messages between other users.
This is how Slack's security architecture is designed. In general it is not possible for any Slack app to monitor all private and direct messaging channel, even if the installing use is an admin / owner.
A common workaround for private channels is to retrieve messages for a bot user and make sure that bot user is a member of all private channels you need to monitor. However, this workaround is not very practical for direct message conversations.
Turns out it is an issue with scopes, following is the message I received from slack support team, they are awesome.
Hi Sasikanth,
Thanks for getting back to me. I took a look and it seems that there was some change with the scopes requested when user2 installed the "My App Name" app.
Here are the scopes that each of these users received upon installing the "My App Name":
user1: im:history,users:read,chat:write:user
user2: users:read,chat:write:user
You'll notice that user 1 above has the im:history scope, whereas user 2 above does not. It's mentioned on the doc for the message.im event type (https://api.slack.com/events/message.im) that the im:history scope is needed.
That's the reason why you're not receiving the message.im event type for DMs sent to user 2.
I hope that helps to explain the issue. What you'll need to do is remove the authorization for user2 from: (my dev app url) and have that user reinstall the app with the appropriate scopes.

Getting Slack user email address for AWS Lex bot

I am creating a bot in aws-lex and will integrate it with Slack, FB Workplace and Yammer to start with.
I need to read the Slack user email address, then validate that against our webservice to ensure the user is registered. This will return some data about the users organisation that I need for further execution in lex.
I have no idea how to pass/extract the Slack user email (the one that is engaging in conversation with my Bot).
Any ideas?? Examples please! New to bot dev.
At least for slack you could do:
Under requestAttributes (from event) you can check the presence of x-amz-lex:channel-type. The value will be Slack if the user comes from slack.
You can then extract the user slack id from the event that is submitted to your lambda under the key userId
With that id, go to Slack API and call the method users.info. Now you can get the user email from the response.

Resources