-
Notifications
You must be signed in to change notification settings - Fork 1
API Exploration: MySchool
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
.
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.
GET /login.php?m=1
.
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
POST /data/common_handler.php?action=Contact::AJAX_U_GetSchedule
.
Parameters:
-
inc_appointment
: No idea what it changes. Keep astrue
, 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 alsoExercise
, 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 theZ
specifier, implying that the time is in UTC, it is actually in local (school) time. This can confuse parsers, so consider removing theZ
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"
.
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"
.
-
GET
/content/common/calendar_for_students.php
. -
Parse out the user_id (regex:
<input.*id="user_id".*value="([0-9]+)"
) -
POST
/data/common_handler.php?action=AssignedExercise::AJAX_U_GetStudentExercise
. Include theexercise_id
from above and theuser_id
from step 2. Warning: If you forget theuser_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> </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> </td>
</tr>
<tr>
<td colspan=2> </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 |