[horde] [whups]: whups-mail-filter assign to ticket type in queue
Carsten
horde-groupware at familie-lahme.de
Wed Mar 14 22:41:22 UTC 2018
Am 14.03.2018 um 14:22 schrieb Carsten:
> Hi all,
>
> I wonder, if I understand the schematic of whups ticket system
> correct, because I am struggling with the implementation.
>
> I understand, that each QUEUE represents a project, where a project
> might be an asset (like a car or an house) or a workflow (compared to
> plan a holiday tour).
>
> I see, that one QUEUE might have multiple types, as compared to a car,
> that might have different kind of handlings, like a planned
> maintenance or a unscheduled repair. More IT-Like: a change or an
> incident.
>
> A vacation planning project might have different types of tasks, like
> booking hotels or flights, buying special stuff like backpacks or tent
> or just a new shaver.
>
> If I would like to feed this matrix, it would be great to have an
> option, to pipe a message direct to the correct type.
>
> Like sending a new available fixpack for software to the QUEUE
> "InternalIT" with TYPE "change" or the message of an unavailable
> website to the type "incident".
>
> And for QUEUE "Holiday planning" it could be good to find the tent on
> the "tobuy" "TYPE" list, but not the plane for the flight, which would
> be good to have on type "tobook".
>
> This leads to the question, if it is possible to give "TYPE" with a
> mail piped to "whups-mail-filter".
>
> What would be needed to implement it in the script. I am not familiar
> with the API of whups. Is there any documentation about the functions
> and workflows?
>
> If available, I would try by myself and post the result, if working as
> some kind of "pull" request ;-)
>
> br
>
> Carsten
>
Hey, yes, Carsten, would be great to have somebody doing such coding.....
Well, what a storm for DEV-requests....
na.. just kidding ;-)
ok,
I have digged into the PHP code and I think, I got a solution.
What my change does, is to add an argument to the command line
"--type"|"-t" which can hold the NAME of the requested type.
Additionaly it scans the piped mail for a line like
"type: [put your type here]"
Mail Body rules out Command line!
Next it scans for possible types and replaces the name with the id.
This is parsed to the regular function, and the ticket is assigned to
the queue with the requested type.
If no type matches or is given, it falls back to "default".
And here comes my modified whups-mail-filter. Have fun with it, and feel
free to comment and/or correct possible mistakes. Neither I am a great
programmer nor a DEV Coder for applications, so please use with caution
only on a test or dev platform.
!!!!__DO NOT USE UNTESTED IN PRODUCTION PLATFORMS__!!!!
Find the changes in between hashed lines
---------------------------------------------------------------
-- whups-mail-filter version with ticket type option
-- BoF
---------------------------------------------------------------
#!/usr/bin/php
<?php
/**
* This script accepts a MIME message on standard input or from a mail
server
* and creates a new ticket from its contents.
*/
function usage()
{
$argv = Console_Getopt::readPHPArgv();
$cmd = basename($argv[0]);
echo <<<EOU
Usage: $cmd [options]
This script parses MIME messages and creates new tickets from their
contents.
Single messages can be passed to the script on standard input. If the --mail
parameters are used, all messages from a mail server folder are processed
instead.
Options:
-h, --help Give this help.
-a, --default-auth A default user to set as the ticket requester,
if the
requester cannot be determined from the message.
-q, --queue-name The name of the queue where the ticket should be
added.
-Q, --queue-id The (numerical) ID of the queue where the ticket
should be added.
-g, --guess-queue Guess the correct queue name from the subject.
If no
(substring) match is found, fall back to -Q or -q.
#################################################
##
## added the -t option
##
-t, --type type of Ticket
#################################################
-k, --ticket Add the message as a comment to this ticket
instead
of creating a new ticket.
--mail-host The IMAP/POP3 server to get the messages from.
Defaults to "localhost".
--mail-user The user name for the mail server.
--mail-pass The password for the mail server.
--mail-port The mail server port. Defaults to "143".
--mail-protocol The mail server protocol. Defaults to
"imap/notls".
--mail-folder The folder on the mail server. Defaults to
"INBOX".
IDs are preferred over names because they are faster to process and avoid
character set ambiguities.
EOU;
}
function _dump($hash)
{
$dump = '';
if (empty($hash)) {
return $dump;
}
$idlen = max(array_map('strlen', array_keys($hash)));
foreach ($hash as $id => $value) {
$dump .= sprintf("\n%${idlen}d: %s", $id, $value);
}
return $dump;
}
function _error()
{
foreach (imap_errors() as $error) {
$GLOBALS['cli']->message($error, 'cli.warning');
}
}
if (file_exists(__DIR__ . '/../../whups/lib/Application.php')) {
$baseDir = __DIR__ . '/../../';
} else {
require_once 'PEAR/Config.php';
$baseDir = PEAR_Config::singleton()
->get('horde_dir', null, 'pear.horde.org') . '/whups/';
}
require_once $baseDir . 'lib/Application.php';
Horde_Registry::appInit('whups', array('cli' => true));
// Set server name.
$conf['server']['name'] = $conf['mail']['server_name'];
$conf['server']['port'] = $conf['mail']['server_port'];
// Read command-line parameters.
$info = array();
$mail = array('host' => 'localhost',
'pass' => '',
'port' => 143,
'protocol' => 'imap/notls',
'folder' => 'INBOX');
$from_mail = false;
// @TODO: Horde_Argv
##################################################
##
## added the 't' to the Argv
##
$options = Console_Getopt::getopt(Console_Getopt::readPHPArgv(),
'ha:q:Q:gk:t:',
array('help',
'default-auth=',
'queue-name=', 'queue-id=',
'guess-queue',
'ticket=',
'mail-host=', 'mail-user=',
'mail-pass=', 'mail-port=',
'mail-protocol=', 'mail-folder='));
#####################################################
if (is_a($options, 'PEAR_Error')) {
usage();
$cli->fatal($options->getMessage());
}
// Convert options into a hash. This is possible because all options are
only
// allowed once.
$opts_hash = array();
list($opts, $args) = $options;
foreach ($opts as $opt) {
list($optName, $optValue) = $opt;
switch ($optName) {
case 'h': $optName = '--help'; break;
case 'a': $optName = '--default-auth'; break;
case 'k': $optName = '--ticket'; break;
case 't': $optName = '--type'; break;
case 'q': $optName = '--queue-name'; break;
case 'Q': $optName = '--queue-id'; break;
case 'g': $optName = '--guess-queue'; break;
}
$opts_hash[$optName] = is_null($optValue) ? true : $optValue;
}
// Process options in this order because some depend on others.
if (isset($opts_hash['--help'])) {
usage();
exit;
}
if (isset($opts_hash['--default-auth'])) {
$info['default_auth'] = $opts_hash['--default-auth'];
$registry->setAuth($info['default_auth'], array());
}
if (isset($opts_hash['--ticket'])) {
$info['ticket'] = (int)$opts_hash['--ticket'];
}
if (isset($opts_hash['--guess-queue'])) {
$info['guess-queue'] = true;
}
if (isset($opts_hash['--queue-name'])) {
$queues = $whups_driver->getQueues();
foreach ($queues as $queueId => $queueName) {
if (strcasecmp($queueName, $opts_hash['--queue-name']) == 0) {
$info['queue'] = $queueId;
break;
}
}
}
if (isset($opts_hash['--queue-id'])) {
$queues = $whups_driver->getQueues();
foreach ($queues as $queueId => $queueName) {
if (strcasecmp($queueId, $opts_hash['--queue-id']) == 0) {
$info['queue'] = $queueId;
break;
}
}
}
##############################################
####### Ticket Type test
##
# we will need to parse the stdin and so we will store it
# this impacts the later call of the function, because now the
# pipe is empty
$this_stdin=$cli->readStdin();
# now check, if we gave a type by command line argument
if (isset($opts_hash['--type'])) {
$info['type'] = $opts_hash['--type'];
}
# if it is set in the mail, it overwrites the cli argument
preg_match("/(^type: )(.*)$/im",$this_stdin,$matchtype);
if ($matchtype[2] <> "") {
$info['type'] = strtolower($matchtype[2]);
}
# if we got a type, we need to resolve it to its ID
if (isset($info['type'])) {
$types = $whups_driver->getTypes($info['queue']);
foreach ($types as $typeId => $typeName) {
if (strcasecmp($typeName, $info['type']) == 0) {
$info['type'] = $typeId;
break;
}
}
}
##
####################################################
foreach (array('host', 'user', 'pass', 'port', 'protocol', 'folder') as
$opt) {
if (isset($opts_hash['--mail-' . $opt])) {
$mail[$opt] = $opts_hash['--mail-' . $opt];
}
}
// Sanity check options.
if (empty($info['ticket'])) {
if (empty($info['queue'])) {
usage();
$msg = _("--queue-name or --queue-id must specify a valid and
public queue.");
if (isset($queues)) {
$msg .= ' ' . _("Available queues:") . _dump($queues);
}
$cli->fatal($msg);
}
}
// Read and parse the message.
if (empty($mail['user'])) {
try {
##########################################
##
## replaced the $cli -> readStdin() methode with the dummy variable
##
Whups_Mail::processMail($this_stdin, $info);
##########################################
} catch (Whups_Exception $e) {
$cli->fatal($e);
}
} else {
$messages = array();
$imap = imap_open(sprintf('{%s:%d/%s}%s',
$mail['host'],
$mail['port'],
$mail['protocol'],
$mail['folder']),
$mail['user'], $mail['pass']);
if (!$imap) {
$cli->fatal(_("Cannot authenticate at mail server:") . ' ' .
implode('; ', imap_errors()));
}
_error();
$mailbox = imap_search($imap, 'ALL', SE_UID);
_error();
if ($mailbox) {
foreach ($mailbox as $uid) {
$message = imap_fetchheader($imap, $uid, FT_UID)
. imap_body($imap, $uid, FT_UID);
try {
Whups_Mail::processMail($message, $info);
imap_delete($imap, $uid, FT_UID);
} catch (Whups_Exception $e) {
$cli->message(_("Error processing message:") . ' ' .
$e->getMessage(), 'cli.error');
}
}
}
imap_expunge($imap);
imap_close($imap);
}
exit(0);
-----------------------------------------------------------------------
-- EoF
-----------------------------------------------------------------------
And here is an examble, to test it:
-----------------------------------------------------------------------
-- Test Bash Script
-- BoF
-----------------------------------------------------------------------
#!/bin/bash
echo "From: [put your sending mail address here]
To: [put Your receiving whups mail here]
subject: [Queuename]: Testticket with type
type: [put your desired type here]
Hello World
"|/usr/bin/whups-mail-filter -g -Q 8 -t '[put your desired type here]';
-----------------------------------------------------------------------
-- EoF
-----------------------------------------------------------------------
Have fun
Carsten
TODO:
--cut out the "type: xxx" line after match found
--adapt on queue to be read from mail body not from subject alone
More information about the horde
mailing list