# Flack
*Integrate slack commands and actions with flask*
![Python Package](https://github.com/carlskeide/flack/workflows/Python%20package/badge.svg)
## Setup
Either initialize the app immediately:
```
from flack import Flack
flack = Flack(app)
```
Or use a deferred initialization:
```
from flack import Flack
flack = Flack()
def get_app():
# Create your flask application.
flack.init_app(app)
```
### Configuration
- `FLACK_TOKEN` Must match the secret generated by Slack when creation your app or integration, will be verified for every request.
- `FLACK_URL_PREFIX` URL namespace for the built-in api endpoints.
- `FLACK_DEFAULT_NAME` Used for any response whera as_user is not explicitly set.
## Slack event handlers
### Triggers
*API Endpoint: `/webhook`*
The most basic type of interations, webhooks invoked by trigger words in a channel.
```
@flack.trigger("!heart", as_user="Cupid")
def heart(text, user):
return "{} :heart: {}".format(user.name, text)
````
Provides:
- `text` Any message after (but not including) the trigger word, may be an empty string.
- `user` The calling user, see: `flack.CALLER`.
### Commmand
*API Endpoint: `/command`*
Slash-commands, may respond to the user privately or interact with the channel in which it was executed.
```
@flack.command("/weather")
def weather(text, user, channel):
return "The weather in {} is currently: {}".format(text, get_weather(text))
````
Provides:
- `text` Any message after the trigger word, may be an empty string.
- `user` The calling user, see: `flack.CALLER`.
- `channel` The active channel or conversation, see: `flack.CHANNEL`.
### Action
*API Endpoint: `/action`*
Action buttons included in advanced messages (see: `flack.message.Action`).
```
@flack.action("remind")
def remind(value, ts, instance, user, channel):
remind_user(user)
````
Provides:
- `value` Generally the same as the action name.
- `ts`: The timestamp of the originating message, used for modifying it through the API.
- `callback`: The Callback ID of the originating message attachment, see: `flack.message.Attachment`
- `user` The interacting user, see: `flack.CALLER`.
- `channel` The originating channel, see: `flack.CHANNEL`.
## Responding
TODO: Document `flack.message` objects
## OAuth
While not necessary for basic usage, Flack has support for registering an OAuth application.
### Configuration
- `FLACK_CLIENT_ID` Provided by Slack when creating an app.
- `FLACK_CLIENT_SECRET` Provided by Slack when creating an app.
- `FLACK_SCOPE` Slack API scope to request (default is `commands,users:read,channels:read,chat:write:bot`).
### Usage
Generate the Slack button HTML snippet and expose it to the client wherever you like with `flack.oauth.render_button()`
Then create a view that can receive the generated credentials from Slack. Make sure the url matches what you provided as the "Redirect URL" when creating the Slack app.
```
import flack.oauth
@app.route('/callback')
@flack.oauth.callback
def callback(credentials):
# Make sure to store the credentials somewhere safe.
your_datastore.write({
"team": credentials.team_id,
"token": credentials.access_token,
"scope": credentials.scope
})
# And make sure to inform the client everything went fine
return "It worked!"
```
The credentials object is a namedtuple containing team_id, access_token, and scope.