cinchrb / cinch Goto Github PK
View Code? Open in Web Editor NEWThe IRC Bot Building Framework
Home Page: http://www.rubydoc.info/gems/cinch
License: MIT License
The IRC Bot Building Framework
Home Page: http://www.rubydoc.info/gems/cinch
License: MIT License
If firing :join directly after joining and before syncing, user code that iterates over the list of users might fail.
At the moment, when defining an already existing rule the body (or block) of the plugin moves into an Array with the rest of the already defined blocks. Meaning a plugin could look like this:
:foo => [Proc, Proc, Proc]
Of course that's a dumbed down example. I've been thinking of whether plugins should be overwritten or extended when they're redefined. This means that the loading of plugins which may exist in external resources could be dynamically reloaded and the initial plugin body would be replaced by a new block.
Anyone have any thoughts on this?
Currently, because of the sleep
it waits several seconds (depending on how many retry attempts it already did).
If a server doesn't pass response 376, the bot will not join any channel you pass to it via channels.
When the bot receives a message that no plugin has responded to, it would be great if there was a way to supply a response message.
A flag like :case_sensitive => false
(Defaults to true), to send along with the options, would be nice to have, so that "!ping", "!Ping" and "!PING" triggers the same thing.
Feature request to have the bot spit out some warnings and not run the plugin if it misses some pre-defined config options.
Say that you have a plugin that requires some options :foo and :bar that is actually required for the bot to run. An API-key or similar. The main problem here is that sometime you need this to do proper request against a web service or similar and and it would be nice to have a standardized way to do this instead of having to implement the same thing in each plugin.
Might look something like:
require_options [:foo, :bar]
And if those config options isn't set then the bot would just warn about it and not run the plugin.
My application produces a lot of messages and speed is important, but there is a spam limit for the server. One way to get around this is to have n + 1 bots, with the n bots dedicated to sending the messages. I have tried this by running each bot in its own thread, with weird results.
I am sure I can find ways around this problem, but the fix may be simple (I haven't been able to find it). Thanks for the awesome framework.
m.host does not work with FreeNode's "unaffiliated/name" vhost pattern.
def join(channel, password=nil)
write("JOIN #{channel}")
end
Shouldn't that be: write("JOIN #{channel} #{password}")
It would be nice to have an example for writing tests for a cinch-bot. Preferably in rspec, but anything would be nice.
if I could get lines like
!! Connecting to irc.freenode.net:6667 << NICK
to come as
MyBot:Cinch: !! Connecting to irc.freenode.net:6667 MyBot:Cinch: << NICK
I would be even more happy with cinch :)
For now I'm using and there is no known (to me) other method of doing this:
@bot.raw "NOTICE #{m.user.nick} :#{text}"
But I would like to see something like
m.user.notice text
or
m.notice text
This is not that hard to implement
def notice(text)
@bot.raw "NOTICE #{nick} :#{text}"
end
and would make bots written with cinch even more beautiful.
I just wonder if @bot.raw is thread safe?
When running the following code
require 'cinch'
bot = Cinch::Bot.new do
configure do |c|
c.nick = "IgorBot"
c.server = "irc.freenode.org"
c.channels = ["#mybotchannel"]
end
# quit
on :message, "!quit" do |m|
bot.quit
end
end
bot.start
and sending the !quit command, I receive following error:
/home/igor/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/thread.rb:185:in
'sleep': deadlock detected (fatal) from /home/igor/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/thread.rb:185:in
block in pop'
from internal:prelude:10:insynchronize' from /home/igor/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/thread.rb:180:in
pop'
from /home/igor/.rvm/gems/ruby-1.9.2-p0/gems/cinch-1.0.2/lib/cinch/message_queue.rb:52:inprocess!' from /home/igor/.rvm/gems/ruby-1.9.2-p0/gems/cinch-1.0.2/lib/cinch/irc.rb:58:in
connect'
from /home/igor/.rvm/gems/ruby-1.9.2-p0/gems/cinch-1.0.2/lib/cinch/bot.rb:404:instart' from mybot.rb:12:in
When the bot times out (due to either the internet going out due to power outage, or some other thing that causes it), it attempts to reconnect, however the process quits instead of retrying. (In the current Cinch code as of 2011-08-23 1:28 PM ADT)
An example of the error is shown below:
[2011/08/23 11:10:40.665] << PING 0
[2011/08/23 11:10:59.618] !! C:/Ruby192/lib/ruby/1.9.1/openssl/buffering.rb:145:in `sysread_nonblock': An existing connection wa
s forcibly closed by the remote host. (Errno::ECONNRESET)
[2011/08/23 11:10:59.620] !! C:/Ruby192/lib/ruby/1.9.1/openssl/buffering.rb:145:in `read_nonblock'
[2011/08/23 11:10:59.621] !! C:/Ruby192/lib/ruby/1.9.1/net/protocol.rb:135:in `rbuf_fill'
[2011/08/23 11:10:59.622] !! C:/Ruby192/lib/ruby/1.9.1/net/protocol.rb:116:in `readuntil'
[2011/08/23 11:10:59.622] !! C:/Ruby192/lib/ruby/1.9.1/net/protocol.rb:126:in `readline'
[2011/08/23 11:10:59.623] !! C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/irc.rb:89:in `block in start_reading_t
hread'
Deprecation warning: Beginning with version 1.2.0, Bot#dispatch should not be used anymore.
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/bot.rb:267:in `dispatch'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/irc.rb:104:in `block in start_reading_thread'
[2011/08/23 11:11:09.843] !! Waiting 1 seconds before reconnecting
[2011/08/23 11:11:10.844] !! Connecting to irc.freenode.net:6697
[2011/08/23 11:11:11.469] !! C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/irc.rb:34:in `initialize': getaddrinfo: N
o such host is known. (SocketError)
[2011/08/23 11:11:11.470] !! C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/irc.rb:34:in `new'
[2011/08/23 11:11:11.471] !! C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/irc.rb:34:in `block in connect'
[2011/08/23 11:11:11.472] !! C:/Ruby192/lib/ruby/1.9.1/timeout.rb:57:in `timeout'
[2011/08/23 11:11:11.472] !! C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/irc.rb:33:in `connect'
[2011/08/23 11:11:11.473] !! C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/irc.rb:140:in `start'
[2011/08/23 11:11:11.474] !! C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/bot.rb:338:in `start'
[2011/08/23 11:11:11.475] !! g:/bot/bot_base.rb:93:in `<main>'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/irc.rb:205:in `message': undefined method `queue' for nil:NilClass (No
MethodError)
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/irc.rb:79:in `send_login'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/irc.rb:141:in `start'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/cinch-1.1.3/lib/cinch/bot.rb:338:in `start'
from g:/bot/bot_base.rb:93:in `<main>'
When are you guys going to release the next cut of cinch? Are there open issues that need to be resolved before you are wiling to cut a new release?
Hi,
i found some problems when I tried to test my cinch plugins (no clean api for testing), so I'm trying to use master version, but I found bug there and maybe there is more. So I would like to ask, do you consider some kind of test/spec coverage? Its hard to contribute a project and do not break anything. But from what I see there is no spec or tests.
Btw bug is https://github.com/cinchrb/cinch/blob/master/lib/cinch/handler_list.rb#L38
type is symbol, but passing symbol to match, blows because it expects integer
When running Cinch with encoding = "iso-2022-jp", Ruby rises Encoding::CompatibilityError. The cause is probably because ISO-2022-JP is not compatible with ASCII. (ISO-2022-JP is commonly used by Japanese in IRCNet.)
(Error message)
/Users/yasu/devel/cinch/lib/cinch/message_queue.rb:68:in `process!': incompatible character encodings: ISO-2022-JP and UTF-8 (Encoding::CompatibilityError)
(Quick fix)
It works, but I'm not sure whether if it is suitable fix.
force_encoding("binary") is required for ASCII incompatible encoding to work.
https://gist.github.com/1528729
Hey,
when I use @bot.quit I get an exception as listed below
on :message, "!quit" do |m|
@bot.quit
end
/Users/nils/.rvm/gems/ruby-1.9.2-p180/bundler/gems/cinch-b0a7419e3e09/lib/cinch/bot.rb:267:in dispatch' /Users/nils/.rvm/gems/ruby-1.9.2-p180/bundler/gems/cinch-b0a7419e3e09/lib/cinch/irc.rb:104:in
block in start_reading_thread'
NoMethodError: undefined method values' for #<Cinch::HandlerList:0x0000010152b730> from /Users/nils/.rvm/gems/ruby-1.9.2-p180/bundler/gems/cinch-b0a7419e3e09/lib/cinch/irc.rb:105:in
block in start_reading_thread'
Can I use cinch to build and extend an irc logger?
I've been using a very old Perl IRC logger http://www.dajobe.org/software/logger/ for logging conversations on the #otrunk channel on freenode -- but it doesn't work very well and I know Ruby not Perl.
I'm not very familiar with irc bot programming but creating a logger out of a mashup of sinatra/rack and cinch might be pretty strait-forward -- and perhaps an example is already around somewhere.
Thanks for any advice/feedback.
Is there a built-in way to reload the bot (without having to kill the ruby process and start a new one)? I'd like to test my code, but I'm getting klined due to rapid reconnects. Not ideal.
I have a bot which sends messages from other threads. How can I do that in a thread safe manner with Cinch?
cinch-1.1.1/lib/cinch/channel.rb:110:in `has_user?': undefined method `User' for #<Channel name="#adfg"> (NoMethodError)
hi! i just started using this gem and it's awesome!
I do have a question though. Is it possible to make the bot send a message to a channel periodically? Because right now the bot is only triggered through the plugin method (i.e. when someone sends a message to a channel)
would be glad for info on this. thanks!
Following message is shown even if loggers.level is set to higher one (such as :warn) in the block associated with Cinch::Bot.new. The reason is that @loggers.level is overwritten just before registering on-connect handler in Cinch::Bot#initialize.
[2012/01/25 00:06:20.225] !! [on handler] Registering handler with pattern `#<Cinch::Pattern:0x00000100860be0 @prefix=nil, @pattern=//, @suffix=nil>`, reacting on `connect`
require "cinch"
bot = Cinch::Bot.new do
loggers.level = :warn # won't work
configure do |c|
c.server = "localhost"
c.port = 6690
c.channels = ["#FatechanMoe"]
end
end
bot.loggers.level = :warn # works!
bot.start
There these thingies called action messages, when you write /me
I would like to have some API for them, since there were none, I wrote myself some:
class Cinch::Message
def action?
return false if message == nil
return ctcp_message.starts_with?("ACTION ")
end
def action_message
return message.split(" ")[1..-1].join(" ")
end
end
But I guess this is an ugly hack and we want to see something more viable!
The network I'm using returns a line like this one when whoising someone:
13:49:47 aitvaras -- | [txdv] is a registered nick
this occures only when the nick is registered AND identified. I guess that is not the raw format is different, I'll look it up.
def spf_regex(r) case r when Regexp return "/#{r.source}/" when String return r end end
plugin.rb:line 128
bot.debug ("[plugin] #{plugin_name}: Registering executor with pattern `#{spf_regex(pattern.pattern)}`, reacting on `#{react_on}`") if bot.config.verbose
Due to a bug, Cinch currently does not support SSL connections. This will be fixed in the next version.
http://pastebin.com/ADyt7Kic this is the script.
http://pastebin.com/cPK4Gv7i this is the behavior.
Flooding the bot with commands results in total unresponsiveness of the actually command, when it uses ActiveRecord objects. I tried it with the google example, but failed to reproduce this particular bug(?).
log method never set prefix when message kind is :generic tho it's the default.
crash in 'lib/cinch/logger/formatted_logger.rb', line 55
[2011/04/12 02:33:32.088] !! /home/max/.rvm/gems/ruby-1.9.2-p180@tornbot/gems/cinch-1.1.2/lib/cinch/logger/formatted_logger.rb:55:in block (2 levels) in log': undefined method
+' for nil:NilClass (NoMethodError)
[2011/04/12 02:33:32.088] !! /home/max/.rvm/gems/ruby-1.9.2-p180@tornbot/gems/cinch-1.1.2/lib/cinch/logger/formatted_logger.rb:31:in each' [2011/04/12 02:33:32.089] !! /home/max/.rvm/gems/ruby-1.9.2-p180@tornbot/gems/cinch-1.1.2/lib/cinch/logger/formatted_logger.rb:31:in
block in log'
[2011/04/12 02:33:32.089] !! internal:prelude:10:in synchronize' [2011/04/12 02:33:32.089] !! /home/max/.rvm/gems/ruby-1.9.2-p180@tornbot/gems/cinch-1.1.2/lib/cinch/logger/formatted_logger.rb:29:in
log'
[2011/04/12 02:33:32.089] !! /home/max/Documents/dev/tornbot/plugins/control.rb:30:in join' [2011/04/12 02:33:32.089] !! /home/max/.rvm/gems/ruby-1.9.2-p180@tornbot/gems/cinch-1.1.2/lib/cinch/plugin.rb:207:in
call'
[2011/04/12 02:33:32.089] !! /home/max/.rvm/gems/ruby-1.9.2-p180@tornbot/gems/cinch-1.1.2/lib/cinch/plugin.rb:207:in block (2 levels) in __register_with_bot' [2011/04/12 02:33:32.089] !! /home/max/.rvm/gems/ruby-1.9.2-p180@tornbot/gems/cinch-1.1.2/lib/cinch/bot.rb:637:in
instance_exec'
[2011/04/12 02:33:32.089] !! /home/max/.rvm/gems/ruby-1.9.2-p180@tornbot/gems/cinch-1.1.2/lib/cinch/bot.rb:637:in block (2 levels) in invoke' [2011/04/12 02:33:32.089] !! /home/max/.rvm/gems/ruby-1.9.2-p180@tornbot/gems/cinch-1.1.2/lib/cinch/bot.rb:636:in
catch'
[2011/04/12 02:33:32.089] !! /home/max/.rvm/gems/ruby-1.9.2-p180@tornbot/gems/cinch-1.1.2/lib/cinch/bot.rb:636:in `block in invoke'
Im using Cinch 1.0.1 and rails 3.0.0.rc and ruby 1.9.2-p0
and i get the following error:
!! Connecting to irc.freenode.org:6667
<< NICK TestmeBot
!! /home/name/.rvm/gems/ruby-1.9.2-p0@getpcw/gems/cinch-1.0.1/lib/cinch/irc.rb:46:in `gets': code converter not found (UTF-8 to UTF-8) (Encoding::ConverterNotFoundError)
!! /home/name/.rvm/gems/ruby-1.9.2-p0@getpcw/gems/cinch-1.0.1/lib/cinch/irc.rb:46:in `block in connect'
<< USER TestmeBot 0 * :cinch
fatal: deadlock detected
from /home/name/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/thread.rb:185:in `sleep'
from /home/name/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/thread.rb:185:in `block in pop'
from <internal:prelude>:10:in `synchronize'
from /home/name/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/1.9.1/thread.rb:180:in `pop'
from /home/name/.rvm/gems/ruby-1.9.2-p0@getpcw/gems/cinch-1.0.1/lib/cinch/message_queue.rb:52:in `process!'
from /home/name/.rvm/gems/ruby-1.9.2-p0@getpcw/gems/cinch-1.0.1/lib/cinch/irc.rb:60:in `connect'
from /home/name/.rvm/gems/ruby-1.9.2-p0@getpcw/gems/cinch-1.0.1/lib/cinch/bot.rb:404:in `start'
from (irb):1
from /home/name/.rvm/gems/ruby-1.9.2-p0@getpcw/gems/railties-3.0.0.rc/lib/rails/commands/console.rb:44:in `start'
from /home/name/.rvm/gems/ruby-1.9.2-p0@getpcw/gems/railties-3.0.0.rc/lib/rails/commands/console.rb:8:in `start'
from /home/name/.rvm/gems/ruby-1.9.2-p0@getpcw/gems/railties-3.0.0.rc/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Im just testing it out, and I have a file called lib/bot.rb
:
class Bot
def self.bot
bot = Cinch::Bot.new do
configure do |c|
c.server = "irc.freenode.org"
c.nick = "TestmeBot"
c.channels = ["#cinch"]
end
on :message, /^!msg (.+?) (.+)/ do |m, who, text|
User(who).send text
end
end
end
end
if I do $ rails console
and do Bot.bot.start
I get the message above. If I run it outside of rails with just `irb' it runs perfect. I don't know if its rails 3 or something eternal stuff with rails and cinch that makes it go boom :(
In my bot:
helpers do
def shutup?
@shutup = false if @shutup_expire <= @shutup
!!@shutup
end
end
And in a plugin:
m.reply @factoids[matches[2].downcase] unless @bot.shutup?
But when running I get:
factoids.rb:31:in `listen': undefined method `shutup?' for #<Cinch::Bot:0x000000028ee098> (NoMethodError)
Am I misunderstanding how helpers work or is this a bug? I thought it would define the methods in the context of the bot object?
The message was: [01:06:22] DEAD opa;): wh
The loggeroutput:
:six!~[email protected] PRIVMSG #six : DEAD 04opa;): wh
in the original message opa was colored red, so colorcode04, but it is not escaped.
it can fail if you use threads in plugins.
actually I think plugins(rules) should be executed in threads and maybe allow to set a timeout option
something like
Timeout.timeout(timeout_option) do
Thread.start do
blk.call(...)
end
end
I've attempted to do the following
irc = Cinch.Setup :verbose => true do
server "irc.gamesurge.net"
nick "xperienceBot"
channels %w(#xperience)
end
irc.run
but the bot doesn't join any channels. I have used this library before and had no problems.
Hi!
I Just tried the "Hello world" example with Cinch 1.1.3 and ruby 1.9.3 (the example is at: https://github.com/cinchrb/cinch/blob/master/examples/plugins/hello.rb). It is my understanding that the bot should reply to "hello" messages, but it does not, although it seems to register the plugin fine.
[2011/09/05 14:12:43.394] !! [on handler] Registering handler with pattern `#<Cinch::Pattern:0x00000001d95138@prefix=nil, @pattern=//, @suffix=nil>`, reacting on `connect`
[2011/09/05 14:12:43.394] !! [plugin] hello: Registering executor with pattern `#<Cinch::Pattern:0x00000001d94350@prefix=/^!/, @pattern=/hello/, @suffix=nil>`, reacting on `message`
[2011/09/05 14:12:43.394] !! [on handler] Registering handler with pattern `#<Cinch::Pattern:0x00000001d94350@prefix=/^!/, @pattern=/hello/, @suffix=nil>`, reacting on `message`
[2011/09/05 14:12:43.394] !! Connecting to irc.freenode.org:6667
# etc. ...
ruby -v is ruby 1.9.3dev (2011-07-31 revision 32789) [x86_64-linux]
I'm not really sure what's wrong here, as I haven't had a lot of time to investigate past this.
HTH.
version 1.0.1
plugin.rb:line 102
lines like that aught to be changed to:
bot.debug("[plugin] #{plugin_name}: Registering listener for type #{listener.event}
") if bot.config.verbose
http://doc.injekt.net/cinch/Cinch/Plugin.html
Would be great to have these back up.
I haven't fully thought this out, but it'd be nice if you could point your ruby code at a directory full of .rb files, and they would:
!help
would show all commands listed, or at least all plugins.!help
would be routed to the right plugin for more information.Ciao!
Hey, I got this error:
/usr/local/rvm/gems/ruby-1.9.2-p290/bundler/gems/cinch-1e606cd6a5d9/lib/cinch/timer.rb:47:in block (3 levels) in start': undefined method
rescue_exception' for #Cinch::Timer:0xa609fdc (NoMethodError)
in my bot I would like to configure the plugins depending on some parameters (say the channel). for example if I want to setup the timezone and translations(i18n) per channel the callback would be like this:
def before_executing_a_plugin(m)
if m.channel && m.channel.name == "#colombia"
Time.zone = "Bogota" #this is thread-safe
I18n.locale = :es
end
end
the callback should be called in the thread in which the actual plugin callback is called
When I try to call opped?, I get an error:
!! /home/alex/tf2.pug.na-IRC-bot/cinch/user.rb:39:in find_ensured': undefined method
irc_downcase' for #Cinch::Message:0x9ab8cf4 (NoMethodError)
Am I doing something wrong or is this a bug?
Thanks.
This is when trying to import a simple plugin.
/Users/wedtm/.rvm/gems/ruby-1.9.2-p180/gems/cinch-1.1.3/lib/cinch/bot.rb:362:in `register_plugins': undefined method `plugins' for [TinyURL]:Array (NoMethodError)
from /Users/wedtm/.rvm/gems/ruby-1.9.2-p180/gems/cinch-1.1.3/lib/cinch/bot.rb:409:in `start'
from fred.rb:29:in `<main>'
~/Dropbox/code/fred >
require 'rubygems'
#require 'bundler/setup'
#Bundler.require
require 'cinch'
require 'nokogiri'
require 'cgi'
Dir[File.join('plugins', '*.rb')].each { |file| require "./" + file }
bot = Cinch::Bot.new do
configure do |c|
c.server = "irc.esper.net"
c.channels = ["#wedtm"]
c.nick = "Fred"
c.user = "Fred"
c.plugins = [TinyURL]
end
on :message, "hello" do |m|
m.reply "Hello, #{m.user.nick}"
end
on :message, /^hello (.+)/ do |m, args|
m.reply "Hello 2, #{args[0]}"
end
end
bot.start
require 'open-uri'
require 'cinch'
class TinyURL
include Cinch::Plugin
listen_to :channel
def shorten(url)
url = open("http://tinyurl.com/api-create.php?url=#{URI.escape(url)}").read
url == "Error" ? nil : url
rescue OpenURI::HTTPError
nil
end
def listen(m)
urls = URI.extract(m.message, "http")
short_urls = urls.map { |url| shorten(url) }.compact
unless short_urls.empty?
m.reply short_urls.join(", ")
end
end
end
I copied and pasted (changed irc server) the plugin hello example and it does not work the non plugin hello example works fine
The simplest way to send message to channel I found isn't very elegant:
class Cinch::Base
def announce_on_all_channels( msg )
channels.each do | channel |
process(":[email protected] PRIVMSG #{channel} :!say #{msg}")
end
end
end
bot = Cinch.setup :verbose => true
bot.plugin("say :text") do |m|
m.reply m.args[:text]
end
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.