Code Monkey home page Code Monkey logo

sendgrid-go's Introduction

Twilio SendGrid Logo

Test and Deploy GoDoc MIT licensed Twitter Follow GitHub contributors Open Source Helpers

This library allows you to quickly and easily use the Twilio SendGrid Web API v3 via Go.

Version 3.X.X of this library provides full support for all Twilio SendGrid Web API v3 endpoints, including the new v3 /mail/send.

This library represents the beginning of a new path for Twilio SendGrid. We want this library to be community driven and Twilio SendGrid led. We need your help to realize this goal. To help make sure we are building the right things in the right order, we ask that you create issues and pull requests or simply upvote or comment on existing issues or pull requests.

If you need help using SendGrid, please check the Twilio SendGrid Support Help Center.

Table of Contents

Installation

Supported Versions

This library supports the following Go implementations:

  • Go 1.14
  • Go 1.15
  • Go 1.16
  • Go 1.17
  • Go 1.18
  • Go 1.19

Prerequisites

  • The Twilio SendGrid service, starting at the free level, to send up to 40,000 emails for the first 30 days, then send 100 emails/day free forever or check out our pricing.

Setup Environment Variables

Update the development environment with your SENDGRID_API_KEY, for example:

echo "export SENDGRID_API_KEY='YOUR_API_KEY'" > sendgrid.env
echo "sendgrid.env" >> .gitignore
source ./sendgrid.env

Install Package

go get github.com/sendgrid/sendgrid-go

Dependencies

Setup Environment Variables

Initial Setup

cp .env_sample .env

Environment Variable

Update the development environment with your SENDGRID_API_KEY, for example:

echo "export SENDGRID_API_KEY='YOUR_API_KEY'" > sendgrid.env
echo "sendgrid.env" >> .gitignore
source ./sendgrid.env

Quick Start

Hello Email

The following is the minimum needed code to send an email with the /mail/send Helper (here is a full example):

With Mail Helper Class

package main

import (
	"fmt"
	"log"
	"os"

	"github.com/sendgrid/sendgrid-go"
	"github.com/sendgrid/sendgrid-go/helpers/mail"
)

func main() {
	from := mail.NewEmail("Example User", "[email protected]")
	subject := "Sending with Twilio SendGrid is Fun"
	to := mail.NewEmail("Example User", "[email protected]")
	plainTextContent := "and easy to do anywhere, even with Go"
	htmlContent := "<strong>and easy to do anywhere, even with Go</strong>"
	message := mail.NewSingleEmail(from, subject, to, plainTextContent, htmlContent)
	client := sendgrid.NewSendClient(os.Getenv("SENDGRID_API_KEY"))
	response, err := client.Send(message)
	if err != nil {
		log.Println(err)
	} else {
		fmt.Println(response.StatusCode)
		fmt.Println(response.Body)
		fmt.Println(response.Headers)
	}
}

The NewEmail constructor creates a personalization object for you. Here is an example of how to add to it.

Without Mail Helper Class

The following is the minimum needed code to send an email without the /mail/send Helper (here is a full example):

package main

import (
	"fmt"
	"github.com/sendgrid/sendgrid-go"
	"log"
	"os"
)

func main() {
	request := sendgrid.GetRequest(os.Getenv("SENDGRID_API_KEY"), "/v3/mail/send", "https://api.sendgrid.com")
	request.Method = "POST"
	request.Body = []byte(` {
	"personalizations": [
		{
			"to": [
				{
					"email": "[email protected]"
				}
			],
			"subject": "Sending with Twilio SendGrid is Fun"
		}
	],
	"from": {
		"email": "[email protected]"
	},
	"content": [
		{
			"type": "text/plain",
			"value": "and easy to do anywhere, even with Go"
		}
	]
}`)
	response, err := sendgrid.API(request)
	if err != nil {
		log.Println(err)
	} else {
		fmt.Println(response.StatusCode)
		fmt.Println(response.Body)
		fmt.Println(response.Headers)
	}
}

General v3 Web API Usage

package main

import (
	"fmt"
	"github.com/sendgrid/sendgrid-go"
	"log"
	"os"
)

func main() {
	request := sendgrid.GetRequest(os.Getenv("SENDGRID_API_KEY"), "/v3/api_keys", "https://api.sendgrid.com")
	request.Method = "GET"

	response, err := sendgrid.API(request)
	if err != nil {
		log.Println(err)
	} else {
		fmt.Println(response.StatusCode)
		fmt.Println(response.Body)
		fmt.Println(response.Headers)
	}
}

Processing Inbound Email

Please see our helper for utilizing our Inbound Parse webhook.

Usage

Use Cases

Examples of common API use cases, such as how to send an email with a transactional template.

Announcements

All updates to this library are documented in our CHANGELOG and releases.

How to Contribute

We encourage contribution to our libraries (you might even score some nifty swag), please see our CONTRIBUTING guide for details.

Quick links:

Troubleshooting

Please see our troubleshooting guide for common library issues.

About

sendgrid-go is maintained and funded by Twilio SendGrid, Inc. The names and logos for sendgrid-go are trademarks of Twilio SendGrid, Inc.

Support

If you need help using SendGrid, please check the Twilio SendGrid Support Help Center.

License

The MIT License (MIT)

sendgrid-go's People

Contributors

af4ro avatar anchepiece avatar andy-trimble avatar arxdsilva avatar brandonmwest avatar cglewis avatar ciceropablo avatar cleanse avatar crweiner avatar deckarep avatar devchas avatar dhoeric avatar dmowcomber avatar eddiezane avatar eshanholtz avatar extemporalgenome avatar jennifermah avatar liychristopher avatar mbernier avatar myzeprog avatar nexweb avatar pangaunn avatar pytlesk4 avatar shwetha-manvinkurke avatar srini156 avatar tariq1890 avatar thinkingserious avatar twilio-ci avatar twilio-dx avatar vaskoz 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  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

sendgrid-go's Issues

Make testing easier with interfaces

For testing purposes I've not been able to find a way to mock out any of the sendgrid-go library (or smtpapi-go for that matter). Even defining my own local interfaces and mocking those I am defeated by the public API using specific types (Send in particular). It would be great if there were 2 interfaces:

type SGClient interface {
    Send(SGMail) error
}

type SGMail interface {
    AddTo(string) error
    AddTos([]string) error
    AddRecipient(*mail.Address)
    ...
}

Then the existing SGClient and SGMail should satisfy these interfaces. The AWS Go SDK for example provides an interface for each service and it makes testing very easy. This should be possible without any breaking changes, the only API change would be to SGClient.Send going from Send(m *sendgrid.SGMail) to Send(m sendgrid.SGMailInterface).

Integration with mail_v3.go

Hi,

I'm trying to integrated my application using this Go library.

My objective is to have emails to be sent at a point in time and so I noticed there is a mail_v3.go file which contains a 'SendAt' field; I assume this is the field to populate to achieve my objective.

However, when i try to Send the message, there is a type conflict ("cannot use message (type *sendgrid.SGMailV3) as type *sendgrid.SGMail"). This is understandable as it's using the old sendgrid.go method of sending.

My question is: Is there a new send method for SGMailV3 type? like a sendgrid_v3.go? If there isn't, is there an alternative solution i can use? It would require to use a SendGrid email template.

It just feels like there's a missing piece to send SGMailV3 type mail.

Many Thanks

Add vendoring

Issue Summary

This pull request is going to be a breaking change.

Adding vendoring will help us manage these breaks easier. We want to avoid surprising breaking changes. Note that we will continue to follow semver.org conventions.

Attachment is nothing when using AddAttachmentFromStream()

I wrote and ran this code:

package main

import (
   "fmt"

   sendgrid "github.com/sendgrid/sendgrid-go"
)

func main() {
   mail := sendgrid.NewMail()
   mail.AddTo("MY_EMAIL_ADDRESS")
   mail.SetFrom("MY_EMAIL_ADDRESS")
   mail.SetFromName("deltam")
   mail.SetSubject("test mail")
   mail.SetText("testing mail send now.")
   mail.AddAttachmentFromStream("test.txt", "test,test")

   sg := sendgrid.NewSendGridClient("MY_USER_ID", "MY_PASSWORD")
   if r := sg.Send(mail); r == nil {
      fmt.Println("Email sent!")
   } else {
      fmt.Println(r)
   }
}

I expect received email that has attachment("test.txt"), but attachment is nothing.

I tried official document example(using cURL). Received email has attachment.

https://sendgrid.com/docs/API_Reference/Web_API/mail.html#-Send-a-test-specifying-the-file-content-type-by-appending-typemime-type-to-the-file-name

Is AddAttachmentFromStream() along API?

https://sendgrid.com/docs/API_Reference/Web_API/mail.html#-send
files Parameter is filename.

Add Rate Limiting Support

We would like to add support for v3 Web API rate limits, as described here.

How would you like this to be implemented? Or please give a thumbs up to express your interest in us implementing to move this task up our queue.

PRs are always welcome as well :)

Send mail failed with v3 API and multi-byte contents.

Issue Summary

We can't send a mail via v3 API with multibyte content.

Steps to Reproduce

func TestSendGrid_bare(t *testing.T) {
    m := mail.NewV3Mail()
    m.SetFrom(mail.NewEmail("ๆ—ฅๆœฌ่ชžๅ1", "[email protected]"))
    m.Subject = "ๆ—ฅๆœฌ่ชžใ‚ฟใ‚คใƒˆใƒซ"
    m.AddContent(mail.NewContent("text/html", "๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™"))

    p := mail.NewPersonalization()
    p.AddTos(mail.NewEmail("ๆ—ฅๆœฌ่ชžๅ2", "[email protected]"))
    m.AddPersonalizations(p)

    request := sendgrid.GetRequest("<my api key>", "/v3/mail/send", "https://api.sendgrid.com")
    request.Method = "POST"
    request.Body = mail.GetRequestBody(m)

    response, err := sendgrid.API(request)
    if err != nil {
        t.Error(err)
    } else if response.StatusCode < 200 || 300 <= response.StatusCode{
        t.Error(response.StatusCode)
        t.Error(response.Body)
        t.Error(response.Headers)
    } else {
        t.Log(response.StatusCode)
        t.Log(response.Body)
        t.Log(response.Headers)
    }
}

func TestSendGrid_emoji(t *testing.T) {
    m := mail.NewV3Mail()
    m.SetFrom(mail.NewEmail("foo", "[email protected]"))
    m.Subject = "title"
    m.AddContent(mail.NewContent("text/plain", "๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ๐Ÿฑ๐Ÿ˜ธ"))

    p := mail.NewPersonalization()
    p.AddTos(mail.NewEmail("fizzbuzz", "[email protected]"))
    m.AddPersonalizations(p)

    request := sendgrid.GetRequest("<my api key>", "/v3/mail/send", "https://api.sendgrid.com")
    request.Method = "POST"
    request.Body = mail.GetRequestBody(m)

    response, err := sendgrid.API(request)
    if err != nil {
        t.Error(err)
    } else if response.StatusCode < 200 || 300 <= response.StatusCode{
        t.Error(response.StatusCode)
        t.Error(response.Body)
        t.Error(response.Headers)
    } else {
        t.Log(response.StatusCode)
        t.Log(response.Body)
        t.Log(response.Headers)
    }
}
=== RUN   TestSendGrid_bare
--- FAIL: TestSendGrid_bare (0.89s)
    sendgrid_test.go:30: 415
    sendgrid_test.go:31: {"errors":[{"message":"Unrecognized UTF8 Byte at position 511","field":null,"help":"http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#-Encoding-Errors"}]}
    sendgrid_test.go:32: map[Server:[nginx] Date:[Thu, 23 Jun 2016 04:21:42 GMT] Content-Type:[application/json] Content-Length:[171] Connection:[keep-alive] X-Frame-Options:[DENY]]
=== RUN   TestSendGrid_emoji
--- FAIL: TestSendGrid_emoji (0.09s)
    sendgrid_test.go:59: 415
    sendgrid_test.go:60: {"errors":[{"message":"Unrecognized UTF8 Byte at position 511","field":null,"help":"http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#-Encoding-Errors"}]}
    sendgrid_test.go:61: map[Content-Length:[171] Connection:[keep-alive] X-Frame-Options:[DENY] Server:[nginx] Date:[Thu, 23 Jun 2016 04:21:42 GMT] Content-Type:[application/json]]

Technical details:

  • sendgrid-go Version: master (latest commit: [21f0869])
  • Go Version: 1.6.2

I'm posted this issue to SendGrid support. Request # 691762

Sendgrid AddUniqueArg problem

We are experiencing an issue with Sendgrid's invaluable feature, UniqueArgs, often not being set on the new mail. We have confirmed that we are definitely setting the unique arg to a non-empty string value, but we don't see the unique arg in Sendgrid's Event Notification POSTs, and Sendgrid's logs don't show any such arg from the client.

Why might the mtmsg_id unique arg. be set?

Here is the relevant application code:
(mtContent and mtMessage are structs from the application)

var sgClient = sendgrid.NewSendGridClient("username", "password");

var message = sendgrid.NewMail();

message.AddUniqueArg("mtmsg_id", mtMessage.Id);

message.AddTo(mtMessage.To);
message.AddToName(mtContent.SenderName);
message.SetReplyTo(mtContent.ReplyTo);
message.SetSubject(mtContent.Subject);
message.SetHTML(mtContent.Html);
message.SetText(mtContent.Text);
message.SetFrom(mtMessage.From);
if r := sgClient.Send(message); r == nil {
// Email sent succesfully!
// Successfully sent, set sync success!

} else {
// Failure handling
}

This is in production, so any help is appreciated!

Utilize Transactional Templates

Acceptance Criteria:

  • Demonstration of usage with all three cases: Send a Single Email to a Single Recipient, Send a Single Email to Multiple Recipients, Send Multiple Emails to Multiple Recipients and

Reference:

Versioning (best practice for dealing with breaking changes)

Issue Summary

Several of you have voiced concerned about the recent breaking changes to the library. As we move forward, there will be more breaking changes. This issue aims to provide a solution that will make those transitions smoother.

So far we have heard the following options:

  1. Include the version number in the URL. (each major version change would go in it's own folder)
  2. Use gopkg.in
  3. Reimplement and expose the old API surface in terms of new API (thanks @aeijdenberg)

Please let us know what you think

Thanks!

Heroku Golang section is out of date

Hello,

The example code used in the Golang section on Heroku is out of date. sendgrid. NewSendGridClient() doesn't appear to exist anymore. The examples on the Github seem to work great.

Technical details:

  • sendgrid-go Version: master (latest commit: [commit number])
  • Go Version: 1.5.1

Issue with attachment

Hi all i tried sending attachment but it didnt work.

Heres my codes:

....
file, err := os.Open("file.go")
fileName := "test.txt"
message.AddAttachment(fileName, file)
err := sg.Send(message)
....

there's no error produced, it actually sent the email but without the attachment.

Thanks in advance!

Correlating with bounced mail

After using this api to send email. Email is SENT / BOUNCED etc.
I have created a event webhook to know what are all the mails that are bounced, so that I can trigger further things within my application.
To correlate between sent mail and webhook, are there any identifiers. From the docs, couldn't identify them. Kindly, let me know if there are anything else that need to done.

The Go sample on sendgrid's frontpage contains a bug

Hi, I was just trying out the API and found a bug in the sample that you guys show on the company homepage.

Current version:

// using SendGrid's Go Library - https://github.com/sendgrid/sendgrid-go
package main

import ("github.com/sendgrid/sendgrid-go")

func main() {
    sendgrid := sendgrid.NewSendGridClient(api_user, api_key)

    message := sendgrid.NewMail()  // <-- Error here "sendgrid" here refers to the client and not the lib import 
    message.AddTo("[email protected]")
    message.SetFrom("[email protected]")
    message.SetSubject("Sending with SendGrid is Fun")
    message.SetHTML("and easy to do anywhere, even with Go")

    sendgrid.Send(message)
}

Fixed version:

// using SendGrid's Go Library - https://github.com/sendgrid/sendgrid-go
package main

import ("github.com/sendgrid/sendgrid-go")

func main() {
    client := sendgrid.NewSendGridClient(api_user, api_key)

    message := sendgrid.NewMail()  // <-- Now "sendgrid" refers to the lib import as expected
    message.AddTo("[email protected]")
    message.SetFrom("[email protected]")
    message.SetSubject("Sending with SendGrid is Fun")
    message.SetHTML("and easy to do anywhere, even with Go")

    client.Send(message)
}

Using "client" as the client name avoids this naming bug.

I know this is not specifically a bug in the driver, but I thought it was better to go via Github than trying to explain this to some support person that can't read Go code...

Best Regards, Robert

Test APIKey

How would I go about testing if the API Key works/verified?

sendgrid.API() isn't returning error properly

Issue Summary

In the code: response, err := sendgrid.API(request), err is nil, even when there are errors. I have to inspect: response.StatusCode to see if the status is 200 or not and then response.Body to find the error. I see the response provides an array of errors, so maybe the first error should be returned.

Steps to Reproduce

Try to send an email with an invalid API key, check err != nil. Also happened for an invalid email.

400
{"errors":[{"message":"Invalid from email address [email protected]:10433","field":"from","help":null}]}
map[Server:[nginx] Date:[Mon, 07 Nov 2016 14:20:55 GMT] Content-Type:[application/json] Content-Length:[109] Connection:[keep-alive] X-Frame-Options:[DENY]]

Technical details:

  • sendgrid-go Version: master (latest commit: [aae62eb])
  • go version go1.7.1 darwin/amd64

Version 2 - V2 - Non-V3 Usage

Version 2 - How to Go Back

Yes, actually it's great v3 is here. This is cool. We can all agree on that. What's not cool is the fact that there are zero instructions about using the v2 library in case of emergency.

Why would anyone want to use the old version? Maybe those who've built shizzle around that API - those using the v2 library. Those who just need to ship a quick change w/o taking loadsa time to re-write their whole application.

Guys and girls, please provide some backwards compatibility instructions for those who can't upgrade right now. This, for example, does not help:

BREAKING CHANGE as of 2016.06.14

Put this in your readme please:

import gopkg.in/sendgrid/sendgrid-go.v2

Over and out

202 response with no email being queued and sent to destinations

My app is running on Google App Engine in Go language. I sent emails out from my app to hotmail and gmail accounts with 202 response with no body from sendgrid server. However, there is no email being sent to any mailbox I have tested.

How can I track the issue furthermore the fix the problem. According to the doc, 202 response means the email is being queued and will be delivered. When I checked it on sendgrid dashboard, there was no email on the queue or was delivered at all.

The code snippet is below. There was no error received just no email getting into the mailbox.

`
sendgrid.DefaultClient.HTTPClient = urlfetch.Client(ctx)

			from := mail.NewEmail("ttt", "[email protected]")
			subject := "subject"
			to := mail.NewEmail("Name", "[email protected]")
			content := mail.NewContent("text/html", invitationMessage)
			m := mail.NewV3MailInit(from, subject, to, content)
                            //API_KEY is a const for the API_KEY
			request := sendgrid.GetRequest(API_KEY, "/v3/mail/send", "https://api.sendgrid.com")
			request.Method = "POST"
			request.Body = mail.GetRequestBody(m)
			response, err := sendgrid.API(request)
			if err != nil {

				PrintJsonErrorResponse(err, w, false)
				return
			} else {

				_responseMessage := responseMessage{}
				_responseMessage.Msg = strconv.Itoa(response.StatusCode) + " : " + response.Body
				_responseMessage.Success = true
				jsonResponse, _ := json.Marshal(_responseMessage)

				w.Header().Set("Content-Type", "application/json")
				fmt.Fprintf(w, "%s", jsonResponse)
			}`

Please use a golint tool

Issue Summary

golint is very useful tool.
please try it!

Steps to Reproduce

  1. go get -u github.com/golang/lint/golint
  2. golint ./...
  3. You got a lot of error!
    e.g... helpers/mail/mail_v3.go:28:6: exported type Personalization should have comment or be unexported
    I want to read the doc comment.

Technical details:

  • sendgrid-go Version: master (latest commit: 21f0869)
  • Go Version: go version go1.6.2 darwin/amd64

Rate limit headers not in response

I successfully sent an email using this package - got 2xx and received email as expected. However, the response that comes back did not include rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) as described here: https://sendgrid.com/docs/API_Reference/Web_API_v3/How_To_Use_The_Web_API_v3/rate_limits.html

Is there another way to access the rate limit information, or is it not included in the response to every request?

Headers from response:
map[Server:[nginx] Date:[Wed, 25 Jan 2017 19:59:59 GMT] Content-Type:[text/plain; charset=utf-8] Content-Length:[0] Connection:[keep-alive] X-Message-Id:[...] X-Frame-Options:[DENY]]

sendgrid-go Version: v3.3.1
Go Version: 1.7

Thanks!

Invalid request

I'm trying to use the sendgrid-go client to test ISMTPD, but I'm getting an Invalid Request error when I try to send an email. I'm not getting this when I do a direct request using curl. Have you seen this before? If not, I can look into it some more.

func TestHTTPSendWithAPIKey(t *testing.T) {
    t.Logf("User should be able to send mail using API Key for authentication")

    apiKey := util.AddAPIKey(t, 180)

    sg := sendgrid.NewSendGridClientWithApiKey(apiKey.Secret)
    sg.APIMail = httpEndpoint + ".json"
    sg.Client = &http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: true,
            },
        },
    }

    message := sendgrid.NewMail()
    message.AddTo("[email protected]")
    message.SetSubject("SendGrid Testing")
    message.SetText("WIN")
    message.SetFrom("[email protected]")
    assert.NoError(t, sg.Send(message))

    util.DeleteAPIKey(t, 180, apiKey.ID)
}

Test results:

--- FAIL: TestHTTPSendWithAPIKey-2 (0.13s)
    send_http_test.go:259: User should be able to send mail using API Key for authentication
    apikeys.go:45: Added API Key &{Secret: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 ID:jwAv5Ea_TbyH4kfyOGGFpQ Name:ismtpd_acceptance 2015-05-19 19:15:46.26892427 +0000 UTC}
        Location:       send_http_test.go:278
    Error:      No error is expected but got sendgrid.go: code:500 error:<nil> body:{"message": "error", "errors": ["Invalid Request"]}

Curl command:

$ curl -X "POST" "http://dock:50350/api/mail.send.json/api/mail.send.json" \
> -H "Authorization: Bearer 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" \
> --data-urlencode "[email protected]" \
> --data-urlencode "subject=test" \
> --data-urlencode "[email protected]" \
> --data-urlencode "text=hello world"
{"message":"success"}

BREAKING CHANGES

As a result of your feedback and as a continuation of the execution of our long term roadmap, there will be breaking changes coming soon. The last time we had a major breaking change, it was for the implementation of v3 Web API support. We announced those changes here on GitHub along with some instructions on how to test and provide feedback.

The feedback we got was amazing, but we didn't quite get the amount or thoroughness of feedback we were hoping for.

We want to continue improving this iterative process, so we are reaching out to you for feedback in order to determine the optimum way to move forward as this library is designed to be community driven, SendGrid led.

Please take a moment to share your thoughts with us.

Following are some ideas we are considering, we will likely choose one from Execution and one from Communication, but not all of the items below.

Execution (for large changes):

  1. Utilize the pre-release functionality in GitHub to gather feedback and contributions to a specific branch
  2. Communicate through a dedicated GitHub issue that references that pre-release branch (e.g C# Dynamic Update)

Communication:

  1. Continue using GitHub issues
  2. Opt-in email newsletter for announcements
  3. Opt-in email mailing list
  4. Dedicated social media account (e.g. @sendgrid_libraries)

How do you prefer to get these announcements? Is this too much? Too little? Please let us know!!

As always, we are listening carefully and are looking forward to working with you.

Note: We will always follow the semver.org convention of using major point releases to signify breaking changes. Please DO NOT auto-update your dependencies. It is important to take a look at the CHANGELOG or releases to find out how the breaking changes will impact your code.

Can't disable subscription tracking

Issue Summary

The API won't allow disabling subscription tracking because the Enable parameter won't be sent when it's false, returning the error: "The subscription_tracking enable parameter is required."

Steps to Reproduce

Send an email with the following options:

trackingSettings := mail.NewTrackingSettings()
subscriptionTrackingSetting := mail.NewSubscriptionTrackingSetting()
subscriptionTrackingSetting.SetEnable(false)
trackingSettings.SetSubscriptionTracking(subscriptionTrackingSetting)
m.SetTrackingSettings(trackingSettings)

The following error will be returned:

&{400 {"errors":[{"message":"The subscription_tracking enable parameter is required.","field":"tracking_settings.subscription_tracking.enable","help":"http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#message.tracking_settings.subscription_tracking.enable"}]} map[X-Frame-Options:[DENY] Server:[nginx] Date:[Fri, 01 Jul 2016 12:09:18 GMT] Content-Type:[application/json] Content-Length:[270] Connection:[keep-alive]]}

This happens because the Enabled field of the SubscriptionTrackingSetting struct has the JSON options json:"enable,omitempty" therefore false is not encoded. See http://stackoverflow.com/questions/37756236/json-golang-boolean-omitempty for more information.

Random 406

I'm getting non-predictable 406 errors. Code issuing the requests is exactly the same whether it fails or succeeds. This is how the error looks like:

sendgrid.go: code:406 error:<nil> body:<html> 
<head><title>406 Not Acceptable</title></head> 
<body bgcolor="white"> 
<center><h1>406 Not Acceptable</h1></center> 
<hr><center>nginx</center> 
</body> 
</html>

This is the code, which is pretty much copied over from README:

sg := sendgrid.NewSendGridClientWithApiKey(os.Getenv("SENDGRID_API_KEY"))
// set http.Client to use the appengine client
sg.Client = urlfetch.Client(*c) //Just perform this swap, and you are good to go.
message := sendgrid.NewMail()
message.AddTo(...)
message.SetFrom(...)
message.SetSubject(...)
message.SetHTML(...)
sg.Send(message)

Any ideas?

Why delete SGClient?

Why delete SGClient out of nowhere and replace it by sending requests to the API? I think the main idea of using a library is to hide the actual calls to the API and wrap them inside a client.

AddRecipient does not make m.ToName equal in length to m.To

// AddRecipient will add mail.Address emails to recipients.
func (m *SGMail) AddRecipient(recipient *mail.Address) {
    m.To = append(m.To, recipient.Address)
    if recipient.Name != "" {
        m.ToName = append(m.ToName, recipient.Name)
    }
}

The docs say "toname must be an array with the exact number of array elements as the to field".

Should we simplify the API

Hi @eddiezane

What do you think about simplifying the API for this codebase? Right now we have duplicate methods that look similar to each other:

Example:

AddCc( cc string)
AddCcs ( ccs []string)

And what I'm thinking is we could actually simplify the API's by removing the plural/non-plural named methods with methods that are variadic.

Example:

AddCc(cc...string)

This way a single method can be used either singularly or variadicly (is that even a word?) as in:

http://play.golang.org/p/hwcWipk_VV

Curious to hear your thoughts on this.

How to migrate from v2 to v3, when using templates?

The examples are all well and good for extremely simple mail, but how do I send sendgrid templated mail, with substitutions, etc?

I am hoping you don't have me writing json by hand... friends don't let friends write json by hand...

Here is an example of my code to send mail with templates using sendgrid v2:

import "github.com/sendgrid/sendgrid-go"

func main() {

    msg := sendgrid.NewMail()

    msg.SMTPAPIHeader.AddFilter("templates", "enable", "1")
    msg.SMTPAPIHeader.AddFilter("templates", "template_id", "<template id>")

    loginLink := fmt.Sprintf("https://%s/dashboard?login&email=%s", domain, url.QueryEscape(emailAddress))
    msg.SMTPAPIHeader.AddSubstitution("[link]", link)

    // The templates already contain the contents,
    // but we must append something for the library to work...
    msg.SetText("\n")
    msg.SetHTML("\n")

    msg.SetSubject("Welcome to ...")

    if err := msg.AddTo(emailAddress); err != nil {
        panic("Unable to parse email address")
    }

    msg.SetFromName("...")
    if err := msg.SetFrom("[email protected]"); err != nil {
        panic("Unable to parse email address")
    }

    if err := msg.SetReplyTo("[email protected]"); err != nil {
        panic("Unable to parse email address")
    }

    sendgrid.NewSendGridClientWithApiKey(unsubSendgridAPIKey).Send(email)
}

Go get fails

# github.com/sendgrid/sendgrid-go
/home/vagrant/src/goenv/src/github.com/sendgrid/sendgrid-go/sendgrid.go:38: m.JsonString undefined (type SGMail has no field or method JsonString)
/home/vagrant/src/goenv/src/github.com/sendgrid/sendgrid-go/sendgrid_mail.go:54: m.Mail.AddRecipient undefined (type smtpmail.Mail has no field or method AddRecipient)

Create a simple web server that can consume Incoming Parse data

Acceptance Criteria:

  • Should be deployable locally and on Heroku
  • Setting are configured in an external configuration file
  • There should be two endpoints, / and inbound (set in configuration). The former should accept GETs and the latter POSTs
  • When receiving an Inbound Parse payload, return a 200 status to SendGrid

Reference:

Transactional Templates

Sending transactional templates doesn't seem to be working. If no message text is set, getting a "Missing email body" error.

Could be that it's not set up correctly, too, so here's the basic attempts I've made, where message is a *SGMail interface:

message.AddHeader("X-SMTPAPI", `{"filters":{"templates": {"settings": {"enable": 1, "template_id": "<template-id-here>"} } } }`)

and also via the SMTPAPIHeader option:

templateFilter := smtpapi.Filter{Settings: make(map[string]string)}
templateFilter.Settings["enable"] = "1"
templateFilter.Settings["template_id"] = sendgridTemplate
message.SMTPAPIHeader.SetFilter("templates", &templateFilter)

If do one/both of the above, and also set the text, the text that's set is what is being send, not the template contents.

To be clear, everything is compiling, etc., it's just not using the template.

Also noticing that there is a SGMailV3 struct available, and maybe that's what I need, since it does look like there is support for templates there, but it's not clear how to use it.

Simplify code

Issue Summary

The code is more complex than it needs to be. Simplify it.

Example One:

The append builtin works with a nil slice as the first argument. The code

if s.Personalizations == nil {
    s.Personalizations = make([]*Personalization, 0)
}
s.Personalizations = append(s.Personalizations, p...)

can be written as:

s.Personalizations = append(s.Personalizations, p...)

This pattern occurs several places throughout the code.

Example 2:

The code json.Marshal function returns a newly allocated []byte for the application. There's no need to copy the value using []byte(string(p)). The code:

b, err := json.Marshal(m)
if err != nil {
    fmt.Println(err)
}
return []byte(string(b))

can be simplified to:

b, err := json.Marshal(m)
if err != nil {
    fmt.Println(err)
}
return b

If you feel you must copy the []byte for some reason, then use:

   bcopy := make([]byte, len(b))
   copy(bcopy, b)

This uses one less allocation than []byte(string(b)).

While I am here, I'll note that printing errors to standard out is not an acceptable error handling strategy.

Technical details:

  • sendgrid-go Version: master (e0b3a5e)
  • Go Version: any

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.