
7 changed files with 193 additions and 77 deletions
-
86README.md
-
73docs/POSTFIX.md
-
34docs/SCHEDULING.md
-
14docs/issue-bot.service
-
29docs/issue-bot.timer
-
16src/cron.rs
-
18src/main.rs
@ -0,0 +1,73 @@ |
|||
# issue-bot with postfix |
|||
|
|||
Setup your mail server to deliver mail with destination `{local_part}+tags@{domain}` to this binary. Simply call the binary and write the email in UTF-8 in the binary's standard input. |
|||
|
|||
On postfix this can be done by creating a transport map and a pipe. A transport map is a file that tells postfix to send mails send to `{local_part}` to a specific program. The pipe will be this program. |
|||
|
|||
**BEWARE**: If `issue-bot` needs to read its configuration file and database file paths from environment variables, create a wrapper script and call that from postfix instead of going through the complicated trouble of setting up the exported environment (see postfix manual pages `master(t)` and `pipe(8)`) |
|||
|
|||
```shell |
|||
/bin/sh |
|||
|
|||
export ISSUE_BOT_CONFIG=_ |
|||
export ISSUE_BOT_DB=_ |
|||
/path/to/issue-bot |
|||
``` |
|||
|
|||
Open `master.cf` and paste this line at the bottom: |
|||
|
|||
```text |
|||
issue_bot unix - n n - - pipe |
|||
user=issuebot directory=/path/to/binarydir/ argv=/path/to/binary |
|||
``` |
|||
|
|||
an example: |
|||
|
|||
```text |
|||
issue_bot unix - n n - - pipe |
|||
user=issuebot directory=/home/issuebot/ argv=/home/issuebot/issue-bot |
|||
``` |
|||
|
|||
Then create your transport map: |
|||
|
|||
```text |
|||
{local_part}@{domain} issue_bot: |
|||
``` |
|||
|
|||
Notice the colon at the end. This means that it refers to a transfer, not an address. Save the file somewhere (eg `/etc/postfix/issue_transport`) and make it readable by postfix. Issue `postmap /etcpostfix/issue_transport`. Finally add the entry `hash:/etc/postfix/issue_transport` in your `transport_maps` and `local_recipient_maps` keys in `main.cf`. `postfix reload` to load the configuration changes. |
|||
|
|||
You will also need the following setting to allow tags in your recipient addresses: |
|||
|
|||
```text |
|||
recipient_delimiter = + |
|||
``` |
|||
|
|||
Setup a periodic check in your preferred task scheduler to run `issue_bot_bin cron` in order to fetch replies to issues. On systemd this can be done with timers. |
|||
|
|||
|
|||
### Troubleshooting |
|||
If you your email stops working or postfix doesn't pass mail to the bot, make sure you're not using a non-default setup like virtual mailboxes. In that case you have to add the transport along with the transports of your setup, whatever that be. |
|||
|
|||
If the e-mail gets to the binary and nothing happens, make sure: |
|||
|
|||
- the binary is executable and readable by the pipe's user |
|||
- the configuration file is in the same directory as the binary |
|||
- that in `master.cf` there are no `flags=` in the transport entry. The mail must be piped unaltered. |
|||
- your auth token works. You can check yourself by issuing requests to your API via cURL. There are examples here: https://docs.gitea.io/en-us/api-usage/ |
|||
|
|||
If commands (using +reply, +close etc) don't work, make sure you have added `recipient_delimiter = +` in your `main.cf` file. |
|||
|
|||
The bot's state is saved in a sqlite3 database in the same directory as the binary. You can view its data by using the `sqlite3` cli tool: |
|||
|
|||
```shell |
|||
root# sqlite3 /home/issuebot/sqlite3.db |
|||
SQLite version ****** ********** ******** |
|||
Enter ".help" for usage hints. |
|||
sqlite> .tables |
|||
issue |
|||
sqlite> select * from issue; |
|||
1|Name <add@res.tld>|1F:|2019-09-29T12:20:21.658495173Z|0|1|issue title|"2019-09-29T15:20:21+03:00" |
|||
2|Name <add@res.tld>|{^D0u|2019-09-29T12:23:48.291970808Z|0|1|issue title#2|"2019-09-29T15:23:48+03:00" |
|||
3|Name <add@res.tld>|Gd)i]|2019-09-29T12:24:31.414792595Z|0|1|issue title again|"2019-09-29T15:26:53+03:00" |
|||
4|Name <add@res.tld>|$3fBוv|2019-09-29T12:28:21.187425505Z|1|1|many issues|"2019-09-29T15:28:21+03:00" |
|||
``` |
@ -0,0 +1,34 @@ |
|||
# issue-bot scheduled jobs |
|||
|
|||
You can set up scheduled jobs by configuring `crontab` to run `issue-bot cron` whenever you want. For the more complicated but more reliable systemd setup, two example files are included in this directory: a service unit file and a timer unit file. The service unit executes once, and the timer unit is responsible for calling the service at the intervals you set. |
|||
|
|||
Copy the example files somewhere else and edit them with your own values. |
|||
|
|||
You can put `dry_run = true` in the config file to check it works without making changes or sending any mail. Also, backup your database if needed. |
|||
|
|||
```shell |
|||
systemctl --user enable issue-bot.service |
|||
``` |
|||
|
|||
You can do a test run with |
|||
|
|||
```shell |
|||
systemctl --user start issue-bot.service |
|||
``` |
|||
|
|||
Now you enable/activate the timer. |
|||
|
|||
```shell |
|||
systemctl --user enable issue-bot.timer |
|||
``` |
|||
|
|||
```shell |
|||
systemctl --user start issue-bot.timer |
|||
``` |
|||
|
|||
|
|||
Monitor the service status: |
|||
|
|||
```shell |
|||
systemctl --user status issue-bot |
|||
``` |
@ -0,0 +1,14 @@ |
|||
[Unit] |
|||
Description=issue-bot cron |
|||
RefuseManualStart=no # Allow manual starts |
|||
RefuseManualStop=no # Allow manual stops |
|||
|
|||
[Service] |
|||
Type=simple |
|||
ExecStart=/path/to/issue-bot cron |
|||
Environment=ISSUE_BOT_CONFIG=/a/b/c/d.toml |
|||
Environment=ISSUE_BOT_DB=/a/b/c/sqlite3.db |
|||
|
|||
|
|||
[Install] |
|||
WantedBy=default.target |
@ -0,0 +1,29 @@ |
|||
[Unit] |
|||
Description=issue-bot crons |
|||
RefuseManualStart=no # Allow manual starts |
|||
RefuseManualStop=no # Allow manual stops |
|||
|
|||
[Timer] |
|||
#Execute job if it missed a run due to machine being off |
|||
Persistent=true |
|||
#Run 120 seconds after boot for the first time |
|||
OnBootSec=120 |
|||
#Run every 5 minutes thereafter |
|||
OnUnitActiveSec=300 |
|||
#File describing job to execute |
|||
Unit=issue-bot.service |
|||
|
|||
|
|||
## more complicated examples: |
|||
# # run on the minute of every minute every hour of every day |
|||
# OnCalendar=*-*-* *:*:00 |
|||
# # run on the hour of every hour of every day |
|||
# OnCalendar=*-*-* *:00:00 |
|||
# # run every day |
|||
# OnCalendar=*-*-* 00:00:00 |
|||
# # run 11:12:13 of the first or fifth day of any month of the year |
|||
# # 2012, but only if that day is a Thursday or Friday |
|||
# OnCalendar=Thu,Fri 2012-*-1,5 11:12:13 |
|||
|
|||
[Install] |
|||
WantedBy=timers.target |
Write
Preview
Loading…
Cancel
Save
Reference in new issue