Skip to content

Get User Ratings and Feedback at End of Meeting

Guido Jäkel edited this page Feb 14, 2021 · 11 revisions

The Feedback Formular - Allow to Users to give Ratings for your Service

This becomes a new Feature in release V1.3.1. It' an drop-in-replacement of the commercial CallStats service used by the upstrem Jitsi Meeting.

For the user point of view, it consists of a feedback form that will appear at a gracefull shutdown of a meeting via the hook button. The form will please the user to rate the quality of audio and video using two well-known five-stars selection bars. In addition, there's a text area to allow to leave comments.

Configuration

The Feedback feature may be customized at the Admin GUI at Pàdé|Jitsi|User Interface|Feedback Page Configuration. They you may

  • enable or disable the the feedback form on leaving a meeting
  • customize the description message, the placeholder text for the comment textarea, the label of the submit button and the following success and error messages. You may use HTML to format the messages. You may check you customizing by directly invoke the feedback form via an URL similar to https://example.com/pade/static/close3.html

Evaluation

The user ratings are received by OpenFire. The data set consist of

  • the timestamp of the rating event
  • the displayName of the sending participant
  • the callStatsUserName used by the JVB as an unique anonymous identifier for logging the participants meeting session. This is the ID used for the last, i.e. just ended session.
  • if entered, the comment
  • if rated, the given number of stars for audio and video

The feedback is stored as an Audit Log entry. At the event colum you'll find it as something like

pade feedback A/V-rating: 3/4

or a -, if unrated. If there is a textual feedback, the length of this message is appended. You may read the user message by using "show details".

The comment is also written into the application log at INFO level as a JSON-formatted string:

20210124-144343.843 INFO [Jetty-QTP-BOSH-313] [o.j.o.p.o.FeedbackServlet] {"callStatsUserName":"Wilfrid-qiY","displayName":"jaekel","comment":"OK","audio":"4","video":"2"}

If there's no comment or audio/video was unrated, the corresponding tags are left out.

Here some sketch how to evaluate:

#!/bin/bash
#
# 20210205/gj
# 20210214/gj   add binning bar


if [ $# -eq 0 ]; then
  cat >&2 <<-EOT
        syntax : $0 logfile...
        purpose: evaluate pade user feedback entries from openfire log

        The feedback aspects logged by the FeedbackServlet are counted and displayed together with the average value and a distribution.
        Below, all feedback is listed.

        Note: The logfile may be already bzipped.
        EOT
  exit 1
fi


declare -i CNT_AUDIO=0 SUM_AUDIO=0 CNT_VIDEO=0 SUM_VIDEO=0 CNT_COMMENT=0
declare -a CNTS_AUDIO CNTS_VIDEO
while read LINE; do
  # 20210205-104517.319 INFO [Jetty-QTP-BOSH-235213] [o.j.o.p.o.FeedbackServlet] {"callStatsUserName":"Earnestine-8my","displayName":"Schmidt, Tobias","comment":"","audio":"5","video":"5"}

  TIMESTAMP=""; REGEX='^([^ ]+)'; [[ "$LINE" =~ $REGEX ]] && TIMESTAMP="${BASH_REMATCH[1]}"
  CALL_STATS_USERNAME=""; REGEX='"callStatsUserName":"([^"]*)"'; [[ "$LINE" =~ $REGEX ]] && CALL_STATS_USERNAME="${BASH_REMATCH[1]}"
  DISPLAY_NAME=""; REGEX='"displayName":"([^"]*)"'; [[ "$LINE" =~ $REGEX ]] && DISPLAY_NAME="${BASH_REMATCH[1]}"
  AUDIO="-"; REGEX='"audio":"([^"]*)"'; [[ "$LINE" =~ $REGEX ]] && AUDIO="${BASH_REMATCH[1]}" && : $((CNT_AUDIO++, SUM_AUDIO+=AUDIO, CNTS_AUDIO[AUDIO]++))
  VIDEO="-"; REGEX='"video":"([^"]*)"'; [[ "$LINE" =~ $REGEX ]] && VIDEO="${BASH_REMATCH[1]}" && : $((CNT_VIDEO++, SUM_VIDEO+=VIDEO, CNTS_VIDEO[VIDEO]++))
  COMMENT=""; REGEX='"comment":"([^"]+)"'; [[ "$LINE" =~ $REGEX ]] && COMMENT="${BASH_REMATCH[1]}" && : $((CNT_COMMENT++))

  printf -v LINE "%s %1s %1s %-15s %-31s %s\n"  "$TIMESTAMP" "$AUDIO" "$VIDEO" "$CALL_STATS_USERNAME" "$DISPLAY_NAME" "$COMMENT"
  FEEDBACK+="$LINE"

done < <(bzgrep -h "FeedbackServlet" $@)

AVG_AUDIO="---"; [ "$CNT_AUDIO" -gt 0 ] && AVG_AUDIO=$((SUM_AUDIO*100/CNT_AUDIO))
AVG_VIDEO="---"; [ "$CNT_VIDEO" -gt 0 ] && AVG_VIDEO=$((SUM_VIDEO*100/CNT_VIDEO))
for ((RATE=1; RATE <= 5; RATE++)); do
  AUDIO=$((CNT_AUDIO > 0 ? CNTS_AUDIO[RATE]*100/CNT_AUDIO : 0 ))
  VIDEO=$((CNT_VIDEO > 0 ? CNTS_VIDEO[RATE]*100/CNT_VIDEO : 0 ))
  BAR_AUDIO+="$([ $AUDIO -gt 0 ] && eval printf '%.s$RATE' {1..$AUDIO})"
  BAR_VIDEO+="$([ $VIDEO -gt 0 ] && eval printf '%.s$RATE' {1..$VIDEO})"
done

printf "audio   : %5s -> %s  %s\n" "$CNT_AUDIO" "${AVG_AUDIO:0:-2}.${AVG_AUDIO: -2:2}" "$BAR_AUDIO"
printf "video   : %5s -> %s  %s\n" "$CNT_VIDEO" "${AVG_VIDEO:0:-2}.${AVG_VIDEO: -2:2}" "$BAR_VIDEO"
printf "comments: %5s\n" "$CNT_COMMENT"
printf "feedback:\n%s\n" "$FEEDBACK"