Git Product home page Git Product logo

wppconnect-team / wa-js Goto Github PK

View Code? Open in Web Editor NEW
313.0 27.0 115.0 247.11 MB

WPPConnect/WA-JS is an open-source project with the aim of exporting functions from WhatsApp Web

Home Page: https://wppconnect.io/wa-js/

License: Apache License 2.0

Shell 0.02% TypeScript 99.90% JavaScript 0.09%
whatsapp wpp wa whatsapp-bot whatsapp-api whatsapp-chatbot whatsapp-integration whatsapp-sdk whatsapp-web whatsapp-web-api whatsapp-web-automation wajs

wa-js's Introduction

WPPConnect/WA-JS

npm version Downloads Average time to resolve an issue Percentage of issues still open

Build Status Build Status Lint Status release-it

WPPConnect/WA-JS is an open-source project with the aim of exporting functions from WhatsApp Web, which can be used to support the creation of any interaction, such as customer service, media sending, intelligence recognition based on phrases artificial and many other things, use your imagination...

Our online channels

Discord Telegram Group WhatsApp Group YouTube

How does it work

This project extract some functions of WhatsApp sources, that uses webpack.

After build, this project generate a file dist/wppconnect-wa.js to be used for injection in WhatsApp Web. When injected, it will explose a global variable named WPP.

Some parts of WPP variable:

  • WPP.webpack - Scripts to exports WhatsApp functions.
  • WPP.whatsapp - Only exported WhatsApp functions.
  • WPP.chat - Chat functions and events.
  • ...

Exported WhatsApp modules

There are a convection name for some exported modules:

  • ...Model - Class for data structure (ClassModel, MsgModel)
  • ...Collection - Class for collection of models (ChatCollection, MsgCollection)
  • ...Store - Default and global instance of a collection (ChatStore, MsgStore)

Development

Steps to run locally:

# install the depencencies
npm install

# download whatsapp javascript and prettify (optional)
npm run wa-source

# build javascript files
npm run build:prd # or build:dev for development

# launch a local browser with automatic injection
npm run launch:local

# or only run in VSCode

How to use this project

Basicaly, you need to inject the wppconnect-wa.js file into the browser after WhatsApp page load.

TamperMonkey or GreaseMonkey

// ==UserScript==
// @name         WA-JS Teste
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Simple example of WA-JS
// @author       You
// @match        https://web.whatsapp.com/*
// @icon         https://www.google.com/s2/favicons?domain=whatsapp.com
// @require      https://github.com/wppconnect-team/wa-js/releases/download/nightly/wppconnect-wa.js
// @grant        none
// ==/UserScript==

/* globals WPP */

(function () {
  'use strict';

  WPP.webpack.onReady(function () {
    alert('Ready to use WPPConnect WA-JS');
  });

  // Your code here...
})();

Playwright

import * as playwright from 'playwright-chromium';

async function start() {
  const browser = await playwright.chromium.launch();
  const page = await browser.newPage();

  await page.goto('https://web.whatsapp.com/');

  await page.addScriptTag({
    path: require.resolve('@wppconnect/wa-js'),
  });

  // Wait WA-JS load
  await page.waitForFunction(() => window.WPP?.isReady);

  // Evaluating code: See https://playwright.dev/docs/evaluating/
  const isAuthenticated: string = await page.evaluate(() =>
    WPP.conn.isAuthenticated()
  );

  // Sending message: See https://playwright.dev/docs/evaluating/
  const sendResult: string = await page.evaluate(
    (to, message) => WPP.chat.sendTextMessage(to, message),
    to,
    message
  );
}

start();

License

Copyright 2021 WPPConnect Team

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

wa-js's People

Contributors

carlosneves0 avatar dependabot[bot] avatar dxpro avatar edgardmessias avatar edupoli avatar ghsgabriel avatar github-actions[bot] avatar icleitoncosta avatar igordepaula avatar joaosouz4dev avatar joselourenc0 avatar keyurboss avatar marcelo386 avatar moskoweb avatar opsjson avatar renat473 avatar renovate-bot avatar renovate[bot] avatar rhutikcodes avatar rustystriker avatar saifallak avatar trexsiddharth avatar valdir-amaral avatar vphelipe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wa-js's Issues

Messages in the format @1234 delivered as mention or undeliverable

Description

I recently had some complaints of undeliverable messages. When debugging I noticed that it is related to the format "@1234", I updated my docker and some messages started to be delivered only on whatsapp of the target cell phone in mention format, but on whatsapp web it is not delivered. The detail is that the message leaves wppconnect, arrives on the cell phone that is linked to it, but often at the destination it is not delivered.

Environment

  • WhatsApp version: 2.2214.12
  • WA-JS version(s): 2.5.0
  • Browser: Chrome
  • MultiDevice (BETA): yes
  • Docker: yes

Steps to Reproduce

  1. Send a message with the text in the format @1234 using the sendMessage route

  2. In whatsapp the message is delivered in mention format
    image

  3. The same message is not delivered in whatsapp web:
    image

Other test attachments:
image

image

Running on chrome extension

When i try to load wppconnect-wa.js using manifest.json content scripts, the WPP gets available in the window object and then disappears. The status never changes for ready.

// manifest.json
{
  "manifest_version": 3,
  "name": "Hitter",
  "homepage_url": "https://hitter.pro",
  "description": "Acelere as suas vendas no WhatsApp!",
  "update_url": "https://clients2.google.com/service/update2/crx",
  "version": "0.0.1",
  "permissions": [
    "tabs",
    "storage",
    "webNavigation",
    "unlimitedStorage",
    "downloads"
  ],
  "action": {
    "default_popup": "index.html",
    "default_title": "React Browser Extension Template"
  },
  "web_accessible_resources": [
    {
      "matches": [
        "*://web.whatsapp.com/*"
      ],
      "resources": [
        "static/js/content.bundle.js"
      ]
    }
  ],
  "background": {
    "service_worker": "static/js/worker.bundle.js"
  },
  "content_scripts": [
    {
      "matches": [
        "*://web.whatsapp.com/*"
      ],
      "js": [
        "static/js/wppconnect-wa.js",
        "static/js/content.bundle.js"
      ]
    }
  ],
  "commands": {
    "_execute_browser_action": {
      "suggested_key": {
        "default": "Ctrl+Shift+H",
        "mac": "MacCtrl+Shift+H",
        "linux": "Ctrl+Shift+H",
        "windows": "Alt+Shift+H"
      },
      "description": "Abre o Hitter"
    }
  },
  "key": ""
}

Como pegar a lista de chats?

No wapi existe a função getAllChats que pega a lista de chats no side-panel, porem não achei nada semelhante aqui.
Estou tentando contribui com a lib em c# mas estou meio perdido no wa-js.

Criar Função WPP.chat.GetMe

// Número do WhatsApp Conectado na Sessão

WPP.chat.GetMe = async function () {

const result = await WPP.whatsapp.UserPrefs.getMaybeMeUser();

if (result) {

  return result.user;
}

};

Publish JS file

Na publicação de uma release, poderia ter a opção de compilar o arquivo js final também

Criar Função WPP.Labels.GetLabels

// Obter Id e Nomes das Etiquetas criadas no WhatsApp Bussiness

WPP.Labels.GetLabels = function () {
var etiquetas = WPP.whatsapp.LabelStore._models.filter((label) => label.colorIndex);
var names = [];

for (var i = 0; i < etiquetas.length; i++) {
	if (etiquetas[i])
	{
	  names.push(etiquetas[i].id + "&" + etiquetas[i].name);	
	}
}

return names;
};

Status das Reações

Pelo que vi, já podemos enviar reações através do WAJS, porém ainda não da pra saber quando uma pessoa que fala comigo, reagiu a uma mensagem que eu enviei.

sendTextMessage with buttons isn't working

Description

When using sendTextMessage / sendFileMessage / sendLocationMessage with buttons, WhatsApp web will display "Could not deliver message" error. If I remove the buttons, the the message will deliver correctly.

WPP.chat.sendTextMessage(
    '[number]@c.us',
    'Test message',
    { buttons: [{ id: 'test', text: 'Click here' }]  } //will deliver correctly if I remove this line
 ); 

Environment

  • WhatsApp version: Latest version available on Android
  • WA-JS version(s): 2.9.0
  • Browser: Chrome 104.0.5112.81
  • OS: Windows 10
  • MultiDevice (BETA): yes

sendLocationMessage with buttons has problem

Prior to WA-JS 2.9.0, sendLocationMessage does not work
In version 2.9.0, sendLocationMessage works both with or without buttons.
In version 2.10.0, sendLocationMessage works without buttons only. If I add buttons to the message, it won't get delivered

Environment

  • WhatsApp version: 2.22.16.75
  • WA-JS version(s): 2.10.0
  • Browser: Chrome 104.0.5112.81
  • OS: Windows 10
  • MultiDevice (BETA): yes

Ao enviar um Status o mesmo não respeita as configurações de Privacidade

Eu tenho uma lista de pessoas que eu deixo bloqueadas de ver meus status e quando fui postar um status, TODOS receberam, sem nenhuma restrição, conforme as configurações de privacidade que eu escolhi no Whatsapp.

Seria interessante que o método respeitasse as configurações que estão no Whatsapp, que podem ser:

1 - Compartilhar com todos os meus contatos
2 - Compartilhar meus contatos, exceto ...
3 - Compartilhar somente com ...

image

setPresenceOnline(FALSE) funciona temporariamente

Description

Eu ativo a função setPresenceOnline passando parâmetro FALSE para que o browser não mostre meu status online 24 horas. Na hora que eu ativo essa função, o status fica OFFLINE (isso está correto). Porém, com o passar dos minutos ou horas (não sei como e nem quando acontece) o status ONLINE volta a aparecer....

Detalhe: Eu uso o WPPConnect, só estou abrindo a issue conforme solicitado no grupo WPPConnect:

image

Environment

  • WhatsApp version: 2.2220.8
  • WA-JS version(s): 2.7.3
  • Browser: Chrome
  • OS: Windows 10 / Linux Centos 7
  • MultiDevice (BETA): yes

Steps to Reproduce

  1. setOnlinePresence(false)

Your Code

client.setOnlinePresence(false);

Additional context / Screenshot

image

Categorise Chats

Is there any way to categorise chats like only groups, unread messages like in Cooby whatsapp chrome extension?

Criar Função WPP.Labels.GetContactLabels

// Obter Contatos através dos Ids das Etiquetas no WhatsApp Bussiness

WPP.Labels.GetContactLabels = function (id) {
const models = WPP.whatsapp.LabelStore._models.filter((label) => label.id === id).map(c => c.labelItemCollection).map(id => id._models);
let resultado = [];
const chat = 'Chat';
if (models) {

  for (let index = 0; index < models.length; index++){
	  const num = models[index];
	  for (let ind = 0; ind < num.length; ind++){
		 let isCOntato = num[ind].__x_parentId.toLowerCase().split("@");
if (isCOntato[1] == "c.us" )
{
	if (num[ind])
	{
	if (num[ind].__x_id.includes(chat))
	{
	resultado.push(num[ind].__x_id);	
	}	
	}
	 
}
	  }
  }
  return resultado;
}

};

How can I use with electron?

Is there any way I can use it with electron?

I'm injecting the script this way

windowInstance.webContents.executeJavaScript("wa-js")

but I'm not sure how to get the WPP instance

Arquivar chat e desarquivar chat

Não encontrei nos fontes nenhuma possibilidade chamar o arquivamento de chat e também para desarquivar.
Se possível implementar, deixa o whatsapp mais leve quando tem muitas conversas.

Status functions

When I upload status - sometimes it works and sometimes it's not.
I can't see the status from my phone, and can't delete it - its super important that we can delete the status.
after I upload the status - my phone's WhatsApp starts to crash for a while.

please help!

ERROR: await WPP.contact.queryExists

Na manhã desta Sexta-feira - 22/04/2022 a função (WPP.contact.queryExists) para verificar a existencia de uma número passou a retornar o erro abaixo:

Uncaught Module Features not found with e=>{var t,r;return(null===(t=e.GK)||void 0===t?void 0:t.supportsFeature)||(null===(r=e.default)||void 0===r?void 0:r.supportsFeature)}

Error: wid error: invalid wid: [email protected]

Unable to send messages getting this error

Uncaught (in promise) Error: wid error: invalid wid: [email protected]
at new l (bootstrap_qr.a93ca7c63be0f2cdef56.js:71:24606)
at s (bootstrap_qr.a93ca7c63be0f2cdef56.js:71:28948)
at Object.d [as createUserWid] (bootstrap_qr.a93ca7c63be0f2cdef56.js:71:29303)
at t.createWid (wp.js:2:182784)
at t.assertWid (wp.js:2:88293)
at t.prepareRawMessage (wp.js:2:120566)
at t.sendRawMessage (wp.js:2:126923)
at Object.t.sendTextMessage (wp.js:2:128197)

Como obter o status de uma sessão

É de muita importância, uma função que pudesse verificar o estado atual de uma sessão, se o celular está desconectado ou o se o computador está desconectado por exemplo!

Documentation

Is there any documentation on how to use this library?
For example, how to get the QrCode or how to send a message?

Posting stories

Hi, used to post status messages by sending them to status@broadcast, but this no longer works. Is there any proposed fix?

Missing options for sticker

Missing options for sticker:

  • stickerSendOrigin
  • stickerIsAnimated
  • stickerIsFirstParty
  • stickerIsFromStickerMaker

Documentation

I am able to set up the environment locally. Can anyone guide me how to and where to write code to send messages using playwright ?

StatusEvent

Como é chamado o registro do evento para saber o status, assim como possui na lib wppconnect-team/wppconnect?

statusFind: (statusSession, session) => {...

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • build(deps-dev): update typescript-eslint monorepo to ^7.10.0 (@typescript-eslint/eslint-plugin, @typescript-eslint/parser)
  • chore(deps): lock file maintenance
  • 🔐 Create all rate-limited PRs at once 🔐

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/build.yml
  • actions/checkout v4@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-node v4.0.2
  • actions/cache v4
.github/workflows/commitlint.yml
  • actions/checkout v4@a5ac7e51b41094c92402da3b24376905380afc29
  • wagoid/commitlint-github-action v5.5.1
.github/workflows/docs.yml
  • actions/checkout v4@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-node v4.0.2
  • actions/cache v4
  • peaceiris/actions-gh-pages v4
.github/workflows/lint.yml
  • actions/checkout v4@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-node v4.0.2
  • actions/cache v4
.github/workflows/nightly.yml
  • actions/checkout v4@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-node v4.0.2
  • actions/cache v4
  • richardsimko/update-tag v1
.github/workflows/publish.yml
  • actions/checkout v4@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-node v4.0.2
  • actions/cache v4
.github/workflows/release.yml
  • actions/checkout v4@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-node v4.0.2
  • actions/cache v4
.github/workflows/test.yml
  • actions/checkout v4@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-node v4.0.2
  • actions/cache v4
  • actions/github-script v7
  • actions/checkout v4@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-node v4.0.2
  • actions/cache v4
  • nick-invision/retry v3
npm
package.json
  • @commitlint/cli ^19.3.0
  • @commitlint/config-conventional ^19.2.2
  • @commitlint/prompt-cli ^19.3.1
  • @playwright/test ^1.44.0
  • @types/debug ^4.1.12
  • @types/node ^16.18.97
  • @types/node-fetch ^2.6.11
  • @types/parse-data-url ^3.0.2
  • @types/prettier ^3.0.0
  • @types/shelljs ^0.8.15
  • @typescript-eslint/eslint-plugin ^7.9.0
  • @typescript-eslint/parser ^7.9.0
  • @wppconnect/wa-version ^1.4.163
  • buffer ^6.0.3
  • compare-versions ^6.1.0
  • compressorjs ^1.2.1
  • conventional-changelog-angular ^8.0.0
  • conventional-changelog-cli ^5.0.0
  • debug ^4.3.4
  • eslint ^8.57.0
  • eslint-config-prettier ^9.1.0
  • eslint-plugin-header ^3.1.1
  • eslint-plugin-import ^2.29.1
  • eslint-plugin-prettier ^5.1.3
  • eslint-plugin-simple-import-sort ^12.1.0
  • eventemitter2 ^6.4.9
  • file-type ~16.5.4
  • husky ^9.0.11
  • lint-staged ^15.2.2
  • node-fetch ^2.7.0
  • parse-data-url ^6.0.0
  • playwright-chromium ^1.44.0
  • prettier ^3.2.5
  • release-it ^17.3.0
  • shx ^0.3.4
  • ts-loader ^9.5.1
  • ts-morph ^22.0.0
  • ts-node ^10.9.2
  • typedoc ^0.25.13
  • typedoc-plugin-mdn-links ^3.1.26
  • typedoc-plugin-missing-exports ^2.2.0
  • typescript ^5.4.5
  • typescript-debounce-decorator ^0.0.18
  • webpack ^5.91.0
  • webpack-cli ^5.1.4

  • Check this box to trigger a request for Renovate to run again on this repository

Criar Função WPP.chat.GetMyContacts

`// Obter Contatos Da Agenda
WPP.chat.GetMyContacts = function () {
var contatos = WPP.whatsapp.ContactStore.filter((contact) => contact.isMyContact === true);
var names = [];
for (var i = 0; i < contatos.length; i++) {
if(contatos[i])
{
names.push('+' + contatos[i].id.user + "," + contatos[i].displayName);
}
}

return names;
};`

Status postado não aparece no Aparelho

Quando eu posto um status usando a LIB eu não consigo ver esse status no Aparelho.

Seria interessante se pudéssemos ver o status postado em todos os dispositivos (aparelho, whatsapp web) afim de saber quem visualizou nossos status, cancelar, etc.

status message ack, como pegar o retorno se a mensagem foi entregue e se foi visualizada para o id único da messagem

Exemplo que encontrei na internet

{ // It has the same JSON payload as /messages has
// Sending to POST JSON body
"messages": [{
//unique id
"id": "[email protected]_DF38E6A25B42CC8CCE57EC40F",
//text message for type "chat" or link to download the file for "ptt", "image", "audio" and "document"
"body": "Ok!",
//type of the message - "chat" - text, "image" - image, "ptt" - voice, "document" - text document, "audio" - audio file, "call_log" - call
"type": "chat",
//Sender name
"senderName": "Ilya",
//true - outgoing, false - incoming
"fromMe": true,
//Author ID of the message, useful for groups
"author": "[email protected]",
//send time, unix timestamp
"time": 1504208593,
//chat ID
"chatId": "[email protected]",
//sequence number of the message in the database
"messageNumber": 100
}, {
//...
}],
"ack": [{//message delivered
"id": "[email protected]_DF38E6A25B42CC8CCE57EC40F",
"queueNumber": 100
"chatId": "[email protected]",
"status": "delivered",
},{//message viewed
"id": "[email protected]_DF38E6A25B42CC8CCE57EC40F",
"queueNumber": 100
"chatId": "[email protected]",
"status": "viewed",
}, {
//...
}],
}

Requerimento para produtos do catalago

Describe the solution you'd like
Oi Edgar boa noite conforme solicitado deixo aqui minha solicitacao.
Basicamente e sobre o catalago.

1 - addProduct - poder adicionar produtos desde api.
2 - editProduct - poder editar um producto por ID
3 - deleteProduct - poder eliminar producto do catalago.
4 - addCollection - poder adicionar uma colecao.
5 - editCollection - poder editar uma colecao
6 - deleteCollecion - poder eliminar uma colecao.
7 - listCollections - poder listar todas as colecoes.
8 - listAllProducts - poder listar todos os productos do catalago.
(obs: talvez aqui vai precisar de um loadproductos para poder carregar mais de 10 no metodo ja existente hoje)
9- listAllProductodCollection - poder listar todos os productos de uma colecao por id da colecao.

desde logo obrigado

Messages with buttons are not showing correctly

The message with buttons can be delivered after adding useTemplateButtons: true but with an issue:

On the sender side, the Android app will display all messages with buttons in a separate chat room with the sender phone number, as if I am sending the messages to myself. However, the messages are displaying correctly on WhatsApp Web at the right chat rooms.

On the recipient side, the messages are showing correctly both on WhatsApp Web and Android app.

I still have the issue after upgrading the Android app to the latest version. And the same issue happens on WhatsApp Business Android app too.

Originally posted by @ccchai in #570 (comment)

QrCode Read Event

Poderia ter um evento que quando o QrCode fosse lido, fosse disparado, sendo com sucesso ou não

Não envia video mp4 no CEF4 TChromium, mas não retornou nenhum erro

Chromium1.Browser.MainFrame.ExecuteJavaScript(comandoJavaScript);

Utilizando a Mesma função envia normal qualquer tipo de imagem, audio e pdf

SendFileMessage.txt

Anexei o trecho do código
WPP.chat.sendFileMessage();

Criei está função Abaixo para tentar pegar o erro no console, mas não retorna nenhum erro, mas também não envia o vídeo

window.WAPI.sendFileMessage2 = async function(chatid, content, options) {
const result = await WPP.chat.sendFileMessage(chatid, content, options);

if (result) {
try {
SetConsoleMessage("sendFileMessage", JSON.stringify(result));

} catch (err) { 
	console.log(err); 
  };      

}else {
console.log(err);

    }  

};

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.