Create a task automatically

at the moment i’m in the process of testing different software product to help my team with task management.
One thing that is forgotten are tasks that need to be done on a regular basis with different servers. Like check logs for errors and if everything is ok delete the logs.
So i would like to automatic create a task on the first of every month to check the logs. So someone can take this task, complete it and push it in the done column.
Maybe i think in the wrong direction for this problem? What would be the best way to solve this? Or am i right and there is a way by a cronjob to create a task?

Something like this already exists, “Recurring Tasks”, just not based on dates, but instead, events.

Give it a read, and see if that’s what you’re looking for.

But to answer your questions:
Maybe i think in the wrong direction for this problem? No, your needs may be different than others needs, and that’s OK.

What would be the best way to solve this? Automatic Action, if the “Recurring Task” feature does not help you.

Or am i right and there is a way by a cronjob to create a task? Yeah, you could setup something like this with your own custom automatic action, using the EVENT_DAILY_CRONJOB.

Hi creecros. I’m not sure what Sphinx wanted, but what I need is a strictly temporally based recurrence. Something that clone task based on time, and independent of the stage of the last task clone. Something like a cron job would be fine, although I would prefer if it could be done within the website, otherwise only me (the admin) will be able to create such tasks. I want to use Kanboard to “organize my family”, so like 1/2 of the tasks would be “do this every Monday”.

So, could you be a bit more specific about how to go about doing this? I’m new to Kanboard, so I don’t really know where to start…

So, you would need to Create a Task every “Day you chose”?

Are you new to PHP?

I read a book about programming PHP, like 10 years ago (literally); didn’t look all to hard. I could probably manage with some help from Google. I normally code in Java and Python…

It really wouldn’t be that difficult, you might just need to look at a few examples to get the jist of it.

If you were to start a repo, on Github, I’d be willing to help. I just don’t want to DO IT for you, like, you need to try your best first ;p

Quick reference:

You’d be using TaskModel::EVENT_DAILY_CRONJOB in getCompatibleEvents()

I understand. I’ll have a look, but maybe first on the weekend. Will post back here if I get stuck. Bye!

Hi. I’ve started looking at the examples, but I’m currently confused about one thing (probably more to come). An event like “TaskModel::EVENT_MOVE_COLUMN” is clearly related to a specific task that is being acted upon, so it makes sense that the task data is in $data of doAction(). But if I only register for TaskModel::EVENT_DAILY_CRONJOB, then I would assume the action would be called once per day, per project(?). So will $data reference no task at all, or will doAction() be called once for every task in that project? If it’s the later case, I can restrict the selected tasks with hasRequiredCondition(), but the system would still go over potentially many tasks. So I assume I get no task at all, and have to select them myself. Searching in Google did not return any example using EVENT_DAILY_CRONJOB.

The event is just the trigger, and unrelated to the event data. If you use EVENT_MOVE_COLUMN, then it will trigger when a task is moved into a particular column, and if you choose EVENT_DAILY_CRONJOB it will run every time the cronjob runs, which you can choose how often that runs. But, both are only triggers and unrelated to the events data.

Take a look at this action:

The event data is defined bygetEventRequiredParameters() and by user input getActionRequiredParameters()

For creating a task, the only event data you will really need is the project id, so you can figure out where to create the task. You will however need a lot of user input data. If it’s day based time, you also need to figure out how to figure out what day it is and determine if the action should run, in the hasRequiredCondition(array $data).

Here are some helpful hints:
If you are doing this “Weekly”, you can create a dropdown list of days of the week in the getActionRequiredParameters() by simply adding an array in the description. i.e.

   'day_to_create_task' => array('Mon' => t('Monday'), 'Tue' => t('Tuesday'),etc...)`

Now in this instance, there is an array of arrays, so to clarify, the first part 'Mon' is the value saved and the value you will get when you grab that data later on, and the second part t('Monday') is what is displayed, the t() isn’t needed unless you plan to add translations.

You can then grab this user input, and compare to what day it actually is in the hasRequiredCondition(array $data), something like:

 return date('D') == $this->getParam('day_to_create_task');

For your do action, you’ll need to look at the taskCreationModel->create, and figure out what data you need to send to it, to effectively create a task.

Hi. After months of procrastinating, I got around to code this thing. I can see the plugin is loaded. I can see the log output in my debug.log. I can see the nginx cronjob that should trigger the EVENT_DAILY_CRONJOB is configured, and seems to work, as I see log output precisely at 08:00. But my action does not get triggered. The first thing it does, is “error_log(…)” which I cannot find in the logs. My action has no “requirements”, beyond the EVENT_DAILY_CRONJOB, so I don’t see why it is not triggered. I have done it somewhat differently than you suggested, but I think it should not affect the triggering behavior.

Could you have a look please?


Once I get it to trigger, than I can start the real debugging (I’ll eat a broom, if it otherwise works without changes).

Ya, give me some time to get to it. Its fathers day.

It’s triggering.

You can’t see your logs?

2019/06/16 17:51:53 [error] 14#14: *27 FastCGI sent in stderr: "PHP message: WeeklyRecurringTask.doAction() CALLED,
PHP message: PHP Fatal error:  Uncaught Error: Call to undefined method Kanboard\Plugin\WeeklyRecurringTasks\Action\WeeklyRecurringTask::projectModel() in /var/www/app/plugins/WeeklyRecurringTasks/Action/WeeklyRecurringTask.php:164,
#4 /var/www/app/app/Console/TaskTriggerCommand.php(" while reading response header from upstream, client:, server: localhost, request: "GET /cronjob?token=afadeae2830f5d602927e950a27fe8d9c4f779ac2d540f04db368ef86a88 HTTP/1.1", upstream: "fastcgi://unix:/var/run/php-fpm.sock:", host: "",
#3 /var/www/app/app/Console/TaskTriggerCommand.php(49): Symfony\Component\EventDispatcher\EventDispatcher->dispatch('task.cronjob.da...', Object(Kanboard\Event\TaskListEvent)),
#2 /var/www/app/vendor/symfony/event-dispatcher/EventDispatcher.php(44): Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(Array, 'task.cronjob.da...', Object(Kanboard\Event\TaskListEvent)),
#1 /var/www/app/vendor/symfony/event-dispatcher/EventDispatcher.php(212): Kanboard\Action\Base->execute(Object(Kanboard\Event\TaskListEvent), 'task.cronjob.da...', Object(Symfony\Component\EventDispatcher\EventDispatcher)),
#0 /var/www/app/app/Action/Base.php(269): Kanboard\Plugin\WeeklyRecurringTasks\Action\WeeklyRecurringTask->doAction(Array),
Stack trace:

remove the () after projectModel on line 164.

After that

2019/06/16 17:57:36 [error] 14#14: *39 FastCGI sent in stderr: "PHP message: WeeklyRecurringTask.doAction() CALLED,
PHP message: WeeklyRecurringTask.doAction() RETURNING 1" while reading response header from upstream, client:, server: localhost, request: "GET /cronjob?token=afadeae2830f5d602927e950a27fe8d9c4f779ac2d540f04db368ef86a88 HTTP/1.1", upstream: "fastcgi://unix:/var/run/php-fpm.sock:", host: "",
PHP message: PHP Warning:  Illegal string offset 'name' in /var/www/app/plugins/WeeklyRecurringTasks/Action/WeeklyRecurringTask.php on line 165,
PHP message: PHP Warning:  Illegal string offset 'id' in /var/www/app/plugins/WeeklyRecurringTasks/Action/WeeklyRecurringTask.php on line 166

Then, switch getListByStatus to getAllByStatus, getListByStatus, is a key/val hashtable, so there is no ['name'] or ['id'], the id would be the index and name would be the value if you used that.

Then you’re all set, no more errors.

Also, FYI, you could go this route: Kanboard and Zapier

Just use the Scheduler App instead of the Email parser, and then the duplicate task api method.


Firstly, thanks again for trying to help out.

This is strange; as I mentioned, I have now enabled debug logging to file:

cd /var/lib/docker/volumes/kanboard_kanboard_data/_data

wc -l debug.log

46106 debug.log

head debug.log

[2019-06-15 16:45:58] [debug] Kanboard\Core\Controller\Runner::executeMiddleware
[2019-06-15 16:45:58] [debug] Subscriber executed:

tail debug.log

[2019-06-17 16:14:34] [debug] SQL: query_duration=3.504753112793E-5
[2019-06-17 16:14:34] [debug] SQL: total_execution_time=0.0015981197357178

There are two full days of logs in there, so I expect the
And I can see my plugin as installed, in “Installed Plugins” in the Web-UI.

But if I do:

egrep -i WeeklyRecurringTask debug.log

I get nothing.

In the kanboard docker container, I can check the cronjob:

/ # crontab -u nginx -l
0 8 * * * cd /var/www/app && ./cli cronjob >/dev/null 2>&1

So it’s there. And I do see output at precisely 08:00. I tried sending
the output of the cronjob to a file, but it is left empty.

If I copy the cronjob, to run at 17:41 instead, then that is what I
see in the debug.log;
No sign of WeeklyRecurringTask anywhere:

[2019-06-17 17:41:00] [debug] Subscriber executed:
[2019-06-17 17:41:00] [debug] SQL: SELECT “option”, “value” FROM “settings”
[2019-06-17 17:41:00] [debug] SQL: query_duration=0.0011899471282959
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0011899471282959
[2019-06-17 17:41:00] [debug] SQL: SELECT * FROM “actions”
[2019-06-17 17:41:00] [debug] SQL: query_duration=7.3909759521484E-5
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0012638568878174
[2019-06-17 17:41:00] [debug] SQL: SELECT * FROM “action_has_params”
[2019-06-17 17:41:00] [debug] SQL: query_duration=4.3869018554688E-5
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0013077259063721
[2019-06-17 17:41:00] [debug] SQL: SELECT * FROM “projects” WHERE
“is_active” = ? ORDER BY “name” ASC
[2019-06-17 17:41:00] [debug] SQL: query_duration=0.00022697448730469
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0015347003936768
[2019-06-17 17:41:00] [debug] SQL: DELETE FROM
“project_daily_column_stats” WHERE “project_id” = ? AND “day” = ?
[2019-06-17 17:41:00] [debug] SQL: query_duration=0.00022196769714355
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0017566680908203
[2019-06-17 17:41:00] [debug] SQL: SELECT “column_id”, COUNT(*) AS
total FROM “tasks” WHERE “project_id” = ? AND “is_active” IN (?, ?)
GROUP BY “column_id”
[2019-06-17 17:41:00] [debug] SQL: query_duration=0.00011897087097168
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.001875638961792
[2019-06-17 17:41:00] [debug] SQL: SELECT “column_id”, SUM(score) AS
score FROM “tasks” WHERE “project_id” = ? AND “is_active” = ? AND
“score” IS NOT NULL GROUP BY “column_id”
[2019-06-17 17:41:00] [debug] SQL: query_duration=7.9154968261719E-5
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0019547939300537
[2019-06-17 17:41:00] [debug] SQL: INSERT INTO
“project_daily_column_stats” (“day”, “project_id”, “column_id”,
“total”, “score”) VALUES (:day, :project_id, :column_id, :total,
[2019-06-17 17:41:00] [debug] SQL: query_duration=4.9114227294922E-5
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0020039081573486
[2019-06-17 17:41:00] [debug] SQL: INSERT INTO
“project_daily_column_stats” (“day”, “project_id”, “column_id”,
“total”, “score”) VALUES (:day, :project_id, :column_id, :total,
[2019-06-17 17:41:00] [debug] SQL: query_duration=2.598762512207E-5
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0020298957824707
[2019-06-17 17:41:00] [debug] SQL: INSERT INTO
“project_daily_column_stats” (“day”, “project_id”, “column_id”,
“total”, “score”) VALUES (:day, :project_id, :column_id, :total,
[2019-06-17 17:41:00] [debug] SQL: query_duration=2.0980834960938E-5
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0020508766174316
[2019-06-17 17:41:00] [debug] SQL: SELECT “date_completed”,
“date_creation”, “date_started” FROM “tasks” WHERE “project_id” = ?
[2019-06-17 17:41:00] [debug] SQL: query_duration=7.6055526733398E-5
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.002126932144165
[2019-06-17 17:41:00] [debug] SQL: DELETE FROM “project_daily_stats”
WHERE “day” = ? AND “project_id” = ?
[2019-06-17 17:41:00] [debug] SQL: query_duration=0.00020599365234375
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0023329257965088
[2019-06-17 17:41:00] [debug] SQL: INSERT INTO “project_daily_stats”
(“day”, “project_id”, “avg_lead_time”, “avg_cycle_time”) VALUES (:day,
:project_id, :avg_lead_time, :avg_cycle_time)
[2019-06-17 17:41:00] [debug] SQL: query_duration=3.7908554077148E-5
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0023708343505859
[2019-06-17 17:41:00] [debug] SQL: SELECT, tasks.title,
tasks.date_due, tasks.project_id, tasks.creator_id, tasks.owner_id, AS project_name, users.username AS assignee_username, AS assignee_name FROM “tasks” LEFT JOIN “projects” ON
“projects”.“id”=“tasks”.“project_id” LEFT JOIN “users” ON
“users”.“id”=“tasks”.“owner_id” WHERE projects.is_active = ? AND
tasks.is_active = ? AND tasks.date_due != ? AND tasks.date_due <= ?
[2019-06-17 17:41:00] [debug] SQL: query_duration=0.00040507316589355
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0027759075164795
[2019-06-17 17:41:00] [debug] SQL: SELECT, users.username,,, users.language, users.notifications_filter
FROM “project_has_users” LEFT JOIN “users” ON
“users”.“id”=“project_has_users”.“user_id” WHERE
project_has_users.project_id = ? AND users.notifications_enabled = ?
AND users.is_active = ? AND != ?
[2019-06-17 17:41:00] [debug] SQL: query_duration=0.00016498565673828
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0029408931732178
[2019-06-17 17:41:00] [debug] SQL: SELECT, users.username,,, users.language, users.notifications_filter
FROM “project_has_groups” LEFT JOIN “group_has_users” ON
“group_has_users”.“group_id”=“project_has_groups”.“group_id” LEFT JOIN
“users” ON “users”.“id”=“group_has_users”.“user_id” WHERE
project_has_groups.project_id = ? AND users.notifications_enabled = ?
AND != ? AND users.is_active = ?
[2019-06-17 17:41:00] [debug] SQL: query_duration=0.0001518726348877
[2019-06-17 17:41:00] [debug] SQL: total_execution_time=0.0030927658081055
[2019-06-17 17:41:00] [debug] APP: nb_queries=16
[2019-06-17 17:41:00] [debug] APP: rendering_time=0.11051511764526
[2019-06-17 17:41:00] [debug] APP: memory_usage=5.22M
[2019-06-17 17:41:00] [debug] APP: uri=
[2019-06-17 17:41:00] [debug] ###############################################

Is there something wrong with that output?

How can the action trigger in your container, but not mine? :smiley:

I am assuming that if I enable debug output, all output goes to that
file, right?

I’ll fix the lines you mentioned, but what I need is to be able to debug myself, otherwise, I would have to
contact you, every time I wanted to change something.

You don’t need Debug = true, to get php errors to show up in your stderr logs, but setting Debug = true to a file will not also place stderr logs in that file… You need your stderr logs, that’s where php errors are going to go.

You said you’re using docker?

on you docker host, in the console, type docker logs <<name of your kanboard container>>, what does it show?

How can the action trigger in your container, but not mine? :smiley:

it can’t, it’s triggering in both, you just don’t realize it, because you haven’t figured out how to see your logs.

Question for you, how do you manage your docker containers? I use Portainer, veiwing your logs are a no brainer with it, you just click the logs button on the container…and boom! Logs!

Are you the guy on the left of this video?

but what I need is to be able to debug myself, otherwise, I would have to
contact you, every time I wanted to change something.

i’d sooner give you access to a kanboard container on my server, which is fairly simple and poses me no security risk, so if you need this, and want to play around with portainer, just ask.

Also, conversing with me is fine as well, for an actual conversation, use, I’m readily available there.

Hi. When I run docker logs for the kanboard container, I see literally nothing. For the webserver that acts as a proxy, and takes care of the SSL, I see tons of output.

I manage my containers like it’s the year 2000…

I’m more like this guy (not entirely sure about the gender):

I’ve had a look at the container you started on your server. Thanks! Unfortunately, the login in the filebrowser says “wrong credentials” (kbtest and dock work just fine). The “logs” of the container (Containers > kb-test-v129 > Logs) only has this message so far, after I created a few issues:

[18-Jun-2019 01:30:27 UTC] PHP Warning: PHP Startup: Unable to load dynamic library ‘fileinfo’ (tried: /usr/lib/php7/modules/fileinfo (Error loading shared library /usr/lib/php7/modules/fileinfo: No such file or directory), /usr/lib/php7/modules/ (Error loading shared library /usr/lib/php7/modules/ No such file or directory)) in Unknown on line 0

So, I can’t quite yet test the plugin like that. :smiley:

I took care of that, and added the php7-fileinfo package.

I’ll reset the filebrowser for you.

and you probably know this, but just in case:

just want to make sure you don’t actually wait for the cronjob to run.

Hi. Without a direct SSH connection into the container, I find it rather difficult to work with the Portainer “Console” only, because it seems to have a “timeout” of about 30 seconds, no scrollback, and no command history. I tried to install “screen”, but I get a message “Must be connected to a terminal” when I run it. This seems to be related to the container not having “-t” enabled. I found in Portainer where this could be set, but re-creating the container failed. I assume I am not allowed to do that.

I’m going to bed now. If you can have a look at that, I can try again tomorrow. Bye.

What on earth are you doing in the console, other than git commands?

But I will check that out, it can annoy me on occasion, apparently not enough to actually do anything about it tho. Never use the console except for git commit, push, pull and clone.

Found this:

And it is running behind nginx reverse proxy, so makes sense.

I think i got it, set for 2400 mintues before timeout…tested for 5, still active.

also updated the portainer container to 1.21.0.