ksucpea / bettercanvas

Dark mode, better todo list, GPA calculator, and more for Canvas
MIT License
110 stars 33 forks source link

Option select all student when sending email #80

Open hsprakash opened 1 month ago

hsprakash commented 1 month ago

Would like to see a button where i can add all the "students" when composing a new inbox email through canvas.

ksucpea commented 1 month ago

Might be hard for me to test this but I'll try looking into it

AdoreJc commented 3 weeks ago

From the Canvas basic guide, it seems like Canvas supports this feature, but it may be hidden on the student end. How do I send a message to all course users in the Inbox?

AdoreJc commented 3 weeks ago

You can hold Ctrl key when selecting the students, so you don't need to open the drop-down bar every time. Is there a way to send a message to all students at once on Canvas?

hsprakash commented 3 weeks ago

I want to be able to just press a single button and be able to email everyone in "Students"

AdoreJc commented 3 weeks ago

This feature should be able to be made by using Canvas API, but only up to 100 students in each course can be selected due to the limitation of Canvas page turn. Courses API #List users in course

url:GET|/api/v1/courses/:course_id/users

You will able to get the students' name, id, and email address in each course.

AdoreJc commented 3 weeks ago

The user list in the inbox is obtained from graphql database, and uses a base64 id to identify users which is like this

TWVzc2FnZWFibGVVc2VyLTEyMzQ1Ng==
MessageableUser-123456

To get the data using post method.

URL: /api/graphql
enctype: application/json
header:
X-Csrf-Token: your token
body: 
{
    "operationName": "GetAddressBookRecipients",
    "variables": {
        "context": "section_123456_students",
        "search": "",
        "userID": "123",
        "courseContextCode": ""
    },
    "query": "query GetAddressBookRecipients($userID: ID!, $context: String, $search: String, $afterUser: String, $afterContext: String, $courseContextCode: String!) {\n  legacyNode(_id: $userID, type: User) {\n    ... on User {\n      id\n      recipients(context: $context, search: $search) {\n        sendMessagesAll\n        contextsConnection(first: 100, after: $afterContext) {\n          nodes {\n            id\n            name\n            userCount\n            __typename\n          }\n          pageInfo {\n            ...PageInfo\n            __typename\n          }\n          __typename\n        }\n        usersConnection(first: 20, after: $afterUser) {\n          nodes {\n            _id\n            id\n            name\n            shortName\n            pronouns\n            commonCoursesConnection {\n              nodes {\n                _id\n                id\n                state\n                type\n                course {\n                  name\n                  id\n                  _id\n                  __typename\n                }\n                __typename\n              }\n              __typename\n            }\n            observerEnrollmentsConnection(contextCode: $courseContextCode) {\n              nodes {\n                associatedUser {\n                  _id\n                  name\n                  __typename\n                }\n                __typename\n              }\n              __typename\n            }\n            __typename\n          }\n          pageInfo {\n            ...PageInfo\n            __typename\n          }\n          __typename\n        }\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n}\n\nfragment PageInfo on PageInfo {\n  endCursor\n  hasNextPage\n  __typename\n}"
}
context: course id
userID: your canvas id
first: items number in a page(get how much items)

It will response the student id and base64 id, which can use to send emails. When you click on the student name, it will add a span label element with base64 user id to the receiver bar, I am not sure if add an element with change the receiver list.

<span data-testid="address-book-tag" id="address-book-label-TWVzc2FnZWFibGVVc2VyLTEyMzQ1Ng==-user"></span>
AdoreJc commented 3 weeks ago

I have trid to send a message, it is trying to post a data into everyone selected, maybe we can add recipients before the message was send.

{
    "operationName": "CreateConversation",
    "variables": {
        "attachmentIds": [],
        "bulkMessage": false,
        "body": "hi",
        "contextCode": "group_123456",
        "recipients": ["123", "234"],
        "subject": "hi",
        "groupConversation": true
    },
    "query": "mutation CreateConversation($attachmentIds: [ID!], $body: String!, $bulkMessage: Boolean, $contextCode: String, $conversationId: ID, $groupConversation: Boolean, $mediaCommentId: ID, $mediaCommentType: String, $recipients: [String!]!, $subject: String, $tags: [String!]) {\n  createConversation(\n    input: {attachmentIds: $attachmentIds, body: $body, bulkMessage: $bulkMessage, contextCode: $contextCode, conversationId: $conversationId, groupConversation: $groupConversation, mediaCommentId: $mediaCommentId, mediaCommentType: $mediaCommentType, recipients: $recipients, subject: $subject, tags: $tags}\n  ) {\n    conversations {\n      ...ConversationParticipant\n      conversation {\n        ...Conversation\n        __typename\n      }\n      __typename\n    }\n    errors {\n      ...Error\n      __typename\n    }\n    __typename\n  }\n}\n\nfragment Error on ValidationError {\n  attribute\n  message\n  __typename\n}\n\nfragment ConversationParticipant on ConversationParticipant {\n  _id\n  id\n  label\n  user {\n    ...User\n    __typename\n  }\n  workflowState\n  __typename\n}\n\nfragment User on User {\n  _id\n  id\n  avatarUrl\n  pronouns\n  name\n  shortName\n  __typename\n}\n\nfragment Conversation on Conversation {\n  _id\n  id\n  contextId\n  contextType\n  contextName\n  contextAssetString\n  subject\n  canReply\n  isPrivate\n  conversationParticipantsConnection {\n    nodes {\n      ...ConversationParticipant\n      __typename\n    }\n    __typename\n  }\n  __typename\n}"
}

More dig into Canvas API, you can set recipients list with course/group ids prefixed with “course” or “group” respectively to able to send to all. Conversations API #List conversations

contextCode: group_<id> or course_<id>
recipients: An array of recipient ids. These may be user ids or course/group ids prefixed with “course_” or “group_” respectively, e.g. [recipients[]=1&recipients](https://canvas.instructure.com/doc/api/conversations.html)=2&recipients[]=course_3. If the course/group has over 100 enrollments, ‘bulk_message’ and ‘group_conversation’ must be set to true.
subject: title
body: context
AdoreJc commented 3 weeks ago

I have tried to created a new group and send message to the group with group id, but I get this.

[{"attribute":"recipients","message":"blank"}]

I think it might be there is only me in the group and I can not send message to my self. I will try it when I add some friends into the group.