Skip to content

API Exploration: MySchool

Marks Polakovs edited this page Nov 13, 2018 · 8 revisions

This page shall document our exploration of the MySchool "API".

Unless otherwise stated, all requests require the Cookie: PHPSESSID=SESSION_ID header.

The server seems to accept both multipart/form-data and application/x-www-form-urlencoded.

Login

OUT OF DATE since O365 introduction!

POST https://es.msm.io/ with the parameters

  • user_email: the user's email
  • user_password: the user's password

Response code will be either 302 with a Location of ./ on success or 302 with a Location of /login.php?m=3&email=USER_EMAIL on failure.

Additionally, the PHPSESSID cookie will be set. This is the login session. This is important.

Logout

GET /login.php?m=1.

Account Info

GET /content/common/account_edit.php. The response is HTML (bleurgh) that needs to be scraped for the following fields:

  • Full name: selector #password_form > table > tbody > tr:nth-child(1) > td:nth-child(2)
  • Email: selector #password_form > table > tbody > tr:nth-child(2) > td:nth-child(2)
  • User ID: selector #password_form > table > tbody > tr:nth-child(3) > td:nth-child(2)
  • Group membership: TODO

Schedule

POST /data/common_handler.php?action=Contact::AJAX_U_GetSchedule.

Parameters:

  • inc_appointment: No idea what it changes. Keep as true, just in case.
  • user_id: Doesn't change anything, however omitting it may break things.
  • start: The UNIX timestamp of the start of the period of timetable entries to be returned.
  • end: The UNIX timestamp of the end of the period of timetable entries to be returned.

The response is JSON in the format

[
  {
    "entry_type": "Course",
    "id": "118420",
    "title": "S5L2-ENC",
    "sql_date": "2016-09-12 ",
    "start": "2016-09-12T08:45:00Z",
    "end": "2016-09-12T09:30:00Z",
    "param_1": "SA014N",
    "param_2": "Period 1          -",
    "allDay": false,
    "teacher_name_list": "REDACTED",
    "room_id": "3",
    "course_diary_id": "0",
    "period_id": "1",
    "color": "#80f31f",
    "textColor": "#000"
  },
  // ...
]

Fields:

NOTE: Only the entry_type == 'Course' fields are documented. Others see below..

  • entry_type: Course for lessons. There is also Exercise, see below.
  • id: The ID of the entry. Seems to be unique for courses.
  • title: Self-explanatory.
  • sql_date: Unknown.
  • start: The time of the start. Note: Even though the datetime string includes the Z specifier, implying that the time is in UTC, it is actually in local (school) time. This can confuse parsers, so consider removing the Z before parsing the datetime.
  • end: See above.
  • param_1: Seems to be used for the room number.
  • param_2: Seems to be used for the period number. No idea what the weird spacing and hyphen are about.
  • allDay: Unknown. Seems to always be false.
  • teacher_name_list: The teacher's name.
  • room_id: Unknown.
  • course_diary_id: Unknown.
  • period_id: The period number.
  • color: The display color.
  • textColor: The text color. Seems to always be "#000".

Graded exercises: List

Request: see above. Response will be

{  
        "entry_type":"Exercise",
        "id":"68156",
        "title":"test long",
        "sql_date":"2016-10-14 ",
        "start":"2016-10-14T00:00:00Z",
        "end":"2016-10-14T00:00:00Z",
        "param_1":"Test \/ S5L3-FRC",
        "param_2":"<a href=\"javascript:alert(68156\">asd<\/a>",
        "allDay":true,
        "teacher_name_list":"",
        "room_id":"0",
        "course_diary_id":"0",
        "period_id":"",
        "color":"#747AFC"
    }

The fields are:

  • entry_type: Exercise.
  • id: The ID of the entry. Seems to be unique for exercises.
  • title: Self-explanatory.
  • sql_date: Unknown.
  • start: 00:00:00 on the day the exercise is due.
  • end: See above.
  • param_1: ${exercise_type$} / ${course}
  • param_2: No idea. Seems to be some leftover testing code.
  • allDay: Unknown. Seems to always be true.
  • teacher_name_list: Seems to always be blank.
  • room_id: Unknown.
  • course_diary_id: Unknown.
  • period_id: Seems to always be blank.
  • color: The display color.
  • textColor: The text color. Seems to always be "#000".

Graded exercises: Details

  1. GET /content/common/calendar_for_students.php.

  2. Parse out the user_id (regex: <input.*id="user_id".*value="([0-9]+)")

  3. POST /data/common_handler.php?action=AssignedExercise::AJAX_U_GetStudentExercise. Include the exercise_id from above and the user_id from step 2. Warning: If you forget the user_id, you will be INSTABANNED!

Response will be HTML (bleurgh), as follows:

<table cellpadding='4' cellspacing='0'><tbody>
		<tr>
			<td class="field_label">Course</td>
			<td>S5L1-LVA</td>
</tr>
		<tr>
			<td class="field_label">Short description</td>
			<td>Ausekļa dzeja</td>
</tr>
		<tr>
			<td class="field_label">Type</td>
			<td>Homework</td>
</tr>
		<tr>
			<td class="field_label">Due date</td>
			<td>05/10/2016</td>
</tr>
		<tr>
			<td class="field_label">General comment</td>
			<td><p>Jāizlasa Ausekļa dzejoļi, jāsagatvo stāstījums par dzejas motīviem un tēliem.</p></td>
</tr>
		<tr>
			<td colspan=2>&nbsp;</td>
</tr>
		<tr>
			<td class="field_label">Student grade</td>
			<td>9/10</td>
</tr>
		<tr>
			<td class="field_label">Status</td>
			<td>Graded</td>
</tr>
		<tr>
			<td class="field_label">Supporting comment</td>
			<td>&nbsp;</td>
</tr>
		<tr>
			<td colspan=2>&nbsp;</td>
</tr>
		<tr>
			<td class="th">Name</td>
			<td class="th right">Comment</td>
</tr>
		<tr id='no_file_yet'>
			<td colspan=2 class="center" style="font-style:italics">no registered files</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>

Selectors:

Item Selector
Course tr:nth-child(1) > td:nth-child(2)
Short description tr:nth-child(2) > td:nth-child(2)
Type tr:nth-child(3) > td:nth-child(2)
Due date tr:nth-child(4) > td:nth-child(2)
General comment (NB: can contain HTML) tr:nth-child(5) > td:nth-child(2)
Grade tr:nth-child(7) > td:nth-child(2)
Status tr:nth-child(8) > td:nth-child(2)
Supporting comment (NB: can contain HTML) tr:nth-child(9) > td:nth-child(2)
Files TODO