• Pathaksa Tongpitak

    Hi Vince,


    Hopefully this code will help you:



            public FileAttachmentIncident[] copyAttachments(Incident incidentSource)

                List<FileAttachmentIncident> fileAttachments = new List<FileAttachmentIncident>();
                if (incidentSource.FileAttachments != null)
                    foreach (FileAttachmentCommon f in incidentSource.FileAttachments)
                        fileAttachments.Add(createFileAttachment(f, incidentSource));

                    return fileAttachments.ToArray();
                    return null;
            public FileAttachmentIncident createFileAttachment(FileAttachmentCommon f, Incident incidentSource)
                FileAttachmentIncident fa = new FileAttachmentIncident();

                fa.action = ActionEnum.add;
                fa.actionSpecified = true;

                fa.ContentType = f.ContentType;
                fa.Data = GetFileData(f.ID, incidentSource, f);

                debugLog += + " = " + f.ContentType + Environment.NewLine;
                fa.Description = f.Description;
                fa.FileName = f.FileName;
                fa.Name = f.Name;
                return fa;
            public byte[] GetFileData(ID fileID, Incident incident, FileAttachmentCommon file)
                ClientInfoHeader clientInfoHeader = new ClientInfoHeader();

                clientInfoHeader.AppID = "Query Example";

                byte[] fileData = _client.GetFileData(clientInfoHeader, incident, fileID, false);

                return fileData;

  • Pathaksa Tongpitak

    Try this in a helper file (\euf\development\helpers\sample_helper.php):


    function getContactID()
        $CI = get_instance();
        return $CI->session->getProfileData('c_id');




    Load it in your template like this:




  • Pathaksa Tongpitak

    According to Allan's post it looks like you can achieve this by following these steps:

    1. associate the Incident with Contact B
    2. add Thread to Incident (Incident.Threads.EntryType = 3)
    3. save Incident
    4. associate the Incident with Contact A
    5. save Incident
  • Pathaksa Tongpitak

    When you open this page the Widgets to display the incident are calling the Incident_Model.

    This model checks whether you are logged in or not. The default behaviour requires you to login before you can update incidents.

    If you wish to get around this you need to create custom Widgets and Models to update the incident using ROQL.

    Good luck.

  • Pathaksa Tongpitak

    I also get the message:

    The type or namespace name 'RightNowSyncPort' could not be found (are you missing a using directive or an assembly reference?)

    I am using VS 2010.

    I followed the Getting Started topic in the Connect_Web_Services_for_SOAP_February_2011 guide:


    I found the solution. You must include a "using" statement in top of your source file.

    If you're following the Getting Started tutorial, the namespace is SampleClient (after the renaming instruction). I named the SOAP WSDL webservice RightNowService.

    When I add the following line of code on top of my source, it works for me:

    using SampleClient.RightNowService;

    This is not mentioned in the tutorial Getting Started.

    Maybe Chris can make sure the documents are updated if this is verified to be incomplete?

    Good luck fellows!



  • Pathaksa Tongpitak

    I suggest you add a question to it:

    • How may I assist you?
    • How can I help you?
    • What can I do for you?
  • Pathaksa Tongpitak


    We managed to add some custom fields to the incident by these steps:

    1. modifying the logic.js _submitFeedback() function to post to a custom controller

    2. create custom controller with a modified submitAnswerFeedback to populate Custom Fields

    Hopefully the code below will point you to the right direction.


        _submitFeedback: function()
            var eventObject = [];
            eventObject[0] = new RightNow.Event.EventObject();
            eventObject[0].w_id = this.instanceID;
            eventObject[0].data = {
                    "summary" :,
                    "a_id"    :,
                    "rate"    : this._rate,
                    "dialog_threshold" :,
                    "options_count"    :,
                    "message" : this._feedbackField.value
            if (
                eventObject[0] =;
            else if (this._emailField)
                eventObject[0] = this._emailField.value;
            var postData = {
                "email": eventObject[0],
                "message": eventObject[0].data.message,
                "summary": eventObject[0].data.summary,
                "a_id": eventObject[0].data.a_id,
                "rate": eventObject[0].data.rate,
                "threshold": eventObject[0].data.dialog_threshold,
                "submitfeedback": eventObject[0].data.submitfeedback,
                "options_count": eventObject[0].data.options_count,

                "department_id" :,                     // will be inserted in custom field  
                "queue_id" :  // will be inserted in custom field
            RightNow.Ajax.makeRequest("/ci/ajaxCustom/submitAnswerFeedback", postData, {"data": {"eventName": "evt_answerFeedbackSubmitResponse", "data": eventObject}});

            return false;


        function submitAnswerFeedback()

            // Do not submit if post data is missing
            if (empty($_POST))

            $answerID = $this->input->post('a_id');
            if($answerID === 'null')
                $answerID = null;

            $rate = $this->input->post('rate');
            $name = null;
            $message = $this->input->post('message');
            $givenEmail = $this->input->post('email');
            $threshold = $this->input->post('threshold');
            $optionsCount = $this->input->post('options_count');

            $incidentId = $this->Incident_model->submitFeedback($answerID, $rate, $threshold, $name, $message, $givenEmail, $optionsCount);

            // Link department to incident
            $incident = RNCPHP_v1_1\Incident::fetch($incidentId);
            $departmentId = $this->input->post('department_id');
            $incident->CustomFields->department_id = $departmentId;

            // Queue ID        
            $queueID = $this->input->post('queue_id');
            $incident->CustomFields->feedback_queue_id = $queueID;
            // Link answer to incident
            $answer = RNCPHP_v1_1\Answer::fetch($answerID);
            $incident->CustomAttributes->CO->answer_id = $answer;
            $incident->CustomFields->answer_id = $answerID;

            echo json_encode($incidentId);

  • Pathaksa Tongpitak

    Hi Idavison,

    I was giving another example with lesser code.

    This is certainly the missing link for refreshing the report. I was suspecting this function was responsible I just didn't know how to implement it.

    Thanks a lot , I will test it and let you know if it works.


  • Pathaksa Tongpitak

    Same happends when I insert a filter using an Hook:


      function PreReportGetHook($hookData)
            $aContactIDFilter = array('100780', '100786');
          if(in_array($hookData['data']['reportId'], $aContactIDFilter))
            $hookData['data']['filters']['c_id']->filters->fltr_id = 1;
            $hookData['data']['filters']['c_id']->filters->oper_id = 10;
            $hookData['data']['filters']['c_id']->filters->data = getContactID();
            $hookData['data']['filters']['c_id']->filters->rnSearchType = 'custom';



    The report keeps reloading when refreshing the report and fetching data using AJAX when you try to sort a column or navigate through the paginator.

  • Pathaksa Tongpitak

    It works indeed when you use a string like "'7,8,9'" instead of an array. Thanks very much!

  • Pathaksa Tongpitak

    Thank you.

    I am now using an hook and want to put access filters with operator type "In menu".

    However the code below treats the filter as equal as last item in array, in this case with equals access ID = 9.

    Am I doing something wrong?

    function PreReportGetHook($hookData)

        if($hookData['data']['reportId'] == '100767')
            $accesslevels = array(7,8,9);
            $hookData['data']['filters']['access_id']->filters->fltr_id = 1;
            $hookData['data']['filters']['access_id']->filters->oper_id = 10;
            $hookData['data']['filters']['access_id']->filters->data = $accesslevels;
            $hookData['data']['filters']['access_id']->filters->rnSearchType = 'custom';     



  • Pathaksa Tongpitak


    That is absolutely possible.

    All you have to do is include the header from

    The last line of the header is something like this:

    list ($common_mbid, $rnw_mbid) = msg_init($p_cfgdir, 'msgbase', array('common', 'rnw'));

    And after that you write the following:
    use RightNow\Connect\v1_1 as RNCPHP;
    require_once( get_cfg_var("doc_root")."/ConnectPHP/Connect_init.php" );


    Good luck!

  • Pathaksa Tongpitak

    The contents of the $ee_file_name can be configured by using a Connector template which you can edit using the RightNow FileManager in the console (just search for the Connector in the dropdown).

    In the connector directory you can have the following incident template:



    The contents of this file contains field separated with |,| like this:



    You can add more fields yourself and then in your external event explode the values using "|,|"


    Good luck

  • Pathaksa Tongpitak

    I would suggest to use Custom Objects instead of the Messagebase.

    Package = Messagebase

    CO = Messagebase.Text

    • Messagebase.Text.ID
    • Messagebase.Text.LanguageID
    • Messagebase.Text.Key
    • Messagebase.Text.Value

    CO = Messagebase.Language

    • Messagebase.Language.ID
    • Messagebase.Language.Code
  • Pathaksa Tongpitak

    It might not be an overkill at all if you managed to create a generic add-in which makes use of WorkspaceConfig properties to specify the fields and External Event names so you can use it on any Primary/Custom Object workspace you like.