Merge pull request #22 from matbgn/master

Add possibility to specify user via mail subject "u-" + Add basic Docker implementation
pull/25/head
Lucian Pricop 2022-05-11 14:01:12 +03:00 zatwierdzone przez GitHub
commit 1f1973fd7f
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
10 zmienionych plików z 160 dodań i 7 usunięć

13
.dockerignore 100644
Wyświetl plik

@ -0,0 +1,13 @@
# Ignore everything
**
# Allow files and directories
!lib/
!docker-utils/
!composer*
!config*
!index.php
# Ignore unnecessary files inside allowed directories
# This should go after the allowed directories
docker-utils/test_mail.php

48
Dockerfile 100644
Wyświetl plik

@ -0,0 +1,48 @@
FROM php:alpine3.15 AS builder
# Install all dependencies required for API calls and mail handling
RUN apk add --no-cache git php-curl php-mbstring php-imap php-xml ssmtp gawk
# Install PHP ext-imap
RUN set -eux; \
persistentDeps=" \
c-client \
"; \
buildDeps=" \
imap-dev \
krb5-dev \
openssl-dev \
"; \
apk add --no-cache --virtual .imap-persistent-deps ${persistentDeps}; \
apk add --no-cache --virtual .imap-build-deps ${buildDeps}; \
\
docker-php-ext-configure imap \
--with-imap-ssl \
--with-kerberos \
; \
docker-php-ext-install -j$(nproc) imap; \
\
apk del --no-cache --no-network .imap-build-deps
# Create a non-root user to own the files and run our server
RUN adduser -D -g "Mail2deck" deckbot
WORKDIR /home/deckbot/mail2deck
# Copy scripts
# Use the .dockerignore file to control what ends up inside the image!
COPY . .
# Install dependencies
RUN docker-utils/install_composer.sh && \
./composer.phar update && \
rm docker-utils/install_composer.sh composer.phar
# Setup SMTP Server
RUN docker-utils/configure_smtp.sh && \
rm docker-utils/configure_smtp.sh
# Use our non-root user
USER deckbot
# Run script once
CMD ["php", "index.php"]

Wyświetl plik

@ -34,6 +34,16 @@ Note:
* Email content will be card description
* You can add attachments in the email and those will be integrated in the created card
### 2.3: Specify assignee
Here's how the email subject should look like:
`Update website logo b-'website' s-'to do' u-'bob'`
* *You can use single or double quotes.*
* *Case-insensitive for board, stack and user respectively.*
# ⚙️ B. For NextCloud admins to setup
## Requirements
This app requires php-curl, php-mbstring ,php-imap and some sort of imap server (e.g. Postfix with Courier).
@ -50,6 +60,7 @@ sudo postconf -e "recipient_delimiter = +"
This could be any hosted email service. The only requirement is that you can connect to it via the IMAP protocol.
*Please note this option may not be as flexible as a self-hosted server. For example your email service may not support the "+"delimiter for directing messages to a specific board.*
## Download and install
### Bare-metal installation
If using a self-hosted Postfix server, clone this repository into the home directory of the *incoming* user. If not self-hosting, you may need to create a new user on your system and adjust the commands in future steps to match that username.<br>
```
su - incoming
@ -62,12 +73,41 @@ cp config.example.php config.php
sudo vim config.php
```
*You can refer to https://www.php.net/manual/en/function.imap-open.php for setting the value of MAIL_SERVER_FLAGS*
## Add a cronjob which will run mail2deck.
#### Add a cronjob which will run mail2deck.
```
sudo crontab -u incoming -e
```
Add the following line in the opened file:
<code>*/5 * * * * /usr/bin/php /home/incoming/mail2deck/index.php >/dev/null 2>&1</code>
### Docker installation
Clone and edit the config.example.php you find in this repository and move it as config.php
```
git clone https://github.com/newroco/mail2deck.git mail2deck
cd mail2deck
cp config.example.php config.php
nano config.php
```
Build your image locally
```
docker build -t mail2deck:latest .
```
Run the docker image mapping the config.json as volume
```
docker run -d --name mail2deck mail2deck:latest
```
Edit your crontab
```
crontab -e
```
And add this line
```
*/5 * * * * /usr/bin/docker start mail2deck
```
## Finish
Now __mail2deck__ will add new cards every five minutes if new emails are received.

2
composer.lock wygenerowano
Wyświetl plik

@ -104,5 +104,5 @@
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.1.0"
"plugin-api-version": "2.3.0"
}

Wyświetl plik

@ -5,6 +5,7 @@ define("NC_PASSWORD", "****");
define("MAIL_SERVER", "localhost"); // server.domain
define("MAIL_SERVER_FLAGS", "/novalidate-cert"); // flags needed to connect to server. Refer to https://www.php.net/manual/en/function.imap-open.php for a list of valid flags.
define("MAIL_SERVER_PORT", "143");
define("MAIL_SERVER_SMTPPORT", "587"); // port for outgoing smtp server. Actually only used to configure Docker image outgoing SMTP Server
define("MAIL_USER", "incoming");
define("MAIL_PASSWORD", "****");
define("DECODE_SPECIAL_CHARACTERS", true); //requires mbstring, if false special characters (like öäüß) won't be displayed correctly

Wyświetl plik

@ -0,0 +1,14 @@
#!/bin/sh
CONFIG_FILE_PATH="config.php"
cat > /etc/ssmtp/ssmtp.conf <<EOM
root=postmaster
mailhub=$(cat "$CONFIG_FILE_PATH" | gawk 'match($0, /"MAIL_SERVER".{3}(.+)"/,a) {print a[1]}'):$(cat "$CONFIG_FILE_PATH" | gawk 'match($0, /"MAIL_SERVER_SMTPPORT".{3}(.+)"/,a) {print a[1]}')
FromLineOverride=NO
rewriteDomain=$(cat "$CONFIG_FILE_PATH" | gawk 'match($0, /"MAIL_USER".+@(.+)"/,a) {print a[1]}')
hostname=$(cat "$CONFIG_FILE_PATH" | gawk 'match($0, /"MAIL_USER".+@(.+)"/,a) {print a[1]}')
AuthUser=$(cat "$CONFIG_FILE_PATH" | gawk 'match($0, /"MAIL_USER".{3}(.+)"/,a) {print a[1]}')
AuthPass=$(cat "$CONFIG_FILE_PATH" | gawk 'match($0, /"MAIL_PASSWORD".{3}(.+)"/,a) {print a[1]}')
UseSTARTTLS=YES
EOM

Wyświetl plik

@ -0,0 +1,17 @@
#!/bin/sh
EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]
then
>&2 echo 'ERROR: Invalid installer checksum'
rm composer-setup.php
exit 1
fi
php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php
exit $RESULT

Wyświetl plik

@ -0,0 +1,13 @@
<?php
// Run it as > php docker-utils/test_mail.php test@example.com
$to = $argv[1];
$subject = 'An issue has been reported!';
$message = '<html><head><title>Mail2Deck response</title></head><body><h1>You created a new issue on board XXXXX.</h1><p>Check out this <a href="https://example.com/">link</a> to see your newly created card.</p></body></html>';
$headers = array(
'From' => 'no-reply@example.com',
'MIME-Version' => '1.0',
'Content-Type' => 'text/html'
);
mail($to, $subject, $message, $headers);

Wyświetl plik

@ -102,13 +102,13 @@ if ($emails)
$newcard = new DeckClass();
$response = $newcard->addCard($data, $mailSender, $board);
$mailSender->userId .= "@{$overview->reply_to[0]->host}";
$mailSender->origin .= "{$overview->reply_to[0]->mailbox}@{$overview->reply_to[0]->host}";
if(MAIL_NOTIFICATION) {
if($response) {
$inbox->reply($mailSender->userId, $response);
$inbox->reply($mailSender->origin, $response);
} else {
$inbox->reply($mailSender->userId);
$inbox->reply($mailSender->origin);
}
}
if(!$response) {

Wyświetl plik

@ -45,6 +45,10 @@ class DeckClass {
$stackFromMail = $m[1];
$params = str_replace($m[0], '', $params);
}
if(preg_match('/u-"([^"]+)"/', $params, $m) || preg_match("/u-'([^']+)'/", $params, $m)) {
$userFromMail = $m[1];
$params = str_replace($m[0], '', $params);
}
$boards = $this->apiCall("GET", NC_SERVER . "/index.php/apps/deck/api/v1.0/boards");
$boardId = $boardName = null;
@ -76,6 +80,7 @@ class DeckClass {
$boardStack->stack = $stackId;
$boardStack->newTitle = $params;
$boardStack->boardTitle = $boardName;
$boardStack->userId = $userFromMail;
return $boardStack;
}
@ -88,9 +93,11 @@ class DeckClass {
$card = $this->apiCall("POST", NC_SERVER . "/index.php/apps/deck/api/v1.0/boards/{$params->board}/stacks/{$params->stack}/cards", $data);
$card->board = $params->board;
$card->stack = $params->stack;
if ($params->userId) $user->userId = $params->userId;
if($this->responseCode == 200) {
if(ASSIGN_SENDER) $this->assignUser($card, $user);
if(ASSIGN_SENDER || $params->userId) $this->assignUser($card, $user);
if($data->attachments) $this->addAttachments($card, $data->attachments);
$card->boardTitle = $params->boardTitle;
} else {