#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2012
    Posts
    3
    Rep Power
    0

    Perl email function help required


    Greeting Gurus...

    I have been pondering this for days but have not succeeder. I have a script that basically functions as a quick FAQs guide. You ask a question. The words are compared to a keywords in "answer" files, and the potential answers are displayed.


    What I want to do is "capture" the question when there is no answer available and then email the question to our support team for them to answer the query manually (and add it to the FAQs).

    I need a input box for the client email and a send button.
    The idea is for the client to enter their email and click the button to get manual help on the question. Or any other way that makes sense.

    The code is as follows and my input box and send button are located here - "## the email input box and "send button" here"

    Any advice on how to go about this would be great...

    Thanks in advance.

    Renoir.
    -----------------------------------------------------

    #!/usr/bin/perl


    ## base directory, like /home/pete
    ## no trailing slash

    $basedir = '/home/domains/public_html';

    ## name of the directory where answer files are stored
    ## no trailing slash

    $studir = 'faq';

    ## baseurl, like (xxxxxxxxxxxxxxxxxxxxxxxxx)~pete, wherever stu.jpg will be stored
    ## no trailing slash

    $baseurl = 'xxxxxxxxxxxxxxxxxxxxxxxxx;

    ## location of this script

    $thiscgi = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx;

    # (post method)

    # Get the input
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

    # Split the name-value pairs
    @pairs = split(/&/, $buffer);

    foreach $pair (@pairs) {
    ($name, $value) = split(/=/, $pair);

    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

    $FORM{$name} = $value;
    }

    print "Content-type: text/html\n\n";

    sub doanswer {
    $file = $FORM{'answer'};

    open(FILE,"$basedir/$studir/$file");
    @lines = <FILE>;
    close(FILE);

    $string = join(' ',@lines);
    $string =~ s/\n//g;

    if ($string =~ /<answer>(.*)<\/answer>/i) {
    @answer = "$1";
    }

    if ($string =~ /<title>(.*)<\/title>/i) {
    $title = "$1";
    }

    print "
    <html>
    <head>
    <title>I know that!</title>
    </head>
    <body>
    <center>
    <table border=0 cellspacing=0 cellpadding=0 width=600>
    <tr><td>

    </td>
    <td width=10>
    <br>
    </td>
    <td><center><img src=\"$baseurl/nerd-do-know.jpg\"><p>
    <b>
    <font face=\"Arial, Verdana, Helvetica\" size=\"3\">
    $title</center></font></b><p><br>
    <font face=\"Arial, Verdana, Helvetica\" size=\"2\">
    @answer
    </font>
    <p>
    <center>
    <font face=\"Arial, Verdana, Helvetica\" size=\"2\">
    <b><a href=\"Javascript:history.back(); history.back();\"><<<< Return</a><p>
    <a href=\"Javascript:history.back();\"><<< Back</a></b>
    </center>
    </font>
    <P>";
    print "<font size=1>
    </td></tr></table>

    </body>
    </html>
    ";

    exit;

    }


    #Get the files here for later...
    @files = ('*.stu');
    &get_files;

    $num=0;

    #Split the user's question by spaces
    $daquest = $FORM{'question'};

    if ($daquest =~ /\?/) {

    chop($daquest);

    }

    @terms = split(/\s+/, $daquest);

    $i=0;


    if ($FORM{'step'} eq "answer") {
    &doanswer;
    }




    foreach $FILE (@FILES) {
    #Loop through each file and search for keywords
    $i++;
    $ismatch=0;

    #Open file here and store it in @lines
    open(FILE,"$FILE");
    @lines = <FILE>;
    close(FILE);

    $string = join(' ',@lines);
    $string =~ s/\n//g;

    if ($string =~ /<keywords>(.*)<\/keywords>/i) {
    $keywords = "$1";
    }
    #split the keywords up too
    @words = split(/\s+/, $keywords);
    foreach $word (@words) {
    #loop through each word and compare it to every keyword
    foreach $term (@terms) {
    if ("\L$term\E" eq "\L$word\E") {
    $ismatch=1;
    }
    }
    }

    #Now ismatch should be 1 if something is found and 0 if it wasn't
    #Now we have to add this file to an array somehow
    if ($ismatch==1) {
    $stus{$i}="yes";
    $nme{$i}=$FILE;
    $num++;
    }

    if ($string =~ /<title>(.*)<\/title>/i) {
    $question{$i} = "$1";
    }

    }


    #Loop here to print out the code for the questions and the answers they can recieve
    $k=0;

    if ($num>0) {

    print "
    <html>
    <head>
    <title>I think I know the answer!</title>
    </head>
    <body>
    <p>
    <center>
    <table border=0 cellspacing=0 cellpadding=0 width=800>
    <tr><td>
    <center><img src=\"$baseurl/nerd-do-know.jpg\" align=\"top\"></center><b>
    <font face=\"Arial, Verdana, Helvetica\" size=\"3\">
    <center>I think I know the answer!</center></font></b><p>
    <center>I searched my knowledge database and I matched your question with some of the potential<br>
    questions I can answer. Use the pulldown box below to locate the question you're looking for. <br>
    Click answer, and you've got it!</center><P>
    <center><form method=\"post\" action=\"$thiscgi\"><br>
    <input type=hidden name=step value=answer>

    <select name=\"answer\">";
    for ($j=1; $j<=$i; $j++) {
    if($stus{$j} eq "yes") {
    print "<option value=$nme{$j}>$question{$j}</option>";
    }
    }


    print "</select>

    <input type=\"submit\" value=\"Answer\">
    </form>
    <center>
    <font face=\"Arial, Verdana, Helvetica\" size=\"2\">
    <b><a href=\"Javascript:history.back();\"><< Back</a></b>
    </font>
    </center>
    <P>";
    # you can remove this blurb if you want....
    # don't feel guilty
    # really
    # it's nooo problem
    # *sniff*
    print "
    <font size=1>
    </td></tr></table>

    ";

    }

    else {
    print "<font face=\"Arial, Verdana, Helvetica\" size=\"3\">
    <html>
    <head><title>Sorry...</title></head>
    <body>

    <center>
    <table border=0 cellspacing=0 cellpadding=0 width=500>
    <tr><td>
    <img src=\"$baseurl/nerd-dont-know.jpg\" align=\"right\"><br>
    <center><b>I am sorry, I don't have an answer to that.</br></center><font size=2><p>
    </b>
    I'm sorry, I do not know the answer to your question. Maybe you can find it elsewhere in the site, or
    use different words in your question?<P>

    ## the email input box and "send button" here

    </font><p></td></tr></table>

    <font face=\"Arial, Verdana, Helvetica\" size=\"2\">
    <b><a href=\"Javascript:history.back();\"><< Back</a></b>
    </font>

    </center>

    </body>
    </html>

    ";

    }

    sub get_files {

    chdir("$basedir/$studir");
    foreach $file (@files) {
    $ls = `ls $file`;
    @ls = split(/\s+/,$ls);
    foreach $temp_file (@ls) {
    if (-d $file) {
    $filename = "$file$temp_file";
    if (-T $filename) {
    push(@FILES,$filename);
    }
    }
    elsif (-T $temp_file) {
    push(@FILES,$temp_file);
    }
    }
    }
    }
  2. #2
  3. !~ /m$/
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    May 2004
    Location
    Reno, NV
    Posts
    4,258
    Rep Power
    1810
    Initial observations:

    You need to use 'warnings' and 'strict' mode at the top of your script.

    You should not parse the user input yourself. That's a really old technique that has been replaced with the standard CGI.pm module. Much easier to get the form data, and more reliable.

    You should not have mark-up in your data file. It should just be keywords and responses. The mark-up is in the way when you want to do comparisons, and harder to maintain since you need to individually mark up each answer.

    Any mark-up would be better in a template (such as HTML::Template) where a single file can be applied consistently to every response.

    A database would probably be a better choice over a plain text file. A database is indexed so you won't have to loop over the whole file for every search. With PostgreSQL , you can do LIKE or regular expression matches. You could create relational entries so that you can direct several keywords (synonyms perhaps) to the same answer. The program logic might be simpler:

    SQL query -> (number of responses > 0) else 'sorry'

    And finally, a search interface might not be best for a FAQ. Unless the number of questions is so large, the topics would probably all fit on one page, along with a link that says 'My question wasn't answered'
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2012
    Posts
    3
    Rep Power
    0

    Cheers keath


    I appreciate your comments but this just added multiple layers of complexity that are going way over my head. I was hoping to just instigate what I had...
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,932
    Rep Power
    1225
    Actually, Keith's suggestions will aide you in writing better quality code and at the same time simplify it.

    For example, if you use the CGI module, this messy code,
    Code:
    # Get the input
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
    
    # Split the name-value pairs
    @pairs = split(/&/, $buffer);
    
    foreach $pair (@pairs) {
    ($name, $value) = split(/=/, $pair);
    
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    
    $FORM{$name} = $value;
    }
    would be simplified to this:
    Code:
    my %form = Vars;
    Or, using the OO interface, which is my preference.
    Code:
    my $cgi = CGI->new;
    my %form = $cgi->Vars;
    Each of the other sections of your code could be simplified in a similar manner.

    Going back to your question. It's unclear if you need help with the html code for the user's email address and related fields, or with the server side when sending the email.

    Comments on this post

    • keath agrees
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2012
    Posts
    3
    Rep Power
    0

    Thanks...


    I fully agree with both but there is an incompatibility with your suggestions and my competency. I thought it would be simple and quick to do this but rewriting all of this puts the finish line beyond the horizon. I'm OK with putting an HTML form together but I'm not sure how to do this within the script. Where the negative response comes up, have an input box for the email and a send button with pre-populating the form with the customer's question. In any case, thanks for your comments, I appreciate it.

IMN logo majestic logo threadwatch logo seochat tools logo