-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add sendgrid bundle for sending emails
Signed-off-by: Nick Hale <[email protected]>
- Loading branch information
Showing
8 changed files
with
209 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
tools: | ||
sendgrid: | ||
reference: ./sendgrid | ||
database: | ||
reference: ./database | ||
atlassian-jira: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.PHONY: build | ||
build: | ||
go build -o bin/gptscript-go-tool . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package cmd | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"strings" | ||
|
||
"github.com/sendgrid/sendgrid-go" | ||
"github.com/sendgrid/sendgrid-go/helpers/mail" | ||
) | ||
|
||
func Send(ctx context.Context, to, subject, textBody, htmlBody string) (string, error) { | ||
// Retrieve and trim environment variables | ||
sendGridAPIKey := strings.TrimSpace(os.Getenv("SENDGRID_API_KEY")) | ||
if sendGridAPIKey == "" { | ||
return "", fmt.Errorf("SENDGRID_API_KEY is not set") | ||
} | ||
|
||
fromEmail := strings.TrimSpace(os.Getenv("OBOT_NO_REPLY_EMAIL")) | ||
if fromEmail == "" { | ||
return "", fmt.Errorf("OBOT_NO_REPLY_EMAIL is not set") | ||
} | ||
|
||
to = strings.TrimSpace(to) | ||
subject = strings.TrimSpace(subject) | ||
textBody = strings.TrimSpace(textBody) | ||
htmlBody = strings.TrimSpace(htmlBody) | ||
|
||
if to == "" { | ||
return "", fmt.Errorf("recipient email (to) is required") | ||
} | ||
|
||
// Split comma-delimited recipients and trim each email | ||
toEmails := strings.Split(to, ",") | ||
for i := range toEmails { | ||
toEmails[i] = strings.TrimSpace(toEmails[i]) | ||
} | ||
|
||
// Remove any empty emails after trimming | ||
var validEmails []string | ||
for _, email := range toEmails { | ||
if email != "" { | ||
validEmails = append(validEmails, email) | ||
} | ||
} | ||
|
||
if len(validEmails) < 1 { | ||
return "", fmt.Errorf("no valid recipient emails provided") | ||
} | ||
|
||
if subject == "" { | ||
return "", fmt.Errorf("subject is required") | ||
} | ||
|
||
if textBody == "" && htmlBody == "" { | ||
return "", fmt.Errorf("either textBody or htmlBody is required") | ||
} | ||
|
||
from := mail.NewEmail("Obot", fromEmail) | ||
personalization := mail.NewPersonalization() | ||
|
||
for _, email := range validEmails { | ||
personalization.AddTos(mail.NewEmail("", email)) | ||
} | ||
|
||
// Create email message | ||
message := mail.NewV3Mail() | ||
message.SetFrom(from) | ||
message.Subject = subject | ||
message.AddPersonalizations(personalization) | ||
if textBody != "" { | ||
message.AddContent(mail.NewContent("text/plain", textBody)) | ||
} | ||
if htmlBody != "" { | ||
message.AddContent(mail.NewContent("text/html", htmlBody)) | ||
} | ||
|
||
client := sendgrid.NewSendClient(sendGridAPIKey) | ||
response, err := client.SendWithContext(ctx, message) | ||
if err != nil { | ||
return "", fmt.Errorf("failed to send email: %w", err) | ||
} | ||
|
||
if response.StatusCode < 200 || response.StatusCode >= 300 { | ||
return "", fmt.Errorf("failed to send email: status code %d, body: %s", response.StatusCode, response.Body) | ||
} | ||
|
||
return fmt.Sprintf("email sent successfully with status code: %d", response.StatusCode), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
Name: SendGrid API Key | ||
Share Credential: github.com/gptscript-ai/credential as sendgrid | ||
with "Please enter your SendGrid API key" as message and | ||
token as field and | ||
SENDGRID_API_KEY as env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module github.com/obot-platform/tools/sendgrid | ||
|
||
go 1.23.4 | ||
|
||
require github.com/sendgrid/sendgrid-go v3.16.0+incompatible | ||
|
||
require ( | ||
github.com/sendgrid/rest v2.6.9+incompatible // indirect | ||
github.com/stretchr/testify v1.10.0 // indirect | ||
golang.org/x/net v0.33.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0= | ||
github.com/sendgrid/rest v2.6.9+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE= | ||
github.com/sendgrid/sendgrid-go v3.16.0+incompatible h1:i8eE6IMkiCy7vusSdacHHSBUpXyTcTXy/Rl9N9aZ/Qw= | ||
github.com/sendgrid/sendgrid-go v3.16.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8= | ||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= | ||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= | ||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
|
||
"github.com/obot-platform/tools/sendgrid/cmd" | ||
) | ||
|
||
func main() { | ||
if len(os.Args) != 2 { | ||
fmt.Println("Usage: gptscript-go-tool <command>") | ||
os.Exit(1) | ||
} | ||
command := os.Args[1] | ||
|
||
// Run the requested command | ||
var ( | ||
result string | ||
err error | ||
ctx = context.Background() | ||
) | ||
switch command { | ||
case "sendEmail": | ||
// Retrieve environment variables for sending email | ||
to := os.Getenv("TO") | ||
subject := os.Getenv("SUBJECT") | ||
textBody := os.Getenv("TEXT_BODY") | ||
htmlBody := os.Getenv("HTML_BODY") | ||
|
||
// Validate required fields | ||
if to == "" || subject == "" || (textBody == "" && htmlBody == "") { | ||
fmt.Println("Missing required environment variables: TO, SUBJECT, and at least one of TEXT_BODY or HTML_BODY") | ||
os.Exit(1) | ||
} | ||
|
||
// Call the Send function | ||
result, err = cmd.Send(ctx, to, subject, textBody, htmlBody) | ||
|
||
default: | ||
fmt.Printf("Unknown command: %s\n", command) | ||
os.Exit(1) | ||
} | ||
|
||
if err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
|
||
fmt.Print(result) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
Name: SendGrid | ||
Metadata: category: Capability | ||
Metadata: icon: https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2/assets/duotone/envelope-duotone.svg | ||
Share Tools: Send Email | ||
|
||
--- | ||
|
||
Name: Send Email | ||
Description: Send an email using SendGrid. | ||
Share Context: Send Email Context | ||
Credentials: ./credential/tool.gpt | ||
Param: to: A comma-delimited list of email addresses to send the email to. | ||
Param: subject: The subject of the email. | ||
Param: html_body: (optional) The HTML body of the email. | ||
Param: text_body: (optional) The plain text body of the email. | ||
|
||
#!${GPTSCRIPT_TOOL_DIR}/bin/gptscript-go-tool sendEmail | ||
|
||
--- | ||
Name: Send Email Context | ||
Type: context | ||
|
||
# START INSTRUCTIONS: Send Email tool | ||
|
||
The Send Email tool allows you to send emails using SendGrid. | ||
|
||
- At least one of `html_body` or `text_body` must be provided. | ||
- If both `html_body` and `text_body` are provided, both will be included in the email. | ||
- Don't sign the email unless otherwise asked to do so. | ||
|
||
# END INSTRUCTIONS: Send Email tool |