Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨(project) pass moodle context to copilot #8

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 45 additions & 10 deletions block_iagora.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,36 +42,53 @@ public function init() {
* @return string The block HTML.
*/
public function get_content() {
if ($this->content !== null) {
if (isset($this->content)) {
return $this->content;
}

$this->content = new stdClass();
$this->content->footer = '';
$copilotendpointurl = isset($this->config->copilotendpointurl) ? $this->config->copilotendpointurl : '';
$copilotendpointurl = $this->config->copilotendpointurl;
$directlineurl = $this->config->directlineurl;

if (empty($copilotendpointurl)) {
if (!isset($copilotendpointurl)) {
$this->content->text = get_string('nocopilotendpointurl', 'block_iagora');
} else {
$this->content->text = $this->generate_chat_content($copilotendpointurl);
return $this->content;
}

if(!isset($directlineurl)) {
$this->content->text = get_string('nodirectlineurl', 'block_iagora');
return $this->content;
}
return $this->content;

$token = json_decode(file_get_contents($copilotendpointurl), true)['token'];
$this->content->text = $this->generate_chat_content($directlineurl, $token);
return $this->content;
}

/**
* Generate the HTML content for the chat block.
*
* @param string $copilotendpointurl The URL to be used in the iframe.
* @param string $directlineurl The Direct Line API base URL.
* @param string $token The Copilot Direct Line token.
* @return string The generated HTML content for the chat.
*/
private function generate_chat_content($copilotendpointurl) {
global $OUTPUT;
private function generate_chat_content($directlineurl, $token) {
global $OUTPUT, $USER, $COURSE, $PAGE;
// Generate a unique identifier for the chat container.
// die(var_dump($PAGE));
$chatid = uniqid('iagora_chat_');
$info = get_fast_modinfo($COURSE);
$context = [
'chatId' => $chatid,
'tokenEndpointURL' => $copilotendpointurl,
'directLineURL' => $directlineurl,
'moodleActivityContent' => $PAGE->activityrecord->content,
'moodleActivityName' => $PAGE->activityrecord->name,
'moodleActivityType' => $PAGE->pagetype,
'moodleCourseName' => $COURSE->fullname,
'moodleSectionName' =>$info->get_section_info($PAGE->cm->sectionnum)->name,
'moodleUserName' => $USER->firstname,
'token' => $token,
];
return $OUTPUT->render_from_template('block_iagora/chat', $context);
}
Expand Down Expand Up @@ -104,7 +121,25 @@ public function instance_allow_config() {
public function instance_config_save($data, $nolongerused = false) {
if (isset($data->copilotendpointurl)) {
$data->copilotendpointurl = clean_param($data->copilotendpointurl, PARAM_URL);
$directlineurl = $this->get_directline_url($data->copilotendpointurl);
$data->directlineurl = clean_param($directlineurl, PARAM_URL);
}
return parent::instance_config_save($data, $nolongerused);
}

/**
* Return the Direct Line API base URI from the Copilot token endpoint URL.
*
* @param string $copilotendpointurl The Copilot token endpoint URL.
* @return string The Direct Line API base URL.
*/
public function get_directline_url($copilotendpointurl) {
$copilotendpoint = parse_url($copilotendpointurl);
parse_str($copilotendpoint['query'], $query);
$base = "{$copilotendpoint['scheme']}://{$copilotendpoint['host']}";
$path = "/powervirtualagents/regionalchannelsettings";
$url = "{$base}{$path}?api-version={$query['api-version']}";
$response = file_get_contents($url);
return json_decode($response, true)['channelUrlsById']['directline'];
}
}
1 change: 1 addition & 0 deletions lang/en/block_iagora.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@
$string['copilotendpointurl_desc'] = 'Microsoft Copilot Token Endpoint URL';
$string['copilotendpointurl_help'] = 'The Microsoft Copilot Token Endpoint URL is used to get the Direct Line token';
$string['nocopilotendpointurl'] = 'No Copilot Endpoint URL defined for this block. Please configure it in the block parameters';
$string['nodirectlineurl'] = 'Failed to get Direct Line URL. Please check and update the Copilot Endpoint URL parameter';
$string['pluginname'] = 'IAGORA';
43 changes: 15 additions & 28 deletions templates/chat.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,17 @@

Context variables required for this template:
* chatId: The ID of the chat div element where to render the chat block.
* tokenEndpointURL: The Copilot Token Endpoint URL for native apps.
* directLineURL: The Copilot Direct Line API base URL.
* token: The Copilot Direct Line token.

Example context (json):
{
"chatId": "iagora_chat_55a6cad25a0f6",
"tokenEndpointURL": "https://insert/your/copilot/endpoint/url"
"directLineURL": "https://directline.botframework.com",
"token": "RCurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR..."
}
}}
{{#pix}} t/message, core {{/pix}}
<div id="{{chatId}}" role="main"></div>
<div id="{{chatId}}" role="main" style="height: 500px;"></div>

<script crossorigin="anonymous" src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>

Expand All @@ -47,30 +48,8 @@
const styleOptions = {
hideUploadButton: true
};
const tokenEndpointURL = new URL('{{tokenEndpointURL}}');
const locale = document.documentElement.lang || 'en';
const apiVersion = tokenEndpointURL.searchParams.get('api-version');

const [directLineURL, token] = await Promise.all([
fetch(new URL(`/powervirtualagents/regionalchannelsettings?api-version=${apiVersion}`, tokenEndpointURL))
.then(response => {
if (!response.ok) {
throw new Error('Failed to retrieve regional channel settings.');
}
return response.json();
})
.then(({channelUrlsById: {directline}}) => directline),
fetch(tokenEndpointURL)
.then(response => {
if (!response.ok) {
throw new Error('Failed to retrieve Direct Line token.');
}
return response.json();
})
.then(({token}) => token)
]);

const directLine = WebChat.createDirectLine({domain: new URL('v3/directline', directLineURL), token});
const directLine = WebChat.createDirectLine({domain: new URL('v3/directline', '{{directLineURL}}'), token: '{{token}}'});

const subscription = directLine.connectionStatus$.subscribe({
next(value) {
Expand All @@ -80,7 +59,15 @@
localTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
locale,
name: 'startConversation',
type: 'event'
type: 'event',
value: {
'MoodleActivityContent': '{{moodleActivityContent}}',
'MoodleActivityName': '{{moodleActivityName}}',
'MoodleActivityType': '{{moodleActivityType}}',
'MoodleCourseName': '{{moodleCourseName}}',
'MoodleSectionName': '{{moodleSectionName}}',
'MoodleUserName': '{{moodleUserName}}',
}
})
.subscribe();
subscription.unsubscribe();
Expand Down
Loading