Blog

Start 1 2 3 4

07.07.2017 // Renée Bäcker

OTRS ist an vielen Stellen einfach durch Konfiguration an die eigenen Bedürfnisse anpassbar. So auch beim Einbinden unterschiedlichster Quellen für Kundendaten. Egal ob man LDAP oder eine relationale Datenbank wie MySQL, PostgreSQL nutzt - eine Änderung in der Konfiguration reicht, um eine oder mehrere dieser Quellen einzubinden.

Man sollte nur auf eines achten: Die Kernel/Config/Defaults.pm sollte nie geändert werden. Das macht ein OTRS-Upgrade nur unnötig umständlich. Für Änderungen sollte immer die Kernel/Config.pm angefasst werden.

Jetzt soll ein LDAP-Backend angebunden werden. Dazu kopieren wir einfach den Teil aus der Kernel/Config/Defaults.pm, der dafür verantwortlich und auskommentiert ist:


    $Self->{CustomerUser} = {
        Name => 'LDAP Backend',
        Module => 'Kernel::System::CustomerUser::LDAP',
        Params => {
            # ldap host
            Host => 'test.example',
            # ldap base dn
            BaseDN => 'ou=seas,o=csuh',
            # search scope (one|sub)
            SSCOPE => 'sub',
            # The following is valid but would only be necessary if the
            # anonymous user does NOT have permission to read from the LDAP tree
            UserDN => '',
            UserPw => '',
            # in case you want to add always one filter to each ldap query, use
            # this option. e. g. AlwaysFilter => '(mail=*)' or AlwaysFilter => '(objectclass=user)'
            AlwaysFilter => '',
            # if the charset of your ldap server is iso-8859-1, use this:
            # SourceCharset => 'iso-8859-1',
            # die if backend can't work, e. g. can't connect to server
            Die => 0,
            # Net::LDAP new params (if needed - for more info see perldoc Net::LDAP)
            Params => {
                port    => 389,
                timeout => 120,
                async   => 0,
                version => 3,
            },
        },
        # customer unique id
        CustomerKey => 'uid',
        # customer #
        CustomerID => 'mail',
        CustomerUserListFields => ['cn', 'mail'],
        CustomerUserSearchFields => ['uid', 'cn', 'mail'],
        CustomerUserSearchPrefix => '',
        CustomerUserSearchSuffix => '*',
        CustomerUserSearchListLimit => 250,
        CustomerUserPostMasterSearchFields => ['mail'],
        CustomerUserNameFields => ['givenname', 'sn'],
        # show now own tickets in customer panel, CompanyTickets
        CustomerUserExcludePrimaryCustomerID => 0,
        # add a ldap filter for valid users (expert setting)
        # CustomerUserValidFilter => '(!(description=gesperrt))',
        # admin can't change customer preferences
        AdminSetPreferences => 0,
        # cache time to live in sec. - cache any ldap queries
        CacheTTL => 0,
        Map => [
            # note: Login, Email and CustomerID needed!
            # var, frontend, storage, shown (1=always,2=lite), required, storage-type, http-link, readonly
            [ 'UserTitle',      'Title',      'title',           1, 0, 'var', '', 0 ],
            [ 'UserFirstname',  'Firstname',  'givenname',       1, 1, 'var', '', 0 ],
            [ 'UserLastname',   'Lastname',   'sn',              1, 1, 'var', '', 0 ],
            [ 'UserLogin',      'Username',   'uid',             1, 1, 'var', '', 0 ],
            [ 'UserEmail',      'Email',      'mail',            1, 1, 'var', '', 0 ],
            [ 'UserCustomerID', 'CustomerID', 'mail',            0, 1, 'var', '', 0 ],
            # [ 'UserCustomerIDs', 'CustomerIDs', 'second_customer_ids', 1, 0, 'var', '', 0 ],
            [ 'UserPhone',      'Phone',      'telephonenumber', 1, 0, 'var', '', 0 ],
            [ 'UserAddress',    'Address',    'postaladdress',   1, 0, 'var', '', 0 ],
            [ 'UserComment',    'Comment',    'description',     1, 0, 'var', '', 0 ],
            # this is needed, if "SMIME::FetchFromCustomer" is active
            # [ 'UserSMIMECertificate', 'SMIMECertificate', 'userSMIMECertificate',      0, 1, 'var', '', 0 ],
        ],
    };  

Einstellungen testen

Bevor man gleich das Kundenbackend in OTRS einträgt, sollte man die Einstellungen testen. Ich habe es nicht nur einmal erlebt, dass die Daten die mir als Zugangsdaten zum LDAP gegeben wurden nicht gepasst haben. Entweder war der LDAP-Server nicht erreichbar oder der User für die Verbindung hatte gar keine Rechte. Oder er war noch gar nicht angelegt.

Es gibt einige Tools, mit denen man die Einstellungen testen kann. Ich persönlich nutze ganz gerne die Kommandozeilentools.

otrsvm@otrs5s:~$ ldapsearch -H ldaps://ldap.jumpcloud.com:636 -x \
    -b "ou=Users,o=<id>,dc=jumpcloud,dc=com" \
    -D "uid=otrs_user,ou=Users,o=<id>,dc=jumpcloud,dc=com" -w "<passwd>"
# extended LDIF
#
# LDAPv3
# base <ou=Users,o=<id>,dc=jumpcloud,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# Users, <id>, jumpcloud.com
dn: ou=Users,o=<id>,dc=jumpcloud,dc=com
ou: Users
objectClass: organizationalUnit
objectClass: top

# otrs_user, Users, <id>, jumpcloud.com
# ... user information ...

Auf SourceForge gibt es das Tool OTRS ActiveDirectory config creator. Das habe ich allerdings noch nie genutzt, kann daher keine Aussage dazu treffen, wie gut das Tool ist.

Konfiguration anpassen

Nachdem die Einstellungen getestet wurden, können diese in die Konfiguration eingetragen werden.

Wird ein ActiveDirectory verwendet, müssen mehrere Sachen angepasst werden, weil die Standardattribute von denen im LDAP abweichen. Statt uid als UserLogin zu verwenden, muss z.B. sAMAccountName verwendet werden.

Weiterhin muss das Mapping angepasst werden. Dazu muss man sich überlegen, welche Eigenschaften eines Kunden sollen im OTRS genutzt werden. Das Beispiel-Mapping nennt nur die grundlegenden Stammdaten, aber eventuell möchte man noch die Mobilnummer anzeigen oder - gerade wenn es unternehmensinterne Kunden sind - die Abteilung und die Kostenstelle.

Wer vom Standardmapping abweichen will, muss sich als erstes die Attribute im LDAP raussuchen.

Für jedes Attribut wird eine Zeile im Mapping angelegt:

[ 'UserPhone',      'Phone',      'telephonenumber', 1, 0, 'var', '', 0 ],

Diese Angaben bedeuten:

  1. Attribut im CustomerUser-Objekt - z.B. zur Verwendung in Benachrichtigungen über <OTRS_CUSTOMER_DATA_UserPhone>
  2. Anzeige in der Oberfläche (wird übersetzt)
  3. Attribut im LDAP/AD
  4. Angabe, ob das Attribut angezeigt werden soll oder nicht
  5. Angabe, ob das Attribut ein Pflichtfeld ist
  6. Legt fest, ob das Attribut eine Zahl oder ein String ist
  7. Template für eine Verlinkung des Attributs (siehe auch [diesen Blogpost](https://blog.feature-addons.de/2017-03-23-callto-tel-link-in-kundendaten))
  8. Angabe, ob nur lesend auf das Attribut zugegriffen wird

Da auf LDAP-Backends nur lesend zugegriffen wird und keine Änderungen der Daten über OTRS möglich ist, sind die Angaben in den Spalten 5, 6 und 8 irrelevant.

JumpCloud

Für alle Entwickler: Um nicht ein eigenes LDAP installieren und warten zu müssen, habe ich mir einen kostenlosen Account bei JumpCloud einen kostenlosen Account geholt und ein paar Beispieldaten eingespielt.

Dann ist es einfach, in Demosystemen oder zu Testzwecken ein LDAP-Backend einzubinden.

LDAPS

Standardmäßig wird eine ungesicherte Verbindung zum LDAP aufgebaut. Wer eine Verbindung über SSL aufbauen möchte, kann das mit nur kleinen Änderungen erreichen.

Als Schema muss ldaps eingetragen und der Port muss angepasst werden. Standardmäßig ist der Port für ldaps der 636.

Der geändert Ausschnitt aus der Konfiguration:


    Params => {
        scheme  => 'ldaps',
        port    => 636,
        timeout => 120,
        async   => 0,
        version => 3,
    },

Zertifikate

Müssen Zertifikate angegeben werden, sind weitergehende Änderungen in der Konfiguration notwendig. Dazu ist es ganz praktisch, dass das LDAP-Authentifizierungsmodul von OTRS einige Parameter aus der Konfiguration direkt an das Modul Net::LDAP weitergibt.

Sobald das Schema ldaps eingetragen ist, können diese Parameter übergeben werden:

  • cafile
  • capath
  • clientcert
  • clientkey
  • ciphers
  • sslversion
  • sslserver

also z.B.


    Params => {
        scheme  => 'ldaps',
        port    => 636,
        timeout => 120,
        async   => 0,
        version => 3,
        clientcert => '/path/to/cert.pem',
        clientkey  => '/path/to/key.pem',
    },

Mehrere Backends nutzen

Möchte man nicht nur LDAP als Kundenbackend nutzen, sondern auch die Datenbank, dann ist das kein Problem. In OTRS kann man mehrere Kundenbackends eintragen - aktuell (OTRS 5.0.20) sind es bis zu 11 Backends. Wer mehr braucht, muss das an vielen Stellen im Code anpassen.

Aber ob die große Zahl an Kundendatenbackends sinnvoll ist, steht wieder auf einem anderen Blatt. Jedes Backend frisst natürlich etwas Performanz, da ggf. Daten über das Netzwerk geschoben werden, evtl. sind auch die LDAP-Hosts oder die Datenbanken nicht erreichbar.

Ich tendiere immer dazu, die Kundenbackends weitestgehend zusammenzufassen - wenn es geht.

Bei zwei Backends lohnt sich das Zusammenführen meist noch nicht, aber wenn es mal mehr als vier Backends werden, sollte man sich mal Gedanken dazu machen.

Die verschiedenen Backends werden durch eine fortlaufende Nummerierung unterschieden:


    $Self->{CustomerUser} = {
        Name => 'LDAP Backend',
        Module => 'Kernel::System::CustomerUser::LDAP',
        # weitere Parameter
    };

    $Self->{CustomerUser1} = {
        Name => 'OTRS DB Backend',
        Module => 'Kernel::System::CustomerUser::DB',
        # weitere Parameter
    };

    $Self->{CustomerUser2} = {
        Name => 'Supplier LDAP Backend',
        Module => 'Kernel::System::CustomerUser::LDAP',
        # weitere Parameter
    };

Authentifizierung

Bisher hat dieser Blogpost nur die Datenhaltung der Kundenbenutzer betrachtet. Wird das Kundenfrontend benutzt, muss ggf. noch die Authentifizierung über das LDAP bzw. über die Datenbank laufen. Auch hierfür gibt es eigene Konfigurationseinstellungen, die in der Kernel/Config.pmgemacht werden müssen.


    #Enable LDAP authentication for Customers / Users
    $Self->{'Customer::AuthModule'} = 'Kernel::System::CustomerAuth::LDAP';
    $Self->{'Customer::AuthModule::LDAP::Host'} = 'host.example.com';
    $Self->{'Customer::AuthModule::LDAP::BaseDN'} = 'ou=BaseOU,dc=example,dc=com';
    $Self->{'Customer::AuthModule::LDAP::UID'} = 'sAMAccountName';

    #The following is valid but would only be necessary if the
    #anonymous user do NOT have permission to read from the LDAP tree
    $Self->{'Customer::AuthModule::LDAP::SearchUserDN'} = 'otrs_ldap';
    $Self->{'Customer::AuthModule::LDAP::SearchUserPw'} = 'PASSWORD';

    # Second auth-backend: The OTRS DB
    $Self->{'Customer::AuthModule1'}                       = 'Kernel::System::CustomerAuth::DB';
    $Self->{'Customer::AuthModule::DB::Table1'}            = 'customer_user';
    $Self->{'Customer::AuthModule::DB::CustomerKey1'}      = 'login';
    $Self->{'Customer::AuthModule::DB::CustomerPassword1'} = 'pw';

Genauso wie bei den Backends für die Kundenbenutzerdaten, kann man mehrere Authentifizierungsbackends angeben. Die Parameter, die zusammengehören, müssen auch den einheitlichen Suffix haben. So wie hier bei allen Parametern für die OTRS-Datenbank den Suffix "1" haben.

Welche Reihenfolge?!

Geht es um mehrere Backends stellt sich die Frage, welche Reihenfolge die Einträge haben sollten.

Das ist nicht ganz einfach pauschal zu beantworten. Ich würde mir Gedanken dazu machen, welche Backends am häufigsten benötigt werden und wie diese Backends angebunden sind. OTRS geht die Backends der Reihe nach durch, also zu erst "CustomerUser", dann "CustomerUser1", anschließend "CustomerUser2" und so weiter.

Ich würde die langsamsten Backends ans Ende stellen - außer es ist ein Backend dabei, aus dem der Großteil der abgerufenen Kundendaten stammt. Dann würde ich das weiter nach vorne einsortieren (und schauen ob ich nicht an der Perfomanz etwas drehen kann).

Die Dokumentation zum Thema "Kundenbenutzerbackends" ist auf github zu finden: http://otrs.github.io/doc/manual/admin/stable/en/html/external-backends.html#customer-user-backend.

Permalink:

12.06.2017 // Renée Bäcker

Im Standard AdvancedTicketCalendar können Tickets auf Basis der Erinnerungszeit und auf Basis von Dynamischen Feldern angezeigt werden.

In diesem Blogpost soll gezeigt werden, wie man weitere Regeln für die Anzeige von Tickets einrichtet. Als Beispiele sollen Entwicklungstickets erstellt werden. Zum einen sollen der Beginn der Entwicklung und die Übergabe als Termine im Kalender angezeigt werden und zum anderen soll es einen Testzeitraum geben.

Dazu werden vier dynamische Felder benötigt:

  • StartDevelopment
  • StartTest
  • EndTest
  • GoingLive

Alle vier Felder müssen vom Typ Date oder DateTime sein. Exemplarisch ist hier das Feld StartDevelopment gezeigt:

Außerdem wird für das Beispiel mit dem Testzeitraum noch ein weiteres dynamisches Feld angelegt und zwar vom Typ Agent. Damit wird in dem Ticket der Testverantwortliche festgelegt.

Dieses dynamische Feld wird später noch von Bedeutung sein wenn es um die Farbgebung der Kalendereinträge geht.

Anschließend wird eine eigene .xml-Datei unter Kernel/Config/Files benötigt. Darin werden drei "ConfigItems" definiert.

Das erste ConfigItem definiert die Termine für den Start der Entwicklung:

<ConfigItem Name="AdvancedTicketCalendar::Fields###StartDevelopment" Required="0" Valid="1">
    <Description Translatable="1">...</Description>
    <Group>AdvancedTicketCalendar</Group>
    <SubGroup>OwnFilters</SubGroup>
    <Setting>
        <Hash>
            <Item Key="Start">DynamicField_StartDevelopment</Item>
            <Item Key="Duration">1</Item>
            <Item Key="Color">#32cd32</Item>
            <Item Key="Icon">calendar</Item>
        </Hash>
    </Setting>
</ConfigItem>

Der Name der Konfig-Option muss mit AdvancedTicketCalendar::Fields### beginnen.

Folgende Einstellungen werden hier vorgenommen:

  • Start
  • Duration
  • Color
  • Icon

Bei Start wird das Feld eingetragen, das den Startzeitpunkt im Kalender bestimmt. In diesem Fall wird das von dem Dynamischen Feld StartDevelopmentbestimmt. Ist es kein ganztägiges Ereigniss und man hat keinen Endzeitpunkt angegeben, kann mit Duration festgelegt werden, wie viele Stunden der Termin im Kalender vereinnahmt.

Gibt es den Color-Eintrag, haben alle Kalendereinträge für diese Gruppe genau diese Farbe. Hier muss eine HTML-Farbe in HEX-Schreibweise eingetragen werden.

Bei jedem Kalendereintrag erscheint ein kleines Icon. Darüber können die Agenten schon auf den ersten Blick erkennen, welche Art von Termin der Eintrag ist. Unterstützt werden die Fontawesome-Icons.

Die zweite Option konfiguriert die Einträge für den Testzeitraum:

</ConfigItem>
<ConfigItem Name="AdvancedTicketCalendar::Fields###Testing" Required="0" Valid="1">
    <Description Translatable="1">...</Description>
    <Group>AdvancedTicketCalendar</Group>
    <SubGroup>OwnFilters</SubGroup>
    <Setting>
        <Hash>
            <Item Key="Start">DynamicField_StartTest</Item>
            <Item Key="Stop">DynamicField_EndTest</Item>
            <Item Key="Color">#00FFFF</Item>
            <Item Key="Icon">bug</Item>
            <Item Key="ColorBy">DynamicField_TestAgent</Item>
        </Hash>
    </Setting>
</ConfigItem>

Zusätzlich zu der Start-Angabe wird das Ende im Kalender über ein weiteres Dynamisches Feld bestimmt: EndTest. Auch haben hier die Kalendereinträge nicht alle die gleiche Farbe. Die Farbe des Termins wird über den Testagenten gesteuert. Deshalb auch das fünfte Dynamische Feld.

Um die Farbgebung zu steuern wird eine zusätzliche Option benötigt:

<ConfigItem Name="AdvancedTicketCalendar::ColorBy###DynamicField_TestAgent" Required="0" Valid="0">
    <Description Translatable="1">If enabled in the fieldconfig the color is defined by the testagent.</Description>
    <Group>AdvancedTicketCalendar</Group>
    <SubGroup>OwnFilters</SubGroup>
    <Setting>
        <Hash>
            <Item Key="ownerlogin">#d8d8d8</Item>
        </Hash>
    </Setting>
</ConfigItem>

Jeder Agent bekommt hier eine Farbe zugeteilt. So kann jeder Testagent gleich erkennen, wann der nächste Zeitraum für ihn/sie beginnt.

Die komplette .xml ist unter http://blog.feature-addons.de/downloads/AdvancedTicketCalendarOwnRules.xml zu finden.

Nachdem die Datei im Kernel/Config/Files-Verzeichnis angelegt wurde, muss der Admin über die Weboberfläche in die SysConfig gehen, die Gruppe "AdvancedTicketCalendar" anwählen und in die Subgrouppe "OwnFilters" gehen. Das sieht dann folgendermaßen aus:

Ist alles eingerichtet, kann man die Dynamischen Felder bei den Tickets füllen:

Dann werden die Einträge entsprechend im Kalender dargestellt.

Und bei einem Update darf man nicht vergessen, diese .xml-Datei mit in das neue OTRS zu übernehmen. Daher empfehlen wir immer, auch eigene kleine Anpassungen in ein Paket zu packen, so dass man nicht immer nach geänderten Dateien suchen muss. Das ist besser als jede Dokumentation. Wenn Sie Fragen dazu haben, dürfen Sie uns gerne kontaktieren.

Sollten Sie Interesse an AdvancedTicketCalendar können wir gerne ein Demo-System für Sie einrichten.

Permalink:

27.05.2017 // Renée Bäcker

Mit der Erweiterung TicketAttachments ist es möglich, automatisiert Anhänge von Tickets zu löschen. Dazu muss man im Adminbereich unter Attachment-Jobs entsprechende Jobs anlegen. Hier werde ich ein paar Beispiele zeigen.

Keine ausführbaren Anwendungen (.exe) erlauben

Werden generell eine Anwendungen als Dateianhang erwartet, kann man diese ggf. löschen. Das kann dazu beitragen, dass Agenten sich keine Trojaner oder ähnliches einfangen. Die Regeln sind dann wie folgt:

  • Es sind alle Tickets betroffen - aus allen Queues egal welcher Status
  • Es sollen nur Dateien mit der Endung "exe" gelöscht werden

Einstellungen .exe-Anhänge löschen

Dateien mit "ISO-..."-Dateinamen löschen

Manchmal sammelt sich einiges an Datenmüll an. Evtl. wurden mal Attachments falsch abgelegt (auf Grund einer Änderung an der Datenbank). Dann kann man Dateien auf Basis des Dateinamens löschen. In diesem Beispiel sollen folgende Anhänge gelöscht werden:

  • Es sind alle Tickets betroffen - aus allen Queues egal welcher Status
  • Es sollen nur Dateien gelöscht werden, deren Dateiname mit "ISO-" anfangen

Dateien mit ISO- am Anfang löschen

Speicherplatz sparen: Bilder die größer als 500 KB sind löschen

Große Datenbanken und/oder viele große Dateien können mit der Zeit zu einem Problem werden. Deswegen kann man z.B. alle Anhänge löschen, die größer als 500 Kilobyte sind. Und nach Möglichkeit nur bei Tickets, die bereits geschlossen sind. Damit ergibt sich folgender Filter

  • Es sind Tickets aus allen Queues betroffen - aber nur wenn sie geschlossen sind.
  • Es sollen nur Dateien gelöscht werden, die größer als 500 KB sind

Anhänge nur löschen wenn sie größer als 500 KB sind

Alle Anhänge von Tickets löschen, die vor mehr als 2 Jahren geschlossen wurden

Werden Tickets, die vor mehr als 2 Jahren geschlossen werden nur noch genutzt um Mails nachzulesen - ohne dass Anhänge interessant sind -, dann kann man neben dem Status "geschlossen" noch einstellen, wann dieser Status erreicht sein muss.

  • Es sind Tickets aus allen Queues betroffen - aber nur wenn sie geschlossen sind.
  • Tickets müssen vor mindestens 2 Jahren geschlossen worden sein

Anhänge bei alten Tickets löschen

Zusammenfassung

Mit diesen Attachment-Jobs kann man sehr flexibel einzelne oder alle Anhänge von Tickets löschen. Die Filter können frei kombiniert werden, so dass man auch sagen kann:

  • Es sind Tickets aus allen Queues betroffen - aber nur wenn sie geschlossen sind.
  • Tickets müssen vor mindestens 2 Jahren geschlossen worden sein
  • Es sollen nur Dateien gelöscht werden, die größer als 500 KB sind
  • Es sollen nur Dateien mit der Endung "exe" gelöscht werden

Häufigkeit der Ausführung einstellen

Diese Jobs werden durch den Daemon gestartet. In der SysConfig gibt es in der Gruppe "Daemon" die Untergruppe "Daemon::SchedulerCronTaskManager::Task". Dort sind die Einstellungen zu den Daemon-Aufgaben zu finden - auch die Aufgabe zum Löschen der Anhänge.

Daemoneinstellungen

Haben wir Ihr Interesse an TicketAttachments geweckt? Dann nehmen Sie doch einfach Kontakt zu uns auf oder fordern Sie gleich Ihr Demosystem an.

Haben Sie noch weitere Ideen und Wünsche? Dann schreiben Sie uns bitte

Permalink:

20.04.2017 // Renée Bäcker

Eine häufiger gestellte Frage ist, wie man verhindern kann dass ein Agent ein Ticket schließt solange noch mindestens eine Aufgabe aus der Checkliste noch offen ist. Hier kann man sich die Ticket-ACLs zu Nutze machen. Immer wenn eine Aufgabe zur Checkliste hinzugefügt wird oder der Status einer bestehenden Aufgabe geändert wird, wird geprüft ob alle Punkte schon abgearbeitet sind oder nicht. Ist das nicht der Fall, wird das Dynamische Feld TicketHasOpenTodos auf den Wert 1 gesetzt.

Auf diesen Wert kann man in der ACL prüfen. Die Prüfung lautet: ist der Wert des Dynamischen TicketHasOpenTodos gleich 1, dann darf das Ticket nicht geschlossen werden. In der ACL sieht das dann wie folgt aus:

Bei den Wertänderungen muss man ausschließen, dass der Agent den "Schließen"-Dialog aufruft und die "geschlossen"-Status sollen in allen anderen Dialogen ausgeschlossen werden:

Wie erkennt TicketChecklist bei eigenen Aufgaben-Status, ob die Aufgaben geschlossen sind oder nicht? Dazu gibt es eine SysConfig-Option die gepflegt werden muss:

Wenn keine Aufgabe einen dieser Status hat, sind alle Aufgaben geschlossen.

Nach dem Speichern der ACL das "Deployen" nicht vergessen. Sonst ist die ACL nicht aktiv. Und nicht mit dem Superuser (root@localhost) testen, denn da greifen keine ACLs.

Haben wir Ihr Interesse an TicketChecklist geweckt? Dann nehmen Sie doch einfach Kontakt zu uns auf oder fordern Sie gleich Ihr Demosystem an.

Haben Sie noch weitere Ideen und Wünsche? Dann schreiben Sie uns bitte.

Permalink:

23.03.2017 // Renée Bäcker

Viele Telefonanlagen können mit callto- oder tel-Links umgehen. So kann der Agent bequem den Kunden anrufen ohne die Nummer selbst zu wählen. Aus diesem Grund kann man in den Kundeninformationen einen Link anzeigen lassen:

Kundeninformation am Ticket

Soweit so gut. Wenn man bei Kundeninformationen einen Link hinterlegt ist vielen wahrscheinlich bekannt. Man kann im Mapping der Kundeninformationen in der Kernel/Config.pm die URL zusammenbauen. Das einfachste wäre einen Link zur URL anzuzeigen:

$Self->{CustomerUser}->{Map} = [

  # note: Login, Email and CustomerID needed!
  # var, frontend, storage, shown (1=always,2=lite), required, storage-type, http-link, readonly, http-link-target, link class(es)
  [ 'UserTitle',      'Title',      'title',      1, 0, 'var', '', 0 ],
  [ 'UserFirstname',  'Firstname',  'first_name', 1, 1, 'var', '', 0 ],
  # ... noch mehr Eigenschaften ...
  [ 'UserURL',          'URL',         'url',          1, 0, 'var', '[% Data.UserURL | html %]', 0 ],
];

In der Spalte nach dem 'var' wird die URL zusammen gebaut. In diesem Fall ist das einfach die URL, die bei dem Kunden gespeichert ist. Als Daten stehen hier die Kundeninformationen zur Verfügung und in Ticketansichten auch Ticketinformationen. So ist es möglich, z.B. bei der E-Mailadresse einen Link zu hinterlegen, bei dem eine Antwort auf das aktuelle Ticket erstellt wird. Das Beispiel dazu ist in der Kernel/Config/Defaults.pm zu finden.

Zurück zum Telefonlink. Der einfachste callto Link würde so aussehen:

'callto:[% Data.UserPhone %]'

Aber da Telefonanlagen meist die Telefonnummer im internationalen Format brauchen und keine Sonderzeichen vertragen, muss die Telefonnummer aufbereitet werden. Die Telefonnummer kann ja in unterschiedlichster Weise eingetragen sein:

  • 0123 3913 - 12
  • 0049 123 3913 - 12
  • 0123/3913 12
  • +49-123 391312
  • ...

Jetzt kommt uns zugute, dass die Template-Engine mit OTRS4 ausgetauscht wurde. Seitdem ist man sehr flexibel was man so alles machen kann. Template::Toolkit - die neue Template-Engine - bietet viele Filter schon von Haus aus. Dazu gehört auch der replace-Filter. Den nutzen wir hier, um zuerst alles was nicht Zahl oder "+" ist rauszulöschen. Das nächste replace ersetzt zwei führende 0en durch "+" und wenn dann noch eine führende Null vorhanden ist, wird diese mit "+49" ersetzt. Daraus ergibt sich folgendes Konstrukt für die Config.pm:

[ 'UserPhone', 'Phone', 'phone', 1, 0, 'var',
    q~callto:[% Data.UserPhone | replace('[^0-9+]','') | replace('\A00','+') | replace('\A0','+49') %]~,
    0 ],

Damit wird aus allen Beispielen oben genau eine Darstellung der Telefonnummer: +49123391312

Kundeninformation am Ticket

Noch mehr Filter sind hier dokumentiert: Template-Dokumentation für OTRS und Template::Toolkit Seite

Permalink:

25.01.2017 // Renée Bäcker

OTRS hat viele Ecken - und in vielen kennt Sie sich vielleicht schon aus. Einige sind vielleicht aber noch nicht erforscht. Wenn Sie diese Ecken kennenlernen möchten, dann helfen Schulungen. Auch in diesem Jahr bieten wir wieder bei der Perl-Academy zahlreiche OTRS-Schulungen an.

Das fängt bei KeyUser-Schulungen an, geht weiter mit Administratoren- und ITSM::ChangeBuilder-Schulungen weiter und muss bei Entwickler-Schulungen nicht aufhören. Gerne bereiten wir auch eine - speziell auf Sie zugeschnittene - Firmenschulung an.

Schon ab dem zweiten Teilnehmer ist die Durchführung garantiert.

Die nächsten Schulungen:

20.-24.02.2017 - OTRS für Entwickler (Englisch)
06.-08.03.2017 - OTRS Administratoren
09.-10.03.2017 - OTRS::ITSM ChangeBuilder

28.04.207 - OTRS KeyUser

19.06.-23.06.2017 - OTRS für Entwickler
26.06.-28.06.2017 - OTRS Administratoren
29.06.-30.06.2017 - OTRS::ITSM ChangeBuilder

16.10.-20.10.2017 - OTRS für Entwickler (Englisch)

13.11.-15.11.2017 - OTRS Administratoren
17.11.2017 - OTRS KeyUser

11.12.-15.12.2017 - OTRS für Entwickler

Wir würden uns freuen, Sie als Teilnehmer in unseren Schulungen begrüßen zu dürfen.

Permalink:

22.01.2017 // Renée Bäcker

Es kommt doch häufiger vor, dass man die gleichen Abfragen macht um Tickets zu suchen: Welche Tickets wurden in den letzten beiden Wochen in der Queue "VIP" erstellt? Welche Tickets wurden zuletzt bearbeitet?

Wer immer die gleichen Abfragen tätigt legt sich meistens ein Suchprofil dafür an. Aber was wenn viele Agenten die gleiche Abfrage benötigen? Das kommt z.B. auch dann vor wenn es eine Abteilungsinterne Absprache gibt wie mit Tickets umgegangen wird. Dann muss im Standard-OTRS jeder Agent diese Anfrage selbst erstellen. Dabei kann es natürlich zu Fehlern kommen, weil man sich vertippt oder ein Suchparameter vergessen wurde.

GlobalSearchProfile bietet hier die Lösung. Hier kann man beim Erstellen eines Suchprofils angeben, dass es "global" verfügbar sein soll und damit jedem Agenten zur Verfügung steht:

Erstellen des Suchprofils

Bei jedem Agenten taucht das Suchprofil dann auf:

Um zu vermeiden dass auf einmal nur noch globale Suchprofile erstellt werden, kann man über die SysConfig bestimmen Mitglieder welcher Gruppen solche Profile anlegen können.

Haben wir Ihr Interesse an GlobalSearchProfile geweckt? Dann nehmen Sie doch einfach Kontakt zu uns auf oder fordern Sie gleich Ihr Demosystem an.

Haben Sie noch weitere Ideen und Wünsche? Dann schreiben Sie uns bitte.

Permalink:

21.01.2017 // Renée Bäcker

Welche Tickets gehören mir? Wer diese Frage mit einem kurzen Klick in die Toolbar beantwortet haben möchte, der kann sich die Erweiterung ToolbarTicketOwner von OPAR herunterladen.

Nach der Installation erscheint ein kleines Icon in der Toolbar, über das man auf eine entsprechende Übersicht kommt:

Der Quellcode ist auf Github zu finden. Wer einen Bug hat, kann ihn dort auch melden.

Permalink:

24.12.2016 // Renée Bäcker

Ein ereignisreiches und erfolgreiches Jahr geht zu Ende. Im Fernsehen gibt es auf jedem Sender einen Rückblick auf das Jahr 2016 - und auch wir wollen kurz zurückschauen auf das was bei uns so los war.

Ich war zweimal in Dormagen auf dem OTRS-Stammtisch und habe dort jeweils einen Vortrag gehalten. Vielen Dank an dieser Stelle an die Fahrer, die mich jeweils zum Treffen und auch wieder zurück nach Köln gebracht haben. Die Treffen sind immer sehr interessant und es macht Spaß sich mit den Teilnehmern/Teilnehmerinnen zu unterhalten - auch über OTRS-fremde Themen. Ich freue mich aber auch sehr über die vielen Anregungen sowohl für die freien Module als auch die kommerziellen Module.

Vielen Dank an das Team von maxence für das Organisieren der Treffens! Ich möchte auch im nächsten Jahr wieder zwei- bis dreimal zu dem Stammtisch fahren. Wenn es Vortragswünsche gibt, bin ich dafür offen.

Unsere Module werden sehr gut angenommen und von den Kunden gibt es immer wieder nützliches Feedback zu den Erweiterungen. Viele gewünschte Features konnten wir in die Erweiterungen einbauen, so dass alle Kunden davon profitieren können. Wir würden uns freuen, wenn es auch im nächsten Jahr so erfolgreich weitergeht.

Viele Erweiterungen konnten wir noch nicht auf der Webseite oder hier im Blog zeigen, weil wir es zeitlich nicht geschafft haben. Und auch im nächsten Jahr wird es einige neue Erweiterungen geben.

Dann habe ich noch OTRSWeekly gestartet - ein wöchentlicher Newsletter zum Thema OTRS.

Jetzt bleibt mir nur noch, Ihnen allen Frohe Weihnachten und ein gutes neues Jahr zu wünschen. Genießen Sie die Feiertage und kommen Sie zur Ruhe.

Permalink:

16.12.2016 // Renée Bäcker

Auf Anregung eines Kunden haben wir TicketChecklist um "Conditions and Actions" erweitert. Damit ist es möglich, auf Änderungen des Status von Aufgaben zu reagieren. Nehmen wir mal als Beispiel die Organisation der Firmen-Weihnachtsfeier, bei der sich folgende Checkliste mit diesen Aufgaben ergibt:

  • Suche eines Veranstaltungsortes
  • Unterschreiben des Vertrags
  • Catering buchen
  • Weihnachtsgeschenke besorgen
  • Rechnungen bezahlen

Die Aufgabe "Weihnachtsgeschenke besorgen" kann völlig unabhängig von den anderen Aufgaben erledigt werden. Aber der Vertrag kann erst unterschrieben werden, wenn ein Veranstaltungsort feststeht. Und das Catering wird erst bestellt, wenn der Vertrag unterschrieben ist da dort eventuell festgehalten ist, dass der Betreiber des Veranstaltungsortes selbst das Catering macht.

Wenn der Veranstaltungsort ausgewählt ist, wird die Aufgabe "Unterschreiben des Vertrags" auf "warten" gesetzt. Das gleiche gilt für "Catering buchen" wenn der Vertrag unterschrieben ist. Aus Anschauungszwecken soll die Rechnungen erst bezahlt werden wenn das Catering gebucht ist. Da das von der Buchhaltung erledigt wird, soll das Ticket dann in die Queue Buchhaltung geschoben werden.

Daraus ergibt sich folgende Übersicht der Aufgaben:

Aufgaben des Tickets

Als erstes werden die Aufgaben mit ihren Verantwortlichen erstellt:

Aufgaben

Danach werden die Conditions und Actions gepflegt. Zuerst definieren wir die Statusänderungen anderer Aufgaben:

Bedingungen und Aktionen

Hier wird immer nur eine andere Aufgabe geändert. Es ist aber auch möglich mehrere Aufgaben zu ändern:

Aktionen auf mehrere Aufgaben

Neben dem Verändern anderer Aufgaben ist es bei den Actions auch möglich ein Dynamisches Feld am Ticket zu setzen. Dazu muss das Action-Modul TicketDynamicFieldSet verwendet werden:

Dynamisches Feld setzen

Das nutzen wir in diesem Beispiel, um das Verschieben des Tickets in die Queue "Buchhaltung" zu ermöglichen. Bei den Parametern muss der Name des Dynamischen Feldes (hier: MoveToQueue) als Schlüssel eingetragen werden und bei Wert der neue Wert des Feldes.

An dieser Stelle wäre es auch denkbar eigene Action-Module zu programmieren, so dass z.B. ein Status "jetzt ausführen" erstellt wird und dass beim Erreichen des Status automatisch ein Programm aufgerufen wird, das ein Programm ausführt oder zusätzliche Informationen aus einem Drittsystem holt.

Auf Basis der Änderung eines Dynamischen Feldes kann man mit GenericAgents das Ticket dann in eine andere Queue verschieben:

Stammdaten GenericAgent

Als Filter wird der neue Wert des Dynamischen Feldes genommen

Ticketfilter

und anschließend das Ticket verschoben

Aktion auf das Ticket

Mit diesen Conditions und Actions kann man mit TicketChecklist sehr viel erreichen weil man auch Einfluss auf das Ticket selbst nehmen kann.

Weitere Änderungen an TicketChecklist:

  • Vorlagen können kopiert werden. Damit ist es jetzt möglich noch schneller ähnliche Vorlagen zu erstellen.
  • Import/Export von Vorlagen, so dass es leicht ist Test- und Livesystem synchron zu halten
  • Export von Aufgaben. In der Ticketansicht und im Dashboard können die Aufgaben als PDF, Excel-Datei und als ics-Datei exportiert werden.

Haben wir Ihr Interesse an TicketChecklist geweckt? Dann nehmen Sie doch einfach Kontakt zu uns auf oder fordern Sie gleich Ihr Demosystem an.

Ausblick:

Auch vor TicketChecklist machen ständige Veränderungen nicht Halt. Als nächstes soll die Anzeige der Aufgaben im Ticket-Kalender ermöglicht werden (im Zusammenspiel mit der Erweiterung AdvancedTicketCalendar. Weiterhin soll es ermöglicht werden, Kundenspezifische Checklistenvorlagen zu erstellen.

Haben Sie noch weitere Ideen und Wünsche? Dann schreiben Sie uns bitte.

Permalink: