{"id":23157248,"url":"https://github.com/mav10/rn-webim-chat","last_synced_at":"2025-04-04T17:45:47.064Z","repository":{"id":63410206,"uuid":"353977928","full_name":"mav10/rn-webim-chat","owner":"mav10","description":"Webim chat wrapper for React-Native. Supports Android and iOS. Fixed issues for native platforms build that are present in the official package.","archived":false,"fork":false,"pushed_at":"2023-02-13T17:05:56.000Z","size":5058,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-12T01:03:27.616Z","etag":null,"topics":["chat","react-native","webim","webim-chat"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mav10.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-04-02T09:57:12.000Z","updated_at":"2024-11-02T09:15:24.000Z","dependencies_parsed_at":"2023-02-13T22:30:30.163Z","dependency_job_id":null,"html_url":"https://github.com/mav10/rn-webim-chat","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mav10%2Frn-webim-chat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mav10%2Frn-webim-chat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mav10%2Frn-webim-chat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mav10%2Frn-webim-chat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mav10","download_url":"https://codeload.github.com/mav10/rn-webim-chat/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247226196,"owners_count":20904464,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chat","react-native","webim","webim-chat"],"created_at":"2024-12-17T21:16:40.369Z","updated_at":"2025-04-04T17:45:47.035Z","avatar_url":"https://github.com/mav10.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rn-webim-chat\n\nImplementation of [webim sdk](https://webim.ru/) for [react-native](https://github.com/facebook/react-native)\n\n_Inspired by [volga-volga/react-native-webim](https://github.com/volga-volga/react-native-webim)_\n\n\n\u003c!-- BADGES/ --\u003e\n\n[![Package publish](https://github.com/mav10/rn-webim-chat/actions/workflows/npm-publish.yml/badge.svg)](https://github.com/mav10/rn-webim-chat/actions/workflows/npm-publish.yml)\n\u003cspan class=\"badge-npmversion\"\u003e\u003ca href=\"https://www.npmjs.com/package/rn-webim-chat\" title=\"View this project on NPM\"\u003e\u003cimg src=\"https://badge.fury.io/js/rn-webim-chat.svg\" alt=\"NPM version\" /\u003e\u003c/a\u003e\u003c/span\u003e\n\u003cspan class=\"badge-npmdownloads\"\u003e\u003ca href=\"https://www.npmjs.com/package/rn-webim-chat\" title=\"View this project on NPM\"\u003e\u003cimg alt=\"npm\" src=\"https://img.shields.io/npm/dm/rn-webim-chat\"\u003e\u003c/a\u003e\u003c/span\u003e\n\u003c!-- /BADGES --\u003e\n___\n\n## Platforms:\n\n![React Native](https://img.shields.io/badge/react_native-%2320232a.svg?style=for-the-badge\u0026logo=react\u0026logoColor=%2361DAFB)\n\n![Android](https://img.shields.io/badge/Android-3DDC84?style=for-the-badge\u0026logo=android\u0026logoColor=white)\n\n![iOS](https://img.shields.io/badge/iOS-000000?style=for-the-badge\u0026logo=ios\u0026logoColor=white)\n\n## Installation\n- Requires React Native version 0.60.0, or later.\n- Supports iOS 10.0, or later.\n\nVia NPM\n```sh\nnpm install rn-webim-chat\n```\n\nVia Yarn\n```sh\nyarn add rn-webim-chat\n```\n\n#### :iphone:iOS (_Extra steps_)\n- add `WebimClientLibrary` to Podfile with specific version (_Wrapper was written for v3.37.4_)\n- pod install\n\nsee [example Podfile](./example/ios/Podfile)\n\nSince the official [WebimClientLibrary](https://github.com/webim/webim-client-sdk-ios) is written is Swift, you need to have Swift enabled in your iOS project. If you already have any .swift files, you are good to go. Otherwise, create a new empty Swift source file in Xcode, and allow it to create the neccessary bridging header when prompted.\n\n## Example\nIn [example folder](./example) there is simple workflow how to:\n - Start and destroy session\n - Resume and Pause session\n - Get and Send messages\n - Rate operator\n - Handle errors\n\nHow it looks like you can see here\nIt is achieved with [simple UI](./example/src/simple) (just test common methods)\n\u003ctable align=\"Center\"\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eNot init session\u003c/td\u003e\n    \u003ctd\u003eRequested messages\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src=\"doc/img.png\" width=400 height=760\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src=\"doc/messages.png\" width=400 height=760\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n \u003c/table\u003e\n\n\n\u003ctable align=\"Center\"\u003e\n  \u003ctr\u003e\n     \u003ctd\u003eError getMessages (as session is null)\u003c/td\u003e\n     \u003ctd\u003eError sendMessage (as session is null)\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src=\"doc/error_1.png\" width=400 height=760\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src=\"doc/error_2.png\" width=400 height=760\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n \u003c/table\u003e\n\n![](doc/chat.png)\n\n_Also there is another [example with chat UI](./example/src/withCustomUI) [`react-native-gifted-chat`](https://github.com/FaridSafi/react-native-gifted-chat)_\n## Methods\n\n**Important:** All methods are promise based and can throw exceptions.\nList of error codes will be provided later as get COMMON for both platform.\n### Init chat\n\n ```ts\nimport { RNWebim } from 'rn-webim-chat';\n\nawait RNWebim.initSession(builderParams: SessionBuilderParams)\n```\n**SessionBuilderParams:**\n- accountName (required) - name of your account in webim system\n- location (required) - name of location. For example \"mobile\"\n- accountJSON - encrypted json with user data. See [**Start chat with user data**](#start-chat-with-user-data)\n- clearVisitorData - clear visitor data before start chat\n- storeHistoryLocally - cache messages in local store\n- title - title for chat in webim web panel\n- providedAuthorizationToken - user token. Session will not start with wrong token. Read webim documentation\n- pushToken - FCM token is enough - but Apple pushes will come through APN, so you are not able to process them in app by default.\n- appVersion - version of your Application\n- prechat - some additional fields to prechat\n\n### Resume session\n\nIf you have already initialized a session you should **resume** it to consume and send messages, get actual information by listeners etc.\n\n**NOTE:** _After that execution operator on web chat will get message that user opens a chat._\n\n ```ts\nimport { RNWebim } from 'rn-webim-chat';\n\nawait RNWebim.resumeSession()\n```\n\n### Pause session\n\nIf you have already initialized a session you should **resume** it to consume and send messages, get actual information by listeners etc.\nAfter that execution operator on web chat will get message that user opens a chat.\n\n ```ts\nimport { RNWebim } from 'rn-webim-chat';\n\nawait RNWebim.pauseSession()\n```\n\n\n### Init events listeners\n\n```js\nimport { RNWebim,  WebimEvents} from 'rn-webim-chat';\n\nconst listener = RNWebim.addNewMessageListener(({ msg }) =\u003e {\n  // do something\n});\n// usubscribe\nlistener.remove();\n\n// or\nconst listener2 = RNWebim.addListener(WebimEvents.NEW_MESSAGE, ({ msg }) =\u003e {\n    // do something\n});\n```\n\nSupported events (`WebimEvents`):\n- WebimEvents.NEW_MESSAGE;\n- WebimEvents.REMOVE_MESSAGE;\n- WebimEvents.EDIT_MESSAGE;\n- WebimEvents.CLEAR_DIALOG;\n- WebimEvents.TOKEN_UPDATED;\n- WebimEvents.ERROR;\n- WebimEvents.STATE;\n- WebimEvents.UNREAD_COUNTER;\n- WebimEvents.TYPING;\n\n- ~~WebimEvents.FILE_UPLOADING_PROGRESS;~~\n\n### Get messages\nAs you called `getAllMessages` after that you should call `nextMessages` as reading \"all messages\" during the same session will get no result (native implementation uses holder and cursor by last loaded message)\n\n```js\nconst { messages } = await RNWebim.getLastMessages(limit);\n// or\nconst { messages } = await RNWebim.getNextMessages(limit);\n// or\nconst { messages } = await RNWebim.getAllMessages();\n```\n\n**Message type**\n```typescript\nexport type WebimMessage = {\n  id: string;\n  serverSideId: string;\n  avatar?: string;\n  time: number;\n  type: MessageTypeAlias; // 'OPERATOR', 'VISITOR', 'INFO', 'ACTION_REQUEST', 'CONTACTS_REQUEST', 'FILE_FROM_OPERATOR', 'FILE_FROM_VISITOR', 'OPERATOR_BUSY', 'KEYBOARD', 'KEYBOARD_RESPONSE';\n  text: string;\n  name: string;\n  status: 'SENT' | 'SENDING';\n  read: boolean;\n  canEdit: boolean;\n  carReply: boolean;\n  isEdited: boolean;\n  canReact: boolean;\n  canChangeReaction: boolean;\n  visitorReaction?: string;\n  stickerId?: number;\n  quote?: Quote;\n  attachment?: WebimAttachment;\n  operatorId?: string;\n}\n\n```\n\n**Quote type**\n```typescript\nexport type Quote = {\n  authorId?: string;\n  senderName: string;\n  messageId: string;\n  messageText: string;\n  messageType: MessageTypeAlias;\n  state: 'FILLED' | 'NOT_FOUND' | 'PENDING';\n  timestamp: Date | number;\n  attachment?: WebimAttachment;\n};\n```\n**Included attachment**\n```typescript\nexport interface WebimAttachment {\n  contentType: string;\n  info: string;\n  name: string;\n  size: number;\n  url: string;\n}\n```\nNote: method `getAllMessages` works strange on iOS, and sometimes returns empty array. We recommend to use `getLastMessages` instead\n\n### Send text message\n\n```typescript\nimport RNWebim from 'rn-webim-chat';\n\nconst messageId = await RNWebim.send(message);\n```\n\n### Read Messages (mark as read)\nYou can manually mark all messages as read by calling this method.\n\n```typescript\nimport RNWebim from 'rn-webim-chat';\n\nawait RNWebim.readMessages();\n```\n\n## Attach files\n\n#### Use build in method for file attaching:\nIn future will add possibility to use external library as `react-native-fs` and some other picker to import files via them.\nFor now there are such methods\n\n### Attach file\n```typescript\nvar result: AttachFileResult = await RNWebim.tryAttachAndSendFile();\n\nconsole.log('uri: ', result.uri)\nconsole.log('name: ', result.name)\nconsole.log('mime: ', result.mime)\nconsole.log('extension: ', result.extension)\n```\n\n\n### Send file\n\n```typescript\nimport RNWebim from 'rn-webim-chat';\n\ntry {\n  RNWebim.sendFile(uri, name, mime, extension)\n  console.log('Result: ', sendingResult.id)\n} catch (e) {\n  // can throw such errors\n  'FILE_SIZE_EXCEEDED', 'FILE_SIZE_TOO_SMALL', 'FILE_TYPE_NOT_ALLOWED', 'MAX_FILES_COUNT_PER_CHAT_EXCEEDED', 'UPLOADED_FILE_NOT_FOUND', 'UNAUTHORIZED',\n}\n\n```\n\n\n### Attach and Send file\n\n```typescript\nconst onSelectFiles = useCallback(async () =\u003e {\n  try {\n    const fileResult = await RNWebim.tryAttachAndSendFile();\n    console.log('File result: ', fileResult);\n  } catch (err: any) {\n    const webimError = err as WebimNativeError;\n    console.log('Chat][File] error: ', webimError);\n    if (webimError.errorType === 'common') {\n      setNotFatalError(\n        webimError.message + `(Code: ${webimError.errorCode})`\n      );\n    } else {\n      setFatalError(webimError.message + `(Code: ${webimError.errorCode})`);\n    }\n  }\n}, []);\n```\n\n### Rate current operator\n\n```js\nRNWebim.rateOperator(rate: number)\n```\n - `rate` (required) - is number from 1 to 5\n\n### Get current operator\n\n```typescript\nimport RNWebim from 'rn-webim-chat';\n\nRNWebim.getCurrentOperator()\n```\n\nit returns such object\n```typescript\nexport type Operator = {\n  id: string;\n  name: string;\n  avatar?: string;\n  title: string;\n  info: string;\n};\n```\n\n### Destroy session\n```js\nRNWebim.destroySession(clearData);\n```\n\n- clearData (optional) boolean - If true wil\n\n## Start chat with user data\n**Tl;DR;**\nYou have to generate private key in your Webim Account and kinda sign your user fields values.\nFor more details see [webim documentation](https://webim.ru/kb/dev/identification/id-2-0.html) for client identification.\n\nin [Example app](./example) there is code how to achieve it.\nExample:\n\nI'd recommend to you use some lightweight library. HMAC-256 is enough. Actually you can use md5 algorithm  - but I'd avoid it.\nThere are some other aproches e.g. with JsCrypto or with [react-native-crypto ](https://github.com/tradle/react-native-crypto). But here you need to hash all your modules.\nLike [here](https://github.com/volga-volga/react-native-webim#start-chat-with-user-data). But the choice it is up to you!\n\n- install [js-sha256](https://github.com/emn178/js-sha256)\n- write hash-function to sign your fields.\n- use it in your app.\n\n```ts\n// chat-utils.ts file\nimport { sha256 } from 'js-sha256';\n\nconst getHmac_sha256 = async (str: string, privateKey: string) =\u003e {\n  return sha256.hmac(privateKey, str);\n};\n\n/**\n * Returns hash value for authorized user.\n * @param obj - User's json fields.\n * @param privateKey - private key value. By that hash will be generated.\n */\nexport const getHashForChatSign = async (\n  obj: { [key: string]: string },\n  privateKey: string\n) =\u003e {\n  const keys = Object.keys(obj).sort();\n  const str = keys.map((key) =\u003e obj[key]).join('');\n  return await getHmac_sha256(str, privateKey);\n};\n```\n\n```tsx\n// App.tsx file\n...\nimport { getHashForChatSign } from './chat-utils';\n\nconst PRIVATE_KEY = 'YOUR-PRIVATE-KEY-FROM-PORTAL';\nconst CHAT_SERVICE_ACCOUNT = 'YOU-ACCOUNT';\n\nconst acc = {\n  fields: {\n    id: 'some-id',\n    display_name: '1.0.0',\n    phone: '+79000000000',\n    address: 'Tomsk',\n  },\n  hash: '',\n};\n\nasync function intSession() {\n  acc.hash = await getHashForChatSign(acc.fields, PRIVATE_KEY);\n  const sessionsParams = {\n    accountName: CHAT_SERVICE_ACCOUNT,\n    location: '',\n    storeHistoryLocally: true,\n    accountJSON: JSON.stringify(acc),\n    appVersion: AppConfig.version,\n    clearVisitorData: true,\n  };\n\n  await RNWebim.resumeSession(sessionsParams);\n  console.log('[Chat][Init] initialized with params: ', sessionsParams);\n};\n\n...\n```\n\n\n## Contributing\nSee the [contributing guide](CONTRIBUTING.md) guide to learn how to contribute to the repository and the development workflow.\n\n## License\nSoftware provided as it is.\nIt will be maintained time-to-time. Currently, I have to use this package in some applications, so I try to keep it on working.\nIf you want to help or improve something see section #Contributing\n\n\n---\n\nMade with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmav10%2Frn-webim-chat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmav10%2Frn-webim-chat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmav10%2Frn-webim-chat/lists"}