├── .env
├── Procfile
├── .gitignore
├── aws-package.sh
├── docs
├── icons
│ ├── icon_bugsnag.png
│ ├── icon_nixstats.png
│ ├── icon_opsgenie.png
│ ├── icon_aha_256x256.png
│ ├── icon_bugsnag_dark.jpg
│ ├── icon_bugsnag_512x512.png
│ ├── icon_datadog_512x512.png
│ ├── icon_enchant_400x400.png
│ ├── icon_heroku_512x512.png
│ ├── icon_librato_128x128.png
│ ├── icon_librato_512x512.png
│ ├── icon_librato_570x570.png
│ ├── icon_marketo_250x250.png
│ ├── icon_marketo_300x300.png
│ ├── icon_marketo_728x728.png
│ ├── icon_pingdom_512x512.png
│ ├── icon_raygun_290x290.jpg
│ ├── icon_raygun_512x512.png
│ ├── icon_wootric_200x200.png
│ ├── icon_appsignal_400x400.png
│ ├── icon_circleci_128x128.png
│ ├── icon_codeship_512x512.png
│ ├── icon_gosquared_128x128.png
│ ├── icon_magnumci_400x400.png
│ ├── icon_opsgenie_128x128.png
│ ├── icon_runscope_400x400.png
│ ├── icon_semaphore_512x512.png
│ ├── icon_travisci_200x200.png
│ ├── icon_travisci_225x225.png
│ ├── icon_userlike_512x512.png
│ ├── icon_victorops_225x225.png
│ ├── icon_webhookrc_512x512.png
│ ├── icon_apteligent_496x496.jpg
│ ├── icon_apteligent_496x496.png
│ ├── icon_chathooks_1024x1024.png
│ ├── icon_chathooks_1024x1024.psd
│ ├── icon_confluence_256x256.png
│ ├── icon_deskdotcom_400x400.png
│ ├── icon_papertrail_128x128.png
│ ├── icon_semaphore_2000x2000.png
│ ├── icon_statuspage_512x512.png
│ ├── icon_webhookrc_1550x1550.png
│ ├── icon_victorops_blue.svg
│ ├── icon_twitter.svg
│ ├── icon_statuspage.svg
│ ├── icon_circleci.svg
│ ├── icon_appsignal.svg
│ ├── icon_victorops.svg
│ ├── icon_opsgenie.svg
│ ├── icon_pingdom.svg
│ ├── icon_elasticsearch.svg
│ ├── icon_heroku.svg
│ ├── icon_codeship.svg
│ └── icon_twitter_alt.svg
├── logos
│ ├── logo_chathooks_1024x1024.png
│ ├── logo_chathooks_1024x1024.psd
│ ├── logo_chathooks_long_600x150.png
│ ├── logo_chathooks_long_600x150.psd
│ ├── logo_chathooks_long_4000x1000.png
│ └── logo_chathooks_long_4000x1000.psd
├── images
│ ├── glip_webhook_step-3_details.png
│ ├── glip_webhook_step-2_add-webhook.png
│ └── glip_webhook_step-1_add-integration.png
├── handlers
│ ├── sumologic
│ │ ├── sumo-logic-logo_100x100.png
│ │ ├── sumo-logic-logo_110x110.png
│ │ ├── sumo-logic-logo_116x116.png
│ │ ├── sumo-logic-logo_120x120.png
│ │ └── sumo-logic-logo_150x150.png
│ ├── bugsnag
│ │ ├── event-example_new-error_slack.png
│ │ └── event-example_new-error_update_slack.png
│ ├── pingdom
│ │ ├── event-example_http-check_demo.png
│ │ ├── README.md
│ │ ├── event-example_transaction-check.json
│ │ ├── event-example_ping-check.json
│ │ ├── event-example_tcp-check.json
│ │ ├── event-example_imap-check.json
│ │ ├── event-example_pop3-check.json
│ │ ├── event-example_smtp-check.json
│ │ ├── event-example_dns-check.json
│ │ ├── event-example_udp-check.json
│ │ ├── event-example_http-custom-check.json
│ │ ├── event-example_http-check.json
│ │ └── event-example_http-check_demo.json
│ ├── gosquared
│ │ ├── event-example_site-traffic_demo.png
│ │ ├── event-example_smart-group-enter_demo.png
│ │ └── event-example_live-chat.json
│ ├── papertrail
│ │ ├── event-example_notifications-array-len-1_demo.png
│ │ ├── event-example_notifications-array-len-1.json
│ │ ├── event-example_notifications-array-len-1_demo.json
│ │ └── event-example_notifications-array.json
│ ├── heroku
│ │ ├── event-example_build.txt
│ │ └── config_heroku.md
│ ├── runscope
│ │ ├── README.md
│ │ └── event-example_notification.json
│ ├── librato
│ │ ├── event-example_alert-cleared.json
│ │ ├── event-example_2.json
│ │ └── event-example_alert-triggered.json
│ ├── servicenow
│ │ └── message-example_incident.json
│ ├── appsignal
│ │ ├── event-example_marker.json
│ │ ├── config_appsignal.md
│ │ ├── event-example_performance.json
│ │ └── event-example_exception.json
│ ├── deskdotcom
│ │ ├── event-example_formatted1.json
│ │ └── event-example_formatted2.json
│ ├── slack
│ │ ├── event-example_attachment.json
│ │ └── event-example_link-emoji.json
│ ├── zendesk
│ │ └── event-example_notification.json
│ ├── sendgrid
│ │ ├── event-example_spamreport.json
│ │ ├── event-example_dropped.json
│ │ ├── event-example_processed.json
│ │ ├── event-example_open.json
│ │ ├── event-example_delivered.json
│ │ ├── event-example_deferred.json
│ │ └── event-example_click.json
│ ├── logentries
│ │ └── event-example_alert.json
│ ├── raygun
│ │ ├── config_raygun.md
│ │ └── event-example_error.json
│ ├── apteligent
│ │ ├── event-example_alert-close.json
│ │ ├── event-example_alert-open.json
│ │ └── event-example_alert.json
│ ├── wootric
│ │ ├── event-example_decline-created.txt
│ │ └── event-example_response-created.txt
│ ├── asana
│ │ └── event-example_notification.json
│ ├── semaphore
│ │ ├── config_semaphore.md
│ │ ├── event-example_build.json
│ │ └── event-example_deploy.json
│ ├── datadog
│ │ └── event-example_formatted1.json
│ ├── userlike
│ │ ├── config_userlike.md
│ │ ├── event-example_operator_away.json
│ │ ├── event-example_operator_back.json
│ │ ├── event-example_operator_offline.json
│ │ ├── event-example_operator_online.json
│ │ ├── event-example_offline-message_receive.json
│ │ ├── README.md
│ │ ├── event-example_chat-meta_forward.json
│ │ └── event-example_chat-meta_start.json
│ ├── magnumci
│ │ ├── config_magnumci.md
│ │ └── event-example_build.json
│ ├── victorops
│ │ └── event-example_formatted1.json
│ ├── codeship
│ │ └── event-example_build.json
│ ├── opsgenie
│ │ ├── event-example_escalate.json
│ │ ├── event-example_delete.json
│ │ ├── event-example_close.json
│ │ ├── event-example_acknowledge.json
│ │ ├── event-example_unacknowledge.json
│ │ ├── event-example_custom-action-test-action.json
│ │ ├── event-example_add-team.json
│ │ ├── event-example_add-note.json
│ │ ├── event-example_remove-tags.json
│ │ ├── event-example_add-recipient.json
│ │ ├── event-example_assign-ownership.json
│ │ ├── event-example_add-tags.json
│ │ ├── event-example_take-ownership.json
│ │ └── event-example_create.json
│ ├── confluence
│ │ ├── event-example_page-created.json
│ │ └── event-example_comment-created.json
│ ├── marketo
│ │ ├── event-example_demo1.json
│ │ ├── event-example_formatted2.json
│ │ ├── event-example_formatted1.json
│ │ └── event-example_formatted1_template.json
│ ├── quickbooks
│ │ └── example__notification.json
│ ├── updown
│ │ ├── event-example_recovery.json
│ │ └── event-example_down.json
│ ├── hubspot
│ │ └── event-example_notification.json
│ ├── statuspage
│ │ ├── event-example_component-updates.json
│ │ ├── event-example_incident-updates-create.json
│ │ └── event-example_incident-updates.json
│ ├── aha
│ │ ├── event-example_feature-add-tag.json
│ │ ├── event-example_release-ship.json
│ │ └── event-example_feature-to-parking-lot.json
│ ├── enchant
│ │ └── event-example_notification.json
│ ├── fabric
│ │ └── event-example_notification.json
│ ├── airbrake
│ │ └── event-example_new-error.json
│ ├── kapost
│ │ └── event-example_create-content.json
│ ├── helpscout
│ │ └── event-example_customer-created.json
│ ├── trello
│ │ └── event-example_notification.json
│ ├── paypal
│ │ └── event-example_payment-authorization-created.json
│ ├── travisci
│ │ └── event-example_build.json
│ ├── pagerduty
│ │ └── event-example_incident_trigger.json
│ └── stripe
│ │ └── event-example_event.json
├── index.html
├── start.md
├── handlers.md
└── slack.md
├── pkg
├── templates
│ └── home.go
├── handlers
│ ├── travisci
│ │ ├── travisci_glip.png
│ │ ├── logo_travisci_201x201.png
│ │ └── handler_travisci_util.go
│ ├── enchant
│ │ ├── logo_enchant_400x400.png
│ │ └── handler_enchant_util.go
│ ├── heroku
│ │ ├── logo_heroku_300x300.jpg
│ │ ├── handler_heroku_out_util.go
│ │ └── handler_heroku_out_test.go
│ ├── raygun
│ │ ├── logo_raygun_290x290.jpg
│ │ └── handler_raygun_out_util.go
│ ├── magnumci
│ │ ├── logo_magnumci_512x512.png
│ │ └── handler_magnumci_util.go
│ ├── userlike
│ │ ├── logo_userlike_512x512.png
│ │ └── util.go
│ ├── appsignal
│ │ ├── logo_appsignal_400x400.png
│ │ └── handler_appsignal_util.go
│ ├── confluence
│ │ ├── logo_confluence_256x256.png
│ │ ├── handler_confluence_util.go
│ │ └── handler_confluence_out_test.go
│ ├── semaphore
│ │ ├── logo_semaphore_2000x2000.png
│ │ └── handler_semaphore_util.go
│ ├── codeship
│ │ └── handler_codeship_util.go
│ ├── circleci
│ │ └── handler_circleci_out_util.go
│ ├── datadog
│ │ ├── handler_datadog_out_util.go
│ │ └── handler_datadog_out.go
│ ├── aha
│ │ └── handler_aha_out_util.go
│ ├── runscope
│ │ └── handler_runscope_out_util.go
│ ├── victorops
│ │ ├── handler_victorops_out_util.go
│ │ └── handler_victorops_out.go
│ ├── wootric
│ │ └── wootric_examples.go
│ ├── bugsnag
│ │ └── handler_bugsnag_util.go
│ ├── slack
│ │ ├── handler_slack_in_util.go
│ │ ├── handler_slack_in_test.go
│ │ └── handler_slack_in.go
│ ├── librato
│ │ └── handler_librato_out_util.go
│ ├── marketo
│ │ ├── handler_marketo_out_util.go
│ │ └── handler_marketo_out.go
│ ├── pingdom
│ │ └── handler_pingdom_out_util.go
│ ├── gosquared
│ │ └── handler_gosquared_out_util.go
│ ├── gosquared2
│ │ └── handler_gosquared2_out_util.go
│ ├── opsgenie
│ │ └── handler_opsgenie_out_util.go
│ ├── apteligent
│ │ └── handler_apteligent_out_util.go
│ ├── deskdotcom
│ │ ├── handler_deskdotcom_out_util.go
│ │ └── handler_deskdotcom_out.go
│ ├── papertrail
│ │ └── handler_papertrail_out_util.go
│ ├── statuspage
│ │ └── handler_statuspage_out_util.go
│ ├── handler_home.go
│ └── templated_handler.go
├── adapters
│ ├── glip_config.go
│ └── adapter.go
└── config
│ ├── configuration_test.go
│ ├── interface_constants.go
│ ├── configuration.go
│ └── icons.go
├── aws-update.sh
├── heroku.yml
├── .codeclimate.yml
├── .github
├── dependabot.yaml
└── workflows
│ ├── lint.yaml
│ └── ci.yaml
├── examples
├── proxy_send
│ ├── sample.env
│ └── README.md
├── build_hook_url
│ └── build_hook_url.go
└── examples.go
├── Makefile
├── Dockerfile
├── CONTRIBUTING.md
├── .golangci.yml
├── main.go
├── LICENSE
├── app.json
└── go.mod
/.env:
--------------------------------------------------------------------------------
1 | REPEAT=10
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: chathooks
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | _*
3 | *.tar
4 | handler.so
5 | handler.zip
6 | main
7 | main.zip
8 |
--------------------------------------------------------------------------------
/aws-package.sh:
--------------------------------------------------------------------------------
1 | rm main
2 | rm main.zip
3 | GOOS=linux go build -o main main.go
4 | zip main.zip main
--------------------------------------------------------------------------------
/docs/icons/icon_bugsnag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_bugsnag.png
--------------------------------------------------------------------------------
/docs/icons/icon_nixstats.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_nixstats.png
--------------------------------------------------------------------------------
/docs/icons/icon_opsgenie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_opsgenie.png
--------------------------------------------------------------------------------
/docs/icons/icon_aha_256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_aha_256x256.png
--------------------------------------------------------------------------------
/docs/icons/icon_bugsnag_dark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_bugsnag_dark.jpg
--------------------------------------------------------------------------------
/docs/icons/icon_bugsnag_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_bugsnag_512x512.png
--------------------------------------------------------------------------------
/docs/icons/icon_datadog_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_datadog_512x512.png
--------------------------------------------------------------------------------
/docs/icons/icon_enchant_400x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_enchant_400x400.png
--------------------------------------------------------------------------------
/docs/icons/icon_heroku_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_heroku_512x512.png
--------------------------------------------------------------------------------
/docs/icons/icon_librato_128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_librato_128x128.png
--------------------------------------------------------------------------------
/docs/icons/icon_librato_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_librato_512x512.png
--------------------------------------------------------------------------------
/docs/icons/icon_librato_570x570.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_librato_570x570.png
--------------------------------------------------------------------------------
/docs/icons/icon_marketo_250x250.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_marketo_250x250.png
--------------------------------------------------------------------------------
/docs/icons/icon_marketo_300x300.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_marketo_300x300.png
--------------------------------------------------------------------------------
/docs/icons/icon_marketo_728x728.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_marketo_728x728.png
--------------------------------------------------------------------------------
/docs/icons/icon_pingdom_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_pingdom_512x512.png
--------------------------------------------------------------------------------
/docs/icons/icon_raygun_290x290.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_raygun_290x290.jpg
--------------------------------------------------------------------------------
/docs/icons/icon_raygun_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_raygun_512x512.png
--------------------------------------------------------------------------------
/docs/icons/icon_wootric_200x200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_wootric_200x200.png
--------------------------------------------------------------------------------
/docs/icons/icon_appsignal_400x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_appsignal_400x400.png
--------------------------------------------------------------------------------
/docs/icons/icon_circleci_128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_circleci_128x128.png
--------------------------------------------------------------------------------
/docs/icons/icon_codeship_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_codeship_512x512.png
--------------------------------------------------------------------------------
/docs/icons/icon_gosquared_128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_gosquared_128x128.png
--------------------------------------------------------------------------------
/docs/icons/icon_magnumci_400x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_magnumci_400x400.png
--------------------------------------------------------------------------------
/docs/icons/icon_opsgenie_128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_opsgenie_128x128.png
--------------------------------------------------------------------------------
/docs/icons/icon_runscope_400x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_runscope_400x400.png
--------------------------------------------------------------------------------
/docs/icons/icon_semaphore_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_semaphore_512x512.png
--------------------------------------------------------------------------------
/docs/icons/icon_travisci_200x200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_travisci_200x200.png
--------------------------------------------------------------------------------
/docs/icons/icon_travisci_225x225.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_travisci_225x225.png
--------------------------------------------------------------------------------
/docs/icons/icon_userlike_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_userlike_512x512.png
--------------------------------------------------------------------------------
/docs/icons/icon_victorops_225x225.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_victorops_225x225.png
--------------------------------------------------------------------------------
/docs/icons/icon_webhookrc_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_webhookrc_512x512.png
--------------------------------------------------------------------------------
/pkg/templates/home.go:
--------------------------------------------------------------------------------
1 | package templates
2 |
3 | type HomeData struct {
4 | HomeURL string
5 | WebhookURL string
6 | }
7 |
--------------------------------------------------------------------------------
/aws-update.sh:
--------------------------------------------------------------------------------
1 | aws lambda update-function-code --function-name='Chathooks' --zip-file='fileb://main.zip' --publish --region='us-east-1'
--------------------------------------------------------------------------------
/docs/icons/icon_apteligent_496x496.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_apteligent_496x496.jpg
--------------------------------------------------------------------------------
/docs/icons/icon_apteligent_496x496.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_apteligent_496x496.png
--------------------------------------------------------------------------------
/docs/icons/icon_chathooks_1024x1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_chathooks_1024x1024.png
--------------------------------------------------------------------------------
/docs/icons/icon_chathooks_1024x1024.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_chathooks_1024x1024.psd
--------------------------------------------------------------------------------
/docs/icons/icon_confluence_256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_confluence_256x256.png
--------------------------------------------------------------------------------
/docs/icons/icon_deskdotcom_400x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_deskdotcom_400x400.png
--------------------------------------------------------------------------------
/docs/icons/icon_papertrail_128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_papertrail_128x128.png
--------------------------------------------------------------------------------
/docs/icons/icon_semaphore_2000x2000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_semaphore_2000x2000.png
--------------------------------------------------------------------------------
/docs/icons/icon_statuspage_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_statuspage_512x512.png
--------------------------------------------------------------------------------
/docs/icons/icon_webhookrc_1550x1550.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/icons/icon_webhookrc_1550x1550.png
--------------------------------------------------------------------------------
/docs/logos/logo_chathooks_1024x1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/logos/logo_chathooks_1024x1024.png
--------------------------------------------------------------------------------
/docs/logos/logo_chathooks_1024x1024.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/logos/logo_chathooks_1024x1024.psd
--------------------------------------------------------------------------------
/pkg/handlers/travisci/travisci_glip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/pkg/handlers/travisci/travisci_glip.png
--------------------------------------------------------------------------------
/docs/logos/logo_chathooks_long_600x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/logos/logo_chathooks_long_600x150.png
--------------------------------------------------------------------------------
/docs/logos/logo_chathooks_long_600x150.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/logos/logo_chathooks_long_600x150.psd
--------------------------------------------------------------------------------
/docs/images/glip_webhook_step-3_details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/images/glip_webhook_step-3_details.png
--------------------------------------------------------------------------------
/docs/logos/logo_chathooks_long_4000x1000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/logos/logo_chathooks_long_4000x1000.png
--------------------------------------------------------------------------------
/docs/logos/logo_chathooks_long_4000x1000.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/logos/logo_chathooks_long_4000x1000.psd
--------------------------------------------------------------------------------
/pkg/handlers/enchant/logo_enchant_400x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/pkg/handlers/enchant/logo_enchant_400x400.png
--------------------------------------------------------------------------------
/pkg/handlers/heroku/logo_heroku_300x300.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/pkg/handlers/heroku/logo_heroku_300x300.jpg
--------------------------------------------------------------------------------
/pkg/handlers/raygun/logo_raygun_290x290.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/pkg/handlers/raygun/logo_raygun_290x290.jpg
--------------------------------------------------------------------------------
/docs/images/glip_webhook_step-2_add-webhook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/images/glip_webhook_step-2_add-webhook.png
--------------------------------------------------------------------------------
/pkg/handlers/magnumci/logo_magnumci_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/pkg/handlers/magnumci/logo_magnumci_512x512.png
--------------------------------------------------------------------------------
/pkg/handlers/travisci/logo_travisci_201x201.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/pkg/handlers/travisci/logo_travisci_201x201.png
--------------------------------------------------------------------------------
/pkg/handlers/userlike/logo_userlike_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/pkg/handlers/userlike/logo_userlike_512x512.png
--------------------------------------------------------------------------------
/pkg/handlers/appsignal/logo_appsignal_400x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/pkg/handlers/appsignal/logo_appsignal_400x400.png
--------------------------------------------------------------------------------
/docs/handlers/sumologic/sumo-logic-logo_100x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/handlers/sumologic/sumo-logic-logo_100x100.png
--------------------------------------------------------------------------------
/docs/handlers/sumologic/sumo-logic-logo_110x110.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/handlers/sumologic/sumo-logic-logo_110x110.png
--------------------------------------------------------------------------------
/docs/handlers/sumologic/sumo-logic-logo_116x116.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/handlers/sumologic/sumo-logic-logo_116x116.png
--------------------------------------------------------------------------------
/docs/handlers/sumologic/sumo-logic-logo_120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/handlers/sumologic/sumo-logic-logo_120x120.png
--------------------------------------------------------------------------------
/docs/handlers/sumologic/sumo-logic-logo_150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/handlers/sumologic/sumo-logic-logo_150x150.png
--------------------------------------------------------------------------------
/docs/images/glip_webhook_step-1_add-integration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/images/glip_webhook_step-1_add-integration.png
--------------------------------------------------------------------------------
/pkg/handlers/confluence/logo_confluence_256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/pkg/handlers/confluence/logo_confluence_256x256.png
--------------------------------------------------------------------------------
/pkg/handlers/semaphore/logo_semaphore_2000x2000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/pkg/handlers/semaphore/logo_semaphore_2000x2000.png
--------------------------------------------------------------------------------
/docs/handlers/bugsnag/event-example_new-error_slack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/handlers/bugsnag/event-example_new-error_slack.png
--------------------------------------------------------------------------------
/docs/handlers/pingdom/event-example_http-check_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/handlers/pingdom/event-example_http-check_demo.png
--------------------------------------------------------------------------------
/docs/handlers/gosquared/event-example_site-traffic_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/handlers/gosquared/event-example_site-traffic_demo.png
--------------------------------------------------------------------------------
/docs/handlers/bugsnag/event-example_new-error_update_slack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/handlers/bugsnag/event-example_new-error_update_slack.png
--------------------------------------------------------------------------------
/docs/handlers/gosquared/event-example_smart-group-enter_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/handlers/gosquared/event-example_smart-group-enter_demo.png
--------------------------------------------------------------------------------
/heroku.yml:
--------------------------------------------------------------------------------
1 | # https://devcenter.heroku.com/articles/heroku-yml-build-manifest
2 | # Officially unsupported, but works.
3 | build:
4 | languages:
5 | - go
6 |
7 | run:
8 | web: chathooks
--------------------------------------------------------------------------------
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | engines:
2 | gofmt:
3 | enabled: true
4 | golint:
5 | enabled: true
6 | govet:
7 | enabled: true
8 |
9 | ratings:
10 | paths:
11 | - "**.go"
12 |
--------------------------------------------------------------------------------
/docs/handlers/papertrail/event-example_notifications-array-len-1_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grokify/chathooks/HEAD/docs/handlers/papertrail/event-example_notifications-array-len-1_demo.png
--------------------------------------------------------------------------------
/.github/dependabot.yaml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: gomod
4 | directory: /
5 | schedule:
6 | interval: daily
7 | - package-ecosystem: github-actions
8 | directory: /
9 | schedule:
10 | interval: daily
11 |
--------------------------------------------------------------------------------
/docs/handlers/heroku/event-example_build.txt:
--------------------------------------------------------------------------------
1 | app=secure-woodland-9775&user=example%40example.com&url=http%3A%2F%2Fsecure-woodland-9775.herokuapp.com&head=4f20bdd&head_long=4f20bdd&prev_head=&git_log=%20%20*%20Michael%20Friis%3A%20add%20bar&release=v7
--------------------------------------------------------------------------------
/docs/handlers/runscope/README.md:
--------------------------------------------------------------------------------
1 | # Runscope Webhook Notes
2 |
3 | * `response_status_code` is a string in webhook, not number
4 | * `,` is needed after `variables`
5 | * `initial_variables` and `variables` have unknown format. Are these `map[string]string`?
--------------------------------------------------------------------------------
/examples/proxy_send/sample.env:
--------------------------------------------------------------------------------
1 | CHATHOOKS_REQ_INPUT_TYPE=aha
2 | CHATHOOKS_REQ_OUTPUT_TYPE=glip
3 | CHATHOOKS_REQ_TOKEN=deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef
4 | CHATHOOKS_REQ_URL=https://hooks.glip.com/webhook/11112222-3333-4444-5555-666677778888
--------------------------------------------------------------------------------
/pkg/adapters/glip_config.go:
--------------------------------------------------------------------------------
1 | package adapters
2 |
3 | import (
4 | "github.com/grokify/commonchat/glip/config"
5 | )
6 |
7 | func GlipConfig() *config.ConverterConfig {
8 | return &config.ConverterConfig{
9 | UseAttachments: true,
10 | UseFieldExtraSpacing: true,
11 | ConvertTripleBacktick: true,
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/docs/handlers/librato/event-example_alert-cleared.json:
--------------------------------------------------------------------------------
1 | {
2 | "alert":{
3 | "id":6268092,
4 | "name":"a.test.name",
5 | "runbook_url":"",
6 | "version":2
7 | },
8 | "account":"youremail@yourdomain.com",
9 | "trigger_time":1457040045,
10 | "clear":"normal"
11 | }
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | GO_BUILD_ENV := CGO_ENABLED=0 GOOS=linux GOARCH=amd64
2 | DOCKER_BUILD=$(shell pwd)/.docker_build
3 | DOCKER_CMD=$(DOCKER_BUILD)/chathooks
4 |
5 | $(DOCKER_CMD): clean
6 | mkdir -p $(DOCKER_BUILD)
7 | $(GO_BUILD_ENV) go build -v -o $(DOCKER_CMD) .
8 |
9 | clean:
10 | rm -rf $(DOCKER_BUILD)
11 |
12 | heroku: $(DOCKER_CMD)
13 | heroku container:push web
--------------------------------------------------------------------------------
/docs/handlers/servicenow/message-example_incident.json:
--------------------------------------------------------------------------------
1 | {
2 | "activity":"Incident was created",
3 | "title":"Incident [INC00100200](https://example.com/) was created",
4 | "text":"**Short Description**\nI cannot login to my account although my username and password are correct",
5 | "icon_url":"http://milindhg.github.io/portfolio/images/SNOW_Icon.png"
6 | }
--------------------------------------------------------------------------------
/docs/handlers/appsignal/event-example_marker.json:
--------------------------------------------------------------------------------
1 | {
2 | "marker":{
3 | "user":"thijs",
4 | "site":"AppSignal",
5 | "environment":"test",
6 | "revision":"3107ddc4bb053d570083b4e3e425b8d62532ddc9",
7 | "repository":"git@github.com:appsignal/appsignal.git",
8 | "url":"https://appsignal.com/test/sites/1385f7e38c5ce90000000000/web/exceptions"
9 | }
10 | }
--------------------------------------------------------------------------------
/docs/handlers/pingdom/README.md:
--------------------------------------------------------------------------------
1 | # Pingdom Webhook Notes
2 |
3 | * Pingdom webhook message does not include a check URL.
4 |
5 | ## References
6 |
7 | * [Pingdom Detailed Error Description Announcement](http://royal.pingdom.com/2007/09/19/new-pingdom-feature-detailed-error-descriptions/)
8 | * [Pingdom Error Descriptions](https://help.pingdom.com/hc/en-us/articles/214566145-What-will-trigger-an-outage-in-Pingdom-)
--------------------------------------------------------------------------------
/docs/handlers/deskdotcom/event-example_formatted1.json:
--------------------------------------------------------------------------------
1 | {
2 | "activity":"Case updated",
3 | "title":"[Help Please!](https://example.desk.com/agent/case/1)",
4 | "attachments":[
5 | {
6 | "fields":[
7 | {
8 | "title":"Case Type",
9 | "value":"new email"
10 | }
11 | ]
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/docs/handlers/slack/event-example_attachment.json:
--------------------------------------------------------------------------------
1 | {
2 | "username":"updown.io",
3 | "attachments":[
4 | {
5 | "text":"*World* :+1:",
6 | "fallback":"Hello World :+1:",
7 | "mrkdwn_in":[
8 | "text",
9 | "pretext",
10 | "fields"
11 | ],
12 | "pretext":"Hello"
13 | }
14 | ],
15 | "icon_url":"https://updown.io/square-logo.png"
16 | }
--------------------------------------------------------------------------------
/docs/handlers/zendesk/event-example_notification.json:
--------------------------------------------------------------------------------
1 | {
2 | "devices":[
3 | {
4 | "identifier":"oiuytrdsdfghjk",
5 | "type":"ios"
6 | },
7 | {
8 | "identifier":"iuytfrdcvbnmkl",
9 | "type":"android"
10 | }
11 | ],
12 | "notification":{
13 | "body":"Agent replied something something",
14 | "title":"Agent replied",
15 | "ticket_id":"5"
16 | }
17 | }
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Chathooks URL Builder
5 |
6 | inputType:
7 | outputType:
8 | url:
9 | token:
10 |
11 |
12 |
--------------------------------------------------------------------------------
/docs/handlers/sendgrid/event-example_spamreport.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "sg_event_id":"sendgrid_internal_event_id",
4 | "sg_message_id":"sendgrid_internal_message_id",
5 | "email":"email@example.com",
6 | "timestamp":1249948800,
7 | "unique_arg_key":"unique_arg_value",
8 | "category":[
9 | "category1",
10 | "category2"
11 | ],
12 | "event":"spamreport",
13 | "asm_group_id":1
14 | }
15 | ]
--------------------------------------------------------------------------------
/docs/handlers/logentries/event-example_alert.json:
--------------------------------------------------------------------------------
1 | {
2 | "alert":{
3 | "name":"500 error"
4 | },
5 | "host":{
6 | "name":"Web",
7 | "hostname":"web.example.com"
8 | },
9 | "log":{
10 | "name":"access.log"
11 | },
12 | "event":"Event",
13 | "context":[
14 | {
15 | "t":1346202355889,
16 | "s":40634540484,
17 | "m":"[26/Aug/2012:10:58:50 +0100] POST /api..."
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/docs/handlers/appsignal/config_appsignal.md:
--------------------------------------------------------------------------------
1 | Adding AppSignal Notifications to Glip
2 | ======================================
3 |
4 | 1. To receive a webhook, go to the "Integrations" tab the site's sidebar and fill out the url where you'd like to receive your webhook data.
5 | 1. Selct the notifications you wish to receive.
6 | 1. Enter your Glip webhook URL.
7 | 1. Click submit.
8 |
9 | See the [AppSignal webhook docs](http://docs.appsignal.com/application/integrations/webhooks.html) for more info.
10 |
--------------------------------------------------------------------------------
/docs/handlers/raygun/config_raygun.md:
--------------------------------------------------------------------------------
1 | Adding Raygun Notifications to Glip
2 | ===================================
3 |
4 | 1. Open your application in Raygun and go to "Integrations" from the left-hand side menu.
5 | 1. On the Integrations page, click the "Webhook" button.
6 | 1. Specify the endpoint the webhook will be delivered to.
7 | 1. Enable (or disable) the webhook and then click "Save Changes."
8 |
9 | See the [Raygun webhook docs](https://raygun.com/docs/integrations/webhooks) for more info.
10 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yaml:
--------------------------------------------------------------------------------
1 | name: lint
2 | on: [push, pull_request]
3 |
4 | jobs:
5 | lint:
6 | strategy:
7 | matrix:
8 | go-version: [1.x]
9 | platform: [ubuntu-latest]
10 | runs-on: ${{ matrix.platform }}
11 |
12 | steps:
13 | - uses: actions/checkout@v6.0.1
14 | - name: golangci-lint
15 | uses: golangci/golangci-lint-action@v9
16 | with:
17 | skip-go-installation: true
18 | version: latest
19 | args: --timeout 3m --verbose
20 |
--------------------------------------------------------------------------------
/pkg/config/configuration_test.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | var ConfigurationTests = []struct {
8 | v int
9 | want string
10 | }{
11 | {8080, ":8080"}}
12 |
13 | func TestConfigurationAddress(t *testing.T) {
14 | for _, tt := range ConfigurationTests {
15 | cfg := Configuration{
16 | Port: tt.v}
17 |
18 | addr := cfg.Address()
19 | if tt.want != addr {
20 | t.Errorf("Configuration.Address(%v): want %v, got %v", tt.v, tt.want, addr)
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/docs/handlers/apteligent/event-example_alert-close.json:
--------------------------------------------------------------------------------
1 | {
2 | "threshold_value":"1",
3 | "description":"The Crashes alert on Crittercism was resolved at 06:40 PM UTC.",
4 | "metric":"Crashes",
5 | "crittercism_app_id":"54aab27451de5e9f042ec7ee",
6 | "trigger_id":"54aabecc1787845ae400000f",
7 | "state":"RESOLVED",
8 | "alert_url":"https://app.crittercism.com/developers/alerts/54aab27451de5e9f042ec7ee?alertId=54aabecc1787845ae400000f",
9 | "filters":"{}",
10 | "application_name":"Crittercism"
11 | }
--------------------------------------------------------------------------------
/examples/proxy_send/README.md:
--------------------------------------------------------------------------------
1 | # Test Proxy Send
2 |
3 | `proxy_send.go` is a test program which will send a test message to a live Chathooks URL.
4 |
5 | Run it from the command line as follows:
6 |
7 | ```
8 | $ go run proxy_send.go --url https://hooks.glip.com/webhook/ \
9 | --input bugsnag --output glip --token -c
10 | ```
11 |
12 | Using AWS API Gateway, a hook URL can look like the following:
13 |
14 | `https://0123456789.execute-api.us-west-1.amazonaws.com/prod/hook`
15 |
--------------------------------------------------------------------------------
/docs/handlers/raygun/event-example_error.json:
--------------------------------------------------------------------------------
1 | {
2 | "event":"error_notification",
3 | "eventType":"NewErrorOccurred",
4 | "error":{
5 | "url":"http://app.raygun.io/error-url",
6 | "message":"",
7 | "firstOccurredOn":"1970-01-28T01:49:36Z",
8 | "lastOccurredOn":"1970-01-28T01:49:36Z",
9 | "usersAffected":1,
10 | "totalOccurrences":1
11 | },
12 | "application":{
13 | "name":"application name",
14 | "url":"http://app.raygun.io/application-url"
15 | }
16 | }
--------------------------------------------------------------------------------
/docs/handlers/sendgrid/event-example_dropped.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "sg_event_id":"sendgrid_internal_event_id",
4 | "sg_message_id":"sendgrid_internal_message_id",
5 | "email":"email@example.com",
6 | "timestamp":1249948800,
7 | "smtp-id":"",
8 | "unique_arg_key":"unique_arg_value",
9 | "category":[
10 | "category1",
11 | "category2"
12 | ],
13 | "reason":"Bounced Address",
14 | "event":"dropped"
15 | }
16 | ]
--------------------------------------------------------------------------------
/docs/handlers/heroku/config_heroku.md:
--------------------------------------------------------------------------------
1 | Adding Heroku Notifications to Glip
2 | ===================================
3 |
4 | 1. Use the Heroku command line app to add a deployment webhook to your app with the following command, replacing the example `url` with your webhook URL.
5 |
6 | ```bash
7 | $ heroku addons:create deployhooks:http \
8 | --url=http://example.org
9 | Adding deployhooks:http to myapp...Done.
10 | ```
11 |
12 | See the [Heroku webhook docs](https://devcenter.heroku.com/articles/deploy-hooks#http-post-hook) for more info.
13 |
--------------------------------------------------------------------------------
/docs/handlers/wootric/event-example_decline-created.txt:
--------------------------------------------------------------------------------
1 | decline[id]=19&decline[email]=nps@example.com&decline[external_id]=123abc&decline[ip_address]=127.0.0.1&decline[origin_url]=https%3A%2F%2Fwootric.com%2F&decline[end_user_id]=31&decline[end_user_properties][pricing_plan]=Pro&decline[end_user_properties][product_plan]=Web%20App&decline[survey_id]=1147&decline[created_at]=2016-08-04%2013%3A58%3A21%20-0700&decline[updated_at]=2016-08-04%2013%3A58%3A21%20-0700&event_name=created&account_token=NPS-xxxxxxx&survey_mode=NPS×tamp=2016-08-04%2013%3A58%3A23%20-0700
--------------------------------------------------------------------------------
/pkg/handlers/heroku/handler_heroku_out_util.go:
--------------------------------------------------------------------------------
1 | package heroku
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, "build")
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/raygun/handler_raygun_out_util.go:
--------------------------------------------------------------------------------
1 | package raygun
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, "error")
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/docs/handlers/deskdotcom/event-example_formatted2.json:
--------------------------------------------------------------------------------
1 | {
2 | "activity":"New email case",
3 | "title":"New email case from John Smith from example.com - #36",
4 | "attachments":[
5 | {
6 | "fields":[
7 | {
8 | "title":"Assigned To",
9 | "value":"(Unassigned)"
10 | },
11 | {
12 | "title":"Case Body",
13 | "value":"I can't log into my account"
14 | }
15 | ]
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/pkg/handlers/codeship/handler_codeship_util.go:
--------------------------------------------------------------------------------
1 | package codeship
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, "build")
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/magnumci/handler_magnumci_util.go:
--------------------------------------------------------------------------------
1 | package magnumci
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, "build")
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/travisci/handler_travisci_util.go:
--------------------------------------------------------------------------------
1 | package travisci
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, "build")
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/userlike/util.go:
--------------------------------------------------------------------------------
1 | package userlike
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/docs/handlers/appsignal/event-example_performance.json:
--------------------------------------------------------------------------------
1 | {
2 | "performance":{
3 | "site":"AppSignal",
4 | "action":"App::ExceptionsController#index",
5 | "path":"/slow",
6 | "duration":552.7897429999999,
7 | "status":200,
8 | "hostname":"frontend.appsignal.com",
9 | "revision":"3107ddc4bb053d570083b4e3e425b8d62532ddc9",
10 | "user":"thijs",
11 | "url":"https://appsignal.com/test/sites/1385f7e38c5ce90000000000/web/performance/App::ExceptionsController-index",
12 | "environment":"test"
13 | }
14 | }
--------------------------------------------------------------------------------
/docs/handlers/asana/event-example_notification.json:
--------------------------------------------------------------------------------
1 | {
2 | "events":[
3 | {
4 | "action":"changed",
5 | "created_at":"2013-08-21T18:20:37.972Z",
6 | "parent":null,
7 | "resource":1337,
8 | "type":"task",
9 | "user":1123
10 | },
11 | {
12 | "action":"changed",
13 | "created_at":"2013-08-21T18:22:45.421Z",
14 | "parent":null,
15 | "resource":1338,
16 | "type":"task",
17 | "user":1428
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/pkg/handlers/circleci/handler_circleci_out_util.go:
--------------------------------------------------------------------------------
1 | package circleci
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, "build")
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/datadog/handler_datadog_out_util.go:
--------------------------------------------------------------------------------
1 | package datadog
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, "formatted1")
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/enchant/handler_enchant_util.go:
--------------------------------------------------------------------------------
1 | package enchant
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, "notification")
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/aha/handler_aha_out_util.go:
--------------------------------------------------------------------------------
1 | package aha
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/runscope/handler_runscope_out_util.go:
--------------------------------------------------------------------------------
1 | package runscope
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, "notification")
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/victorops/handler_victorops_out_util.go:
--------------------------------------------------------------------------------
1 | package victorops
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, "formatted1")
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/wootric/wootric_examples.go:
--------------------------------------------------------------------------------
1 | package wootric
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/bugsnag/handler_bugsnag_util.go:
--------------------------------------------------------------------------------
1 | package bugsnag
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/slack/handler_slack_in_util.go:
--------------------------------------------------------------------------------
1 | package slack
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/appsignal/handler_appsignal_util.go:
--------------------------------------------------------------------------------
1 | package appsignal
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/librato/handler_librato_out_util.go:
--------------------------------------------------------------------------------
1 | package librato
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/marketo/handler_marketo_out_util.go:
--------------------------------------------------------------------------------
1 | package marketo
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/pingdom/handler_pingdom_out_util.go:
--------------------------------------------------------------------------------
1 | package pingdom
2 |
3 | import (
4 | "github.com/grokify/chathooks/pkg/config"
5 | "github.com/grokify/chathooks/pkg/handlers"
6 | "github.com/grokify/chathooks/pkg/util"
7 |
8 | cc "github.com/grokify/commonchat"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/semaphore/handler_semaphore_util.go:
--------------------------------------------------------------------------------
1 | package semaphore
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/confluence/handler_confluence_util.go:
--------------------------------------------------------------------------------
1 | package confluence
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/gosquared/handler_gosquared_out_util.go:
--------------------------------------------------------------------------------
1 | package gosquared
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/gosquared2/handler_gosquared2_out_util.go:
--------------------------------------------------------------------------------
1 | package gosquared2
2 |
3 | import (
4 | "github.com/grokify/chathooks/pkg/config"
5 | "github.com/grokify/chathooks/pkg/handlers"
6 | "github.com/grokify/chathooks/pkg/util"
7 | cc "github.com/grokify/commonchat"
8 | )
9 |
10 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
11 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
12 | if err != nil {
13 | return cc.Message{}, err
14 | }
15 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/handlers/opsgenie/handler_opsgenie_out_util.go:
--------------------------------------------------------------------------------
1 | package opsgenie
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/docs/handlers/semaphore/config_semaphore.md:
--------------------------------------------------------------------------------
1 | Adding Semaphore CI Notifications to Glip
2 | =========================================
3 |
4 | 1. Navigate to the project you wish to set up a notification for.
5 | 1. Click on “settings” next to your project on the dashboard.
6 | 1. Open the “Webhooks” tab on project settings page.
7 | 1. Add your Glip URL to receive the payload.
8 | 1. Click on “Test” to receive an example payload and verify that it all works.
9 | 1. Save your settings.
10 |
11 | See the [Semaphore CI webhook docs](https://semaphoreci.com/docs/post-build-webhooks.html) for more info.
12 |
--------------------------------------------------------------------------------
/pkg/handlers/apteligent/handler_apteligent_out_util.go:
--------------------------------------------------------------------------------
1 | package apteligent
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/deskdotcom/handler_deskdotcom_out_util.go:
--------------------------------------------------------------------------------
1 | package deskdotcom
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/papertrail/handler_papertrail_out_util.go:
--------------------------------------------------------------------------------
1 | package papertrail
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/handlers/statuspage/handler_statuspage_out_util.go:
--------------------------------------------------------------------------------
1 | package statuspage
2 |
3 | import (
4 | cc "github.com/grokify/commonchat"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/util"
9 | )
10 |
11 | func ExampleMessage(cfg config.Configuration, data util.ExampleData, eventSlug string) (cc.Message, error) {
12 | bytes, err := data.ExampleMessageBytes(HandlerKey, eventSlug)
13 | if err != nil {
14 | return cc.Message{}, err
15 | }
16 | return Normalize(cfg, handlers.HandlerRequest{Body: bytes})
17 | }
18 |
--------------------------------------------------------------------------------
/docs/handlers/librato/event-example_2.json:
--------------------------------------------------------------------------------
1 | {"alert":{"id":6799146,"name":"glip.test","runbook_url":"","version":2},"account":"gmafglip@gmail.com","trigger_time":1488887279,"conditions":[{"id":21352240,"type":"above","threshold":50,"summary_function":"average","duration":300},{"id":21363654,"type":"above","threshold":20,"summary_function":"min","duration":300}],"violations":{"test-source":[{"metric":"librato.cpu.percent.idle","value":92,"recorded_at":1488887279,"condition_violated":21352240},{"metric":"librato.memory.memory.used","value":62,"recorded_at":1488887279,"condition_violated":21363654}]},"triggered_by_user_test":true}
--------------------------------------------------------------------------------
/docs/icons/icon_victorops_blue.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/handlers/apteligent/event-example_alert-open.json:
--------------------------------------------------------------------------------
1 | {
2 | "threshold_value":"1",
3 | "triggering_value":"4",
4 | "incident_time":"2015-01-05T18:15:56.976000",
5 | "description":"Alert on Crittercism at 06:15 PM UTC. Crashes threshold 4 exceeds 1.",
6 | "metric":"Crashes",
7 | "crittercism_app_id":"54aab27451de5e9f042ec7ee",
8 | "trigger_id":"54aabecc1787845ae400000f",
9 | "state":"TRIGGERED",
10 | "alert_url":"https://app.crittercism.com/developers/alerts/54aab27451de5e9f042ec7ee?incidentId=54aad4dcf39917103e0041b6",
11 | "filters":"{}",
12 | "application_name":"Crittercism"
13 | }
--------------------------------------------------------------------------------
/docs/handlers/apteligent/event-example_alert.json:
--------------------------------------------------------------------------------
1 | {
2 | "threshold_value":"2",
3 | "triggering_value":"9",
4 | "incident_time":"2014-05-08T01:30:24.230000",
5 | "description":"Alert on Zapier Demo at 01:30 AM UTC. App Loads threshold 9 exceeds 2.",
6 | "metric":"App Loads",
7 | "crittercism_app_id":"5351712740ec921171000003",
8 | "trigger_id":"536add5b0729df3fe9000008",
9 | "state":"TRIGGERED",
10 | "alert_url":"https://app.crittercism.com/developers/alerts/5351712740ec921171000003?incidentId=536ade306f10274d97000008",
11 | "filters":"{}",
12 | "application_name":"Zapier Demo"
13 | }
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM heroku/heroku:16-build as build
2 |
3 | COPY . /app
4 | WORKDIR /app
5 |
6 | # Setup buildpack
7 | RUN mkdir -p /tmp/buildpack/heroku/go /tmp/build_cache /tmp/env
8 | RUN curl https://codon-buildpacks.s3.amazonaws.com/buildpacks/heroku/go.tgz | tar xz -C /tmp/buildpack/heroku/go
9 |
10 | #Execute Buildpack
11 | RUN STACK=heroku-16 /tmp/buildpack/heroku/go/bin/compile /app /tmp/build_cache /tmp/env
12 |
13 | # Prepare final, minimal image
14 | FROM heroku/heroku:16
15 |
16 | COPY --from=build /app /app
17 | ENV HOME /app
18 | WORKDIR /app
19 | RUN useradd -m heroku
20 | USER heroku
21 | CMD /app/bin/chathooks
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Set your GO env variables
2 |
3 | ```
4 | GOPATH=~/go
5 | PATH=$PATH:$GOPATH/bin
6 | ```
7 |
8 | Prepare your workspace
9 |
10 | ```
11 | mkdir -p ~/go/src/github.com/grokify
12 | ```
13 |
14 | Clone the project
15 |
16 | ```
17 | cd ~/go/src/github.com/grokify
18 | clone git@github.com:grokify/chathooks.git
19 | cd chathooks
20 | ```
21 |
22 | Install godep (dependency manager)
23 |
24 | ```
25 | go get github.com/tools/godep
26 | ```
27 |
28 | Download all dependencies
29 |
30 | ```
31 | godep restore
32 | ```
33 |
34 | Run the project then visit http://localhost:3000/
35 |
36 | ```
37 | go run main.go
38 | ```
39 |
--------------------------------------------------------------------------------
/docs/handlers/datadog/event-example_formatted1.json:
--------------------------------------------------------------------------------
1 | {
2 | "activity":"Event triggered",
3 | "title":"[Event 1234567](https://app.datadoghq.com/event/jump_to?event_id=123456): [Triggered] [Memory Alert]",
4 | "attachments":[
5 | {
6 | "fields":[
7 | {
8 | "title":"Priority",
9 | "value":"normal"
10 | },
11 | {
12 | "title":"Alert",
13 | "value":"system.load.1 over host:my-host was > 0 at least once during the last 1m"
14 | }
15 | ]
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/docs/handlers/userlike/config_userlike.md:
--------------------------------------------------------------------------------
1 | Adding Userlike Notifications to Glip
2 | =====================================
3 |
4 | 1. Go to the [Addons section](https://www.userlike.com/en/dashboard/config/addon/overview) and select the API configure option.
5 | 1. Enter the callback URL of your Glip API endpoint. HTTP and HTTPS are supported as protocols.
6 | 1. Select the filtering you wish to receive for Offline Messages and/or Chats.
7 | 1. Select the data you wish to add including detailed user information and/or custom data.
8 |
9 | See the [Userlike webhook docs](https://www.userlike.com/en/public/tutorial/addon/api) for more info.
10 |
--------------------------------------------------------------------------------
/docs/start.md:
--------------------------------------------------------------------------------
1 | # Chathooks Developer Guide
2 |
3 | Chathooks is a webhook to chat proxy framework that converts outbound cloud app webhooks to inbound team chat webhooks.
4 |
5 | ## Creating a New Handler
6 |
7 | 1. Select one of the handlers in the `src/handlers` folder and create a duplicate, for example in th dirctory `src/handlers/myapp`.
8 | 1. Add examples `docs/handlers/myapp`.
9 | 1. Add examples filenames to `src/util/example_events.go`.
10 | 1. Add icon to `docs/icons` folder. Add icon reference to `src/config/icons/go`.
11 | 1. Add to `examples/local_send/local_send.go`.
12 | 1. Run `examples/local_send/local_send.go` to test handler.
--------------------------------------------------------------------------------
/docs/handlers/wootric/event-example_response-created.txt:
--------------------------------------------------------------------------------
1 | response[id]=1128&response[email]=nps@example.com&response[external_id]=123abc&response[score]=7&response[text]=okay&response[ip_address]=127.0.0.1&response[origin_url]=https%3A%2F%2Fwootric.com%2F&response[end_user_id]=30&response[end_user_properties][pricing_plan]=Enterprise&response[end_user_properties][product_plan]=Web%20App&response[survey_id]=1146&response[created_at]=2016-08-04%2013%3A57%3A26%20-0700&response[updated_at]=2016-08-04%2013%3A57%3A26%20-0700&response[excluded_from_calculations]=false&event_name=created&account_token=NPS-xxxxxxx&survey_mode=NPS×tamp=2016-08-04%2013%3A57%3A31%20-0700
--------------------------------------------------------------------------------
/docs/handlers/magnumci/config_magnumci.md:
--------------------------------------------------------------------------------
1 | Adding Magnum CI Notifications to Glip
2 | ======================================
3 |
4 | 1. Login to Magnum CI, and then on the Dashboard page, menu, click your project that you want to add a webhook to.
5 | 1. On the Project page menu bar, click Settings.
6 | 1. In the Basic Setup section on the left navigation menu, click Web Hooks. The Web Hooks page is displayed for your project.
7 | 1. In the Add a Web Hook field, enter your Glip webhook URL for the alert, and then click the Add icon.
8 |
9 | See the [Magnum CI webhook docs](https://github.com/magnumci/documentation/blob/master/webhooks.md) for more info.
10 |
--------------------------------------------------------------------------------
/docs/handlers/victorops/event-example_formatted1.json:
--------------------------------------------------------------------------------
1 | {
2 | "activity":"Event triggered",
3 | "title":"[Event 1234567](https://portal.victorops.com/client/-/popoutIncident?incidentName=1): [Triggered] [Memory Alert]",
4 | "attachments":[
5 | {
6 | "fields":[
7 | {
8 | "title":"Priority",
9 | "value":"normal"
10 | },
11 | {
12 | "title":"Alert",
13 | "value":"system.load.1 over host:my-host was > 0 at least once during the last 1m"
14 | }
15 | ]
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/docs/handlers/codeship/event-example_build.json:
--------------------------------------------------------------------------------
1 | {
2 | "build":{
3 | "build_url":"https://www.codeship.com/projects/10213/builds/973711",
4 | "commit_url":"https://github.com/codeship/docs/commit/96943dc5269634c211b6fbb18896ecdcbd40a047",
5 | "project_id":10213,
6 | "build_id":973711,
7 | "status":"testing",
8 | "project_name":"codeship/docs",
9 | "commit_id":"96943dc5269634c211b6fbb18896ecdcbd40a047",
10 | "short_commit_id":"96943",
11 | "message":"Merge pull request #34 from codeship/feature/shallow-clone",
12 | "committer":"beanieboi",
13 | "branch":"master"
14 | }
15 | }
--------------------------------------------------------------------------------
/.golangci.yml:
--------------------------------------------------------------------------------
1 | version: "2"
2 | linters:
3 | enable:
4 | - dogsled
5 | - dupl
6 | - gosec
7 | - misspell
8 | - nakedret
9 | - staticcheck
10 | - unconvert
11 | - unparam
12 | - whitespace
13 | exclusions:
14 | generated: lax
15 | presets:
16 | - comments
17 | - common-false-positives
18 | - legacy
19 | - std-error-handling
20 | paths:
21 | - third_party$
22 | - builtin$
23 | - examples$
24 | formatters:
25 | enable:
26 | - gofmt
27 | - goimports
28 | exclusions:
29 | generated: lax
30 | paths:
31 | - third_party$
32 | - builtin$
33 | - examples$
34 |
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_escalate.json:
--------------------------------------------------------------------------------
1 | {
2 | "escalationId":"51859f57-7fad-467b-ad79-59acbc69cb6a",
3 | "headers":{
4 | "foo":"bar"
5 | },
6 | "integrationName":"Webhook_Test",
7 | "escalationNotify":{
8 | "name":"test@ifountain.com",
9 | "id":"64818849-71d6-40ce-87c6-ed5e588702fd",
10 | "type":"default",
11 | "entity":"user"
12 | },
13 | "integrationId":"868be72a-8015-432e-8b23-c1f7f4374baa",
14 | "escalationName":"test_esc",
15 | "alert":{
16 | "alertId":"7ba97e3a-d328-4b5e-8f9a-39e945a3869a"
17 | },
18 | "escalationTime":0,
19 | "action":"Escalate",
20 | "repeatCount":0
21 | }
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | push:
4 | branches:
5 | - master
6 | pull_request:
7 | branches:
8 | - master
9 | workflow_dispatch:
10 | jobs:
11 | test:
12 | strategy:
13 | matrix:
14 | go-version: [1.25.x, 1.24.x]
15 | platform: [ubuntu-latest, macos-latest, windows-latest]
16 | runs-on: ${{ matrix.platform }}
17 | steps:
18 | - name: Install Go
19 | if: success()
20 | uses: actions/setup-go@v6
21 | with:
22 | go-version: ${{ matrix.go-version }}
23 | - name: Checkout code
24 | uses: actions/checkout@v6.0.1
25 | - name: Run tests
26 | run: go test -v -covermode=count ./...
27 |
--------------------------------------------------------------------------------
/docs/icons/icon_twitter.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_delete.json:
--------------------------------------------------------------------------------
1 | {
2 | "source":{
3 | "name":"",
4 | "type":"web"
5 | },
6 | "alert":{
7 | "tinyId":"23",
8 | "alias":"aliastest",
9 | "entity":"",
10 | "message":"test alert",
11 | "updatedAt":1420452374669001603,
12 | "alertId":"052652ac-5d1c-464a-812a-7dd18bbfba8c",
13 | "username":"fili@ifountain.com",
14 | "source":"fili@ifountain.com",
15 | "createdAt":1420452191104,
16 | "userId":"daed1180-0ce8-438b-8f8e-57e1a5920a2d"
17 | },
18 | "action":"Delete",
19 | "integrationId":"37c8f316-17c6-49d7-899b-9c7e540c048d",
20 | "integrationName":"Integration1"
21 | }
--------------------------------------------------------------------------------
/docs/handlers/appsignal/event-example_exception.json:
--------------------------------------------------------------------------------
1 | {
2 | "exception":{
3 | "exception":"ActionView::Template::Error",
4 | "site":"AppSignal",
5 | "message":"undefined method 'encoding' for nil:NilClass",
6 | "action":"App::ErrorController#show",
7 | "path":"/errors",
8 | "revision":"3107ddc4bb053d570083b4e3e425b8d62532ddc9",
9 | "user":"thijs",
10 | "first_backtrace_line":"/usr/local/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/cgi/util.rb:7:in 'escape'",
11 | "url":"https://appsignal.com/test/sites/1385f7e38c5ce90000000000/web/exceptions/App::SnapshotsController-show/ActionView::Template::Error",
12 | "environment":"test"
13 | }
14 | }
--------------------------------------------------------------------------------
/docs/icons/icon_statuspage.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/handlers/sendgrid/event-example_processed.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "sg_event_id":"sendgrid_internal_event_id",
4 | "sg_message_id":"sendgrid_internal_message_id",
5 | "email":"email@example.com",
6 | "timestamp":1249948800,
7 | "smtp-id":"",
8 | "unique_arg_key":"unique_arg_value",
9 | "category":[
10 | "category1",
11 | "category2"
12 | ],
13 | "event":"processed",
14 | "newsletter":{
15 | "newsletter_user_list_id":"10557865",
16 | "newsletter_id":"1943530",
17 | "newsletter_send_id":"2308608"
18 | },
19 | "asm_group_id":1,
20 | "send_at":1249949000
21 | }
22 | ]
--------------------------------------------------------------------------------
/docs/handlers/confluence/event-example_page-created.json:
--------------------------------------------------------------------------------
1 | {
2 | "page":{
3 | "spaceKey":"~admin",
4 | "modificationDate":1471926079631,
5 | "creatorKey":"ff80808154510724015451074c160001",
6 | "creatorName":"admin",
7 | "lastModifierKey":"ff80808154510724015451074c160001",
8 | "self":"https://cloud-development-environment.atlassian.net/wiki/display/~admin/Some+random+test+page",
9 | "lastModifierName":"admin",
10 | "id":16777227,
11 | "title":"Some random test page",
12 | "creationDate":1471926079631,
13 | "version":1
14 | },
15 | "user":"admin",
16 | "userKey":"ff80808154510724015451074c160001",
17 | "timestamp":1471926079645,
18 | "username":"admin"
19 | }
--------------------------------------------------------------------------------
/docs/handlers/magnumci/event-example_build.json:
--------------------------------------------------------------------------------
1 | {
2 | "id":1603,
3 | "project_id":43,
4 | "title":"[PASS] project-name #130 (master - e91e132) by Dan Sosedoff",
5 | "number":130,
6 | "commit":"e91e132612d263d95211aae6de2df9e503f22704",
7 | "author":"Dan Sosedoff",
8 | "committer":"Dan Sosedoff",
9 | "message":"Commit Message",
10 | "branch":"master",
11 | "state":"finished",
12 | "status":"pass",
13 | "result":0,
14 | "duration":158,
15 | "duration_string":"2m 38s",
16 | "commit_url":"http://domain.com/commit/e91e132612d263...",
17 | "compare_url":null,
18 | "build_url":"http://magnum-ci.com/projects/43/builds/1603",
19 | "started_at":"2013-02-14T00:09:01-06:00",
20 | "finished_at":"2013-02-14T00:11:39-06:00"
21 | }
--------------------------------------------------------------------------------
/docs/handlers/marketo/event-example_demo1.json:
--------------------------------------------------------------------------------
1 | {
2 | "activity":"Contact Us form fill",
3 | "title":"Marketo",
4 | "attachments":[
5 | {
6 | "fields":[
7 | {
8 | "title":"Name",
9 | "value":"Jane Doe"
10 | },
11 | {
12 | "title":"Email",
13 | "value":"jane.doe@example.com"
14 | },
15 | {
16 | "title":"Company",
17 | "value":"Example.com"
18 | },
19 | {
20 | "title":"Message",
21 | "value":"We are glad to see you!"
22 | }
23 | ]
24 | }
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/docs/handlers/marketo/event-example_formatted2.json:
--------------------------------------------------------------------------------
1 | {
2 | "activity":"New lead visit",
3 | "attachments":[
4 | {
5 | "fields":[
6 | {
7 | "title":"Name",
8 | "value":"Jane Doe"
9 | },
10 | {
11 | "title":"Email",
12 | "value":"jane.doe@example.com"
13 | },
14 | {
15 | "title":"Company",
16 | "value":"Example.com"
17 | },
18 | {
19 | "title":"Visited URL",
20 | "value":"https://example.com/integrating-glip-with-marketo"
21 | }
22 | ]
23 | }
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/docs/handlers/quickbooks/example__notification.json:
--------------------------------------------------------------------------------
1 | {
2 | "eventNotifications":[
3 | {
4 | "realmId":"1185883450",
5 | "dataChangeEvent":{
6 | "entities":[
7 | {
8 | "name":"Customer",
9 | "id":"1",
10 | "operation":"Create",
11 | "lastUpdated":"2015-10-05T14:42:19-0700"
12 | },
13 | {
14 | "name":"Vendor",
15 | "id":"1",
16 | "operation":"Create",
17 | "lastUpdated":"2015-10-05T14:42:19-0700"
18 | }
19 | ]
20 | }
21 | }
22 | ]
23 | }
--------------------------------------------------------------------------------
/docs/handlers/updown/event-example_recovery.json:
--------------------------------------------------------------------------------
1 | {
2 | "username":"updown.io",
3 | "attachments":[
4 | {
5 | "text":"Up since *23:29:36 (UTC)*, after being down for *4 minutes* because: *Bad Gateway*",
6 | "fallback":"RECOVERY: Chathooks Up since 23:29:36 (UTC), after being down for 4 minutes because: Bad Gateway",
7 | "mrkdwn_in":[
8 | "text",
9 | "pretext",
10 | "fields"
11 | ],
12 | "pretext":"RECOVERY: :sunny:",
13 | "author_name":"Chathooks",
14 | "author_icon":"https://updown.io/checks/wgsw/favicon",
15 | "author_link":"https://chathooks.ngrok.io/about",
16 | "color":"#5c4",
17 | "fields":[
18 |
19 | ]
20 | }
21 | ],
22 | "icon_url":"https://updown.io/square-logo.png"
23 | }
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_close.json:
--------------------------------------------------------------------------------
1 | {
2 | "source":{
3 | "name":"",
4 | "type":"web"
5 | },
6 | "alert":{
7 | "updatedAt":1420452374669001603,
8 | "tags":[
9 | "tag1",
10 | "tag2"
11 | ],
12 | "message":"test alert",
13 | "username":"fili@ifountain.com",
14 | "alertId":"052652ac-5d1c-464a-812a-7dd18bbfba8c",
15 | "source":"fili@ifountain.com",
16 | "alias":"aliastest",
17 | "tinyId":"23",
18 | "createdAt":1420452191104,
19 | "userId":"daed1180-0ce8-438b-8f8e-57e1a5920a2d",
20 | "entity":""
21 | },
22 | "action":"Close",
23 | "integrationId":"37c8f316-17c6-49d7-899b-9c7e540c048d",
24 | "integrationName":"Integration1"
25 | }
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 |
7 | "github.com/grokify/mogo/config"
8 | "github.com/grokify/sogo/net/http/httpsimple"
9 |
10 | "github.com/grokify/chathooks/pkg/service"
11 | )
12 |
13 | /*
14 |
15 | Use the `CHATHOOKS_TOKENS` environment variable to load secret
16 | tokens as a comma delimited string.
17 |
18 | */
19 |
20 | // CHATHOOKS_URL=http://localhost:8080/hook CHATHOOKS_HOME_URL=http://localhost:8080 go run main.go
21 |
22 | func main() {
23 | if _, err := config.LoadDotEnv(
24 | []string{os.Getenv("ENV_PATH"), "./.env"}, 1); err != nil {
25 | panic(err)
26 | }
27 |
28 | svc := service.NewService()
29 | fmt.Printf("Starting on port [%d] with engine [%s].\n",
30 | svc.PortInt(), svc.HTTPEngine())
31 | httpsimple.Serve(svc)
32 | }
33 |
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_acknowledge.json:
--------------------------------------------------------------------------------
1 | {
2 | "source":{
3 | "name":"",
4 | "type":"web"
5 | },
6 | "alert":{
7 | "updatedAt":1420452224764002246,
8 | "tags":[
9 | "tag1",
10 | "tag2"
11 | ],
12 | "message":"test alert",
13 | "username":"fili@ifountain.com",
14 | "alertId":"052652ac-5d1c-464a-812a-7dd18bbfba8c",
15 | "source":"fili@ifountain.com",
16 | "alias":"aliastest",
17 | "tinyId":"23",
18 | "createdAt":1420452191104,
19 | "userId":"daed1180-0ce8-438b-8f8e-57e1a5920a2d",
20 | "entity":""
21 | },
22 | "action":"Acknowledge",
23 | "integrationId":"37c8f316-17c6-49d7-899b-9c7e540c048d",
24 | "integrationName":"Integration1"
25 | }
--------------------------------------------------------------------------------
/docs/handlers/marketo/event-example_formatted1.json:
--------------------------------------------------------------------------------
1 | {
2 | "activity":"Contact Us form fill",
3 | "attachments":[
4 | {
5 | "fields":[
6 | {
7 | "title":"Name",
8 | "value":"Jane Doe"
9 | },
10 | {
11 | "title":"Email",
12 | "value":"jane.doe@example.com"
13 | },
14 | {
15 | "title":"Company",
16 | "value":"Example.com"
17 | },
18 | {
19 | "title":"Message",
20 | "value":"Hello, I'm looking to speak to someone about buying your product."
21 | }
22 | ]
23 | }
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_unacknowledge.json:
--------------------------------------------------------------------------------
1 | {
2 | "source":{
3 | "name":"",
4 | "type":"web"
5 | },
6 | "alert":{
7 | "updatedAt":1420452224764002246,
8 | "tags":[
9 | "tag1",
10 | "tag2"
11 | ],
12 | "message":"test alert",
13 | "username":"fili@ifountain.com",
14 | "alertId":"052652ac-5d1c-464a-812a-7dd18bbfba8c",
15 | "source":"fili@ifountain.com",
16 | "alias":"aliastest",
17 | "tinyId":"23",
18 | "createdAt":1420452191104,
19 | "userId":"daed1180-0ce8-438b-8f8e-57e1a5920a2d",
20 | "entity":""
21 | },
22 | "action":"UnAcknowledge",
23 | "integrationId":"37c8f316-17c6-49d7-899b-9c7e540c048d",
24 | "integrationName":"Integration1"
25 | }
--------------------------------------------------------------------------------
/docs/handlers/sendgrid/event-example_open.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "email":"email@example.com",
4 | "timestamp":1249948800,
5 | "ip":"255.255.255.255",
6 | "sg_event_id":"sendgrid_internal_event_id",
7 | "sg_message_id":"sendgrid_internal_message_id",
8 | "useragent":"Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0 (via ggpht.com GoogleImageProxy)",
9 | "event":"open",
10 | "unique_arg_key":"unique_arg_value",
11 | "category":[
12 | "category1",
13 | "category2"
14 | ],
15 | "newsletter":{
16 | "newsletter_user_list_id":"10557865",
17 | "newsletter_id":"1943530",
18 | "newsletter_send_id":"2308608"
19 | },
20 | "asm_group_id":1
21 | }
22 | ]
--------------------------------------------------------------------------------
/pkg/handlers/slack/handler_slack_in_test.go:
--------------------------------------------------------------------------------
1 | package slack
2 |
3 | import (
4 | "testing"
5 |
6 | ccslack "github.com/grokify/commonchat/slack"
7 | )
8 |
9 | var SlackWebhookMessageFromBytesTests = []struct {
10 | v []byte
11 | want ccslack.Message
12 | }{
13 | {[]byte(`{"username":"Ghost Bot [bot]"}`), ccslack.Message{Username: "Ghost Bot [bot]"}}}
14 |
15 | func TestSlackWebhookMessageFromBytes(t *testing.T) {
16 | for _, tt := range SlackWebhookMessageFromBytesTests {
17 | msg, err := ccslack.ParseMessageJSON(tt.v)
18 |
19 | if err != nil {
20 | t.Errorf("ParseMessageJSON(%v): want %v, err %v", tt.v, tt.want, err)
21 | }
22 |
23 | if tt.want.Username != msg.Username {
24 | t.Errorf("ParseMessageJSON(%v): want %v, got %v", tt.v, tt.want, msg.Username)
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_custom-action-test-action.json:
--------------------------------------------------------------------------------
1 | {
2 | "source":{
3 | "name":"",
4 | "type":"web"
5 | },
6 | "alert":{
7 | "updatedAt":1420452275002000962,
8 | "tags":[
9 | "tag1",
10 | "tag2"
11 | ],
12 | "message":"test alert",
13 | "username":"fili@ifountain.com",
14 | "alertId":"052652ac-5d1c-464a-812a-7dd18bbfba8c",
15 | "source":"fili@ifountain.com",
16 | "alias":"aliastest",
17 | "tinyId":"23",
18 | "createdAt":1420452191104,
19 | "userId":"daed1180-0ce8-438b-8f8e-57e1a5920a2d",
20 | "entity":""
21 | },
22 | "action":"TestAction",
23 | "integrationId":"37c8f316-17c6-49d7-899b-9c7e540c048d",
24 | "integrationName":"Integration1"
25 | }
--------------------------------------------------------------------------------
/docs/handlers/hubspot/event-example_notification.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "objectId":1246965,
4 | "propertyName":"lifecyclestage",
5 | "propertyValue":"subscriber",
6 | "changeSource":"ACADEMY",
7 | "eventId":3816279340,
8 | "subscriptionId":25,
9 | "portalId":33,
10 | "appId":1160452,
11 | "occurredAt":1462216307945,
12 | "subscriptionType":"contact.propertyChange",
13 | "attemptNumber":0
14 | },
15 | {
16 | "objectId":1246978,
17 | "changeSource":"IMPORT",
18 | "eventId":3816279480,
19 | "subscriptionId":22,
20 | "portalId":33,
21 | "appId":1160452,
22 | "occurredAt":1462216307945,
23 | "subscriptionType":"contact.creation",
24 | "attemptNumber":0
25 | }
26 | ]
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_add-team.json:
--------------------------------------------------------------------------------
1 | {
2 | "source":{
3 | "name":"",
4 | "type":"web"
5 | },
6 | "alert":{
7 | "updatedAt":1420452256147001924,
8 | "tags":[
9 | "tag1",
10 | "tag2"
11 | ],
12 | "message":"test alert",
13 | "username":"fili@ifountain.com",
14 | "alertId":"052652ac-5d1c-464a-812a-7dd18bbfba8c",
15 | "source":"fili@ifountain.com",
16 | "alias":"aliastest",
17 | "tinyId":"23",
18 | "createdAt":1420452191104,
19 | "userId":"daed1180-0ce8-438b-8f8e-57e1a5920a2d",
20 | "entity":"",
21 | "team":"team2"
22 | },
23 | "action":"AddTeam",
24 | "integrationId":"37c8f316-17c6-49d7-899b-9c7e540c048d",
25 | "integrationName":"Integration1"
26 | }
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_add-note.json:
--------------------------------------------------------------------------------
1 | {
2 | "source":{
3 | "name":"",
4 | "type":"web"
5 | },
6 | "alert":{
7 | "updatedAt":1420452275002000962,
8 | "tags":[
9 | "tag1",
10 | "tag2"
11 | ],
12 | "message":"test alert",
13 | "username":"fili@ifountain.com",
14 | "alertId":"052652ac-5d1c-464a-812a-7dd18bbfba8c",
15 | "source":"fili@ifountain.com",
16 | "alias":"aliastest",
17 | "tinyId":"23",
18 | "createdAt":1420452191104,
19 | "userId":"daed1180-0ce8-438b-8f8e-57e1a5920a2d",
20 | "entity":"",
21 | "note":"note to test alert"
22 | },
23 | "action":"AddNote",
24 | "integrationId":"37c8f316-17c6-49d7-899b-9c7e540c048d",
25 | "integrationName":"Integration1"
26 | }
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_remove-tags.json:
--------------------------------------------------------------------------------
1 | {
2 | "source":{
3 | "name":"",
4 | "type":"web"
5 | },
6 | "alert":{
7 | "updatedAt":1420452275002000962,
8 | "tags":[
9 | "tag1",
10 | "tag2"
11 | ],
12 | "removedTags":"tag3",
13 | "message":"test alert",
14 | "username":"fili@ifountain.com",
15 | "alertId":"052652ac-5d1c-464a-812a-7dd18bbfba8c",
16 | "source":"fili@ifountain.com",
17 | "alias":"aliastest",
18 | "tinyId":"23",
19 | "createdAt":1420452191104,
20 | "userId":"daed1180-0ce8-438b-8f8e-57e1a5920a2d",
21 | "entity":""
22 | },
23 | "action":"RemoveTags",
24 | "integrationId":"37c8f316-17c6-49d7-899b-9c7e540c048d",
25 | "integrationName":"Integration1"
26 | }
--------------------------------------------------------------------------------
/docs/handlers/sendgrid/event-example_delivered.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "response":"250 OK",
4 | "sg_event_id":"sendgrid_internal_event_id",
5 | "sg_message_id":"sendgrid_internal_message_id",
6 | "event":"delivered",
7 | "email":"email@example.com",
8 | "timestamp":1249948800,
9 | "smtp-id":"",
10 | "unique_arg_key":"unique_arg_value",
11 | "category":[
12 | "category1",
13 | "category2"
14 | ],
15 | "newsletter":{
16 | "newsletter_user_list_id":"10557865",
17 | "newsletter_id":"1943530",
18 | "newsletter_send_id":"2308608"
19 | },
20 | "asm_group_id":1,
21 | "ip":"127.0.0.1",
22 | "tls":"1",
23 | "cert_err":"1"
24 | }
25 | ]
--------------------------------------------------------------------------------
/examples/build_hook_url/build_hook_url.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/google/go-querystring/query"
7 | )
8 |
9 | type Options struct {
10 | InputType string `url:"inputType"`
11 | OutputType string `url:"outputType"`
12 | URL string `url:"url"`
13 | Token string `url:"token"`
14 | }
15 |
16 | func BuildURL(baseUrl string, opts Options) string {
17 | v, _ := query.Values(opts)
18 | return fmt.Sprintf("%v?%v", baseUrl, v.Encode())
19 | }
20 |
21 | func main() {
22 | baseUrl := "https://12345678.ngrok.io/hook"
23 | opts := Options{
24 | InputType: "aha",
25 | OutputType: "glip",
26 | URL: "https://hooks.glip.com/webhook/11112222-3333-4444-5555-666677778888",
27 | Token: "deadbeefdeadbeefdeadbeefdeadbeef",
28 | }
29 | fmt.Println(BuildURL(baseUrl, opts))
30 | }
31 |
--------------------------------------------------------------------------------
/docs/handlers/marketo/event-example_formatted1_template.json:
--------------------------------------------------------------------------------
1 | {
2 | "activity":"Contact Us form fill",
3 | "attachments":[
4 | {
5 | "fields":[
6 | {
7 | "title":"Name",
8 | "value":"{{lead.First Name:default= }} {{lead.Last Name:default= }}"
9 | },
10 | {
11 | "title":"Email",
12 | "value":"{{lead.Email Address:default= }}"
13 | },
14 | {
15 | "title":"Company",
16 | "value":"{{lead.Company:default= }}"
17 | },
18 | {
19 | "title":"Message",
20 | "value":"{{lead.Message:default= }}"
21 | }
22 | ]
23 | }
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_add-recipient.json:
--------------------------------------------------------------------------------
1 | {
2 | "source":{
3 | "name":"",
4 | "type":"web"
5 | },
6 | "alert":{
7 | "updatedAt":1420452274617001925,
8 | "tags":[
9 | "tag1",
10 | "tag2"
11 | ],
12 | "message":"test alert",
13 | "username":"fili@ifountain.com",
14 | "alertId":"052652ac-5d1c-464a-812a-7dd18bbfba8c",
15 | "source":"fili@ifountain.com",
16 | "alias":"aliastest",
17 | "tinyId":"23",
18 | "createdAt":1420452191104,
19 | "userId":"daed1180-0ce8-438b-8f8e-57e1a5920a2d",
20 | "entity":"",
21 | "recipient":"team2_escalation"
22 | },
23 | "action":"AddRecipient",
24 | "integrationId":"37c8f316-17c6-49d7-899b-9c7e540c048d",
25 | "integrationName":"Integration1"
26 | }
--------------------------------------------------------------------------------
/docs/handlers/userlike/event-example_operator_away.json:
--------------------------------------------------------------------------------
1 | {
2 | "_event":"away",
3 | "_type":"operator",
4 | "dashboard_url":"https://devel.userlike.local/dashboard/config/operator/edit/5",
5 | "email":"david@userlike.com",
6 | "first_name":"David",
7 | "id":5,
8 | "is_active":true,
9 | "jid":"david@userlike.com",
10 | "lang":"en",
11 | "last_name":"Voswinkel",
12 | "locale":"en_IS",
13 | "name":"David Voswinkel",
14 | "operator_group":{
15 | "id":14,
16 | "name":"Testing David"
17 | },
18 | "operator_group_id":14,
19 | "role":"a",
20 | "role_name":"Admin",
21 | "timezone":"Atlantic/Reykjavik",
22 | "url_image":"devel-cdn-operators.s3-eu-west-1.amazonaws.com/306ff79697ad929289f900ee013e8c33a4b7a371e80b5617e197264f953143d7_80x80.jpg",
23 | "username":"david"
24 | }
--------------------------------------------------------------------------------
/docs/handlers/userlike/event-example_operator_back.json:
--------------------------------------------------------------------------------
1 | {
2 | "_event":"back",
3 | "_type":"operator",
4 | "dashboard_url":"https://devel.userlike.local/dashboard/config/operator/edit/5",
5 | "email":"david@userlike.com",
6 | "first_name":"David",
7 | "id":5,
8 | "is_active":true,
9 | "jid":"david@userlike.com",
10 | "lang":"en",
11 | "last_name":"Voswinkel",
12 | "locale":"en_IS",
13 | "name":"David Voswinkel",
14 | "operator_group":{
15 | "id":14,
16 | "name":"Testing David"
17 | },
18 | "operator_group_id":14,
19 | "role":"a",
20 | "role_name":"Admin",
21 | "timezone":"Atlantic/Reykjavik",
22 | "url_image":"devel-cdn-operators.s3-eu-west-1.amazonaws.com/306ff79697ad929289f900ee013e8c33a4b7a371e80b5617e197264f953143d7_80x80.jpg",
23 | "username":"david"
24 | }
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_assign-ownership.json:
--------------------------------------------------------------------------------
1 | {
2 | "source":{
3 | "name":"",
4 | "type":"web"
5 | },
6 | "alert":{
7 | "updatedAt":1420452374669001603,
8 | "tags":[
9 | "tag1",
10 | "tag2"
11 | ],
12 | "message":"test alert",
13 | "username":"fili@ifountain.com",
14 | "alertId":"052652ac-5d1c-464a-812a-7dd18bbfba8c",
15 | "source":"fili@ifountain.com",
16 | "alias":"aliastest",
17 | "tinyId":"23",
18 | "createdAt":1420452191104,
19 | "userId":"daed1180-0ce8-438b-8f8e-57e1a5920a2d",
20 | "entity":"",
21 | "owner":"user2@ifountain.com"
22 | },
23 | "action":"AssignOwnership",
24 | "integrationId":"37c8f316-17c6-49d7-899b-9c7e540c048d",
25 | "integrationName":"Integration1"
26 | }
--------------------------------------------------------------------------------
/docs/handlers/userlike/event-example_operator_offline.json:
--------------------------------------------------------------------------------
1 | {
2 | "_event":"offline",
3 | "_type":"operator",
4 | "dashboard_url":"https://devel.userlike.local/dashboard/config/operator/edit/5",
5 | "email":"david@userlike.com",
6 | "first_name":"David",
7 | "id":5,
8 | "is_active":true,
9 | "jid":"david@userlike.com",
10 | "lang":"en",
11 | "last_name":"Voswinkel",
12 | "locale":"en_IS",
13 | "name":"David Voswinkel",
14 | "operator_group":{
15 | "id":14,
16 | "name":"Testing David"
17 | },
18 | "operator_group_id":14,
19 | "role":"a",
20 | "role_name":"Admin",
21 | "timezone":"Atlantic/Reykjavik",
22 | "url_image":"devel-cdn-operators.s3-eu-west-1.amazonaws.com/306ff79697ad929289f900ee013e8c33a4b7a371e80b5617e197264f953143d7_80x80.jpg",
23 | "username":"david"
24 | }
--------------------------------------------------------------------------------
/docs/handlers/userlike/event-example_operator_online.json:
--------------------------------------------------------------------------------
1 | {
2 | "_event":"online",
3 | "_type":"operator",
4 | "dashboard_url":"https://devel.userlike.local/dashboard/config/operator/edit/5",
5 | "email":"david@userlike.com",
6 | "first_name":"David",
7 | "id":5,
8 | "is_active":true,
9 | "jid":"david@userlike.com",
10 | "lang":"en",
11 | "last_name":"Voswinkel",
12 | "locale":"en_IS",
13 | "name":"David Voswinkel",
14 | "operator_group":{
15 | "id":14,
16 | "name":"Testing David"
17 | },
18 | "operator_group_id":14,
19 | "role":"a",
20 | "role_name":"Admin",
21 | "timezone":"Atlantic/Reykjavik",
22 | "url_image":"devel-cdn-operators.s3-eu-west-1.amazonaws.com/306ff79697ad929289f900ee013e8c33a4b7a371e80b5617e197264f953143d7_80x80.jpg",
23 | "username":"david"
24 | }
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_add-tags.json:
--------------------------------------------------------------------------------
1 | {
2 | "source":{
3 | "name":"",
4 | "type":"web"
5 | },
6 | "alert":{
7 | "updatedAt":1420452275002000962,
8 | "tags":[
9 | "tag1",
10 | "tag2",
11 | "tag3"
12 | ],
13 | "addedTags":"tag1,tag2,tag3",
14 | "message":"test alert",
15 | "username":"fili@ifountain.com",
16 | "alertId":"052652ac-5d1c-464a-812a-7dd18bbfba8c",
17 | "source":"fili@ifountain.com",
18 | "alias":"aliastest",
19 | "tinyId":"23",
20 | "createdAt":1420452191104,
21 | "userId":"daed1180-0ce8-438b-8f8e-57e1a5920a2d",
22 | "entity":""
23 | },
24 | "action":"AddTags",
25 | "integrationId":"37c8f316-17c6-49d7-899b-9c7e540c048d",
26 | "integrationName":"Integration1"
27 | }
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_take-ownership.json:
--------------------------------------------------------------------------------
1 | {
2 | "integrationType":"Integration1",
3 | "alert":{
4 | "createdAt":1470226893192,
5 | "tinyId":"47",
6 | "alias":"8a745a79-3ed3-4044-8427-98e067c0623c",
7 | "alertId":"8a745a79-3ed3-4044-8427-98e067c0623c",
8 | "source":"test@test.com",
9 | "message":"message test",
10 | "userId":"ac6a9ab7-98fe-4256-8a0e-30dc082a55e7",
11 | "entity":"",
12 | "tags":[
13 | "tag1",
14 | "tag2"
15 | ],
16 | "updatedAt":1470383477928000335,
17 | "username":"test@test.com"
18 | },
19 | "integrationName":"Webhook",
20 | "action":"TakeOwnership",
21 | "integrationId":"fd8755c1-7a5e-4829-9ecc-8990e1a2eed3",
22 | "source":{
23 | "name":"",
24 | "type":"web"
25 | }
26 | }
--------------------------------------------------------------------------------
/docs/handlers/sendgrid/event-example_deferred.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "response":"400 Try again",
4 | "sg_event_id":"sendgrid_internal_event_id",
5 | "sg_message_id":"sendgrid_internal_message_id",
6 | "event":"deferred",
7 | "email":"email@example.com",
8 | "timestamp":1249948800,
9 | "smtp-id":"",
10 | "unique_arg_key":"unique_arg_value",
11 | "category":[
12 | "category1",
13 | "category2"
14 | ],
15 | "attempt":"10",
16 | "newsletter":{
17 | "newsletter_user_list_id":"10557865",
18 | "newsletter_id":"1943530",
19 | "newsletter_send_id":"2308608"
20 | },
21 | "asm_group_id":1,
22 | "ip":"127.0.0.1",
23 | "tls":"0",
24 | "cert_err":"0"
25 | }
26 | ]
--------------------------------------------------------------------------------
/docs/handlers/statuspage/event-example_component-updates.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta":{
3 | "unsubscribe":"http://statustest.flyingkleinbrothers.com:5000/?unsubscribe=j0vqr9kl3513",
4 | "documentation":"http://doers.statuspage.io/customer-notifications/webhooks/"
5 | },
6 | "page":{
7 | "id":"j2mfxwj97wnj",
8 | "status_indicator":"major",
9 | "status_description":"Partial System Outage"
10 | },
11 | "component_update":{
12 | "created_at":"2013-05-29T21:32:28Z",
13 | "new_status":"operational",
14 | "old_status":"major_outage",
15 | "id":"k7730b5v92bv",
16 | "component_id":"rb5wq1dczvbm"
17 | },
18 | "component":{
19 | "created_at":"2013-05-29T21:32:28Z",
20 | "id":"rb5wq1dczvbm",
21 | "name":"Some Component",
22 | "status":"operational"
23 | }
24 | }
--------------------------------------------------------------------------------
/docs/handlers/pingdom/event-example_transaction-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "check_id":12345,
3 | "check_name":"Name of transaction check",
4 | "check_type":"TRANSACTION",
5 | "check_params":{
6 | "encryption":true,
7 | "port":443,
8 | "url":"https://www.example.com/"
9 | },
10 | "tags":[
11 | "example_tag"
12 | ],
13 | "previous_state":"FAILING",
14 | "current_state":"SUCCESS",
15 | "state_changed_timestamp":1451610061,
16 | "state_changed_utc_time":"2016-01-01T01:01:01",
17 | "description":"Error message",
18 | "first_probe":{
19 | "ip":"123.4.5.6",
20 | "ipv6":"2001:4800:1020:209::5",
21 | "location":"Stockholm, Sweden"
22 | },
23 | "second_probe":{
24 | "ip":"123.4.5.6",
25 | "ipv6":"2001:4800:1020:209::5",
26 | "location":"Austin, US"
27 | }
28 | }
--------------------------------------------------------------------------------
/docs/handlers/semaphore/event-example_build.json:
--------------------------------------------------------------------------------
1 | {
2 | "branch_name":"gem_updates",
3 | "branch_url":"https://semaphoreci.com/projects/44/branches/50",
4 | "project_name":"base-app",
5 | "project_hash_id":"123-aga-471-6a8",
6 | "build_url":"https://semaphoreci.com/projects/44/branches/50/builds/15",
7 | "build_number":15,
8 | "result":"passed",
9 | "event":"build",
10 | "started_at":"2012-07-09T15:23:53Z",
11 | "finished_at":"2012-07-09T15:30:16Z",
12 | "commit":{
13 | "id":"dc395381e650f3bac18457909880829fc20e34ba",
14 | "url":"https://github.com/renderedtext/base-app/commit/dc395381e650f3bac18457909880829fc20e34ba",
15 | "author_name":"Vladimir Saric",
16 | "author_email":"vladimir@renderedtext.com",
17 | "message":"Update 'shoulda' gem.",
18 | "timestamp":"2012-07-04T18:14:08Z"
19 | }
20 | }
--------------------------------------------------------------------------------
/docs/handlers/pingdom/event-example_ping-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "check_id":12345,
3 | "check_name":"Name of Ping check",
4 | "check_type":"PING",
5 | "check_params":{
6 | "hostname":"www.example.com",
7 | "basic_auth":false,
8 | "ipv6":false
9 | },
10 | "tags":[
11 | "example_tag"
12 | ],
13 | "previous_state":"UP",
14 | "current_state":"DOWN",
15 | "state_changed_timestamp":1451610061,
16 | "state_changed_utc_time":"2016-01-01T01:01:01",
17 | "long_description":"Long error message",
18 | "description":"Short error message",
19 | "first_probe":{
20 | "ip":"123.4.5.6",
21 | "ipv6":"2001:4800:1020:209::5",
22 | "location":"Stockholm, Sweden"
23 | },
24 | "second_probe":{
25 | "ip":"123.4.5.6",
26 | "ipv6":"2001:4800:1020:209::5",
27 | "location":"Austin, US"
28 | }
29 | }
--------------------------------------------------------------------------------
/docs/handlers.md:
--------------------------------------------------------------------------------
1 | {
2 | "event":"audit",
3 | "audit":{
4 | "id":"1011112222333344445555666",
5 | "audit_action":"create",
6 | "created_at":"2018-01-24T22:29:16.361Z",
7 | "interesting":false,
8 | "user":{
9 | "id":"2011112222333344445555666",
10 | "name":"John Wang",
11 | "email":"john.wang@example.com",
12 | "created_at":"2017-11-21T20:09:39.022Z",
13 | "updated_at":"2018-01-24T21:50:03.013Z"
14 | },
15 | "auditable_type":"tagging",
16 | "auditable_id":"3011112222333344445555666",
17 | "description":"tagged feature API-1 My Awesome Feature - Use Cases",
18 | "auditable_url":"https://example.aha.io/features/API-1",
19 | "changes":[
20 | {
21 | "field_name":"Tag",
22 | "value":"Awesome"
23 | }
24 | ]
25 | }
26 | }
--------------------------------------------------------------------------------
/docs/handlers/papertrail/event-example_notifications-array-len-1.json:
--------------------------------------------------------------------------------
1 | {
2 | "events":[
3 | {
4 | "id":7711561783320576,
5 | "received_at":"2011-05-18T20:30:02-07:00",
6 | "display_received_at":"May 18 20:30:02",
7 | "source_ip":"208.75.57.121",
8 | "source_name":"abc",
9 | "source_id":2,
10 | "hostname":"abc",
11 | "program":"CROND",
12 | "severity":"Info",
13 | "facility":"Cron",
14 | "message":"message body"
15 | }
16 | ],
17 | "saved_search":{
18 | "id":42,
19 | "name":"Important stuff",
20 | "query":"cron OR server1",
21 | "html_edit_url":"https://papertrailapp.com/searches/42/edit",
22 | "html_search_url":"https://papertrailapp.com/searches/42"
23 | },
24 | "max_id":7711582041804800,
25 | "min_id":7711561783320576
26 | }
--------------------------------------------------------------------------------
/docs/handlers/pingdom/event-example_tcp-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "check_id":12345,
3 | "check_name":"Name of TCP check",
4 | "check_type":"PORT_TCP",
5 | "check_params":{
6 | "hostname":"www.example.com",
7 | "basic_auth":false,
8 | "ipv6":false,
9 | "port":80
10 | },
11 | "tags":[
12 | "example_tag"
13 | ],
14 | "previous_state":"UP",
15 | "current_state":"DOWN",
16 | "state_changed_timestamp":1451610061,
17 | "state_changed_utc_time":"2016-01-01T01:01:01",
18 | "long_description":"Long error message",
19 | "description":"Short error message",
20 | "first_probe":{
21 | "ip":"123.4.5.6",
22 | "ipv6":"2001:4800:1020:209::5",
23 | "location":"Stockholm, Sweden"
24 | },
25 | "second_probe":{
26 | "ip":"123.4.5.6",
27 | "ipv6":"2001:4800:1020:209::5",
28 | "location":"Austin, US"
29 | }
30 | }
--------------------------------------------------------------------------------
/docs/handlers/librato/event-example_alert-triggered.json:
--------------------------------------------------------------------------------
1 | {
2 | "alert":{
3 | "id":5846005,
4 | "name":"collectd.high.load",
5 | "runbook_url":"http://example.com/runbook.pdf",
6 | "version":2
7 | },
8 | "account":"m@example.com",
9 | "trigger_time":1444177459,
10 | "conditions":[
11 | {
12 | "id":1150670,
13 | "type":"above",
14 | "threshold":2,
15 | "duration":300
16 | }
17 | ],
18 | "violations":{
19 | "example-ubuntu-14.04":[
20 | {
21 | "metric":"collectd.load.load.shortterm",
22 | "value":7.190000057220459,
23 | "recorded_at":1444177454,
24 | "condition_violated":1150670,
25 | "count":31,
26 | "begin":1444177140,
27 | "end":1444177440
28 | }
29 | ]
30 | }
31 | }
--------------------------------------------------------------------------------
/docs/icons/icon_circleci.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
--------------------------------------------------------------------------------
/docs/handlers/pingdom/event-example_imap-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "check_id":12345,
3 | "check_name":"Name of IMAP check",
4 | "check_type":"IMAP",
5 | "check_params":{
6 | "hostname":"www.example.com",
7 | "basic_auth":false,
8 | "encryption":false,
9 | "ipv6":false,
10 | "port":143
11 | },
12 | "tags":[
13 | "example_tag"
14 | ],
15 | "previous_state":"UP",
16 | "current_state":"DOWN",
17 | "state_changed_timestamp":1451610061,
18 | "state_changed_utc_time":"2016-01-01T01:01:01",
19 | "long_description":"Long error message",
20 | "description":"Short error message",
21 | "first_probe":{
22 | "ip":"123.4.5.6",
23 | "ipv6":"2001:4800:1020:209::5",
24 | "location":"Stockholm, Sweden"
25 | },
26 | "second_probe":{
27 | "ip":"123.4.5.6",
28 | "ipv6":"2001:4800:1020:209::5",
29 | "location":"Austin, US"
30 | }
31 | }
--------------------------------------------------------------------------------
/docs/handlers/pingdom/event-example_pop3-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "check_id":12345,
3 | "check_name":"Name of POP3 check",
4 | "check_type":"POP3",
5 | "check_params":{
6 | "basic_auth":false,
7 | "encryption":false,
8 | "hostname":"www.example.com",
9 | "ipv6":false,
10 | "port":110
11 | },
12 | "tags":[
13 | "example_tag"
14 | ],
15 | "previous_state":"UP",
16 | "current_state":"DOWN",
17 | "state_changed_timestamp":1451610061,
18 | "state_changed_utc_time":"2016-01-01T01:01:01",
19 | "long_description":"Long error message",
20 | "description":"Short error message",
21 | "first_probe":{
22 | "ip":"123.4.5.6",
23 | "ipv6":"2001:4800:1020:209::5",
24 | "location":"Stockholm, Sweden"
25 | },
26 | "second_probe":{
27 | "ip":"123.4.5.6",
28 | "ipv6":"2001:4800:1020:209::5",
29 | "location":"Austin, US"
30 | }
31 | }
--------------------------------------------------------------------------------
/docs/handlers/pingdom/event-example_smtp-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "check_id":123456,
3 | "check_name":"Name of SMTP check",
4 | "check_type":"SMTP",
5 | "check_params":{
6 | "basic_auth":false,
7 | "encryption":false,
8 | "hostname":"www.example.com",
9 | "ipv6":false,
10 | "port":25
11 | },
12 | "tags":[
13 | "example_tag"
14 | ],
15 | "previous_state":"UP",
16 | "current_state":"DOWN",
17 | "state_changed_timestamp":1451610061,
18 | "state_changed_utc_time":"2016-01-01T01:01:01",
19 | "long_description":"Long error message",
20 | "description":"Short error message",
21 | "first_probe":{
22 | "ip":"123.4.5.6",
23 | "ipv6":"2001:4800:1020:209::5",
24 | "location":"Stockholm, Sweden"
25 | },
26 | "second_probe":{
27 | "ip":"123.4.5.6",
28 | "ipv6":"2001:4800:1020:209::5",
29 | "location":"Austin, US"
30 | }
31 | }
--------------------------------------------------------------------------------
/docs/handlers/aha/event-example_feature-add-tag.json:
--------------------------------------------------------------------------------
1 | {
2 | "event":"audit",
3 | "audit":{
4 | "id":"1011112222333344445555666",
5 | "audit_action":"create",
6 | "created_at":"2018-01-24T22:29:16.361Z",
7 | "interesting":false,
8 | "user":{
9 | "id":"2011112222333344445555666",
10 | "name":"John Wang",
11 | "email":"john.wang@example.com",
12 | "created_at":"2017-11-21T20:09:39.022Z",
13 | "updated_at":"2018-01-24T21:50:03.013Z"
14 | },
15 | "auditable_type":"tagging",
16 | "auditable_id":"3011112222333344445555666",
17 | "description":"tagged feature API-1 My Awesome Feature - Use Cases",
18 | "auditable_url":"https://example.aha.io/features/API-1",
19 | "changes":[
20 | {
21 | "field_name":"Tag",
22 | "value":"Awesome"
23 | }
24 | ]
25 | }
26 | }
--------------------------------------------------------------------------------
/docs/handlers/userlike/event-example_offline-message_receive.json:
--------------------------------------------------------------------------------
1 | {
2 | "_event":"receive",
3 | "_type":"offline_message",
4 | "browser_name":"Chrome",
5 | "browser_os":"Mac OS X",
6 | "browser_version":"32",
7 | "chat_widget":{
8 | "id":2,
9 | "name":"Website"
10 | },
11 | "client_email":"support@userlike.com",
12 | "client_name":"Userlike Support",
13 | "created_at":"2014-12-20 14:50:23",
14 | "custom":{
15 |
16 | },
17 | "data_privacy":null,
18 | "id":3,
19 | "loc_city":"Cologne",
20 | "loc_country":"Germany",
21 | "loc_lat":50.9333000183105,
22 | "loc_lon":6.94999980926514,
23 | "marked_read":true,
24 | "message":"We are happy to welcome you as a Userlike user!",
25 | "page_impressions":5,
26 | "screenshot_oid":null,
27 | "screenshot_url":null,
28 | "status":"new",
29 | "topic":"Support",
30 | "url":"http://www.userlike.com",
31 | "visits":1
32 | }
--------------------------------------------------------------------------------
/docs/handlers/aha/event-example_release-ship.json:
--------------------------------------------------------------------------------
1 | {
2 | "event":"audit",
3 | "audit":{
4 | "id":"1011112222333344445555666",
5 | "audit_action":"update",
6 | "created_at":"2018-01-24T23:12:00.903Z",
7 | "interesting":true,
8 | "user":{
9 | "id":"2011112222333344445555666",
10 | "name":"John Wang",
11 | "email":"john.wang@example.com",
12 | "created_at":"2017-11-21T20:09:39.022Z",
13 | "updated_at":"2018-01-24T21:50:03.013Z"
14 | },
15 | "auditable_type":"release",
16 | "auditable_id":"3011112222333344445555666",
17 | "description":"updated release API-R-8 8.0",
18 | "auditable_url":"https://example.aha.io/releases/API-R-8",
19 | "changes":[
20 | {
21 | "field_name":"Workflow status",
22 | "value":"Ready to ship \u0026rarr; Shipped"
23 | }
24 | ]
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/docs/handlers/enchant/event-example_notification.json:
--------------------------------------------------------------------------------
1 | {
2 | "id":"7f94629",
3 | "account_id":"a91bb74",
4 | "account_url":"company.enchant.com",
5 | "created_at":"2016-10-17T19:52:43Z",
6 | "type":"ticket.label_added",
7 | "data":{
8 | "label_id":"97b0a40",
9 | "label_name":"High Priority",
10 | "label_color":"red"
11 | },
12 | "actor_type":"user",
13 | "actor_id":"a91bb75",
14 | "actor_name":"Michelle Han",
15 | "model_type":"ticket",
16 | "model_id":"a52ec86",
17 | "model":{
18 | "id":"a52ec86",
19 | "number":53249,
20 | "user_id":"a91bb75",
21 | "state":"open",
22 | "subject":"email from customer",
23 | "label_ids":[
24 | "97b0a3e",
25 | "97b0a40"
26 | ],
27 | "customer_id":"97b0a43",
28 | "type":"email",
29 | "reply_to":"john@smith.com",
30 | "created_at":"2016-10-14T20:15:46Z"
31 | }
32 | }
--------------------------------------------------------------------------------
/docs/handlers/pingdom/event-example_dns-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "check_id":12345,
3 | "check_name":"Name of DNS check",
4 | "check_type":"DNS",
5 | "check_params":{
6 | "hostname":"www.example.com",
7 | "basic_auth":false,
8 | "expected_ip":"123.4.5.6",
9 | "ipv6":false,
10 | "nameserver":"example.com"
11 | },
12 | "tags":[
13 | "example_tag"
14 | ],
15 | "previous_state":"UP",
16 | "current_state":"DOWN",
17 | "state_changed_timestamp":1451610061,
18 | "state_changed_utc_time":"2016-01-01T01:01:01",
19 | "long_description":"Long error message",
20 | "description":"Short error message",
21 | "first_probe":{
22 | "ip":"123.4.5.6",
23 | "ipv6":"2001:4800:1020:209::5",
24 | "location":"Stockholm, Sweden"
25 | },
26 | "second_probe":{
27 | "ip":"123.4.5.6",
28 | "ipv6":"2001:4800:1020:209::5",
29 | "location":"Austin, US"
30 | }
31 | }
--------------------------------------------------------------------------------
/docs/icons/icon_appsignal.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/handlers/opsgenie/event-example_create.json:
--------------------------------------------------------------------------------
1 | {
2 | "source":{
3 | "name":"web",
4 | "type":"API"
5 | },
6 | "alert":{
7 | "updatedAt":1420452193166002000,
8 | "tags":[
9 | "tag1",
10 | "tag2"
11 | ],
12 | "teams":[
13 | "team1",
14 | "team2"
15 | ],
16 | "recipients":[
17 | "recipient1",
18 | "recipient2"
19 | ],
20 | "message":" test alert",
21 | "username":"fili@ifountain.com",
22 | "alertId":"052652ac-5d1c-464a-812a-7dd18bbfba8c",
23 | "source":"fili@ifountain.com",
24 | "alias":"aliastest",
25 | "tinyId":"23",
26 | "createdAt":1420452191104,
27 | "userId":"daed1180-0ce8-438b-8f8e-57e1a5920a2d",
28 | "entity":""
29 | },
30 | "action":"Create",
31 | "integrationId":"37c8f316-17c6-49d7-899b-9c7e540c048d",
32 | "integrationName":"Integration1"
33 | }
--------------------------------------------------------------------------------
/docs/handlers/papertrail/event-example_notifications-array-len-1_demo.json:
--------------------------------------------------------------------------------
1 | {
2 | "events":[
3 | {
4 | "id":7711561783320576,
5 | "received_at":"2011-05-18T20:30:02-07:00",
6 | "display_received_at":"May 18 20:30:02",
7 | "source_ip":"208.75.57.121",
8 | "source_name":"abc",
9 | "source_id":2,
10 | "hostname":"localhost",
11 | "program":"sshd",
12 | "severity":"Error",
13 | "facility":"sshd",
14 | "message":"Cound not load host key: /etc/ssh/ssh_host_abc123_key"
15 | }
16 | ],
17 | "saved_search":{
18 | "id":42,
19 | "name":"SSH key missing",
20 | "query":"Could not load host key",
21 | "html_edit_url":"https://papertrailapp.com/searches/42/edit",
22 | "html_search_url":"https://papertrailapp.com/searches/42"
23 | },
24 | "max_id":7711582041804800,
25 | "min_id":7711561783320576
26 | }
--------------------------------------------------------------------------------
/docs/handlers/pingdom/event-example_udp-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "check_id":12345,
3 | "check_name":"Name of UDP check",
4 | "check_type":"UDP",
5 | "check_params":{
6 | "hostname":"www.example.com",
7 | "basic_auth":false,
8 | "expect":"string to expect",
9 | "ipv6":false,
10 | "port":80,
11 | "send":"string to send"
12 | },
13 | "tags":[
14 | "example_tag"
15 | ],
16 | "previous_state":"UP",
17 | "current_state":"DOWN",
18 | "state_changed_timestamp":1451610061,
19 | "state_changed_utc_time":"2016-01-01T01:01:01",
20 | "long_description":"Long error message",
21 | "description":"Short error message",
22 | "first_probe":{
23 | "ip":"123.4.5.6",
24 | "ipv6":"2001:4800:1020:209::5",
25 | "location":"Stockholm, Sweden"
26 | },
27 | "second_probe":{
28 | "ip":"123.4.5.6",
29 | "ipv6":"2001:4800:1020:209::5",
30 | "location":"Austin, US"
31 | }
32 | }
--------------------------------------------------------------------------------
/docs/handlers/aha/event-example_feature-to-parking-lot.json:
--------------------------------------------------------------------------------
1 | {
2 | "event":"audit",
3 | "audit":{
4 | "id":"1011112222333344445555666",
5 | "audit_action":"update",
6 | "created_at":"2018-01-24T22:21:16.155Z",
7 | "interesting":true,
8 | "user":{
9 | "id":"2011112222333344445555666",
10 | "name":"John Wang",
11 | "email":"john.wang@example.com",
12 | "created_at":"2017-11-21T20:09:39.022Z",
13 | "updated_at":"2018-01-24T21:50:03.013Z"
14 | },
15 | "auditable_type":"feature",
16 | "auditable_id":"3011112222333344445555666",
17 | "description":"updated feature X-7 Secret and Awesome Feature",
18 | "auditable_url":"https://example.aha.io/features/X-7",
19 | "changes":[
20 | {
21 | "field_name":"Release",
22 | "value":"X-R-3 Est 18Q2 \u0026rarr; X-R-10 Parking Lot"
23 | }
24 | ]
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/pkg/handlers/heroku/handler_heroku_out_test.go:
--------------------------------------------------------------------------------
1 | package heroku
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | const (
8 | TestAppName = "secure-woodland-9775"
9 | )
10 |
11 | var ConfigurationTests = []struct {
12 | v string
13 | want HerokuOutMessage
14 | }{
15 | {HookData(), HerokuOutMessage{App: "secure-woodland-9775"}}}
16 |
17 | func TestConfluence(t *testing.T) {
18 | for _, tt := range ConfigurationTests {
19 | msg, err := HerokuOutMessageFromQuery([]byte(tt.v))
20 | if err != nil {
21 | t.Errorf("error %v", err)
22 | continue
23 | }
24 | if msg.App != TestAppName {
25 | t.Errorf("error HerokuOutMessageFromQueryString(%v): want [%v], got [%v]", tt.v, "secure-woodland-9775", tt.want.App)
26 | }
27 | }
28 | }
29 |
30 | func HookData() string {
31 | return `app=secure-woodland-9775&user=example%40example.com&url=http%3A%2F%2Fsecure-woodland-9775.herokuapp.com&head=4f20bdd&head_long=4f20bdd&prev_head=&git_log=%20%20*%20Michael%20Friis%3A%20add%20bar&release=v7
32 | `
33 | }
34 |
--------------------------------------------------------------------------------
/docs/handlers/sendgrid/event-example_click.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "sg_event_id":"sendgrid_internal_event_id",
4 | "sg_message_id":"sendgrid_internal_message_id",
5 | "ip":"255.255.255.255",
6 | "useragent":"Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53",
7 | "event":"click",
8 | "email":"email@example.com",
9 | "timestamp":1249948800,
10 | "url":"http://yourdomain.com/blog/news.html",
11 | "url_offset":{
12 | "index":0,
13 | "type":"html"
14 | },
15 | "unique_arg_key":"unique_arg_value",
16 | "category":[
17 | "category1",
18 | "category2"
19 | ],
20 | "newsletter":{
21 | "newsletter_user_list_id":"10557865",
22 | "newsletter_id":"1943530",
23 | "newsletter_send_id":"2308608"
24 | },
25 | "asm_group_id":1
26 | }
27 | ]
--------------------------------------------------------------------------------
/docs/handlers/pingdom/event-example_http-custom-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "check_id":12345,
3 | "check_name":"Name of HTTP Custom check",
4 | "check_type":"HTTP_CUSTOM",
5 | "check_params":{
6 | "basic_auth":false,
7 | "encryption":false,
8 | "full_url":"https://www.example.com/path",
9 | "hostname":"www.example.com",
10 | "ipv6":false,
11 | "port":80,
12 | "url":"/"
13 | },
14 | "tags":[
15 | "example_tag"
16 | ],
17 | "previous_state":"UP",
18 | "current_state":"DOWN",
19 | "state_changed_timestamp":1451610061,
20 | "state_changed_utc_time":"2016-01-01T01:01:01",
21 | "long_description":"Long error message",
22 | "description":"Short error message",
23 | "first_probe":{
24 | "ip":"123.4.5.6",
25 | "ipv6":"2001:4800:1020:209::5",
26 | "location":"Stockholm, Sweden"
27 | },
28 | "second_probe":{
29 | "ip":"123.4.5.6",
30 | "ipv6":"2001:4800:1020:209::5",
31 | "location":"Austin, US"
32 | }
33 | }
--------------------------------------------------------------------------------
/docs/handlers/pingdom/event-example_http-check.json:
--------------------------------------------------------------------------------
1 | {
2 | "check_id":12345,
3 | "check_name":"Name of HTTP check",
4 | "check_type":"HTTP",
5 | "check_params":{
6 | "basic_auth":false,
7 | "encryption":true,
8 | "full_url":"https://www.example.com/path",
9 | "header":"User-Agent:Pingdom.com_bot",
10 | "hostname":"www.example.com",
11 | "ipv6":false,
12 | "port":443,
13 | "url":"/path"
14 | },
15 | "tags":[
16 | "example_tag"
17 | ],
18 | "previous_state":"UP",
19 | "current_state":"DOWN",
20 | "state_changed_timestamp":1451610061,
21 | "state_changed_utc_time":"2016-01-01T01:01:01",
22 | "long_description":"Long error message",
23 | "description":"Short error message",
24 | "first_probe":{
25 | "ip":"123.4.5.6",
26 | "ipv6":"2001:4800:1020:209::5",
27 | "location":"Stockholm, Sweden"
28 | },
29 | "second_probe":{
30 | "ip":"123.4.5.6",
31 | "ipv6":"2001:4800:1020:209::5",
32 | "location":"Austin, US"
33 | }
34 | }
--------------------------------------------------------------------------------
/docs/handlers/pingdom/event-example_http-check_demo.json:
--------------------------------------------------------------------------------
1 | {
2 | "check_id":12345,
3 | "check_name":"My Awesome Website",
4 | "check_type":"HTTP",
5 | "check_params":{
6 | "basic_auth":false,
7 | "encryption":true,
8 | "full_url":"https://my-awesome-site.com",
9 | "header":"User-Agent:Pingdom.com_bot",
10 | "hostname":"my-awesome-site.com",
11 | "ipv6":false,
12 | "port":443,
13 | "url":"/path"
14 | },
15 | "tags":[
16 | "example_tag"
17 | ],
18 | "previous_state":"UP",
19 | "current_state":"DOWN",
20 | "state_changed_timestamp":1451610061,
21 | "state_changed_utc_time":"2016-01-01T01:01:01",
22 | "long_description":"Long error message",
23 | "description":"Timeout (> 30s)",
24 | "first_probe":{
25 | "ip":"123.4.5.6",
26 | "ipv6":"2001:4800:1020:209::5",
27 | "location":"Stockholm, Sweden"
28 | },
29 | "second_probe":{
30 | "ip":"123.4.5.6",
31 | "ipv6":"2001:4800:1020:209::5",
32 | "location":"Austin, US"
33 | }
34 | }
--------------------------------------------------------------------------------
/pkg/handlers/marketo/handler_marketo_out.go:
--------------------------------------------------------------------------------
1 | package marketo
2 |
3 | import (
4 | "encoding/json"
5 |
6 | cc "github.com/grokify/commonchat"
7 |
8 | "github.com/grokify/chathooks/pkg/config"
9 | "github.com/grokify/chathooks/pkg/handlers"
10 | "github.com/grokify/chathooks/pkg/models"
11 | )
12 |
13 | const (
14 | DisplayName = "Marketo"
15 | HandlerKey = "marketo"
16 | MessageDirection = "out"
17 | MessageBodyType = models.JSON
18 | )
19 |
20 | func NewHandler() handlers.Handler {
21 | return handlers.Handler{MessageBodyType: MessageBodyType, Normalize: Normalize}
22 | }
23 |
24 | func Normalize(cfg config.Configuration, hReq handlers.HandlerRequest) (cc.Message, error) {
25 | ccMsg, err := CcMessageFromBytes(hReq.Body)
26 | if err != nil {
27 | return ccMsg, err
28 | }
29 | iconURL, err := cfg.GetAppIconURL(HandlerKey)
30 | if err == nil {
31 | ccMsg.IconURL = iconURL.String()
32 | }
33 | return ccMsg, nil
34 | }
35 |
36 | func CcMessageFromBytes(bytes []byte) (cc.Message, error) {
37 | msg := cc.Message{}
38 | err := json.Unmarshal(bytes, &msg)
39 | return msg, err
40 | }
41 |
--------------------------------------------------------------------------------
/pkg/handlers/victorops/handler_victorops_out.go:
--------------------------------------------------------------------------------
1 | package victorops
2 |
3 | import (
4 | "encoding/json"
5 |
6 | cc "github.com/grokify/commonchat"
7 |
8 | "github.com/grokify/chathooks/pkg/config"
9 | "github.com/grokify/chathooks/pkg/handlers"
10 | "github.com/grokify/chathooks/pkg/models"
11 | )
12 |
13 | const (
14 | DisplayName = "VictorOps"
15 | HandlerKey = "victorops"
16 | MessageDirection = "out"
17 | MessageBodyType = models.JSON
18 | )
19 |
20 | func NewHandler() handlers.Handler {
21 | return handlers.Handler{MessageBodyType: MessageBodyType, Normalize: Normalize}
22 | }
23 |
24 | func Normalize(cfg config.Configuration, hReq handlers.HandlerRequest) (cc.Message, error) {
25 | ccMsg, err := CcMessageFromBytes(hReq.Body)
26 | if err != nil {
27 | return ccMsg, err
28 | }
29 |
30 | iconURL, err := cfg.GetAppIconURL(HandlerKey)
31 | if err == nil {
32 | ccMsg.IconURL = iconURL.String()
33 | }
34 |
35 | return ccMsg, nil
36 | }
37 |
38 | func CcMessageFromBytes(bytes []byte) (cc.Message, error) {
39 | var msg cc.Message
40 | return msg, json.Unmarshal(bytes, &msg)
41 | }
42 |
--------------------------------------------------------------------------------
/docs/handlers/semaphore/event-example_deploy.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_name":"heroku-deploy-test",
3 | "project_hash_id":"123-aga-471-6a8",
4 | "result":"passed",
5 | "event":"deploy",
6 | "server_name":"server-heroku-master-automatic-2",
7 | "number":2,
8 | "created_at":"2013-07-30T13:52:33Z",
9 | "updated_at":"2013-07-30T13:53:21Z",
10 | "started_at":"2013-07-30T13:52:38Z",
11 | "finished_at":"2013-07-30T13:53:21Z",
12 | "html_url":"https://semaphoreci.com/projects/2420/servers/81/deploys/2",
13 | "build_number":10,
14 | "branch_name":"master",
15 | "branch_html_url":"https://semaphoreci.com/projects/2420/branches/58394",
16 | "build_html_url":"https://semaphoreci.com/projects/2420/branches/58394/builds/7",
17 | "commit":{
18 | "author_email":"rastasheep3@gmail.com",
19 | "author_name":"Aleksandar Diklic",
20 | "id":"43ddb7516ecc743f0563abd7418f0bd3617348c4",
21 | "message":"One more time",
22 | "timestamp":"2013-07-19T12:56:25Z",
23 | "url":"https://github.com/rastasheep/heroku-deploy-test/commit/43ddb7516ecc743f0563abd7418f0bd3617348c4"
24 | }
25 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017-2025 grokify
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/handlers/fabric/event-example_notification.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_name":"heroku-deploy-test",
3 | "project_hash_id":"123-aga-471-6a8",
4 | "result":"passed",
5 | "event":"deploy",
6 | "server_name":"server-heroku-master-automatic-2",
7 | "number":2,
8 | "created_at":"2013-07-30T13:52:33Z",
9 | "updated_at":"2013-07-30T13:53:21Z",
10 | "started_at":"2013-07-30T13:52:38Z",
11 | "finished_at":"2013-07-30T13:53:21Z",
12 | "html_url":"https://semaphoreci.com/projects/2420/servers/81/deploys/2",
13 | "build_number":10,
14 | "branch_name":"master",
15 | "branch_html_url":"https://semaphoreci.com/projects/2420/branches/58394",
16 | "build_html_url":"https://semaphoreci.com/projects/2420/branches/58394/builds/7",
17 | "commit":{
18 | "author_email":"rastasheep3@gmail.com",
19 | "author_name":"Aleksandar Diklic",
20 | "id":"43ddb7516ecc743f0563abd7418f0bd3617348c4",
21 | "message":"One more time",
22 | "timestamp":"2013-07-19T12:56:25Z",
23 | "url":"https://github.com/rastasheep/heroku-deploy-test/commit/43ddb7516ecc743f0563abd7418f0bd3617348c4"
24 | }
25 | }
--------------------------------------------------------------------------------
/docs/handlers/airbrake/event-example_new-error.json:
--------------------------------------------------------------------------------
1 | {
2 | "error":{
3 | "id":37463546,
4 | "error_message":"KitchenException: You are all out of bacon!",
5 | "error_class":"KitchenException",
6 | "file":"[PROJECT_ROOT]/app/controllers/bacon_controller.rb",
7 | "line_number":35,
8 | "project":{
9 | "id":1111,
10 | "name":"Baconator"
11 | },
12 | "last_notice":{
13 | "id":4505303522,
14 | "request_method":null,
15 | "request_url":"http://airbrake.io:445/bacon/cook",
16 | "backtrace":[
17 | "[PROJECT_ROOT]/app/controllers/bacon_controller.rb:35:in `cook'",
18 | "[PROJECT_ROOT]/app/middleware/kitchen.rb:19:in `oven'",
19 | "[PROJECT_ROOT]/app/middleware/kitchen.rb:33:in `chef'",
20 | "[PROJECT_ROOT]/app/middleware/salumi.rb:23:in `store'"
21 | ]
22 | },
23 | "environment":"avocado",
24 | "first_occurred_at":"2012-02-23T22:03:03Z",
25 | "last_occurred_at":"2012-03-21T08:37:15Z",
26 | "times_occurred":118
27 | },
28 | "airbrake_error_url":"https://airbrake.io/airbrake-error-url"
29 | }
--------------------------------------------------------------------------------
/pkg/handlers/slack/handler_slack_in.go:
--------------------------------------------------------------------------------
1 | package slack
2 |
3 | import (
4 | "strings"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | "github.com/grokify/chathooks/pkg/handlers"
8 | "github.com/grokify/chathooks/pkg/models"
9 | cc "github.com/grokify/commonchat"
10 | "github.com/valyala/fasthttp"
11 |
12 | ccslack "github.com/grokify/commonchat/slack"
13 | )
14 |
15 | const (
16 | DisplayName = "Slack"
17 | HandlerKey = "slack"
18 | MessageDirection = "in"
19 | MessageBodyType = models.URLEncodedJSONPayloadOrJSON
20 | )
21 |
22 | func NewHandler() handlers.Handler {
23 | return handlers.Handler{MessageBodyType: MessageBodyType, Normalize: Normalize}
24 | }
25 |
26 | func BuildInboundMessageBytes(ctx *fasthttp.RequestCtx) []byte {
27 | ct := string(ctx.Request.Header.Peek("Content-Type"))
28 | ct = strings.TrimSpace(strings.ToLower(ct))
29 | if strings.Contains(ct, "application/json") {
30 | return ctx.PostBody()
31 | }
32 | return ctx.FormValue("payload")
33 | }
34 |
35 | func Normalize(config config.Configuration, hReq handlers.HandlerRequest) (cc.Message, error) {
36 | slMsg, err := ccslack.ParseMessageAny(hReq.Body)
37 | if err != nil {
38 | return cc.Message{}, err
39 | }
40 | return ccslack.WebhookInBodySlackToCc(slMsg), nil
41 | }
42 |
--------------------------------------------------------------------------------
/pkg/handlers/handler_home.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/valyala/fasthttp"
7 |
8 | "github.com/grokify/chathooks/pkg/adapters"
9 | "github.com/grokify/chathooks/pkg/config"
10 | )
11 |
12 | const (
13 | QueryParamNamedOutputs = config.ParamNameAdapters
14 | QueryParamInputType = config.ParamNameInputType
15 | QueryParamOutputType = config.ParamNameOutputType
16 | QueryParamOutputURL = config.ParamNameOutputURL
17 | QueryParamToken = config.ParamNameToken
18 | QueryParamDefaultActivity = config.ParamNameActivityDefault
19 | QueryParamDefaultIcon = config.ParamNameIconDefault
20 | //QueryParamURL = config.ParamNameURL
21 | )
22 |
23 | var (
24 | ShowDisplayName = false
25 | )
26 |
27 | // HomeHandler is a fasthttp handler for handling the webhoo proxy homepage.
28 | func HomeHandler(ctx *fasthttp.RequestCtx) {
29 | fmt.Fprintf(ctx, "%s", []byte("Chathooks\nSource: https://github.com/grokify/chathooks"))
30 | }
31 |
32 | type Configuration struct {
33 | ConfigData config.Configuration
34 | AdapterSet adapters.AdapterSet
35 | }
36 |
37 | func IntegrationActivitySuffix(displayName string) string {
38 | if !ShowDisplayName || len(displayName) < 1 {
39 | return ""
40 | }
41 | return ""
42 | }
43 |
--------------------------------------------------------------------------------
/docs/handlers/confluence/event-example_comment-created.json:
--------------------------------------------------------------------------------
1 | {
2 | "comment":{
3 | "spaceKey":"~admin",
4 | "parent":{
5 | "spaceKey":"~admin",
6 | "modificationDate":1471926079631,
7 | "creatorKey":"ff80808154510724015451074c160001",
8 | "creatorName":"admin",
9 | "lastModifierKey":"ff80808154510724015451074c160001",
10 | "self":"https://cloud-development-environment.atlassian.net/wiki/display/~admin/Some+random+test+page",
11 | "lastModifierName":"admin",
12 | "id":16777227,
13 | "title":"Some random test page",
14 | "creationDate":1471926079631,
15 | "version":1
16 | },
17 | "modificationDate":1471926091465,
18 | "creatorKey":"ff80808154510724015451074c160001",
19 | "creatorName":"admin",
20 | "lastModifierKey":"ff80808154510724015451074c160001",
21 | "self":"https://cloud-development-environment/wiki/display/~admin/Some+random+test+page?focusedCommentId=16777228#comment-16777228",
22 | "lastModifierName":"admin",
23 | "id":16777228,
24 | "creationDate":1471926091465,
25 | "version":1
26 | },
27 | "user":"admin",
28 | "userKey":"ff80808154510724015451074c160001",
29 | "timestamp":1471926091468,
30 | "username":"admin"
31 | }
--------------------------------------------------------------------------------
/pkg/handlers/templated_handler.go:
--------------------------------------------------------------------------------
1 | package handlers
2 |
3 | import (
4 | "encoding/json"
5 | "regexp"
6 | "strconv"
7 | "strings"
8 |
9 | "github.com/grokify/commonchat"
10 | "github.com/tidwall/gjson"
11 |
12 | "github.com/grokify/chathooks/pkg/config"
13 | )
14 |
15 | func NewTemplatedHandler(tmpl string) Handler {
16 | return Handler{Normalize: getTemplatedNormalizer(tmpl)}
17 | }
18 |
19 | func getTemplatedNormalizer(tmpl string) func(cfg config.Configuration, hReq HandlerRequest) (commonchat.Message, error) {
20 | return func(cfg config.Configuration, hReq HandlerRequest) (commonchat.Message, error) {
21 | ccMsg := commonchat.NewMessage()
22 | src := string(hReq.Body)
23 |
24 | tokenPattern := regexp.MustCompile(`\${.+?}`)
25 | keyPattern := regexp.MustCompile(`\${(.+?)}`)
26 | formattedJSON := tokenPattern.ReplaceAllStringFunc(tmpl, func(match string) string {
27 | matches := keyPattern.FindStringSubmatch(match)
28 | result := gjson.Get(src, strings.TrimSpace(matches[1]))
29 | switch result.Type {
30 | case gjson.String:
31 | return result.Str
32 | case gjson.Number:
33 | return strconv.FormatFloat(result.Num, 'f', -1, 64)
34 | case gjson.JSON:
35 | return result.Raw
36 | default:
37 | return result.Type.String()
38 | }
39 | })
40 |
41 | return ccMsg, json.Unmarshal([]byte(formattedJSON), &ccMsg)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Chathooks",
3 | "description": "Webhook proxy for team chat",
4 | "keywords": ["glip"],
5 | "website": "https://github.com/grokify/chathooks",
6 | "repository": "https://github.com/grokify/chathooks",
7 | "addons": [
8 | "papertrail:choklad"
9 | ],
10 | "formation": {
11 | "web": {
12 | "quantity": 1,
13 | "size": "Free"
14 | }
15 | },
16 | "env": {
17 | "CHATHOOKS_HOME_URL":{
18 | "description": "Homepage for project, for homepage rendering only.",
19 | "value": "https://.herokuapp.com",
20 | "required": false
21 | },
22 | "CHATHOOKS_WEBHOOK_URL":{
23 | "description": "Webhook URL for project, for homepage rendering only.",
24 | "value": "https://.herokuapp.com/hook",
25 | "required": false
26 | },
27 | "CHATHOOKS_TOKENS": {
28 | "description": "Comma-delimited list of secret tokens for validation",
29 | "default": "demo account - do not use for production",
30 | "required": false
31 | },
32 | "CHATHOOKS_ENGINE": {
33 | "description": "HTTP server engine to use, e.g. 'fasthttp' or 'nethttp'.",
34 | "value": "fasthttp",
35 | "required": false
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/docs/handlers/updown/event-example_down.json:
--------------------------------------------------------------------------------
1 | {
2 | "username":"updown.io",
3 | "attachments":[
4 | {
5 | "text":"Down since *23:25:37 (UTC)*, reason: *Bad Gateway*",
6 | "fallback":"ALERT: DOWN Chathooks Down since 23:25:37 (UTC), reason: Bad Gateway",
7 | "mrkdwn_in":[
8 | "text",
9 | "pretext",
10 | "fields"
11 | ],
12 | "pretext":"ALERT: DOWN :exclamation:",
13 | "author_name":"Chathooks",
14 | "author_icon":"https://updown.io/checks/wgsw/favicon",
15 | "author_link":"https://chathooks.ngrok.io/about",
16 | "color":"#e43",
17 | "fields":[
18 | {
19 | "title":"🔇 Mute alerts:",
20 | "value":", , , or "
21 | },
22 | {
23 | "title":"↻ Reproduce request:",
24 | "value":"```curl -gkvLI -b '' -H 'User-Agent: updown.io daemon 2.6' -H 'Accept: */*' -H 'Connection: Close' -H 'Accept-Language: en' -m 30 --connect-timeout 10 ```"
25 | }
26 | ]
27 | }
28 | ],
29 | "icon_url":"https://updown.io/square-logo.png"
30 | }
--------------------------------------------------------------------------------
/docs/icons/icon_victorops.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/docs/handlers/kapost/event-example_create-content.json:
--------------------------------------------------------------------------------
1 | {
2 | "operation":"create",
3 | "type":"content",
4 | "payload":{
5 | "full_post":{
6 | "id":"523381424aaaaecc80000001",
7 | "idea_title":null,
8 | "content_title":null,
9 | "creator_id":"51e477b9e1f419ecf4000004",
10 | "assignee_id":"51e477b9e1f419ecf4000004",
11 | "campaign_ids":[
12 |
13 | ],
14 | "is_draft":false,
15 | "submission_deadline":null,
16 | "publish_deadline":null,
17 | "next_task":"Discuss post with creator",
18 | "updated_at":"2013-09-13T21:18:58Z",
19 | "privacy":"members",
20 | "idea":null,
21 | "content":null,
22 | "tags":[
23 |
24 | ],
25 | "custom_fields":{
26 |
27 | },
28 | "excerpt":null,
29 | "categories":[
30 |
31 | ],
32 | "persona_ids":[
33 |
34 | ],
35 | "stage_ids":[
36 |
37 | ],
38 | "attachments":[
39 |
40 | ],
41 | "content_type":{
42 | "id":"515b373751c35c02000001c3",
43 | "display_name":"Blog Post"
44 | }
45 | }
46 | },
47 | "instance":{
48 | "id":"515b373751c35c02000001c2",
49 | "subdomain":"mongohq"
50 | }
51 | }
--------------------------------------------------------------------------------
/pkg/handlers/deskdotcom/handler_deskdotcom_out.go:
--------------------------------------------------------------------------------
1 | package deskdotcom
2 |
3 | import (
4 | "encoding/json"
5 |
6 | cc "github.com/grokify/commonchat"
7 |
8 | "github.com/grokify/chathooks/pkg/config"
9 | "github.com/grokify/chathooks/pkg/handlers"
10 | "github.com/grokify/chathooks/pkg/models"
11 | )
12 |
13 | const (
14 | DisplayName = "Desk.com"
15 | HandlerKey = "deskdotcom"
16 | MessageDirection = "out"
17 | DocumentationURL = "https://support.desk.com/customer/portal/articles/869334-configuring-webhooks-in-desk-com-apps"
18 | MessageBodyType = models.JSON
19 | )
20 |
21 | func NewHandler() handlers.Handler {
22 | return handlers.Handler{MessageBodyType: MessageBodyType, Normalize: Normalize}
23 | }
24 |
25 | func Normalize(cfg config.Configuration, hReq handlers.HandlerRequest) (cc.Message, error) {
26 | ccMsg, err := CcMessageFromBytes(hReq.Body)
27 | if err != nil {
28 | return ccMsg, err
29 | }
30 | iconURL, err := cfg.GetAppIconURL(HandlerKey)
31 | if err == nil {
32 | ccMsg.IconURL = iconURL.String()
33 | }
34 | return ccMsg, nil
35 | }
36 |
37 | /*
38 |
39 | Example template:
40 |
41 | {
42 | "activity":"Case {{case.id}} updated",
43 | "body":"**Case Type**\n{{case.status}} {{case.type}}\n **Subject**\n[{{case.subject}}]({{case.direct_url}})"
44 | }
45 |
46 | */
47 |
48 | func CcMessageFromBytes(bytes []byte) (cc.Message, error) {
49 | msg := cc.Message{}
50 | err := json.Unmarshal(bytes, &msg)
51 | return msg, err
52 | }
53 |
--------------------------------------------------------------------------------
/examples/examples.go:
--------------------------------------------------------------------------------
1 | package examples
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "path/filepath"
7 | "regexp"
8 |
9 | "github.com/grokify/mogo/os/osutil"
10 | )
11 |
12 | const (
13 | HandlersDir = "github.com/grokify/chathooks/docs/handlers"
14 | Examples = "aha,appsignal,apteligent,circleci,codeship,confluence,datadog,deskdotcom,enchant,gosquared,heroku,librato,magnumci,marketo,opsgenie,papertrail,pingdom,raygun,runscope,semaphore,statuspage,travisci,userlike,victorops"
15 | )
16 |
17 | func AbsDirGopath(dir string) string {
18 | return filepath.Join(os.Getenv("GOPATH"), "src", dir)
19 | }
20 |
21 | func DocsHandlersDirInfo() ([]string, []string, error) {
22 | handlersDir := AbsDirGopath(HandlersDir)
23 | fmt.Println(handlersDir)
24 |
25 | var dirs []string
26 | var exampleFiles []string
27 | sdirs, err := osutil.ReadDirMore(handlersDir, nil, true, false, false)
28 |
29 | if err != nil {
30 | return dirs, exampleFiles, err
31 | }
32 |
33 | for _, sdir := range sdirs {
34 | fmt.Printf("SDIR: %v\n", sdir.Name())
35 | absSubDir := filepath.Join(handlersDir, sdir.Name())
36 | exEntries, err := osutil.ReadDirMore(absSubDir,
37 | regexp.MustCompile(`^event-example_.+\.(json|txt)$`), false, true, false)
38 | if err != nil {
39 | return dirs, exampleFiles, err
40 | }
41 | if len(exEntries) > 0 {
42 | dirs = append(dirs, sdir.Name())
43 | for _, f := range exEntries {
44 | fmt.Printf("FILE: %v\n", f.Name())
45 | exFilepath := filepath.Join(absSubDir, f.Name())
46 | exampleFiles = append(exampleFiles, exFilepath)
47 | }
48 | }
49 | }
50 | return dirs, exampleFiles, nil
51 | }
52 |
--------------------------------------------------------------------------------
/docs/handlers/slack/event-example_link-emoji.json:
--------------------------------------------------------------------------------
1 | {
2 | "username":"updown.io",
3 | "attachments":[
4 | {
5 | "text":"Down since *20:17:29 (CEST)*, reason: *Couldn't find the string*",
6 | "fallback":"DOWN ALERT: http://example.com Down since 20:17:29 (CEST), reason: Couldn't find the string",
7 | "mrkdwn_in":[
8 | "text",
9 | "pretext",
10 | "fields"
11 | ],
12 | "pretext":"DOWN ALERT: :frowning:",
13 | "author_name":"http://example.com",
14 | "author_icon":"https://staging.updown.io/checks/mycheck/favicon",
15 | "author_link":"http://example.com",
16 | "color":"#e43",
17 | "fields":[
18 | {
19 | "title":"String match:",
20 | "value":"_“12345”_",
21 | "short":true
22 | },
23 | {
24 | "title":"🔇 Mute alerts:",
25 | "value":"\u003chttps://staging.updown.io/checks/mycheck/mute#1h|For 1 hour\u003e, \u003chttps://staging.updown.io/checks/mycheck/mute#1d|for 1 day\u003e, \u003chttps://staging.updown.io/checks/mycheck/mute#1w|for 1 week\u003e, \u003chttps://staging.updown.io/checks/mycheck/mute#recovery|until recovery\u003e or \u003chttps://staging.updown.io/checks/mycheck/mute#forever|forever\u003e"
26 | },
27 | {
28 | "title":"↻ Reproduce request:",
29 | "value":"```curl -gkvL -H 'User-Agent: updown.io daemon 2.2' -H 'Accept: */*' -H 'Connection: Close' -H 'Accept-Language: en' -m 30 --connect-timeout 5 \u003chttp://example.com|http://example.com\u003e```"
30 | }
31 | ]
32 | }
33 | ],
34 | "icon_url":"https://updown.io/square-logo.png"
35 | }
--------------------------------------------------------------------------------
/docs/slack.md:
--------------------------------------------------------------------------------
1 | # Example Requests
2 |
3 | Most of the time you will likely either:
4 |
5 | * use the proxy URL in an outbound webhook service that supports the Slack format or
6 | * use a client library
7 |
8 | The following examples are provided for reference and testing.
9 |
10 | ## Using `application/json`
11 |
12 | ```bash
13 | $ curl -X POST \
14 | -H "Content-Type: application/json" \
15 | -d '{"username":"ghost-bot", "icon_emoji": ":ghost:", "text":"BOO!"}' \
16 | "http://localhost:8080/hook?inputType=slack&outputType=glip&url=11112222-3333-4444-5555-666677778888"
17 | ```
18 |
19 | ## Using `application/x-www-form-urlencoded`
20 |
21 | ```bash
22 | $ curl -X POST \
23 | --data-urlencode 'payload={"username":"ghost-bot", "icon_emoji": ":ghost:", text":"BOO!"}' \
24 | "http://localhost:8080/hook?inputType=slack&outputType=glip&url=11112222-3333-4444-5555-666677778888"
25 | ```
26 |
27 | ## Using `multipart/form-data`
28 |
29 | ```bash
30 | $ curl -X POST \
31 | -F 'payload={"username":"ghost-bot", "icon_emoji": ":ghost:", text":"BOO!"}' \
32 | "http://localhost:8080/hook?inputType=slack&outputType=glip&url=11112222-3333-4444-5555-666677778888"
33 | ```
34 |
35 | ## Using Community Ruby SDK
36 |
37 | This has been tested using:
38 |
39 | * [https://github.com/rikas/slack-poster](https://github.com/rikas/slack-poster)
40 |
41 | ```ruby
42 | require 'slack/poster'
43 |
44 | url = 'http://localhost:8080/hook?inputType=slack&outputType=glip&url=11112222-3333-4444-5555-666677778888'
45 |
46 | opts = {
47 | username: 'Ghost Bot [Bot]',
48 | icon_emoji: ':ghost:'
49 | }
50 |
51 | poster = Slack::Poster.new url, opts
52 | poster.send_message 'BOO!'
53 | ```
--------------------------------------------------------------------------------
/docs/icons/icon_opsgenie.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/icons/icon_pingdom.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
23 |
--------------------------------------------------------------------------------
/docs/handlers/helpscout/event-example_customer-created.json:
--------------------------------------------------------------------------------
1 | {
2 | "id":29418,
3 | "firstName":"Vernon",
4 | "lastName":"Bear",
5 | "photoUrl":"http://twitter.com/img/some-avatar.jpg",
6 | "photoType":"twitter",
7 | "gender":"Male",
8 | "age":"30-35",
9 | "organization":"Acme, Inc",
10 | "jobTitle":"CEO and Co-Founder",
11 | "location":"Greater Dallas/FT Worth Area",
12 | "background":"I've worked with Vernon before and he's really great.",
13 | "createdAt":"2012-07-23T12:34:12Z",
14 | "modifiedAt":"2012-07-24T20:18:33Z",
15 | "address":{
16 | "id":1234,
17 | "lines":[
18 | "123 West Main St",
19 | "Suite 123"
20 | ],
21 | "city":"Dallas",
22 | "state":"TX",
23 | "postcalCode":"74206",
24 | "country":"US",
25 | "createdAt":"2012-07-23T12:34:12Z",
26 | "modifiedAt":"2012-07-24T20:18:33Z"
27 | },
28 | "socialProfiles":[
29 | {
30 | "id":9184,
31 | "value":"https://twitter.com/helpscout",
32 | "type":"twitter"
33 | }
34 | ],
35 | "emails":[
36 | {
37 | "id":98131,
38 | "value":"vbear@mywork.com",
39 | "location":"work"
40 | }
41 | ],
42 | "phones":[
43 | {
44 | "id":22381,
45 | "value":"222-333-4444 ",
46 | "location":"home"
47 | }
48 | ],
49 | "chats":[
50 | {
51 | "id":77183,
52 | "value":"jsprout",
53 | "type":"aim"
54 | }
55 | ],
56 | "websites":[
57 | {
58 | "id":5584,
59 | "value":"http://www.somewhere.com"
60 | }
61 | ]
62 | }
--------------------------------------------------------------------------------
/docs/icons/icon_elasticsearch.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pkg/config/interface_constants.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import "strings"
4 |
5 | const (
6 | ParamNameAdapters = "adapters"
7 | ParamNameActivityDefault = "defaultActivity"
8 | ParamNameIconDefault = "defaultIcon"
9 | ParamNameInputType = "inputType"
10 | ParamNameOutputType = "outputType"
11 | ParamNameOutputFormat = "outputFormat" // `card`, `adaptivecard`, `nocard`. Default is `card`.
12 | ParamNameOutputURL = "outputURL"
13 | ParamNameToken = "token"
14 | EnvPath = "ENV_PATH"
15 | EnvEngine = "CHATHOOKS_ENGINE" // awslambda, nethttp, fasthttp
16 | EnvTokens = "CHATHOOKS_TOKENS"
17 | EnvWebhookURL = "CHATHOOKS_URL"
18 | EnvHomeURL = "CHATHOOKS_HOME_URL"
19 | ErrRequiredTokenNotFound = "401.01 Required Token Not Found"
20 | ErrRequiredTokenNotValid = "401.02 Required Token Not Valid"
21 | // ParamNameURL = "url" // legacy. deprecated.
22 |
23 | ParamNameOutputFormatNocard = "nocard"
24 | ParamNameOutputFormatCard = "card"
25 | ParamNameOutputFormatAdaptivecard = "adaptivecard"
26 | )
27 |
28 | func MustParseOutputFormat(input string) string {
29 | input = strings.ToLower(strings.TrimSpace(input))
30 | switch input {
31 | case ParamNameOutputFormatNocard:
32 | return ParamNameOutputFormatNocard
33 | case ParamNameOutputFormatNocard + "s":
34 | return ParamNameOutputFormatNocard
35 | case ParamNameOutputFormatCard:
36 | return ParamNameOutputFormatCard
37 | case ParamNameOutputFormatCard + "s":
38 | return ParamNameOutputFormatCard
39 | case ParamNameOutputFormatAdaptivecard:
40 | return ParamNameOutputFormatAdaptivecard
41 | case ParamNameOutputFormatAdaptivecard + "s":
42 | return ParamNameOutputFormatAdaptivecard
43 | default:
44 | return ""
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/pkg/handlers/confluence/handler_confluence_out_test.go:
--------------------------------------------------------------------------------
1 | package confluence
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/grokify/chathooks/pkg/config"
7 | )
8 |
9 | var ConfigurationTests = []struct {
10 | v int
11 | want string
12 | }{
13 | {8080, ":8080"}}
14 |
15 | func TestConfluence(t *testing.T) {
16 | for _, tt := range ConfigurationTests {
17 | cfg := config.Configuration{
18 | Port: tt.v}
19 |
20 | addr := cfg.Address()
21 | if tt.want != addr {
22 | t.Errorf("Configuration.Address(%v): want %v, got %v", tt.v, tt.want, addr)
23 | }
24 | }
25 | }
26 |
27 | func CommentCreated() []byte {
28 | bytes := []byte(`{
29 | "comment": {
30 | "spaceKey": "~admin",
31 | "parent": {
32 | "spaceKey": "~admin",
33 | "modificationDate": 1471926079631,
34 | "creatorKey": "ff80808154510724015451074c160001",
35 | "creatorName": "admin",
36 | "lastModifierKey": "ff80808154510724015451074c160001",
37 | "self": "https://cloud-development-environment.atlassian.net/wiki/display/~admin/Some+random+test+page",
38 | "lastModifierName": "admin",
39 | "id": 16777227,
40 | "title": "Some random test page",
41 | "creationDate": 1471926079631,
42 | "version": 1
43 | },
44 | "modificationDate": 1471926091465,
45 | "creatorKey": "ff80808154510724015451074c160001",
46 | "creatorName": "admin",
47 | "lastModifierKey": "ff80808154510724015451074c160001",
48 | "self": "https://cloud-development-environment/wiki/display/~admin/Some+random+test+page?focusedCommentId=16777228#comment-16777228",
49 | "lastModifierName": "admin",
50 | "id": 16777228,
51 | "creationDate": 1471926091465,
52 | "version": 1
53 | },
54 | "user": "admin",
55 | "userKey": "ff80808154510724015451074c160001",
56 | "timestamp": 1471926091468,
57 | "username": "admin"
58 | }`)
59 | return bytes
60 | }
61 |
--------------------------------------------------------------------------------
/docs/handlers/runscope/event-example_notification.json:
--------------------------------------------------------------------------------
1 | {
2 | "variables":{
3 | "foo":"bar",
4 | "baz":"qux"
5 | },
6 | "test_id":"76598752-cbda-4e1d-820f-6274a62f74ff",
7 | "test_name":"Buckets Test",
8 | "test_run_id":"9c15aa62-21f0-48f2-a819-c99bdf8e4543",
9 | "team_id":"6b9c7f65-9e11-4f77-85ad-e6ee7a28232d",
10 | "team_name":"Acme Inc.",
11 | "environment_uuid":"98290cfc-a008-4ab7-9ea4-8906f12b228f",
12 | "environment_name":"Staging Settings",
13 | "bucket_name":"Rocket Sled",
14 | "bucket_key":"bucket_key",
15 | "test_url":"https://www.runscope.com/radar/bucket_key/76598752-cbda-4e1d-820f-6274a62f74ff",
16 | "test_run_url":"https://www.runscope.com/radar/bucket_key/76598752-cbda-4e1d-820f-6274a62f74ff/results/9c15aa62-21f0-48f2-a819-c99bdf8e4543",
17 | "trigger_url":"https://api.runscope.com/radar/09039249-fdfd-4e1d-820f-6274a62f74ff/trigger",
18 | "result":"fail",
19 | "started_at":1384281308.548077,
20 | "finished_at":1384281310.680218,
21 | "agent":null,
22 | "region":"us1",
23 | "region_name":"US East - Northern Virginia",
24 | "initial_variables":{
25 |
26 | },
27 | "requests":[
28 | {
29 | "url":"https://api.runscope.com/",
30 | "variables":{
31 | "fail":0,
32 | "total":1,
33 | "pass":1
34 | },
35 | "assertions":{
36 | "fail":0,
37 | "total":2,
38 | "pass":2
39 | },
40 | "scripts":{
41 | "fail":0,
42 | "total":1,
43 | "pass":1
44 | },
45 | "result":"pass",
46 | "method":"GET",
47 | "response_time_ms":123,
48 | "response_size_bytes":2048,
49 | "response_status_code":"200",
50 | "note":"Root URL"
51 | }
52 | ]
53 | }
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/grokify/chathooks
2 |
3 | // +heroku goVersion go1.22
4 | go 1.24.0
5 |
6 | toolchain go1.24.1
7 |
8 | require (
9 | github.com/apex/gateway v1.1.2
10 | github.com/aws/aws-lambda-go v1.50.0
11 | github.com/buaazp/fasthttprouter v0.1.1
12 | github.com/caarlos0/env/v9 v9.0.0
13 | github.com/google/go-querystring v1.1.0
14 | github.com/grokify/commonchat v0.3.18
15 | github.com/grokify/mogo v0.72.0
16 | github.com/grokify/sogo v0.12.12
17 | github.com/jessevdk/go-flags v1.6.1
18 | github.com/joho/godotenv v1.5.1
19 | github.com/microcosm-cc/bluemonday v1.0.27
20 | github.com/rs/zerolog v1.34.0
21 | github.com/tidwall/gjson v1.18.0
22 | github.com/valyala/fasthttp v1.68.0
23 | github.com/valyala/quicktemplate v1.8.0
24 | )
25 |
26 | require (
27 | github.com/andybalholm/brotli v1.2.0 // indirect
28 | github.com/aymerick/douceur v0.2.0 // indirect
29 | github.com/caarlos0/env/v11 v11.3.1 // indirect
30 | github.com/derekstavis/go-qs v0.0.0-20250518184349-717ef4cb7534 // indirect
31 | github.com/gorilla/css v1.0.1 // indirect
32 | github.com/gorilla/mux v1.8.1 // indirect
33 | github.com/grokify/bitcoinmath v0.1.0 // indirect
34 | github.com/grokify/go-glip v0.5.21 // indirect
35 | github.com/huandu/xstrings v1.5.0 // indirect
36 | github.com/json-iterator/go v1.1.12 // indirect
37 | github.com/klauspost/compress v1.18.1 // indirect
38 | github.com/mattn/go-colorable v0.1.14 // indirect
39 | github.com/mattn/go-isatty v0.0.20 // indirect
40 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
41 | github.com/modern-go/reflect2 v1.0.2 // indirect
42 | github.com/pkg/errors v0.9.1 // indirect
43 | github.com/tidwall/match v1.2.0 // indirect
44 | github.com/tidwall/pretty v1.2.1 // indirect
45 | github.com/valyala/bytebufferpool v1.0.0 // indirect
46 | golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 // indirect
47 | golang.org/x/net v0.47.0 // indirect
48 | golang.org/x/sys v0.38.0 // indirect
49 | golang.org/x/text v0.31.0 // indirect
50 | )
51 |
--------------------------------------------------------------------------------
/docs/handlers/statuspage/event-example_incident-updates-create.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta":{
3 | "unsubscribe":"http://statustest.flyingkleinbrothers.com:5000/?unsubscribe=j0vqr9kl3513",
4 | "documentation":"http://doers.statuspage.io/customer-notifications/webhooks/"
5 | },
6 | "page":{
7 | "id":"j2mfxwj97wnj",
8 | "status_indicator":"critical",
9 | "status_description":"Major System Outage"
10 | },
11 | "incident":{
12 | "backfilled":false,
13 | "created_at":"2013-05-29T15:08:51-06:00",
14 | "impact":"critical",
15 | "impact_override":null,
16 | "monitoring_at":"2013-05-29T16:07:53-06:00",
17 | "postmortem_body":null,
18 | "postmortem_body_last_updated_at":null,
19 | "postmortem_ignored":false,
20 | "postmortem_notified_subscribers":false,
21 | "postmortem_notified_twitter":false,
22 | "postmortem_published_at":null,
23 | "resolved_at":null,
24 | "scheduled_auto_transition":false,
25 | "scheduled_for":null,
26 | "scheduled_remind_prior":false,
27 | "scheduled_reminded_at":null,
28 | "scheduled_until":null,
29 | "shortlink":"http://j.mp/18zyDQx",
30 | "status":"monitoring",
31 | "updated_at":"2013-05-29T16:30:35-06:00",
32 | "id":"lbkhbwn21v5q",
33 | "organization_id":"j2mfxwj97wnj",
34 | "incident_updates":[
35 | {
36 | "body":"The cloud, located in Norther Virginia, has once again gone the way of the dodo.",
37 | "created_at":"2013-05-29T15:08:51-06:00",
38 | "display_at":"2013-05-29T15:08:51-06:00",
39 | "status":"investigating",
40 | "twitter_updated_at":null,
41 | "updated_at":"2013-05-29T15:28:51-06:00",
42 | "wants_twitter_update":false,
43 | "id":"qbbsfhy5s9kk",
44 | "incident_id":"lbkhbwn21v5q"
45 | }
46 | ],
47 | "name":"Virginia Is Down"
48 | }
49 | }
--------------------------------------------------------------------------------
/docs/handlers/userlike/README.md:
--------------------------------------------------------------------------------
1 | How to add a Userlike Bot
2 | =========================
3 |
4 | ## Configuring Webhook
5 |
6 | Use the following steps to configure a webhook connection in Userlike.
7 |
8 | 1. Login to *Userlike* and then, on the left navigation menu, click **Config**.
9 | 2. On the *Config* menu, click **Addons Settings**.
10 | 3. In the *SERVICE* column and the *API* row, click the **Edit** icon in the *ACTION* column to display the *Configure Callback API* page.
11 | 4. In the *Configure* section's **Callback URL** field, enter your Userlike proxy URL.
12 | 5. Select one or more events in the next sections that will trigger a webhook alert message, and then click **Update Settings**.
13 |
14 | ## Events
15 |
16 | The following is a list of events from [Userlike's API addon page](https://www.userlike.com/en/public/tutorial/addon/api).
17 |
18 | | TYPE | EVENT | DESCRIPTION |
19 | |------|-------|-------------|
20 | | `offline_message` | `receive` | Receive a callback for each new offline message you receive. |
21 | | `chat_meta` | `start` | Receive a callback for each new chat session. |
22 | | `chat_meta` | `forward` | Receive a callback when are chat session gets forwarded. |
23 | | `chat_meta` | `rating` | Receive a callback when a chat session receives a rating. |
24 | | `chat_meta` | `feedback` | Receive a callback when a chat session receives a feedback. |
25 | | `chat_meta` | `survey` | Receive a callback when a chat session receives a survey. |
26 | | `chat_meta` | `receive` | Receive a callback when a chat session ends and the conversation is finished. |
27 | | `chat_meta` | `goal` | Receive a callback when a goal was reached. |
28 | | `chat_widget` | `config` | Receive a callback when a chat widget configuration changes. |
29 | | `operator` | `online` | Receive a callback when an operator goes online. |
30 | | `operator` | `offline` | Receive a callback when an operator goes offline. |
31 | | `operator` | `away` | Receive a callback when an operator goes away. |
32 | | `operator` | `back` | Receive a callback when an operator comes back. |
33 |
--------------------------------------------------------------------------------
/docs/handlers/trello/event-example_notification.json:
--------------------------------------------------------------------------------
1 | {
2 | "action":{
3 | "id":"51f9424bcd6e040f3c002412",
4 | "idMemberCreator":"4fc78a59a885233f4b349bd9",
5 | "data":{
6 | "board":{
7 | "name":"Trello Development",
8 | "id":"4d5ea62fd76aa1136000000c"
9 | },
10 | "card":{
11 | "idShort":1458,
12 | "name":"Webhooks",
13 | "id":"51a79e72dbb7e23c7c003778"
14 | },
15 | "voted":true
16 | },
17 | "type":"voteOnCard",
18 | "date":"2013-07-31T16:58:51.949Z",
19 | "memberCreator":{
20 | "id":"4fc78a59a885233f4b349bd9",
21 | "avatarHash":"2da34d23b5f1ac1a20e2a01157bfa9fe",
22 | "fullName":"Doug Patti",
23 | "initials":"DP",
24 | "username":"doug"
25 | }
26 | },
27 | "model":{
28 | "id":"4d5ea62fd76aa1136000000c",
29 | "name":"Trello Development",
30 | "desc":"Trello board used by the Trello team to track work on Trello. How meta!\n\nThe development of the Trello API is being tracked at https://trello.com/api\n\nThe development of Trello Mobile applications is being tracked at https://trello.com/mobile",
31 | "closed":false,
32 | "idOrganization":"4e1452614e4b8698470000e0",
33 | "pinned":true,
34 | "url":"https://trello.com/b/nC8QJJoZ/trello-development",
35 | "prefs":{
36 | "permissionLevel":"public",
37 | "voting":"public",
38 | "comments":"public",
39 | "invitations":"members",
40 | "selfJoin":false,
41 | "cardCovers":true,
42 | "canBePublic":false,
43 | "canBeOrg":false,
44 | "canBePrivate":false,
45 | "canInvite":true
46 | },
47 | "labelNames":{
48 | "yellow":"Infrastructure",
49 | "red":"Bug",
50 | "purple":"Repro'd",
51 | "orange":"Feature",
52 | "green":"Mobile",
53 | "blue":"Verified"
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/docs/handlers/paypal/event-example_payment-authorization-created.json:
--------------------------------------------------------------------------------
1 | {
2 | "id":"8PT597110X687430LKGECATA",
3 | "create_time":"2013-06-25T21:41:28Z",
4 | "resource_type":"authorization",
5 | "event_type":"PAYMENT.AUTHORIZATION.CREATED",
6 | "summary":"A payment authorization was created",
7 | "resource":{
8 | "id":"2DC87612EK520411B",
9 | "create_time":"2013-06-25T21:39:15Z",
10 | "update_time":"2013-06-25T21:39:17Z",
11 | "state":"authorized",
12 | "amount":{
13 | "total":"7.47",
14 | "currency":"USD",
15 | "details":{
16 | "subtotal":"7.47"
17 | }
18 | },
19 | "parent_payment":"PAY-36246664YD343335CKHFA4AY",
20 | "valid_until":"2013-07-24T21:39:15Z",
21 | "links":[
22 | {
23 | "href":"https://api.sandbox.paypal.com/v1/payments/authorization/2DC87612EK520411B",
24 | "rel":"self",
25 | "method":"GET"
26 | },
27 | {
28 | "href":"https://api.sandbox.paypal.com/v1/payments/authorization/2DC87612EK520411B/capture",
29 | "rel":"capture",
30 | "method":"POST"
31 | },
32 | {
33 | "href":"https://api.sandbox.paypal.com/v1/payments/authorization/2DC87612EK520411B/void",
34 | "rel":"void",
35 | "method":"POST"
36 | },
37 | {
38 | "href":"https://api.sandbox.paypal.com/v1/payments/payment/PAY-36246664YD343335CKHFA4AY",
39 | "rel":"parent_payment",
40 | "method":"GET"
41 | }
42 | ]
43 | },
44 | "links":[
45 | {
46 | "href":"https://api.sandbox.paypal.com/v1/notfications/webhooks-events/8PT597110X687430LKGECATA",
47 | "rel":"self",
48 | "method":"GET"
49 | },
50 | {
51 | "href":"https://api.sandbox.paypal.com/v1/notfications/webhooks-events/8PT597110X687430LKGECATA/resend",
52 | "rel":"resend",
53 | "method":"POST"
54 | }
55 | ]
56 | }
--------------------------------------------------------------------------------
/pkg/config/configuration.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "encoding/json"
5 | "net/url"
6 | "os"
7 | "path"
8 | "strconv"
9 |
10 | env "github.com/caarlos0/env/v9"
11 | "github.com/rs/zerolog"
12 | )
13 |
14 | const (
15 | DocsHandlersSrcDir = "github.com/grokify/chathooks/docs/handlers"
16 | IconBaseURL = "http://grokify.github.io/chathooks/icons/"
17 | EmojiURLFormat = "https://grokify.github.io/emoji/assets/images/%s.png"
18 |
19 | InfoInputMessageParseBegin = "INFO - Input Message Parse Begin"
20 | ErrorInputMessageParseFailed = "FAIL - Input Message Parse Failed"
21 | )
22 |
23 | func DocsHandlersDir() string {
24 | return path.Join(os.Getenv("GOPATH"), "src", DocsHandlersSrcDir)
25 | }
26 |
27 | // Configuration is the webhook proxy configuration struct.
28 | type Configuration struct {
29 | Port int `env:"PORT" envDefault:"3000"`
30 | Engine string `env:"CHATHOOKS_ENGINE" envDefault:"fasthttp"`
31 | HomeURL string `env:"CHATHOOKS_HOME_URL"`
32 | WebhookURL string `env:"CHATHOOKS_WEBHOOK_URL"`
33 | Tokens []string `env:"CHATHOOKS_TOKENS" envSeparator:","`
34 | LogFormat string `env:"CHATHOOKS_LOG_FORMAT"`
35 | EmojiURLFormat string
36 | IconBaseURL string
37 | LogLevel zerolog.Level
38 | }
39 |
40 | func NewConfigurationEnv() (Configuration, error) {
41 | cfg := Configuration{}
42 | if err := env.Parse(&cfg); err != nil {
43 | return cfg, err
44 | }
45 | cfg.EmojiURLFormat = EmojiURLFormat
46 | cfg.IconBaseURL = IconBaseURL
47 | cfg.LogLevel = 1
48 | return cfg, nil
49 | }
50 |
51 | func ReadConfigurationFile(filepath string) (Configuration, error) {
52 | var configuration Configuration
53 | bytes, err := os.ReadFile(filepath)
54 | if err != nil {
55 | return configuration, err
56 | }
57 | err = json.Unmarshal(bytes, &configuration)
58 | return configuration, err
59 | }
60 |
61 | // Address returns the port address as a string with a `:` prefix
62 | func (c *Configuration) Address() string {
63 | return ":" + strconv.Itoa(c.Port)
64 | }
65 |
66 | func (c *Configuration) GetAppIconURL(appSlug string) (*url.URL, error) {
67 | return buildIconURL(c.IconBaseURL, appSlug)
68 | }
69 |
--------------------------------------------------------------------------------
/docs/handlers/travisci/event-example_build.json:
--------------------------------------------------------------------------------
1 | {
2 | "id":1,
3 | "number":"1",
4 | "status":null,
5 | "started_at":null,
6 | "finished_at":null,
7 | "status_message":"Passed",
8 | "commit":"62aae5f70ceee39123ef",
9 | "branch":"master",
10 | "message":"the commit message",
11 | "compare_url":"https://github.com/svenfuchs/minimal/compare/master...develop",
12 | "committed_at":"2011-11-11T11: 11: 11Z",
13 | "committer_name":"Sven Fuchs",
14 | "committer_email":"svenfuchs@artweb-design.de",
15 | "author_name":"Sven Fuchs",
16 | "author_email":"svenfuchs@artweb-design.de",
17 | "type":"push",
18 | "build_url":"https://travis-ci.org/svenfuchs/minimal/builds/1",
19 | "repository":{
20 | "id":1,
21 | "name":"minimal",
22 | "owner_name":"svenfuchs",
23 | "url":"http://github.com/svenfuchs/minimal"
24 | },
25 | "config":{
26 | "notifications":{
27 | "webhooks":[
28 | "http://evome.fr/notifications",
29 | "http://example.com/"
30 | ]
31 | }
32 | },
33 | "matrix":[
34 | {
35 | "id":2,
36 | "repository_id":1,
37 | "number":"1.1",
38 | "state":"created",
39 | "started_at":null,
40 | "finished_at":null,
41 | "config":{
42 | "notifications":{
43 | "webhooks":[
44 | "http://evome.fr/notifications",
45 | "http://example.com/"
46 | ]
47 | }
48 | },
49 | "status":null,
50 | "log":"",
51 | "result":null,
52 | "parent_id":1,
53 | "commit":"62aae5f70ceee39123ef",
54 | "branch":"master",
55 | "message":"the commit message",
56 | "committed_at":"2011-11-11T11: 11: 11Z",
57 | "committer_name":"Sven Fuchs",
58 | "committer_email":"svenfuchs@artweb-design.de",
59 | "author_name":"Sven Fuchs",
60 | "author_email":"svenfuchs@artweb-design.de",
61 | "compare_url":"https://github.com/svenfuchs/minimal/compare/master...develop"
62 | }
63 | ]
64 | }
--------------------------------------------------------------------------------
/pkg/config/icons.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "errors"
5 | "net/url"
6 | )
7 |
8 | const (
9 | DefaultIconFile = "icon_webhookrc_512x512.png"
10 | )
11 |
12 | var Icons = map[string]string{
13 | "aha": "icon_aha_256x256.png",
14 | "appsignal": "icon_appsignal_400x400.png",
15 | "apteligent": "icon_apteligent_496x496.png",
16 | "bugsnag": "icon_bugsnag_512x512.png",
17 | "circleci": "icon_circleci_128x128.png",
18 | "codeship": "icon_codeship_512x512.png",
19 | "confluence": "icon_confluence_256x256.png",
20 | "datadog": "icon_datadog_512x512.png",
21 | "deskdotcom": "icon_deskdotcom_400x400.png",
22 | "enchant": "icon_enchant_400x400.png",
23 | "gosquared": "icon_gosquared_128x128.png",
24 | "heroku": "icon_heroku_512x512.png",
25 | "librato": "icon_librato_128x128.png",
26 | "magnumci": "icon_magnumci_400x400.png",
27 | "marketo": "icon_marketo_250x250.png",
28 | "opsgenie": "icon_opsgenie_128x128.png",
29 | "papertrail": "icon_papertrail_128x128.png",
30 | "pingdom": "icon_pingdom_512x512.png",
31 | "raygun": "icon_raygun_512x512.png",
32 | "runscope": "icon_runscope_400x400.png",
33 | "semaphore": "icon_semaphore_512x512.png",
34 | "statuspage": "icon_statuspage_512x512.png",
35 | "travisci": "icon_travisci_225x225.png",
36 | "userlike": "icon_userlike_512x512.png",
37 | "victorops": "icon_victorops_225x225.png",
38 | "wootric": "icon_wootric_200x200.png"}
39 |
40 | func joinURL(baseURL string, pathPart string) (*url.URL, error) {
41 | u, err := url.Parse(pathPart)
42 | if err != nil {
43 | return &url.URL{}, nil
44 | }
45 | base, err := url.Parse(baseURL)
46 | if err != nil {
47 | return &url.URL{}, nil
48 | }
49 | return base.ResolveReference(u), nil
50 | }
51 |
52 | func getAppIconFile(appSlug string) (string, error) {
53 | if file, ok := Icons[appSlug]; ok {
54 | return file, nil
55 | }
56 | return "", errors.New("E_NO_APP_ICON_FILE")
57 | }
58 |
59 | func getAppIconFileWithDefault(appSlug string) string {
60 | file, err := getAppIconFile(appSlug)
61 | if err != nil {
62 | file = DefaultIconFile
63 | }
64 | return file
65 | }
66 |
67 | func buildIconURL(baseURL string, appSlug string) (*url.URL, error) {
68 | iconFile := getAppIconFileWithDefault(appSlug)
69 | return joinURL(baseURL, iconFile)
70 | }
71 |
--------------------------------------------------------------------------------
/pkg/adapters/adapter.go:
--------------------------------------------------------------------------------
1 | package adapters
2 |
3 | import (
4 | "github.com/grokify/commonchat"
5 | "github.com/rs/zerolog/log"
6 | "github.com/valyala/fasthttp"
7 |
8 | "github.com/grokify/chathooks/pkg/models"
9 | )
10 |
11 | var (
12 | ShowDisplayName = false
13 | )
14 |
15 | type AdapterSet struct {
16 | Adapters map[string]commonchat.Adapter
17 | }
18 |
19 | func NewAdapterSet() AdapterSet {
20 | return AdapterSet{Adapters: map[string]commonchat.Adapter{}}
21 | }
22 |
23 | func (set *AdapterSet) SendWebhooks(hookData models.HookData) []models.ErrorInfo {
24 | errs := []models.ErrorInfo{}
25 | hookOpts := map[string]any{}
26 | if hookData.OutputFormat == "nocard" {
27 | hookOpts["useAttachments"] = false
28 | log.Debug().
29 | Str("hookData.outputFormat", hookData.OutputFormat).
30 | Bool("hookOpts.useAttachments", hookOpts["useAttachments"].(bool)).
31 | Msg("AdapterSet.SendWebhooks.HookOpts")
32 | }
33 | if len(hookData.OutputType) > 0 && len(hookData.OutputURL) > 0 {
34 | if adapter, ok := set.Adapters[hookData.OutputType]; ok {
35 | var msg any
36 | req, res, err := adapter.SendWebhook(
37 | hookData.OutputURL, hookData.CanonicalMessage, &msg, hookOpts)
38 | log.Debug().
39 | Str("output_type", hookData.OutputType).
40 | Int("status_code", res.StatusCode()).
41 | Str("output_url", hookData.OutputURL).
42 | Str("body", string(res.Body())).
43 | Msg("ADAPTER_API_REQ_RES_INFO")
44 | errs = set.procResponse(errs, req, res, err)
45 | }
46 | }
47 | for _, namedAdapter := range hookData.OutputNames {
48 | if adapter, ok := set.Adapters[namedAdapter]; ok {
49 | var msg any
50 | req, res, err := adapter.SendMessage(
51 | hookData.CanonicalMessage, &msg, hookOpts)
52 | errs = set.procResponse(errs, req, res, err)
53 | }
54 | }
55 | return errs
56 | }
57 |
58 | func (set *AdapterSet) procResponse(errs []models.ErrorInfo, req *fasthttp.Request, res *fasthttp.Response, err error) []models.ErrorInfo {
59 | if err != nil {
60 | errs = append(errs, models.ErrorInfo{StatusCode: 500, Body: []byte(err.Error())})
61 | } else if res.StatusCode() > 299 {
62 | errs = append(errs, models.ErrorInfo{
63 | StatusCode: res.StatusCode(),
64 | Body: res.Body(),
65 | })
66 | }
67 | fasthttp.ReleaseRequest(req)
68 | fasthttp.ReleaseResponse(res)
69 | return errs
70 | }
71 |
--------------------------------------------------------------------------------
/docs/icons/icon_heroku.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
59 |
--------------------------------------------------------------------------------
/docs/handlers/gosquared/event-example_live-chat.json:
--------------------------------------------------------------------------------
1 | {
2 | "version":"0.0.1",
3 | "site_token":"GSN-67890-A",
4 | "timestamp":"2017-05-02T05:19:34.252Z",
5 | "person":{
6 | "id":"Anon Chat: bba4b6264b073a17c74f1b0da7720114",
7 | "email":"",
8 | "name":"",
9 | "avatar":"",
10 | "chat":{
11 | "archived":null,
12 | "latest":{
13 | "message":{
14 | "type":"message",
15 | "id":"167c06cf-ff7c-4d09-880c-5533795f9673",
16 | "content":"hello world",
17 | "timestamp":1493702374252,
18 | "from":"client",
19 | "private":false,
20 | "session":{
21 | "title":"",
22 | "href":"http://127.0.0.1:2015/"
23 | },
24 | "data":{
25 |
26 | },
27 | "entities":[
28 |
29 | ]
30 | },
31 | "timestamp":1493702374252
32 | },
33 | "agent":{
34 | "assigned":"31e043150da1d922ff90f3e54940600d",
35 | "read":1493373060143,
36 | "delivered":1493372637305
37 | },
38 | "client":{
39 | "read":1493702374252,
40 | "delivered":1493372587362
41 | }
42 | },
43 | "lead":{
44 | "email":"johndoe@example.com"
45 | },
46 | "status":"",
47 | "presence":"online",
48 | "_anon":{
49 | "name":"Anon: Steel Blue Shoeprints",
50 | "color":"#4B77BE",
51 | "shape":"human-shoes-footprints"
52 | },
53 | "_links":[
54 | {
55 | "rel":"self",
56 | "href":"https://api.gosquared.com/chat/v1/chats/Anon%20Chat%3A%20bba4b6264b073a17c74f1b0da7720114",
57 | "method":"GET"
58 | }
59 | ]
60 | },
61 | "message":{
62 | "type":"message",
63 | "id":"167c06cf-ff7c-4d09-880c-5533795f9673",
64 | "content":"hello world",
65 | "timestamp":1493702374252,
66 | "from":"client",
67 | "private":false,
68 | "session":{
69 | "title":"",
70 | "href":"http://127.0.0.1:2015/"
71 | },
72 | "data":{
73 |
74 | },
75 | "entities":[
76 |
77 | ],
78 | "person_id":"Anon Chat: bba4b6264b073a17c74f1b0da7720114"
79 | }
80 | }
--------------------------------------------------------------------------------
/docs/handlers/statuspage/event-example_incident-updates.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta":{
3 | "unsubscribe":"http://statustest.flyingkleinbrothers.com:5000/?unsubscribe=j0vqr9kl3513",
4 | "documentation":"http://doers.statuspage.io/customer-notifications/webhooks/"
5 | },
6 | "page":{
7 | "id":"j2mfxwj97wnj",
8 | "status_indicator":"critical",
9 | "status_description":"Major System Outage"
10 | },
11 | "incident":{
12 | "backfilled":false,
13 | "created_at":"2013-05-29T15:08:51-06:00",
14 | "impact":"critical",
15 | "impact_override":null,
16 | "monitoring_at":"2013-05-29T16:07:53-06:00",
17 | "postmortem_body":null,
18 | "postmortem_body_last_updated_at":null,
19 | "postmortem_ignored":false,
20 | "postmortem_notified_subscribers":false,
21 | "postmortem_notified_twitter":false,
22 | "postmortem_published_at":null,
23 | "resolved_at":null,
24 | "scheduled_auto_transition":false,
25 | "scheduled_for":null,
26 | "scheduled_remind_prior":false,
27 | "scheduled_reminded_at":null,
28 | "scheduled_until":null,
29 | "shortlink":"http://j.mp/18zyDQx",
30 | "status":"monitoring",
31 | "updated_at":"2013-05-29T16:30:35-06:00",
32 | "id":"lbkhbwn21v5q",
33 | "organization_id":"j2mfxwj97wnj",
34 | "incident_updates":[
35 | {
36 | "body":"A fix has been implemented and we are monitoring the results.",
37 | "created_at":"2013-05-29T16:07:53-06:00",
38 | "display_at":"2013-05-29T16:07:53-06:00",
39 | "status":"monitoring",
40 | "twitter_updated_at":null,
41 | "updated_at":"2013-05-29T16:09:09-06:00",
42 | "wants_twitter_update":false,
43 | "id":"drfcwbnpxnr6",
44 | "incident_id":"lbkhbwn21v5q"
45 | },
46 | {
47 | "body":"We are waiting for the cloud to come back online and will update when we have further information",
48 | "created_at":"2013-05-29T15:18:51-06:00",
49 | "display_at":"2013-05-29T15:18:51-06:00",
50 | "status":"identified",
51 | "twitter_updated_at":null,
52 | "updated_at":"2013-05-29T15:28:51-06:00",
53 | "wants_twitter_update":false,
54 | "id":"2rryghr4qgrh",
55 | "incident_id":"lbkhbwn21v5q"
56 | },
57 | {
58 | "body":"The cloud, located in Norther Virginia, has once again gone the way of the dodo.",
59 | "created_at":"2013-05-29T15:08:51-06:00",
60 | "display_at":"2013-05-29T15:08:51-06:00",
61 | "status":"investigating",
62 | "twitter_updated_at":null,
63 | "updated_at":"2013-05-29T15:28:51-06:00",
64 | "wants_twitter_update":false,
65 | "id":"qbbsfhy5s9kk",
66 | "incident_id":"lbkhbwn21v5q"
67 | }
68 | ],
69 | "name":"Virginia Is Down"
70 | }
71 | }
--------------------------------------------------------------------------------
/docs/handlers/pagerduty/event-example_incident_trigger.json:
--------------------------------------------------------------------------------
1 | {
2 | "messages":[
3 | {
4 | "type":"incident.trigger",
5 | "data":{
6 | "incident":{
7 | "id":"PRORDTY",
8 | "incident_number":2126,
9 | "created_on":"2016-02-22T21:02:55Z",
10 | "status":"triggered",
11 | "pending_actions":[
12 | {
13 | "type":"escalate",
14 | "at":"2016-02-22T13:07:55-08:00"
15 | },
16 | {
17 | "type":"resolve",
18 | "at":"2016-02-22T17:02:55-08:00"
19 | }
20 | ],
21 | "html_url":"https://webdemo.pagerduty.com/incidents/PRORDTY",
22 | "incident_key":"17a02d0d370d4add8e53132199614121",
23 | "service":{
24 | "id":"PDS1SN6",
25 | "name":"Production XDB Cluster",
26 | "html_url":"https://webdemo.pagerduty.com/services/PDS1SN6",
27 | "deleted_at":null,
28 | "description":"Primary production datastore."
29 | },
30 | "escalation_policy":{
31 | "id":"P5ARF12",
32 | "name":"Database Team",
33 | "deleted_at":null
34 | },
35 | "assigned_to_user":{
36 | "id":"P553OPV",
37 | "name":"Laura Haley",
38 | "email":"laura.haley@example.com",
39 | "html_url":"https://webdemo.pagerduty.com/users/P553OPV"
40 | },
41 | "trigger_summary_data":{
42 | "subject":"CPU Load High on xdb_production_echo"
43 | },
44 | "trigger_details_html_url":"https://webdemo.pagerduty.com/incidents/PRORDTY/log_entries/Q2AIXW2ZIMCI4P",
45 | "trigger_type":"web_trigger",
46 | "last_status_change_on":"2016-02-22T21:02:55Z",
47 | "last_status_change_by":null,
48 | "number_of_escalations":0,
49 | "assigned_to":[
50 | {
51 | "at":"2016-02-22T21:02:55Z",
52 | "object":{
53 | "id":"P553OPV",
54 | "name":"Laura Haley",
55 | "email":"laura.haley@example.com",
56 | "html_url":"https://webdemo.pagerduty.com/users/P553OPV",
57 | "type":"user"
58 | }
59 | }
60 | ],
61 | "urgency":"high"
62 | }
63 | },
64 | "id":"a52d3f80-d9a7-11e5-8db3-22000ad5aec9",
65 | "created_on":"2016-02-22T21:02:55Z"
66 | }
67 | ]
68 | }
--------------------------------------------------------------------------------
/docs/icons/icon_codeship.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/handlers/papertrail/event-example_notifications-array.json:
--------------------------------------------------------------------------------
1 | {
2 | "events":[
3 | {
4 | "id":7711561783320576,
5 | "received_at":"2011-05-18T20:30:02-07:00",
6 | "display_received_at":"May 18 20:30:02",
7 | "source_ip":"208.75.57.121",
8 | "source_name":"abc",
9 | "source_id":2,
10 | "hostname":"abc",
11 | "program":"CROND",
12 | "severity":"Info",
13 | "facility":"Cron",
14 | "message":"message body"
15 | },
16 | {
17 | "id":7711562567655424,
18 | "received_at":"2011-05-18T20:30:02-07:00",
19 | "display_received_at":"May 18 20:30:02",
20 | "source_ip":"208.75.57.120",
21 | "source_name":"server1",
22 | "source_id":19,
23 | "hostname":"def",
24 | "program":"CROND",
25 | "severity":"Info",
26 | "facility":"Cron",
27 | "message":"A short event"
28 | },
29 | {
30 | "id":7711561783320576,
31 | "received_at":"2011-05-18T20:30:02-07:00",
32 | "display_received_at":"May 18 20:30:02",
33 | "source_ip":"208.75.57.121",
34 | "source_name":"abc",
35 | "source_id":2,
36 | "hostname":"abc",
37 | "program":"CROND",
38 | "severity":"Info",
39 | "facility":"Cron",
40 | "message":"message body"
41 | },
42 | {
43 | "id":7711562567655424,
44 | "received_at":"2011-05-18T20:30:02-07:00",
45 | "display_received_at":"May 18 20:30:02",
46 | "source_ip":"208.75.57.120",
47 | "source_name":"server1",
48 | "source_id":19,
49 | "hostname":"def",
50 | "program":"CROND",
51 | "severity":"Info",
52 | "facility":"Cron",
53 | "message":"A short event"
54 | },
55 | {
56 | "id":7711561783320576,
57 | "received_at":"2011-05-18T20:30:02-07:00",
58 | "display_received_at":"May 18 20:30:02",
59 | "source_ip":"208.75.57.121",
60 | "source_name":"abc",
61 | "source_id":2,
62 | "hostname":"abc",
63 | "program":"CROND",
64 | "severity":"Info",
65 | "facility":"Cron",
66 | "message":"message body"
67 | },
68 | {
69 | "id":7711562567655424,
70 | "received_at":"2011-05-18T20:30:02-07:00",
71 | "display_received_at":"May 18 20:30:02",
72 | "source_ip":"208.75.57.120",
73 | "source_name":"server1",
74 | "source_id":19,
75 | "hostname":"def",
76 | "program":"CROND",
77 | "severity":"Info",
78 | "facility":"Cron",
79 | "message":"A short event"
80 | }
81 | ],
82 | "saved_search":{
83 | "id":42,
84 | "name":"Important stuff",
85 | "query":"cron OR server1",
86 | "html_edit_url":"https://papertrailapp.com/searches/42/edit",
87 | "html_search_url":"https://papertrailapp.com/searches/42"
88 | },
89 | "max_id":7711582041804800,
90 | "min_id":7711561783320576
91 | }
--------------------------------------------------------------------------------
/docs/handlers/stripe/event-example_event.json:
--------------------------------------------------------------------------------
1 | {
2 | "id":"evt_1A1RbA2eZvKYlo2CScZ8ykYw",
3 | "object":"event",
4 | "api_version":"2017-02-14",
5 | "created":1490497160,
6 | "data":{
7 | "object":{
8 | "id":"in_1A1Qet2eZvKYlo2CAPY95Tpf",
9 | "object":"invoice",
10 | "amount_due":0,
11 | "application_fee":null,
12 | "attempt_count":0,
13 | "attempted":true,
14 | "charge":null,
15 | "closed":true,
16 | "currency":"usd",
17 | "customer":"cus_4I2DPXVGMnHeJD",
18 | "date":1490493547,
19 | "description":null,
20 | "discount":null,
21 | "ending_balance":0,
22 | "forgiven":false,
23 | "lines":{
24 | "object":"list",
25 | "data":[
26 | {
27 | "id":"sub_4I2DOLbYLeFwjZ",
28 | "object":"line_item",
29 | "amount":0,
30 | "currency":"usd",
31 | "description":null,
32 | "discountable":true,
33 | "livemode":false,
34 | "metadata":{
35 |
36 | },
37 | "period":{
38 | "start":1490493480,
39 | "end":1493171880
40 | },
41 | "plan":{
42 | "id":"6milkg",
43 | "object":"plan",
44 | "amount":0,
45 | "created":1403747879,
46 | "currency":"usd",
47 | "interval":"month",
48 | "interval_count":1,
49 | "livemode":false,
50 | "metadata":{
51 |
52 | },
53 | "name":"Starter",
54 | "statement_descriptor":null,
55 | "trial_period_days":null
56 | },
57 | "proration":false,
58 | "quantity":1,
59 | "subscription":null,
60 | "subscription_item":"si_18RaBe2eZvKYlo2ChGRGCYYW",
61 | "type":"subscription"
62 | }
63 | ],
64 | "has_more":false,
65 | "total_count":1,
66 | "url":"/v1/invoices/in_1A1Qet2eZvKYlo2CAPY95Tpf/lines"
67 | },
68 | "livemode":false,
69 | "metadata":{
70 |
71 | },
72 | "next_payment_attempt":null,
73 | "paid":true,
74 | "period_end":1490493480,
75 | "period_start":1488074280,
76 | "receipt_number":null,
77 | "starting_balance":0,
78 | "statement_descriptor":null,
79 | "subscription":"sub_4I2DOLbYLeFwjZ",
80 | "subtotal":0,
81 | "tax":null,
82 | "tax_percent":null,
83 | "total":0,
84 | "webhooks_delivered_at":1490493558
85 | }
86 | },
87 | "livemode":false,
88 | "pending_webhooks":0,
89 | "request":null,
90 | "type":"invoice.payment_succeeded"
91 | }
--------------------------------------------------------------------------------
/pkg/handlers/datadog/handler_datadog_out.go:
--------------------------------------------------------------------------------
1 | package datadog
2 |
3 | import (
4 | "encoding/json"
5 |
6 | cc "github.com/grokify/commonchat"
7 |
8 | "github.com/grokify/chathooks/pkg/config"
9 | "github.com/grokify/chathooks/pkg/handlers"
10 | "github.com/grokify/chathooks/pkg/models"
11 | )
12 |
13 | const (
14 | DisplayName = "Datadog"
15 | HandlerKey = "datadog"
16 | MessageDirection = "out"
17 | DocumentationURL = "http://docs.datadoghq.com/integrations/webhooks/"
18 | MessageBodyType = models.JSON
19 | )
20 |
21 | func NewHandler() handlers.Handler {
22 | return handlers.Handler{MessageBodyType: MessageBodyType, Normalize: Normalize}
23 | }
24 |
25 | func Normalize(cfg config.Configuration, hReq handlers.HandlerRequest) (cc.Message, error) {
26 | ccMsg, err := CcMessageFromBytes(hReq.Body)
27 | if err != nil {
28 | return ccMsg, err
29 | }
30 | iconURL, err := cfg.GetAppIconURL(HandlerKey)
31 | if err == nil {
32 | ccMsg.IconURL = iconURL.String()
33 | }
34 | return ccMsg, nil
35 | }
36 |
37 | /*
38 |
39 | $ID ID of the event (ex: 1234567)
40 | $EVENT_TITLE Title of the event (ex: [Triggered] [Memory Alert])
41 | $EVENT_MSG Text of the event (ex: @webhook-url Sending to the webhook)
42 | $EVENT_TYPE Type of the event (values: metric_alert_monitor, event_alert, or service_check)
43 | $LAST_UPDATED Date when the event was last updated .
44 | $DATE Date (epoch) where the event happened (ex: 1406662672000)
45 | $AGGREG_KEY ID to aggregate events belonging together (ex: 9bd4ac313a4d1e8fae2482df7b77628)
46 | $ORG_ID ID of your organization (ex: 11023)
47 | $ORG_NAME Name of your organization (ex: Datadog)
48 | $USER User posting the event that triggered the webhook (ex: rudy)
49 | $SNAPSHOT Url of the image if the event contains a snapshot (ex: https://url.to.snpashot.com/)
50 | $LINK Url of the event (ex: https://app.datadoghq.com/event/jump_to?event_id=123456)
51 | $PRIORITY Priority of the event (values: normal or low)
52 | $TAGS Comma-separated list of the event tags (ex: monitor, name:myService, role:computing-node)
53 | $ALERT_ID ID of alert (ex: 1234)
54 | $ALERT_TITLE Title of the alert
55 | $ALERT_METRIC Name of the metric if it’s an alert (ex: system.load.1)
56 | $ALERT_SCOPE Comma-separated list of tags triggering the alert (ex: availability-zone:us-east-1a, role:computing-node)
57 | $ALERT_QUERY Query of the monitor that triggered the webhook
58 | $ALERT_STATUS Summary of the alert status (ex: system.load.1 over host:my-host was > 0 at least once during the last 1m)
59 | $ALERT_TRANSITION Type of alert notification (values: Triggered or Recovered)
60 | If you want to post your webhooks to a service requiring authentication, you can Basic HTTP authentication my modifing your URL from https://my.service.com to https://username:password@my.service.com.
61 |
62 | Example template:
63 |
64 | {
65 | "activity":"Event triggered",
66 | "body":"[Event $ID]($LINK): $EVENT_TITLE\n**Priority**\n$PRIORITY\n**Alert**\n$ALERT_STATUS"
67 | }
68 |
69 | {
70 | "activity":"Event triggered",
71 | "body":"[Event 1234567](https://app.datadoghq.com/event/jump_to?event_id=123456): [Triggered] [Memory Alert]\n**Priority**\n#PRIORITY\n**Alert**\nystem.load.1 over host:my-host was > 0 at least once during the last 1m"
72 | }
73 |
74 | */
75 |
76 | func CcMessageFromBytes(bytes []byte) (cc.Message, error) {
77 | msg := cc.Message{}
78 | err := json.Unmarshal(bytes, &msg)
79 | return msg, err
80 | }
81 |
--------------------------------------------------------------------------------
/docs/icons/icon_twitter_alt.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
67 |
--------------------------------------------------------------------------------
/docs/handlers/userlike/event-example_chat-meta_forward.json:
--------------------------------------------------------------------------------
1 | {
2 | "_event":"forward",
3 | "_type":"chat_meta",
4 | "browser_name":"Safari",
5 | "browser_os":"Mac OS X",
6 | "browser_version":"8",
7 | "chat_widget":{
8 | "id":9,
9 | "name":"Testing David"
10 | },
11 | "chat_widget_goal":{
12 | "id":null,
13 | "name":null
14 | },
15 | "client_additional01_name":null,
16 | "client_additional01_value":null,
17 | "client_additional02_name":null,
18 | "client_additional02_value":null,
19 | "client_additional03_name":null,
20 | "client_additional03_value":null,
21 | "client_email":"david@optixx.org",
22 | "client_name":"Jo",
23 | "client_uuid":"nEitxHDooFzsPhMoVn0QCw8E.L3mmogIcp+FGwXos5a4NUdZ9/uQbSCBx0wDIRVFWM+o",
24 | "created_at":"2014-12-29 11:26:24",
25 | "custom":{
26 | "basket":{
27 | "item01":{
28 | "desc":"33X Optical Zoom Camcorder Mini DV",
29 | "id":"2acefe58-91e5-11e1-beba-000c2979313a",
30 | "price":139.99,
31 | "url":"http://application/en/electronics/34-camcorder.html"
32 | },
33 | "item02":{
34 | "desc":"Home Theater System",
35 | "id":"31aca2f2-91e5-11e1-beba-000c2979313a",
36 | "long":"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
37 | "price":499.99,
38 | "url":"https://application/en/electronics/39-home-theater.html"
39 | }
40 | },
41 | "id":"428614f0-91e5-11e1-beba-000c2979313a",
42 | "ref":"3efd5462e"
43 | },
44 | "data_privacy":false,
45 | "duration":"00:00:13",
46 | "ended_at":null,
47 | "feedback_message":null,
48 | "id":71,
49 | "inital_url":"https://devel.userlike.local/en/",
50 | "loc_city":null,
51 | "loc_country":null,
52 | "loc_lat":null,
53 | "loc_lon":null,
54 | "marked_read":false,
55 | "messages":[
56 |
57 | ],
58 | "notes":[
59 |
60 | ],
61 | "operator_created":{
62 | "email":"david@userlike.com",
63 | "first_name":"David",
64 | "id":5,
65 | "last_name":"Voswinkel",
66 | "name":"David Voswinkel",
67 | "operator_group":{
68 | "id":14,
69 | "name":"Testing David"
70 | }
71 | },
72 | "operator_created_id":5,
73 | "operator_current":{
74 | "email":"beavis@userlike.com",
75 | "first_name":"Beavis",
76 | "id":13,
77 | "last_name":"",
78 | "name":"Beavis",
79 | "operator_group":{
80 | "id":8,
81 | "name":"Testing"
82 | }
83 | },
84 | "operator_current_id":13,
85 | "page_impressions":2,
86 | "post_survey_option":null,
87 | "rate":null,
88 | "referrer":null,
89 | "status":"new",
90 | "topic":null,
91 | "url":"https://devel.userlike.local/en/debug/9",
92 | "visits":10,
93 | "was_proactive":false
94 | }
--------------------------------------------------------------------------------
/docs/handlers/userlike/event-example_chat-meta_start.json:
--------------------------------------------------------------------------------
1 | {
2 | "_event":"start",
3 | "_type":"chat_meta",
4 | "browser_name":"Safari",
5 | "browser_os":"Mac OS X",
6 | "browser_version":"8",
7 | "chat_widget":{
8 | "id":9,
9 | "name":"Testing David"
10 | },
11 | "chat_widget_goal":{
12 | "id":null,
13 | "name":null
14 | },
15 | "client_additional01_name":null,
16 | "client_additional01_value":null,
17 | "client_additional02_name":null,
18 | "client_additional02_value":null,
19 | "client_additional03_name":null,
20 | "client_additional03_value":null,
21 | "client_email":"david@optixx.org",
22 | "client_name":"Jo",
23 | "client_uuid":"nEitxHDooFzsPhMoVn0QCw8E.L3mmogIcp+FGwXos5a4NUdZ9/uQbSCBx0wDIRVFWM+o",
24 | "created_at":"2014-12-29 11:26:24",
25 | "custom":{
26 | "basket":{
27 | "item01":{
28 | "desc":"33X Optical Zoom Camcorder Mini DV",
29 | "id":"2acefe58-91e5-11e1-beba-000c2979313a",
30 | "price":139.99,
31 | "url":"http://application/en/electronics/34-camcorder.html"
32 | },
33 | "item02":{
34 | "desc":"Home Theater System",
35 | "id":"31aca2f2-91e5-11e1-beba-000c2979313a",
36 | "long":"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
37 | "price":499.99,
38 | "url":"https://application/en/electronics/39-home-theater.html"
39 | }
40 | },
41 | "id":"428614f0-91e5-11e1-beba-000c2979313a",
42 | "ref":"3efd5462e"
43 | },
44 | "data_privacy":false,
45 | "duration":"00:00:13",
46 | "ended_at":null,
47 | "feedback_message":null,
48 | "id":71,
49 | "inital_url":"https://devel.userlike.local/en/",
50 | "loc_city":null,
51 | "loc_country":null,
52 | "loc_lat":null,
53 | "loc_lon":null,
54 | "marked_read":false,
55 | "messages":[
56 |
57 | ],
58 | "notes":[
59 |
60 | ],
61 | "operator_created":{
62 | "email":"david@userlike.com",
63 | "first_name":"David",
64 | "id":5,
65 | "last_name":"Voswinkel",
66 | "name":"David Voswinkel",
67 | "operator_group":{
68 | "id":14,
69 | "name":"Testing David"
70 | }
71 | },
72 | "operator_created_id":5,
73 | "operator_current":{
74 | "email":"david@userlike.com",
75 | "first_name":"David",
76 | "id":5,
77 | "last_name":"Voswinkel",
78 | "name":"David Voswinkel",
79 | "operator_group":{
80 | "id":14,
81 | "name":"Testing David"
82 | }
83 | },
84 | "operator_current_id":5,
85 | "page_impressions":2,
86 | "post_survey_option":null,
87 | "rate":null,
88 | "referrer":null,
89 | "status":"new",
90 | "topic":null,
91 | "url":"https://devel.userlike.local/en/debug/9",
92 | "visits":10,
93 | "was_proactive":false
94 | }
--------------------------------------------------------------------------------