groupme-js / GroupMeCommunityDocs

21 stars 8 forks source link

Add documentation for Group Events #6

Open not-so-smart opened 2 years ago

not-so-smart commented 2 years ago

Not to be confused with Calendar Events Events are things that happen in Groups on GroupMe. When an Event happens, a Message is emitted. The message has a top-level event property containing an Event object.

event object structure:

{
    type: string;
    data: object;
}

To make things even more confusing, certain Group Events correspond to Calendar Events. If the Event is related to a Calendar Event, the Message will have an Attachment of type event (described below)

event attachment structure:

{
    type:     "event";
    view:     "brief" | "full";
    event_id: string;
}

I analyzed a bunch of messages from a large group and found these event types. (Sample: 80,000 messages from 1 group, August 2020-August 2021) bot.add bot.del calendar.event.created calendar.event.starting calendar.event.user.going calendar.event.user.not_going calendar.event.user.undecided group.added_to_directory group.avatar_change group.like_icon_set group.name_change group.office_mode_disabled group.office_mode_enabled group.role_change_admin group.theme_change group.topic_change group.type_change membership.announce.added membership.announce.joined membership.announce.rejoined membership.avatar_changed membership.nickname_changed membership.notifications.autokicked membership.notifications.exited membership.notifications.removed message.deleted poll.created poll.finished poll.reminder

There could easily be more, but these are the ones I found in my sample. I think this should be enough for a starting point for a new doc page. The corresponding data object structures for each type will be a pain to document... I'll start posting examples in the comments

not-so-smart commented 2 years ago

object reference

some of these data structures are very repetitive so I've condensed some common types into interfaces

for example, any User object will have two fields: id and nickname

User {
    id:       number;
    nickname: string;
}

any other common types will be at the end of each section

not-so-smart commented 2 years ago

Bots

bot.add

{
    type: "bot.add",
    data: {
        user: User,
        bot:  string,
    },
}

bot.del

{
    type: "bot.del",
    data: {
        user: User,
        bot:  string,
    },
}
not-so-smart commented 2 years ago

Calendar

calendar.event.created

{
    type: "calendar.event.created",
    data: {
        event: {
            id:   string,
            name: string,
        },
        url:   string,
        user:  UserWeird,
    },
}

Calendar User Responses

calendar.event.user.going

{
    type: "calendar.event.user.going",
    data: CalendarEventUserData,
}

calendar.event.user.not_going

{
    type: "calendar.event.user.not_going",
    data: CalendarEventUserData,
}

calendar.event.user.undecided

{
    type: "calendar.event.user.undecided",
    data: CalendarEventUserData,
}

all of the above use the same data structure

CalendarEventUserData {
    event: {
        id:   string,
        name: string,
    },
    user:  UserWeird,
}
not-so-smart commented 2 years ago

Group updates

TODO: there's almost certainly a "change owner" event in here but I don't feel like finding a sample for it also, is it possible to remove a group from a directory? if so then there's probably an event for that too

group.added_to_directory

{
    type: "group.added_to_directory",
    data: {
        user:           User,
        directory_name: string,
    },
}

group.avatar_change

{
    type: "group.avatar_change",
    data: {
        user:       User,
        avatar_url: string,
    },
}

group.like_icon_set

{
    type: "group.like_icon_set",
    data: {
        user:      User,
        like_icon: {
            pack_id:    number,
            pack_index: number,
            type:       string,
        },
    },
}

group.name_change

{
    type: "group.name_change",
    data: {
        user: User,
        name: string,
    },
}

group.office_mode_disabled

{
    type: "group.office_mode_disabled",
    data: {
        user: User,
    },
}

group.office_mode_enabled

{
    type: "group.office_mode_enabled",
    data: {
        user: User,
    },
}

group.role_change_admin

{
    type: "group.role_change_admin",
    data: {
        user:   User,
        role:   "admin",
        member: User,
    },
}

group.theme_change

{
    type: "group.theme_change",
    data: {
        user:       User,
        theme_name: string,
    },
}

group.topic_change

{
    type: "group.topic_change",
    data: {
        user:  User,
        topic: string,
    },
}

group.type_change

{
    type: "group.type_change",
    data: {
        user: User,
        type: string,
    },
}
not-so-smart commented 2 years ago

Members

membership.announce.added

{
    type: "membership.announce.added",
    data: {
        added_users: User[],
        adder_user:  User,
    },
}

membership.announce.joined

{
    type: "membership.announce.joined",
    data: {
        user: User,
    },
}

membership.announce.rejoined

{
    type: "membership.announce.rejoined",
    data: {
        user: User,
    },
}

membership.avatar_changed

{
    type: "membership.avatar_changed",
    data: {
        user:       User,
        avatar_url: string,
    },
}

membership.nickname_changed

{
    type: "membership.nickname_changed",
    data: {
        user: User,
        name: string,
    },
}

membership.notifications.autokicked

{
    type: "membership.notifications.autokicked",
    data: {
        user: User,
    },
}

membership.notifications.exited

{
    type: "membership.notifications.exited",
    data: {
        removed_user: User,
    },
}

membership.notifications.removed

{
    type: "membership.notifications.removed",
    data: {
        remover_user: User,
        removed_user: User,
    },
}
not-so-smart commented 2 years ago

Messages

more like "message" cuz still no edit/pin

message.deleted

{
    type: "message.deleted",
    data: {
        message_id:     string,
        deleted_at:     number,
        deletion_actor: "sender",
        deleter_id:     string,
    },
}
not-so-smart commented 2 years ago

Polls

poll.created

{
    type: "poll.created",
    data: {
        conversation: {
            id: string,
        },
        poll:         {
            id:       string,
            subject:  string,
        },
        user:         UserWeird,
    },
}
not-so-smart commented 2 years ago

Messages

more like "message" cuz still no edit/pin

message.deleted

{
    type: "message.deleted",
    data: {
        message_id:     string,
        deleted_at:     number,
        deletion_actor: "sender",
        deleter_id:     string,
    },
}
  • deletion_actor - this is always "sender" for now

    • at some point, admins/owner will (maybe) be able to delete other users' messages

the deletion_actor can also be system when GroupMe steps in to remove messages due to abuse

however, the deleter_id remains unchanged. You would think it gets set to system or null but instead it just stays as the author's ID

not-so-smart commented 2 years ago

Polls

poll.finished

{
    type: "poll.finished",
    data: {
        conversation: {
            id: string,
        },
        options:      Option[],
        poll:         {
            id:       string,
            subject:  string,
        },
    },
}
  • options - an array of objects, each following the format:

    • Option {
      id:         string,
      title:      string,
      votes?:     number,
      voter_ids?: string[],
      }
    • options[i].votes - (optional) may be missing

    • options[i].voter_ids - (optional) may be missing

    • TODO: my theory is that one of these is always present -- either votes for anonymous polls or voter_ids for open polls

    • however I don't feel like checking this so further research is needed

votes is always present (regardless of type/visibility) UNLESS the option has 0 votes, in which case it is omitted entirely.

voter_ids is also present alongside votes if the poll's visibility is set to public.

However, if the option has 0 votes, both votes and voter_ids fields are omitted.