matrix-org / matrix-js-sdk

Matrix Client-Server SDK for JavaScript
Apache License 2.0
1.61k stars 589 forks source link

Lack of examples and documentation #608

Closed pixelass closed 4 months ago

pixelass commented 6 years ago

Sorry but I just spent hours trying to figure out how to get the most basic things to work. I had to look through google and ask colleagues to even find the right documentation.

It seems you expect developers to read your source code to understand how things work.

If there is any link to prove me wrong please add it here or in the Readme (in a place ewhere everybody can see it)

To me it seems like a waste of time to even try integrating this in my app. I'm not sure if that is the feeling you want to reflect on developers.

I don't mean to be rude. I just have a hard time expressing myself.

Half-Shot commented 6 years ago

https://github.com/matrix-org/matrix-js-sdk#api-reference points to https://matrix-org.github.io/matrix-js-sdk/0.9.2/index.html which contains a fairly complete documentation on the library.

theilgaard commented 6 years ago

I have now written a simple client and am working on implementing e2e crypto on it. While the e2e impl. guide helps for understanding the protocol, it is unclear how much is covered by the sdk and should be called by the client, and how much is internal.

I do not think usage examples, or more strict guide-lining would hurt the project. The existing usage examples are very nice, and do not need to be exhaustive, but could say ".. see the rest of the events here." whilst pointing to the events in the reference or similar.

select commented 6 years ago

here is a list of all functions of the MatrixClient class

I found it a bit difficult to discover all functions without an index, so I created one

new MatrixClient(opts) _requestTokenFromEndpoint(endpoint, params) → {module:client.Promise} acceptGroupInvite(groupId, opts) → {module:client.Promise|module:http-api.MatrixError} addListener(event, listener) → {EventEmitter} addPushRule(scope, kind, ruleId, body, callback) → {module:client.Promise|module:http-api.MatrixError} addRoomToGroup(groupId, roomId, isPublic) → {module:client.Promise|module:http-api.MatrixError} addRoomToGroupSummary(groupId, roomId, categoryId) → {module:client.Promise|module:http-api.MatrixError} addThreePid(creds, bind, callback) → {module:client.Promise|module:http-api.MatrixError} addUserToGroupSummary(groupId, userId, roleId) → {module:client.Promise|module:http-api.MatrixError} backPaginateRoomEventsSearch(searchResults) → {module:client.Promise|Error} ban(roomId, userId, reason, callback) → {module:client.Promise|module:http-api.MatrixError} cancelAndResendEventRoomKeyRequest(event) cancelPendingEvent(event) cancelUpload(promise) → {boolean} claimOneTimeKeys(devices, key_algorithm opt) → {module:client.Promise} clearStores() → {Promise} createAlias(alias, roomId, callback) → {module:client.Promise|module:http-api.MatrixError} createFilter(content) → {Filter|module:http-api.MatrixError} createGroup(content) → {module:client.Promise|module:http-api.MatrixError} createRoom(options, callback) → {module:client.Promise|module:http-api.MatrixError} deactivateAccount(auth, erase) → {module:client.Promise} deleteAlias(alias, callback) → {module:client.Promise|module:http-api.MatrixError} deleteDevice(device_id, auth) → {module:client.Promise|module:http-api.MatrixError} deleteMultipleDevices(devices, auth) → {module:client.Promise|module:http-api.MatrixError} deletePushRule(scope, kind, ruleId, callback) → {module:client.Promise|module:http-api.MatrixError} deleteRoomTag(roomId, tagName, callback) → {module:client.Promise|module:http-api.MatrixError} deleteThreePid(medium, address) → {module:client.Promise|module:http-api.MatrixError} downloadKeys(userIds, forceDownload) → {Promise} downloadKeysForUsers(userIds, opts opt) → {module:client.Promise} dropFromPresenceList(callback, userIds) → {module:client.Promise|module:http-api.MatrixError} emit(event, listener) → {boolean} exportRoomKeys() → {module:client.Promise} forget(roomId, deleteRoom, callback) → {module:client.Promise|module:http-api.MatrixError} generateClientSecret() → {string} getAccessToken() → (nullable) {String} getAccountData(eventType) → (nullable) {object} getCanResetTimelineCallback() → (nullable) {function} getCasLoginUrl(redirectUrl) → {string} getCurrentUploads() → {array} getDeviceEd25519Key() → (nullable) {string} getDeviceId() → (nullable) {string} getDevices() → {module:client.Promise|module:http-api.MatrixError} getDomain() → (nullable) {string} getEventMapper() → {function} getEventSenderDeviceInfo(event) → {Promise.<?module:crypto/deviceinfo>} getEventTimeline(timelineSet, eventId) → {module:client.Promise} getFallbackAuthUrl(loginType, authSessionId) → {string} getFilter(userId, filterId, allowCached) → {module:client.Promise|module:http-api.MatrixError} getGlobalBlacklistUnverifiedDevices() → {boolean} getGroup(groupId) → {Group} getGroupInvitedUsers(groupId) → {module:client.Promise|module:http-api.MatrixError} getGroupProfile(groupId) → {module:client.Promise|module:http-api.MatrixError} getGroupRooms(groupId) → {module:client.Promise|module:http-api.MatrixError} getGroups() → {Array.<Group>} getGroupSummary(groupId) → {module:client.Promise|module:http-api.MatrixError} getGroupUsers(groupId) → {module:client.Promise|module:http-api.MatrixError} getHomeserverUrl() → {string} getIdentityServerUrl(stripProto) → {string} getIgnoredUsers() → {Array.<string>} getJoinedGroups() → {module:client.Promise|module:http-api.MatrixError} getKeyChanges(oldToken, newToken) → {module:client.Promise} getNotifTimelineSet() → {EventTimelineSet} getOpenIdToken() → {module:client.Promise|module:http-api.MatrixError} getOrCreateFilter(filterName, filter) → {Promise.<String>} getPresenceList(callback) → {module:client.Promise|module:http-api.MatrixError} getProfileInfo(userId, info, callback) → {module:client.Promise|module:http-api.MatrixError} getPublicisedGroups(userIds) → {module:client.Promise|module:http-api.MatrixError} getPushActionsForEvent(event) → {module:pushprocessor\~PushAction} getPushers(callback) → {module:client.Promise|module:http-api.MatrixError} getPushRules(callback) → {module:client.Promise|module:http-api.MatrixError} getRoom(roomId) → {Room} getRoomDirectoryVisibility(roomId, callback) → {module:client.Promise|module:http-api.MatrixError} getRoomIdForAlias(alias, callback) → {module:client.Promise|module:http-api.MatrixError} getRoomPushRule(scope, roomId) → {object} getRooms() → {Array.<Room>} getRoomTags(roomId, callback) → {module:client.Promise|module:http-api.MatrixError} getScheduler() → (nullable) {module:scheduler\~MatrixScheduler} getStateEvent(roomId, eventType, stateKey, callback) → {module:client.Promise|module:http-api.MatrixError} getStoredDevice(userId, deviceId) → {Promise.<?module:crypto-deviceinfo>} getStoredDevicesForUser(userId) → {Promise.<Array.<module:crypto-deviceinfo>>} getSyncState() → (nullable) {string} getSyncStateData() → (nullable) {Object} getThirdpartyLocation(protocol, params) → {module:client.Promise} getThirdpartyProtocols() → {module:client.Promise} getThreePids(callback) → {module:client.Promise|module:http-api.MatrixError} getTurnServers() → {Array.<Object>} getUrlPreview(url, ts, callback) → {module:client.Promise|module:http-api.MatrixError} getUser(userId) → (nullable) {User} getUserId() → (nullable) {string} getUserIdLocalpart() → (nullable) {string} getUsers() → {Array.<User>} importRoomKeys(keys) → {module:client.Promise} initCrypto() invite(roomId, userId, callback) → {module:client.Promise|module:http-api.MatrixError} inviteByEmail(roomId, email, callback) → {module:client.Promise|module:http-api.MatrixError} inviteByThreePid(roomId, medium, address, callback) → {module:client.Promise|module:http-api.MatrixError} inviteToPresenceList(callback, userIds) → {module:client.Promise|module:http-api.MatrixError} inviteUserToGroup(groupId, userId) → {module:client.Promise|module:http-api.MatrixError} isCryptoEnabled() → {boolean} isEventSenderVerified(event) → {boolean} isGuest() → {boolean} isLoggedIn() → {boolean} isRoomEncrypted(roomId) → {bool} isUserIgnored(userId) → {boolean} isUsernameAvailable(username) → {module:client.Promise} joinGroup(groupId) → {module:client.Promise|module:http-api.MatrixError} joinRoom(roomIdOrAlias, opts, callback) → {module:client.Promise|module:http-api.MatrixError} kick(roomId, userId, reason, callback) → {module:client.Promise|module:http-api.MatrixError} leave(roomId, callback) → {module:client.Promise|module:http-api.MatrixError} leaveGroup(groupId) → {module:client.Promise|module:http-api.MatrixError} login(loginType, data, callback) → {module:client.Promise|module:http-api.MatrixError} loginFlows(callback) → {module:client.Promise|module:http-api.MatrixError} loginWithPassword(user, password, callback) → {module:client.Promise|module:http-api.MatrixError} loginWithSAML2(relayState, callback) → {module:client.Promise|module:http-api.MatrixError} loginWithToken(token, callback) → {module:client.Promise|module:http-api.MatrixError} logout(callback) → {module:client.Promise} lookupThreePid(medium, address, callback) → {module:client.Promise|module:http-api.MatrixError} makeTxnId() → {string} mxcUrlToHttp(mxcUrl, width, height, resizeMethod, allowDirectLinks) → (nullable) {string} on(event, listener) → {EventEmitter} once(event, listener) → {EventEmitter} paginateEventContext(eventContext, opts) → {module:client.Promise|Error} paginateEventTimeline(eventTimeline, opts opt) → {module:client.Promise} peekInRoom(roomId) → {module:client.Promise|module:http-api.MatrixError} publicRooms(options, callback) → {module:client.Promise|module:http-api.MatrixError} redactEvent(roomId, eventId, callback) → {module:client.Promise|module:http-api.MatrixError} register(username, password, sessionId, auth, bindThreepids, guestAccessToken, callback) → {module:client.Promise|module:http-api.MatrixError} registerGuest(opts opt, callback) → {module:client.Promise|module:http-api.MatrixError} registerRequest(data, kind opt, callback opt) → {module:client.Promise|module:http-api.MatrixError} removeAllListeners(event) → {EventEmitter} removeListener(event, listener) → {EventEmitter} removeRoomFromGroup(groupId, roomId) → {module:client.Promise|module:http-api.MatrixError} removeRoomFromGroupSummary(groupId, roomId) → {module:client.Promise|module:http-api.MatrixError} removeUserFromGroup(groupId, userId) → {module:client.Promise|module:http-api.MatrixError} removeUserFromGroupSummary(groupId, userId) → {module:client.Promise|module:http-api.MatrixError} requestAdd3pidEmailToken(email, clientSecret, sendAttempt, nextLink) → {module:client.Promise} requestAdd3pidMsisdnToken(phoneCountry, phoneNumber, clientSecret, sendAttempt, nextLink) → {module:client.Promise} requestEmailToken(email, clientSecret, sendAttempt, nextLink, callback) → {module:client.Promise|module:http-api.MatrixError} requestPasswordEmailToken(email, clientSecret, sendAttempt, nextLink, callback) → {module:client.Promise} requestPasswordMsisdnToken(phoneCountry, phoneNumber, clientSecret, sendAttempt, nextLink) → {module:client.Promise} requestRegisterEmailToken(email, clientSecret, sendAttempt, nextLink) → {module:client.Promise} requestRegisterMsisdnToken(phoneCountry, phoneNumber, clientSecret, sendAttempt, nextLink) → {module:client.Promise} resendEvent(event, room) → {module:client.Promise|module:http-api.MatrixError} resetNotifTimelineSet() resolveRoomAlias(roomAlias, callback) → {module:client.Promise|module:http-api.MatrixError} retryImmediately() → {boolean} roomInitialSync(roomId, limit, callback) → {module:client.Promise|module:http-api.MatrixError} roomState(roomId, callback) → {module:client.Promise|module:http-api.MatrixError} scrollback(room, limit, callback) → {module:client.Promise|module:http-api.MatrixError} search(opts, callback) → {module:client.Promise|module:http-api.MatrixError} searchMessageText(opts, callback) → {module:client.Promise|module:http-api.MatrixError} searchRoomEvents(opts) → {module:client.Promise|module:http-api.MatrixError} searchUserDirectory(opts) → {module:client.Promise} sendEmoteMessage(roomId, body, txnId, callback) → {module:client.Promise|module:http-api.MatrixError} sendEvent(roomId, eventType, content, txnId, callback) → {module:client.Promise|module:http-api.MatrixError} sendHtmlEmote(roomId, body, htmlBody, callback) → {module:client.Promise|module:http-api.MatrixError} sendHtmlMessage(roomId, body, htmlBody, callback) → {module:client.Promise|module:http-api.MatrixError} sendHtmlNotice(roomId, body, htmlBody, callback) → {module:client.Promise|module:http-api.MatrixError} sendImageMessage(roomId, url, info, text, callback) → {module:client.Promise|module:http-api.MatrixError} sendMessage(roomId, content, txnId, callback) → {module:client.Promise|module:http-api.MatrixError} sendNotice(roomId, body, txnId, callback) → {module:client.Promise|module:http-api.MatrixError} sendReadReceipt(event, callback) → {module:client.Promise|module:http-api.MatrixError} sendReceipt(event, receiptType, callback) → {module:client.Promise|module:http-api.MatrixError} sendStateEvent(roomId, eventType, content, stateKey, callback) → {module:client.Promise|module:http-api.MatrixError} sendStickerMessage(roomId, url, info, text, callback) → {module:client.Promise|module:http-api.MatrixError} sendTextMessage(roomId, body, txnId, callback) → {module:client.Promise|module:http-api.MatrixError} sendToDevice(eventType, contentMap, txnId opt) → {module:client.Promise} sendTyping(roomId, isTyping, timeoutMs, callback) → {module:client.Promise|module:http-api.MatrixError} setAccountData(eventType, contents, callback) → {module:client.Promise|module:http-api.MatrixError} setAvatarUrl(url, callback) → {module:client.Promise|module:http-api.MatrixError} setDeviceBlocked(userId, deviceId, blocked opt) → {Promise} setDeviceDetails(device_id, body) → {module:client.Promise|module:http-api.MatrixError} setDeviceKnown(userId, deviceId, known opt) → {Promise} setDeviceVerified(userId, deviceId, verified opt) → {Promise} setDisplayName(name, callback) → {module:client.Promise|module:http-api.MatrixError} setForceTURN(forceTURN) setGlobalBlacklistUnverifiedDevices(value) setGroupJoinPolicy(groupId, policy) → {module:client.Promise|module:http-api.MatrixError} setGroupProfile(groupId, profile) → {module:client.Promise|module:http-api.MatrixError} setGroupPublicity(groupId, isPublic) → {module:client.Promise|module:http-api.MatrixError} setGuest(isGuest) setGuestAccess(roomId, opts) → {module:client.Promise|module:http-api.MatrixError} setIgnoredUsers(userIds, callback opt) → {module:client.Promise|module:http-api.MatrixError} setMaxListeners(n) → {EventEmitter} setNotifTimelineSet(notifTimelineSet) setPassword(authDict, newPassword, callback) → {module:client.Promise|module:http-api.MatrixError} setPowerLevel(roomId, userId, powerLevel, event, callback) → {module:client.Promise|module:http-api.MatrixError} setPresence(opts, callback) → {module:client.Promise|module:http-api.MatrixError} setProfileInfo(info, data, callback) → {module:client.Promise|module:http-api.MatrixError} setPusher(pusher, callback) → {module:client.Promise|module:http-api.MatrixError} setPushRuleActions(scope, kind, ruleId, actions, callback) → {module:client.Promise|module:http-api.MatrixError} setPushRuleEnabled(scope, kind, ruleId, enabled, callback) → {module:client.Promise|module:http-api.MatrixError} setRoomAccountData(roomId, eventType, content, callback) → {module:client.Promise|module:http-api.MatrixError} setRoomDirectoryVisibility(roomId, visibility, callback) → {module:client.Promise|module:http-api.MatrixError} setRoomDirectoryVisibilityAppService(networkId, roomId, visibility, callback) → {module:client.Promise|module:http-api.MatrixError} setRoomEncryption(roomId, config) → {Promise} setRoomMutePushRule(scope, roomId, mute) → {module:client.Promise|module:http-api.MatrixError} setRoomName(roomId, name, callback) → {module:client.Promise|module:http-api.MatrixError} setRoomReadMarkers(roomId, eventId, rrEvent) → {module:client.Promise} setRoomReadMarkersHttpRequest(roomId, rmEventId, rrEventId) → {module:client.Promise} setRoomTag(roomId, tagName, metadata, callback) → {module:client.Promise|module:http-api.MatrixError} setRoomTopic(roomId, topic, callback) → {module:client.Promise|module:http-api.MatrixError} startClient(opts opt) stopClient() stopPeeking() submitMsisdnToken(sid, clientSecret, token) → {module:client.Promise|module:http-api.MatrixError} supportsVoip() → {boolean} syncLeftRooms() → {module:client.Promise|module:http-api.MatrixError} turnServer(callback) → {module:client.Promise|module:http-api.MatrixError} unban(roomId, userId, callback) → {module:client.Promise|module:http-api.MatrixError} updateGroupRoomVisibility(groupId, roomId, isPublic) → {module:client.Promise|module:http-api.MatrixError} uploadContent(file, opts) → {module:client.Promise} uploadKeys() → {object} uploadKeysRequest(content, opts opt, callback opt) → {module:client.Promise}"

select commented 6 years ago

@theilgaard can you please share how you wrote your client using e2e with this sdk? I would really appreciate it.

Dexwell commented 4 years ago

Still very true—the docs are a disaster. Improving on them might make Matrix a lot more appealing to developers.

For example, notice how clear Twitter's docs are. They don't just have a clear, categorized API reference, but also guides that explain use cases. Try replicating that; how does one set up the client, how to get all conversations, how to paginate, what are filters, how to get user info, how to implement push rules, how to implement crypto, etc.

ara4n commented 4 years ago

Given a choice between improving the usability, performance and stability of Matrix’s reference implementations so that people can actually use it in favour of Slack/Discord/WhatsApp... versus building SDK doc websites, we’re prioritising the former.

This is an open source project. Agreed that the js-sdk docs could be improved - we will very gladly accept contributions to improve them. It doesn’t all have to come from the core team; enough people have figured out the js sdk sufficiently to help write tutorials and glossy doc.

Dexwell commented 4 years ago

Very understandable. Making those docs does sound like a fun project :) But I'm unsure people outside the core team are going to invest their spare time and effort in writing them.

ara4n commented 4 years ago

that would be the tragedy of the commons, then (doubly so on a bug tagged “help wanted” and “easy”).

Dexwell commented 4 years ago

It's also a chicken-or-egg situation :D Better docs → more clients → more interest → more contributions → better docs.

Perhaps we only need to kickstart it with a better doc foundation, and then pin an issue to the top of this repo asking people to write content. Worked out pretty well for React Native.

berniezhao11 commented 4 years ago

I agree with others that a basic skeleton series of "How to" will get things started much faster. Also it gets developers like me interested and can contribute back to the documentation. At the moment even I want to I don't know how to do these things like "how to get unread count", "how to set read receipt". The more basic documents the Core team could provide, the more active the community is, hence more help on the document. Just my two cents.

qalqi commented 4 years ago

Open source clxxxd documentation

mithray commented 4 years ago

I'm interested in helping with this. As @Dexwell wisely pointed out, it is somewhat of a chicken and egg situation! It's hard to contribute when the existing documentation is quite minimal.

I have a question. Shouldn't the API be the same in every SDK? With the only differences being the Grammar? Shouldn't this make documentation really easy? I'm not attempting to criticize, just understand how perhaps I might be able to help and to see perhaps some symmetry across the SDKs that might reduce maintenance.

mithray commented 4 years ago

Apparently the docs here are nearly 3 years old, but yet, they are JSDoc so presumably have been autogenerated. I couldn't find the repo where those docs are stored. Could someone tell me how I could help in this area?

t3chguy commented 4 years ago

Hence you should probably use the index https://matrix-org.github.io/matrix-js-sdk/ which has the docs for newer versions of the SDK. This index is linked to in the README of this repo.

All those docs are generated via the package.json script and stored in https://github.com/matrix-org/matrix-js-sdk/tree/gh-pages

mithray commented 4 years ago

Thanks for the link. Still, unfortunately it seems like that doc doesn't show what would seem to be the most basic use cases, such as Registering and Creating a room. For even the most simple cases, it seems like the docs are unhelpful.

If the docs do explain it, I can't see it on the surface, and I have made more progress just by reading the source code.

mithray commented 4 years ago

I'm trying to figure out a basic workflow for Register, Login, Create Room, Send Message.

It seems like Registration requires an authSessionId, but I can't find anything that returns it, so I don't know how to get it. And do you need to do a guestRegister before you do a register? I put an guest_access_token from guestRegister into register and the token was considered invalid, yet the documentation says that a guest_access_token is required.

ghost commented 3 years ago

The API reference is good, and I've been relying on that ever since. But I agree that there should be a guide for developers that teaches the fundamentals.

The only guides that I know of are the ones from the README and https://matrix.org/docs/guides/usage-of-the-matrix-js-sdk.

Synapse includes its documentation in the repo and hosts it here: https://matrix-org.github.io/synapse/latest/. Maybe we can do the same with matrix-js-sdk?

dimitri-bourreau commented 2 years ago

Hi everyone,

Is there any news on this topic?

It's been some weeks I'm using this SDK, and I'm affraid I'm not using it the right way.

Would be great to dedicate some time on a repo, at least.

I'd be happy to help on this, if at least some one experienced with this SDK is available.

genjudev commented 2 years ago

Nope. After 18 years im still trying to restore a backup.

c10b10 commented 2 years ago

Been trying to understand this sdk and how to integrate it into a react app by reading the code in the repo and in https://github.com/matrix-org/matrix-react-sdk/ but it has proven difficult.

I've been trying to attach to timeline events but I'm missing core concepts like: what is a timeline set? Can't find any documentation on it anywhere.

genjudev commented 2 years ago

When you want to understand the concept behind all you should Read the Client-Server API:

also:

I wrote some "debugging" tool to see data directly from the server. This helped me also understand the data which is transferred. Also how data looks in RAW.

When working with matrix-js-sdk you need to be careful because you are working with the SDK event system and also with Reacts state management. It can be ugly when you're not skilled in any of this.

c10b10 commented 2 years ago

any way of working with notifications? i'm been trying to find a way to see the list of unread notifications (not only the count), but I can't seem to find a way to do this with this sdk.

genjudev commented 2 years ago

The Room Model has getAccountData which you can get the latest event you read. https://github.com/matrix-org/matrix-js-sdk/blob/1645867ea6220763f86456f35093365017534da9/src/models/room.ts#L2822

.getAccountData('m.full_read') -> gives you the latest event you read.

So you could check if some notifications are there with the count and then check which event you read at last. After that get the timelineset for this event forwards.

But I wouldnt recommended this. You also just take the live timelineset check if fthe full_read event is in there. Because theoreticly it could lead to performance issues when the event is realy old and thousand of other events are in between.

Also no warranty ;)

richvdh commented 4 months ago

duplicate of https://github.com/matrix-org/matrix-js-sdk/issues/430