[rt-users] Tool for canned responses (v0.2)

Marc Hedlund marc at popularpower.com
Sun Aug 6 01:45:53 EDT 2000


Okay, I'm attaching a 'version 0.2' of cannery (see below).  This version
corrects the installation instructions and removes that 'reply' bug, and
it sorts the list of canned responses alphabetically by title.  I also
added an informational message if the script cannot find any form letters
to pull in, and more comments to the perl section.  Again, let me know if
you have trouble.

Thanks,
-Marc <marc at popularpower.com>

	     Give your computer something to dream about.    (tm)
		 Popular Power - www.popularpower.com


On Sat, 5 Aug 2000, I wrote:
> We use RT to track feedback on our site.  We often get frequently asked
> questions (despite a FAQ list...) and want to quickly respond to them.  I
> wrote a utility to use JavaScript to insert a set of canned responses into
> the reply form in RT, and thought it might be useful to others.
> 
> It will require a little configuration, which is documented in comments at
> the head of the script.  Basically you make a directory of canned
> responses, where the first line of each file is a description, and the
> rest is the response.  Then run the script, and modify one line of
> rt/lib/rt/ui/web/forms.pm to point to the generated JavaScript
> file.  That's all it should take.
> 
> Let me know if you have suggestions or wind up using this.  Enjoy.
> 
> -Marc <marc at popularpower.com>
> 
> 	     Give your computer something to dream about.    (tm)
> 		 Popular Power - www.popularpower.com
> 
> 
-------------- next part --------------
#!/usr/bin/perl -w

# cannery - produce a JavaScript file to insert canned responses for RT
# Copyright (c) 2000 Marc Hedlund <marc at popularpower.com> 
#
# Version: 0.2
# Date: 5 August 2000

###########
# LICENSE #
###########

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA

################
# INSTRUCTIONS #
################

# This script auto-generates a JavaScript file (canned.js) to write a
# 'select' pop-up menu into the RT reply form, from which an RT queue
# member can select a canned response to insert into the reply
# textarea.  (See <http://www.fsck.com/projects/rt/> for more about
# RT.)  Canned responses are read from a set of plaintext files in the
# firectory named by $formdir, below.  These files should be written
# so that the first line describes the canned response -- this is the
# line that will be shown in the pop-up menu.  The rest of the file is
# the response itself, which will be inserted into the top of the
# reply textarea.  
#
# You may also want to edit the part of the JavaScript below (see line
# 243) that creates the standard closing, which is tacked onto all
# canned responses.  You can edit it out if you don't need that.
#
# Running this script will write the JavaScript file into the $webdir
# directory specified below, which should be a directory in the
# document root of the Web server running RT.  Once that is done,
# insert the following line at line 378 rt/lib/rt/ui/web/forms.pm
# (relative to the rt home directory), just above the textarea tag: 
#
#  <script language=\"JavaScript1.1\" src=\"/etc/rt/canned.js\"></script>
#
# where "/etc/rt/canned.js" points to the file generated by running
# this script, starting at the document root of the Web server.
#
# That's all you should have to do to install canned responses.  When
# you come up with more to add, just drop them in the 'uncanned'
# directory and re-run 'cannery' -- they will be added immediately.
#
# If you have comments or suggestions about this script, please let me
# know.  Thanks!  --Marc Hedlund <marc at popularpower.com>

use strict;
use diagnostics;

##########################################
### Beginning of configuration section ###
##########################################

# The generated JavaScript file will be written here.  This directory
# should be reachable from the Web server running RT.

my $webdir  = "/home/www/in.popularpower.com/etc/rt";

# The canned responses should be in plain text files in this
# directory.  See the comments above for their format.

my $formdir = "$webdir/uncanned";

####################################
### End of configuration section ###
####################################

# This format is used to write out the body of the canned responses
# into the JavaScript file.

my $bodyformat = &bodyformat();

# Open the JavaScript file for writing

open(INSERT, ">$webdir/canned.js")
    or die "Unable to write to canned.js: $!\n";

print INSERT &header();

# Read in the canned response plain text files from the 'uncanned'
# directory

opendir(FORMS, "$formdir") or &noletters();

sub noletters {
    print "No form letters found -- see the comments at the top of\n" .
	"this script for help.\n";
    exit(1);
}

my @formletters = grep { $_ ne '.' and $_ ne '..' } readdir FORMS;

closedir FORMS;

# Read in and clean up the canned responses

my %cans  = ();

for (my $idx = 0; $idx < scalar(@formletters); $idx++) {
    my $formfile = $formletters[$idx];

    open(FORM, "$formdir/$formfile")
	or warn "Unable to open $formfile: $!\n";

    # Clean up the lines of the canned response, skipping any
    # blank lines between the question and answer, and escaping
    # any '"' characters.

    my $linecount = '';
    my @formlines = map { 
	if ($_ =~ /\w/) {
	    $linecount++;
	    chomp $_; 
	    $_ =~ s/\"/\\\"/g; 
	    $_ . " ";
	} elsif ($linecount > 1) {
	    '\n\n';
	} else {
	    '';
	}
    } <FORM>;
    
    close FORM;

    # Separate the question from the answer and format the answer.

    my $question = shift @formlines;
    my $answer   = join('', @formlines);
    my $formanswer = swrite($bodyformat, $answer);

    $question   =~ s/\s+$//;
    $formanswer =~ s/\s+\"\s\+\s*$/\ \"\ \+/mg;

    # Store everything in a hashtable so we can sort the questions
    # below.

    $cans{$formfile}{'question'} = $question;
    $cans{$formfile}{'answer'}   = $formanswer;
}

# Sort and output the questions/answers.

foreach my $name (sort { 
                    $cans{$a}{'question'} cmp $cans{$b}{'question'} 
		  } keys %cans) {

    my $question = $cans{$name}{'question'};
    my $answer   = $cans{$name}{'answer'};

    print qq(Writing template "$question"...\n);

    print INSERT "new template(\"$name\", \"$question\",\n$answer\n";
    print INSERT '             "\n\n");' . "\n\n";
}


# Write out the rest of the JavaScript file (taken from the '__DATA__'
# tag below).  We do this even if there are no canned responses to
# help avoid creating JavaScript errors.

while (my $line = <DATA>) {
    print INSERT $line;
}

# swrite (taken from _Programming Perl_) is used for writing out the
# answer lines in a wrapped format.

sub swrite {
    my $format = shift;
    $^A = "";
    formline($format, @_);
    return $^A;
}

# Write out the top of the JavaScript file.

sub header {
    return <<'HEADER';
/*
 * This file is auto-generated by the "cannery" script.
 * Please don't edit this file -- edit the "cannery" script and
 * re-run it instead.  If you want to enter a new template, just put a
 * new plaintext file in the "formletters" directory, where the first
 * line is the question to be answered, and the rest of the lines are
 * the answer.
 *
 * "cannery" written by Marc Hedlund <marc at popularpower.com>
 */

/*
 * Set up data structures
 */

var questions = new Object();
var answers   = new Object();

/*
 * Build the canned response entries.  These are drawn from the 
 * "uncanned" directory.
 */

HEADER
}

# This is down here so it does screw up perl-mode with respect to
# indentation.

sub bodyformat {
    return <<'FORMAT';
~~           "^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< " +
FORMAT
}

# That's the end of the script -- everything below is read in from the
# script above using the <DATA> filehandle.

exit(0);

__DATA__
/*
 * This is the closing line that will be inserted at the bottom of
 * every template.
 */

var closing = 
  "Thanks very much for taking the time to write to us, " +
  "and for your interest in Popular Power!\n\n";

/*
 * Nothing below here should be changed in the usual case -- this is
 * just the 'guts'.  If you do make changes below that you think would
 * be generally useful, let me know!  <marc at popularpower.com>
 */

// Write out the select tag and the embedded option tags.

writeMenu();

// Functions, called above or from the HTML page.

/*
 * Adds an entry to the canned response collection.
 */

function template(key, question, answer) {
  questions[key] = question;
  answers[key]   = answer;
}

/*
 * Writes a menu of canned responses into the current HTML page
 */

function writeMenu() {
  document.writeln('<br><select name="templates" size="1"' +
                   'onChange="insert(document.forms[0].content, ' +
                   'document.forms[0].templates)">');
  
  document.writeln('  <option value="none" selected>Select a template...');

  for (var key in questions) {
    document.writeln('  <option value="' + key + '">' + questions[key]);
  }

  document.write("</select>\n\n");
}

/*
 * Inserts a canned response selected by the user into the reply 
 * textarea.
 */

function insert(textarea, select) {
  for (var i = 0; i < select.options.length; i++) {
    var option = select.options[i];
    if (option.selected && option.value != "none") {
      textarea.value =
        answers[option.value] + closing + textarea.value;
    }
  }
}


More information about the rt-users mailing list