Giter Club home page Giter Club logo

mobile's Introduction

Glific - Two Way Open Source Communication Platform

License: AGPL v3 Code coverage badge Glific on hex.pm GitHub issues Discord codebeat badge Commits Glific

Pre-requisites

Understanding of middle to advanced level required: It is assumed that you're comfortable using a terminal, installing tools and other dependencies, have git and curl for the backend, and yarn and react for the frontend.

  1. Software dependency - Postgres server
  2. Software dependency - Erlang / Elixir
  3. Backend - Download
  4. External service - Gupshup. <-- Get a Free trial to get API-key
  5. External service - Oban. <-- Needs 100 Euro per month (patch available to work with free version)
  6. Backend - Install certificate
  7. Backend - Config
  8. Frontend

1. Software dependency - Postgres server

For Postgres, for the development server, we default to using postgres/postgres/postgres as the username/password/machine name - this is configurable.

We tested and developed against the following versions:

    - postgres : v13.x, v14.x

2. Software dependency - Erlang / Elixir

For Ubuntu users, you also need to install the inotify-tools package.

We tested and developed against the following versions (please check .tool-versions in the repository for the latest version we are using):

    - erlang : 26.1.2
    - elixir : 1.15.7-otp-26

After installing the asdf core, install the Erlang and Elixir plugins.

asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git
asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir.git

If you want to install the specific versions that were used for developing and testing:

asdf install erlang 26.1.2
asdf install elixir 1.15.7-otp-26
asdf global erlang 26.1.2
asdf global elixir 1.15.7-otp-26

If you get any warnings for missing packages, just install them using apt and try again.

Note: It is important to use asdf to install Erlang and Elixir.

3. Backend - Download

git clone https://github.com/glific/glific

DO NOT run mix deps.get until the next steps are completed.

4. External service - Gupshup Create and link your Gupshup Account

Gupshup is an external service that connects to WhatsApp.

You will need to do the following:

  • Create a Gupshup Account
  • Create an app and select Access API
  • You can name it NewNameHere "GlificTest <-- Bot Name is already in use, then use another one"
  • Run the following command cp config/dev.secret.exs.txt config/dev.secret.exs
  • Now, in Gupshup, find your API Key: check the top right corner and click the profile picture or inside the curl sample message
  • Enter your APP name and API Key in the dev.secret.exs file using any text editor.

5. External service - Oban Pro

Oban is a cron-like library. Glific depends 100% on job processing. Oban is required before running mix for Glific to operate.

For contributors on social impact projects (including NGOs): Please get in touch with the team on Discord and get a limited-time key. Once they're provided to you, run:

For others, if you want to use the free Oban solution People have created and contributed versions of the code to allow Glific to work with the free version of Oban: #2391

mix hex.repo add oban https://getoban.pro/repo --fetch-public-key SHA256:4/abc/edf/gef+aIWPc --auth-key abcdefghi

with your keys

For production use: You must purchase a license. When purchasing, you must buy WEB+PRO. After purchasing, Go to account and run this command in glific_backend:

mix hex.repo add oban https://getoban.pro/repo --fetch-public-key SHA256:4/abc/edf/gef+aIWPc --auth-key abcdefghi

where public key "SHA256:4/abc/edf/gef+aIWPc" is replaced by your public key and auth key "abcdefghi" is replaced by your auth key.

Make sure your key is in the list:

mix hex.repo list
Name        URL                             Public key                                          Auth key
oban        https://getoban.pro/repo        SHA256:4/abc/edf/gef+aIWPc   abdedcqweasdj__KEY_AUTH__asdafasdf

If you see two key entries - caused by Oban moving from a public to a private repository - it will fail. This is what an example of failing looks like:

Name        URL                             Public key                                          Auth key
hexpm:oban  https://repo.hex.pm/repos/oban  SHA256:abc/edf/gef+aIWPc     abdedcqweasdj__KEY_AUTH__asdafasdf
oban        https://getoban.pro/repo        SHA256:4/abc/edf/gef+aIWPc   abdedcqweasdj__KEY_AUTH__asdafasdf

This is wrong. When you run mix deps.get as is, it will try to fetch from the public repository instead of the private one and fail. Simply follow the instructions below to remove the public key:

mix hex.repo remove hexpm:oban

Now, check again:

mix hex.repo list
Name        URL                             Public key                                          Auth key
oban        https://getoban.pro/repo        SHA256:4/abc/edf/gef+aIWPc   abdedcqweasdj__KEY_AUTH__asdafasdf

6. Install certificate - Use SSL for frontend and backend

Before completing the install, you need to create an SSL cert. Go to the glific_backend folder in the terminal console, and:

  • Install mkcert (https://github.com/FiloSottile/mkcert)

  • mkcert --install

  • mkcert glific.test api.glific.test

  • mkdir priv/cert

  • mv glific.test* priv/cert

  • cd priv/cert

  • ls -1 Check that glific.test+1-key.pem and glific.test+1.pem exists.

  • Check port 4001 sudo lsof -n -i:4001 | grep LISTEN should return nothing.

  • Check hosts file grep glific /etc/hosts

    if it returns nothing, add these 3 lines to the hosts file:
    127.0.0.1 glific.test 
    127.0.0.1 api.glific.test
    127.0.0.1 postgres
    

For Windows the steps is as follows:

  • Install mkcert (https://github.com/FiloSottile/mkcert)

  • Run the following command to install the local CA certificates: mkcert --install

  • mkcert glific.test api.glific.test

  • mkdir priv/cert

  • move glific.test* priv/cert

  • cd priv/cert

  • dir Check that glific.test+1-key.pem and glific.test+1.pem exists.

  • Check port 4001 netstat -ano | findstr :4001 should return nothing.

  • Check hosts file bytype %SystemRoot%\System32\drivers\etc\hosts | findstr glific

    if returns nothing
    add these three lines in your hosts file
    127.0.0.1 glific.test
    127.0.0.1 api.glific.test
    127.0.0.1 postgres
    

7. Backend - Config

  • Run: cp config/.env.dev.txt config/.env.dev

  • Run mix deps.get if this fails try mix local.hex --force followed by mix deps.get

    if you see the error below, then your Oban key is wrong or failing. Check step 5 or contact Oban.

    ❯ mix deps.get Failed to fetch record for 'hexpm:oban/oban_pro' from registry (using cache instead) This could be because the package does not exist, it was spelled incorrectly or you don't have permissions to it Failed to fetch record for 'hexpm:oban/oban_web' from registry (using cache instead) This could be because the package does not exist, it was spelled incorrectly or you don't have permissions to it ** (Mix) Unknown package oban_pro in lockfile

  • Run mix setup At this point, you may get an error saying password authentication failed for user "postgres", in which case, you need to configure the postgres server properly:

createuser postgres -s # needed for more recent versions of postgres on MacOSgit
sudo -u postgres psql
ALTER USER postgres WITH PASSWORD 'postgres';

Exit the PostgreSQL terminal by typing \q and pressing Enter. Run mix setup again.

  • Run iex -S mix phx.server
  • Inside the iex (you might need to hit enter/return to see the prompt)
    • Update HSM templates by running the following command:
    • Glific.Templates.sync_hsms_from_bsp(1)

Now you can visit https://glific.test:4001 from your browser.

For Windows the steps is as follows:

  • Copy the file: cp config/dev.secret.exs.txt config/dev.secret.exs

  • Copy the file: cp config/.env.dev.txt config/.env.dev. You may not need to edit the default values for DB URL and hostnames in this file if they look suitable for your needs.

  • Run this on the command prompt:

    cd <path-to-glific-backend>
    set /p=DUMMY < config\.env.dev
    

    Replace with the actual path to the glific_backend directory. This will load the environment variables from the .env.dev file.

  • Run mix deps.get if this fails try mix local.hex --force followed by mix deps.get

    if you see the error below, then your Oban key is wrong or failing. Check step 5 or contact Oban.

    ❯ mix deps.get Failed to fetch record for 'hexpm:oban/oban_pro' from registry (using cache instead) This could be because the package does not exist, it was spelled incorrectly or you don't have permissions to it Failed to fetch record for 'hexpm:oban/oban_web' from registry (using cache instead) This could be because the package does not exist, it was spelled incorrectly or you don't have permissions to it ** (Mix) Unknown package oban_pro in lockfile

  • Run mix setup

  • Run iex -S mix phx.server

  • Inside the iex (you might need to hit enter/return to see the prompt)

    • Update HSM templates by running the following command:
    • Glific.Templates.sync_hsms_from_bsp(1)

Now you can visit https://glific.test:4001 from your browser.

8. Front-end - Install glific front-end

You cannot do much from the glific backend unless you are an API developer. To see Glific in its glory, please install Glific Frontend

Front-end credentials

  • Phone 917834811114
  • Password Secret1234!

Optional - Using NGROK

  • Install ngrok
  • Start ngrok to proxy port 4000:
    • Start the backend server: mix phx.server
    • $ ngrok http 4000 --host-header=glific.test:4000 (do this in a new window))
    • Remember the URL it assigns you, something like: https://9f6a7c7822d2.ngrok.io
  • Goto the app settings section, Dashboard -> {{your_appname}} -> Settings.
  • On that page, Search for Manage your Template messaging settings and enable it
  • Goto app webhooks section, Dashboard -> {{your_appname}} -> Webhooks.
  • Enter your callback URL that ngrok gave you, add: /gupshup to the end. Something like: https://9f6a7c7822d2.ngrok.io/gupshup/.
  • Click Set. It should give you a Callback set successfully message. If not, check the above steps.
  • Save the number +917834811114 on whatsapp and send a message PROXY {{your_appname}}.

Updating your instance

Run the following commands to update your codebase from the Glific repository.

  • Ensure you are in the top-level directory of the Glific API code.
  • Get the latest code from master: git switch master && git pull
  • Ensure you have not modified any files in this directory, by running: git status
  • Run the setup command: mix deps.get, compile, ecto.migrate

Documentation

Learn more

Glific

Chat with us

Funders

Thanks to our generous funders over the past few years who have funded this project:

mobile's People

Contributors

abhay-86 avatar abro0058t avatar ajaman190 avatar aneesh-2003 avatar arkaprabhachowdhury avatar chandra-pro avatar kurund avatar mdshamoon avatar nishant25062002 avatar praneeth-rdy avatar siva20021 avatar soumyadiptopal avatar srijanshovit avatar vishalz123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

mobile's Issues

Updates in the server URL flow

@ajaman190 mostly looks good. Minor things to update:

  1. If serverURL is present in storage- Redirect to the login screen.
  2. Use the serverUrl in the apollo.ts file as well
  3. The backend url format is https://api.{URL}/api
    For ex: If my frontend URL is staging.tides.coloredcow.com then the server URL will become
    https://api.staging.tides.coloredcow.com/api. The User will only type the frontend URL and
    the rest we will manage in the code

You can take this up in a separate branch as there are a lot of file changes here

Originally posted by @mdshamoon in #61 (review)

Implement dynamic notifications

Currently the notifications displayed are hardcoded.
Query the backend for notifications and display those in the notification screen

Render a collection list on the collection tab

Is your feature request related to a problem? Please describe.
When we switch over to the collection tab it should load a list of collection similar to the contacts

Describe the solution you'd like
Use the same search graphql api as we have used for contacts. The variables will be changed a bit

const variables = {
  filter: { searchGroup: true},
  messageOpts: {
    limit: 3,
    offset: 0,
  },
  contactOpts: {
    limit: 10,
    offset: 0,
  },
};

Add badge for count of the notifications

Is your feature request related to a problem? Please describe.
We want to know the number of notifications on the home screen.
image

API to get the number of notifications:



export const GET_NOTIFICATIONS_COUNT = gql`
  query countNotifications($filter: NotificationFilter) {
    countNotifications(filter: $filter)
  }
`;

 variables: {
      filter: {
        is_read: false,
      },
    },

Add an emoji library to add emojis in a message that we can send

Is your feature request related to a problem? Please describe.
Along with text we want to enable the emoji functionality for a user to send the message

Describe the solution you'd like

  • Check out various emoji libraries and add one of them (or we can use native keyboard emojis).
  • When we click on the emoji button it opens up a modal to select an emoji or something like WhatsApp where it opens up from the bottom
  • After selecting an emoji it shows up in the input box
image

Check the desgins here: https://www.figma.com/file/SbP0ru8kiB2l334ieX1ESe/Mobile-app?type=design&node-id=195-2043

Organization URL Setup as One-Time Process

Organization URL Setup as One-Time Process

Currently, the app requires users to set up the Organization URL each time they log in. This need to be implement as one-time setup for the Organization URL.

Approach

  • Implement an initial setup screen that prompts the user to enter the server URL during the first app launch.
  • Store the entered server URL securely using async storage, ensuring it persists across app launches.
  • After successful setup and login, update the app's logic to skip the server URL screen during subsequent logins.

Create a github action file for unit testing with jest

Is your feature request related to a problem? Please describe.
For each PR we want to check if nothing is breaking from those changes. To ensure that we will be running the unit test on each Pull request and only merge it if it passes the check

Describe the solution you'd like
Create a unit-testing.yml file and check if the action is working on a PR against the main branch

Describe alternatives you've considered
Take reference from here: https://github.com/glific/glific-frontend/blob/master/.github/workflows/unit-testing.yml

[C4GT] Implement authentication and chat interface for the mobile app according to the designs

Product Explanation

Glific is a WhatsApp based open source 2-way communication platform for NGOs to have conversations with their community.

We want to solve the problem of NGOs’ program delivery through this chatbot, that NGOs use to engage with their beneficiaries, distribute content, provide useful information at their pace & get feedback.

It enables them to launch their programs in a chatbot format quickly, cost-effectively and at scale.

Features to be Implemented

We will be building a mobile version for our web interface in this project. The end result will be an IOS/Android application built on React Native that will help NGO staff members to check and easily communicate with their beneficiaries using their mobile devices.

This request has come up many times by a lot of NGO organizations that we work with and we feel that it would really help easy managing of daily operations.

We will create a POC and work with several Glific NGO to enhance/update the features of the app.
Design file for the app: https://www.figma.com/file/SbP0ru8kiB2l334ieX1ESe/Mobile-app?type=design

The first version will contain the following features:

  • A login screen that uses the same credentials as Glific web app.
  • A chat interface similar to the Glific web app that contains:
    • Sliding sidebar with the list of contacts and ability to search and select the contacts.
    • All messages of the selected contact.
    • An input box similar to the web interface for sending a text message.
  • Simple notification for errors like Update gupshup balance while not on the app.

Learning Path

Category Rating
Difficulty Medium
Risk/Exploratory High
Skills Javascript, React Native, Typescript
Possible mentors @mdshamoon
Project size 6-8 weeks

Product Set Up:

To set up the project on a system, follow the guidelines in Readme of the project.

Additional resources:

Acceptance Criteria:

The acceptance criteria for this project are:

  • A platfrom user can successfully authenticate in the mobile app
  • After the user logs in, they will be able to see a chat screen with a list of contacts and messages
  • A notification should appear on the phone if its triggered by the server

Out of Scope Elements:

The following elements are out of scope for this project:

  • Adding backend APIs
  • Pixel perfect design

Store the access token in a store after login

Is your feature request related to a problem? Please describe.
After login we will get an access token that needs to be stored in some local storage to use in further API calls

Describe the solution you'd like
Research and implement various local storage libraries and add one of them in the project to store access token

Additional context
Check among these packages https://reactnative.directory/?search=storage

Create contact search functionality

Is your feature request related to a problem? Please describe.
When we type something in the search box it should return the search results and display in the contact list area

Describe the solution you'd like
For this we will use the same search query but with the filter variable included:

const variables = {
  filter: { term: "Search value"},
  messageOpts: { limit: 3, offset: 0 },
  contactOpts: { limit: 10, offset: 0 },
};

Add wallet balance option in the sidedrawer

Is your feature request related to a problem? Please describe.
Users need to check the amount of balance left on their bot messaging

Describe the solution you'd like
We will show the remaining wallet balance in the sidedrawer.
image

API for getting wallet balance

const BSPBALANCE = gqlquery bspbalance { bspbalance };

Run this query using Apollo's useQuery hook.

Design file https://www.figma.com/file/SbP0ru8kiB2l334ieX1ESe/Mobile-app?type=design&node-id=195-2043

Implement dedicated video player

Is your feature request related to a problem? Please describe.
Create a dedicated video player.

Describe the solution you'd like

  • On press video message, the video player should open in full-screen mode.
  • Users should be able to control the video using video controller.
  • The video player should have an option to return back to the message thread view, and have sender information.

Clear Conversation for a contact

Clear Conversation for a contact

Implement the Clear Conversation option in the chat options. This would clear the conversation for a contact.
API - https://api.glific.com/#fa65529d-9ce9-48ca-a944-4304291ace58

Approach -

  • When the user selects the "Clear Conversation" option, a confirmation prompt or dialog box should appear to confirm their intention to clear the conversation.
  • Provide two options for the user to choose from, such as "Clear" and "Cancel." The "Clear" option will proceed with clearing the conversation, while the "Cancel" option will dismiss the prompt without taking any action.

A logged in user should not be able to go back to login screen

Is your feature request related to a problem? Please describe.
Right now when we are on the chat screen and press the back button it takes us back to the login.

Describe the solution you'd like
An authenticated user should not be able to go back to the login page unless they click on logout

Setup apollo client and make a graphQL api call using the access token we get after login

Is your feature request related to a problem? Please describe.
To communicate with the backend we have fairly good documented APIs https://api.glific.com . We need to setup Apollo client and use these graphQL API to get data from backend

Describe the solution you'd like

Terminate Flow for Contact

Terminate Flow for Contact

Implement the Terminate Flow option in the chat options. This would allow users to manually interrupt and stop an active flow within the chat.
API- https://api.glific.com/#ba10052f-89f3-46bc-bf60-f2d17838cf8b

Approach-

  • When the user selects the "Terminate Flows" option, a confirmation prompt or dialog box should appear to confirm their intention to terminate the flow.
  • Provide two options for the user to choose from, such as "Terminate" and "Cancel." The "Terminate" option will proceed with terminating the flow, while the "Cancel" option will dismiss the prompt without taking any action.

Create Photo, GIF, Video, and Voice Message Component

Is your feature request related to a problem? Please describe.

Create photo, gif, video and voice message component.

Requirement:

  1. Implement proper error handling and validation for uploading and displaying media files.
  2. Optimize performance by efficiently handling media file storage, retrieval, and rendering.
  3. Consider compatibility with different file formats and sizes commonly used for photos, GIFs, videos, and voice messages.
  4. Make the components accessible and compatible with screen readers and assistive technologies.
  5. Write comprehensive unit tests to ensure the components' functionality and stability.

Figma link: https://www.figma.com/file/SbP0ru8kiB2l334ieX1ESe/Mobile-app?type=design&node-id=761-6807&t=ywP1UTPjrUYSZVMQ-0

Create contact profile page

Is your feature request related to a problem? Please describe.
After reading the messages of a contact I want to check the various details of the contact. For that we need a contact profile page

Describe the solution you'd like

  • Create a static contact profile page according to the designs:
  • This page would open when we click on the contacts name in the messages section similar to how we have on WhatsApp
image

Design file link: https://www.figma.com/file/SbP0ru8kiB2l334ieX1ESe/Mobile-app?type=design&node-id=372-3254&t=Ioc2SXIPBBrgS7Im-0

Implement login functionality

Is your feature request related to a problem? Please describe.
The login page UI is already completed. Now we need to make it functional by making a request to the backend and getting an access token. This token will be used further to make further backend API calls.

Describe the solution you'd like

Additional context
Backend testing URL: https://api.staging.tides.coloredcow.com/api
Phone: 917834811114
Password: secret1234

Or you can setup the backend in local for ease in testing. Steps for setting up the backend :
https://github.com/glific/glific#readme

Implement dynamic Advanced Search

Implement Dynamic Advanced Search

Description:
The goal of this issue is to implement the dynamic Advanced Search feature in the Glific web interface. This feature will allow users to refine their searches using various parameters such as keywords, tags, groups, staff, and date.

The UI for adding search parameters is already built. The next step is to implement the backend functionality to query the API and retrieve search results based on the selected parameters.
API for query - https://api.glific.com/#3924c334-3632-4a32-af55-de5763370d76


Add env file for local, staging and production environments

Is your feature request related to a problem? Please describe.
Some environment configurations will be different for local and production. We need to add an environment configuration file.

Describe the solution you'd like
The configuration file will have the variable BACKEND_URL that will be different for different environments. Also update the steps in Readme to include this.

Additional context
Use this package to add env file https://github.com/goatandsheep/react-native-dotenv

Open the contact messages page with contact details and messages

Is your feature request related to a problem? Please describe.
When we press a contact from the list it should open the messages for the contact along with the contact name on top

Describe the solution you'd like

image

We will use the same search graphql API for getting a particular contacts messages but with different variables


{filter: {id: "21"}, contactOpts: {limit: 1}, messageOpts: {limit: 20, offset: 1}}

Research and implement push notifications for React Native with Elixir backend

Is your feature request related to a problem? Please describe.
At some point we will need to send push notifications on the app for various things like errors or events happening

Describe the solution you'd like

  • When a notification is send from the server it shows notification bar on the mobile even if the app is not open
  • Research on how we can do this with an elixir backend

Update UI for contact list

Is your feature request related to a problem? Please describe.
Make the UI for the contact list page similar to the designs

Describe the solution you'd like
Things to add for a contact:

  • Contact name
  • Contact last message
  • Contact last message time
  • Contact session time left

We are getting all of these details from the backend using the search API

image

Design file link: https://www.figma.com/file/SbP0ru8kiB2l334ieX1ESe/Mobile-app?type=design&node-id=195-2043&t=A9vZTjztIb82wmQZ-0

Implement dedicated image viewer for image message component

Is your feature request related to a problem? Please describe.
Create a dedicated full-screen image viewer.

Describe the solution you'd like

  • On press, the image viewer should open in full-screen mode, providing a closer look at the image.
  • Users should be able to swipe left or right to view the next or previous image respectively, within the same message thread.
  • The image viewer should have an option to return back to the message thread view.

Use jest to create a setup file and write a test case for login

Is your feature request related to a problem? Please describe.
Write unit test case for the login component

Describe the solution you'd like

  • Add a command yarn test to run all test cases.
  • Write a test case for Login component
  • The test should also show the coverage after running

Increase unit test coverage to 80 percent

Is your feature request related to a problem? Please describe.
Increase unit test coverage to 80 percent

Describe the solution you'd like
we are using jest for unit testing

Add a contact messages page

Is your feature request related to a problem? Please describe.
When we click on a particular contact it will show a list of messages for that contact.

Describe the solution you'd like
We will create a structure for the contact messages. The initial version would have the following features:

  • Contact name at the top
  • A section for time left
  • 4-5 messages

The data will be static for now and we will integrate with the backend at a later stage

image

Design file link: https://www.figma.com/file/SbP0ru8kiB2l334ieX1ESe/Mobile-app?type=design&node-id=195-2043&t=4dgUT2BddcRhRzRm-0

Block a Contact

Block a Contact

Implement the Block Contact option in the chat option. This option will allow users to prevent further interaction with a particular contact in the chat list.
API - https://api.glific.com/#c67ad317-1d94-429e-8a9f-2a2fe7f73cbf

Approach:

  • When the user selects the "Block Contact" option, a confirmation prompt or dialog box should appear to confirm their intention to block the contact.
  • Provide a clear and concise message and two options for the user to choose from, such as "Block" and "Cancel." The "Block" option will proceed with blocking the contact, while the "Cancel" option will dismiss the prompt without taking any action.

Add PR submission guidelines in the Readme

Is your feature request related to a problem? Please describe.
When a Pull request is raised it should have the following things:

  • Pass unit test cases
  • The issue link and problem its trying to solve
  • Have no deepscan issue
  • Fomatting should be correct using prettier

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.