Scripts querying Toggl and applying certain custom rules on Praqma's workspace
Read more about the project seed provided by `stdlib` [here](stdlib.md)
The document on the Design Decisions can be found [here](docs/design-and-usage-decisions.md).
Have a look at our [Roadmap](docs/design-and-usage-decisions.md#roadmap) too!
## StdLib - function as service
This is what a REST API endpoint looks that will trigger the function execution:
1. `toggl-bot` defines the service name
1. `@dev` will use the code deployed to the development environment. In production it references the version number, like `@1.3.0`
1. `mail_invoices` is the name of the function we want to call
1. Any URL parameter is appended to the URL, like `.../mail_invoices/?user=epe&name=eddie`
|0.3.0|Added feat. to auto-join people to the toggl channel.|
|0.4.0|Added feat. to PM people who did not log time the day before|
|0.4.1|Fixed a bug in dailyCheckup [#70](https://github.com/Praqma/toggl-rules/issues/70)|
|0.5.0|Added function notifying about missing task descriptions. <br> Improved security with token based authentication.|
|0.5.1|Added more details to messages on missing task descriptions|
|0.5.2|Fixed bug that would cause posting in the testing channel|
## Functions in Service
### 1. Daily Checkup
This function fetches all time entries for the day before and runs a check on them to see if they have a task and project properely assigned. The users who did not enter their time registration correctly will be mentioned the next morning in a Slack post in the timelogging channel. Later the day, an evening check will follow up to make sure people fixed thier registrations.
- [x] No time entry without a Praqma client -> post to Slack
- [x] No time entry without a task -> post to Slack
- [x] Users are invited if not a member of the channel
- [ ] No project without client -> notify project manager
Using the stdlib web interface we can set Scheduled Tasks that will trigger our functions periodically. This function is set to execute every weekday morning at 9am local time. Scheduled Tasks' settings can be found [here](https://dashboard.stdlib.com/dashboard/#/tasks).
#### Scheduling Tasks
When a function is released into production (see the release steps below) it can be set to trigger periodically in the visual scheduler of stdlib. This is a manual step each time a new version is released.
- Log in with your credentials and navigate to the [StdLib Dashboard](https://dashboard.stdlib.com/dashboard)
- Create a new scheduled task:
![Deployment step 1](docs/deployment-step1.png)
- Task configuration
![Deployment step 2](docs/deployment-step2.png)
1. Choose a name. E.g. Morning Check / Evening Reminder
1. Prefer the most recent version.
1. The function `daily_checkup` should be triggered in the daily checks.
1. To schedule a morning checkup choose `false`. If you are setting up an evening reminder, pick `true`.
1. Set the schedule. Note that times are in UTC (+1), so for a reminder at 9AM pick 8AM instead.
1. Verify your schedule will perform at the time when you expect it.
1. Save the setting.
- Repeat the above steps for setting up a second reminder (e.g evening check).
- When you created new ones, delete the already existing scheduled tasks, so they won't be duplicate.
The channel field can be left blank and will default to our `toggl-plz-fix` channel. Change it if you want to post to a different channel.
#### Inviting users
Users that are not members of the `toggl-plz-fix` channel will automatically be joined if their name is mentioned.
Since invitation to channels cannot be done with a bot token, we will use a user's token which has the required access to the API. A Slack user called `Bot User` was set up with the email `firstname.lastname@example.org` who is a contributor to our Toggl-Bot Slack app. Thus we can use its access token to join people to channels.
### 2. Mail Invoices (aka Invoice Lines)
See issue [#48](https://github.com/Praqma/toggl-rules/issues/48) on the invoice report and #57 on the email setup
This program generates the invoices for the current month as a CSV file. When triggered it will send this file to **email@example.com**.
Initially, it was proposed to use a template slack application provided by *stdlib* to hook up to our slash commands. This application would authenticate itself when installing it to the workspace using the provided credentials. Thus the exposed APIs would only be accessible for our application. However, due to an error with the authentication, this solution was not implemented.
**Solution**: We ended up publicly exposing an API endpoint (also using *stdlib*) which when called will trigger the function sending the email. This endpoint then could be directly attached to the slash command. Even writing a response back to the user.
#### Slash comands
The API endpoint for the *Mail Invoices* function is attached to a slash command and can be triggered from Praqma's Slack workspace. Typing `/invoices` will run the program and deliver the invoice report to the right person's inbox.
![Slash command exmaple](docs/slash-command-example.png)
In the settings we can configure the command.
![Slash command settings](docs/slash-command-setting.png)
You can read about the template app and how to build a Slack bot with slash commands [here](https://medium.com/slack-developer-blog/build-a-serverless-slack-bot-in-9-minutes-with-node-js-and-stdlib-b993cfa15358).
See issue [#62](https://github.com/Praqma/toggl-rules/issues/62) on security
This function is not protected with OATH nor other forms of authentication, as the API endpoint is publicly exposed. Since the report can only be sent to the hard-coded address, this publicly available function call is not a security concern. In the worst case someone can spam a little our inboxes. But only a bit as unauthenticated calls from outside stdlib have been set a limit of 100 requests per hour. Our services run being authenticated to the platform.
### 3. Comments (Projects requiring task description)
See issue [#32](https://github.com/Praqma/toggl-rules/issues/32)
If users forget to add a description to their Toggl time entry, this program will check that for the day before and notify them on Slack so they can add it. It is a scheduled task on StdLib that will run every weekday at 3pm. A filter is defined in the configuration that will allow for certain projects/clients to not require a description. This function also joins users that are not members of the channel.
### 4. Daily Logs PM
See issue [#67](https://github.com/Praqma/toggl-rules/issues/67)
When a user did not log any time the previous working day Toggl-Bot will notify them about it in a PM (private message).
All of our functions except the **invoice lines** are protected with token based authentication by StdLib and can only be access with Praqma's library token found on StdLib. When a function is scheduled for execution it is triggered directly by the Praqma account and the token is automatically passed on.
Authentication over HTTP happens via POST requests. Add an `Authentication` header to the request with the value `Bearer <token>`. You can find the token under `authorizationToken` in the [toggl-rules-configuration](https://github.com/Praqma/toggl-rules-configuration/blob/f1f70585deddda8455a79b2780a6d4d46651a19a/credentials.json).
Slash commands in Slack use GET requests to perform an action. Therefore, we need to leave the **invoice_lines** function unprotected as Slack cannot perform POST requests at the moment. We will look into other forms of authentication for the
**invoice_lines** in the future.
Read more about [Authenticating your StdLib microservices](http://docs.stdlib.com/main/#/calling-services/authentication)
Learn more: [Separate the what from the how](docs/design-and-usage-decisions.md#separate-the-what-from-the-how). See also issue [#53](https://github.com/Praqma/toggl-rules/issues/53).
We use token based authentication for our bot interactions with Slack and Toggl.
A private repo is imported as submodule under `/toggl-rules-configuration` which contains all credentials and configuration.
The *Daily Checkup* function uses a token provided by Toggl to query the time registrations from their API. Can be found in `credentials.json > toggl.autorizationToken`. The token belonging to the bot created in the web interface of Slack will be used to authenticate messages to our channels. See in `credentials.json > slackBot.apiToken`
### Getting a running project on your computer
1. Since this repo contains a submodule, clone it with the `recursive` flag.
`git clone --recursive <this-repo>`
1. Install project dependencies - inside the project run the command:
If you are not from Praqma and do not have access to the private submodule containing the credentials, go over to our [Contributions Guidelines](CONTRIBUTING.md)
### Deploying the changes
This project is deployed to `StdLib.com`, a funcion as service platform becoming popular after Amazons's Lambda service.
First make sure you have the npm package `lib` installed globally
sudo npm install -g lib
#### Running the function locally
To test the `daily_checkup` function, run this command in your terminal in the root of your project:
If the execution was successful it will return the following message potentially with some logs on top
"message": "Message delivered to Slack channel."
#### Deploying for testing in the cloud
lib up dev
#### Releasing a production version
- First, up the version number in `package.json`
- Publish to stdlib with the command:
$ lib logs praqma.toggl-bot # shows all logs, all envs + fns
$ lib logs praqma.toggl-bot[@dev] # main fn logs
$ lib logs praqma.toggl-bot[@dev].start # start logs
$ lib logs praqma.toggl-bot[@dev].shutdown # shutdown logs
$ lib logs praqma.toggl-bot[@dev]* # all dev fn logs